add SFTPClient.truncate. add chmod, chown, utime, and truncate to SFTPFile. and of course tests.
This commit is contained in:
parent
8446c0bda1
commit
4be91d1c4d
|
@ -59,7 +59,7 @@ class SFTPClient (BaseSFTP):
|
||||||
An alternate way to create an SFTP client context is by using
|
An alternate way to create an SFTP client context is by using
|
||||||
L{from_transport}.
|
L{from_transport}.
|
||||||
|
|
||||||
@param sock: an open L{Channel} using the C{"sftp"} subsystem.
|
@param sock: an open L{Channel} using the C{"sftp"} subsystem
|
||||||
@type sock: L{Channel}
|
@type sock: L{Channel}
|
||||||
"""
|
"""
|
||||||
BaseSFTP.__init__(self)
|
BaseSFTP.__init__(self)
|
||||||
|
@ -84,10 +84,10 @@ class SFTPClient (BaseSFTP):
|
||||||
"""
|
"""
|
||||||
Create an SFTP client channel from an open L{Transport}.
|
Create an SFTP client channel from an open L{Transport}.
|
||||||
|
|
||||||
@param t: an open L{Transport} which is already authenticated.
|
@param t: an open L{Transport} which is already authenticated
|
||||||
@type t: L{Transport}
|
@type t: L{Transport}
|
||||||
@return: a new L{SFTPClient} object, referring to an sftp session
|
@return: a new L{SFTPClient} object, referring to an sftp session
|
||||||
(channel) across the transport.
|
(channel) across the transport
|
||||||
@rtype: L{SFTPClient}
|
@rtype: L{SFTPClient}
|
||||||
"""
|
"""
|
||||||
chan = t.open_session()
|
chan = t.open_session()
|
||||||
|
@ -185,13 +185,13 @@ class SFTPClient (BaseSFTP):
|
||||||
buffering, C{1} uses line buffering, and any number greater than 1
|
buffering, C{1} uses line buffering, and any number greater than 1
|
||||||
(C{>1}) uses that specific buffer size.
|
(C{>1}) uses that specific buffer size.
|
||||||
|
|
||||||
@param filename: name of the file to open.
|
@param filename: name of the file to open
|
||||||
@type filename: string
|
@type filename: str
|
||||||
@param mode: mode (python-style) to open in.
|
@param mode: mode (python-style) to open in
|
||||||
@type mode: string
|
@type mode: str
|
||||||
@param bufsize: desired buffering (-1 = default buffer size)
|
@param bufsize: desired buffering (-1 = default buffer size)
|
||||||
@type bufsize: int
|
@type bufsize: int
|
||||||
@return: a file object representing the open file.
|
@return: a file object representing the open file
|
||||||
@rtype: SFTPFile
|
@rtype: SFTPFile
|
||||||
|
|
||||||
@raise IOError: if the file could not be opened.
|
@raise IOError: if the file could not be opened.
|
||||||
|
@ -223,13 +223,13 @@ class SFTPClient (BaseSFTP):
|
||||||
|
|
||||||
def remove(self, path):
|
def remove(self, path):
|
||||||
"""
|
"""
|
||||||
Remove the file at the given path.
|
Remove the file at the given path. This only works on files; for
|
||||||
|
removing folders (directories), use L{rmdir}.
|
||||||
|
|
||||||
@param path: path (absolute or relative) of the file to remove.
|
@param path: path (absolute or relative) of the file to remove
|
||||||
@type path: string
|
@type path: str
|
||||||
|
|
||||||
@raise IOError: if the path refers to a folder (directory). Use
|
@raise IOError: if the path refers to a folder (directory)
|
||||||
L{rmdir} to remove a folder.
|
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
self._log(DEBUG, 'remove(%r)' % path)
|
self._log(DEBUG, 'remove(%r)' % path)
|
||||||
|
@ -241,13 +241,13 @@ class SFTPClient (BaseSFTP):
|
||||||
"""
|
"""
|
||||||
Rename a file or folder from C{oldpath} to C{newpath}.
|
Rename a file or folder from C{oldpath} to C{newpath}.
|
||||||
|
|
||||||
@param oldpath: existing name of the file or folder.
|
@param oldpath: existing name of the file or folder
|
||||||
@type oldpath: string
|
@type oldpath: str
|
||||||
@param newpath: new name for the file or folder.
|
@param newpath: new name for the file or folder
|
||||||
@type newpath: string
|
@type newpath: str
|
||||||
|
|
||||||
@raise IOError: if C{newpath} is a folder, or something else goes
|
@raise IOError: if C{newpath} is a folder, or something else goes
|
||||||
wrong.
|
wrong
|
||||||
"""
|
"""
|
||||||
oldpath = self._adjust_cwd(oldpath)
|
oldpath = self._adjust_cwd(oldpath)
|
||||||
newpath = self._adjust_cwd(newpath)
|
newpath = self._adjust_cwd(newpath)
|
||||||
|
@ -260,9 +260,9 @@ class SFTPClient (BaseSFTP):
|
||||||
The default mode is 0777 (octal). On some systems, mode is ignored.
|
The default mode is 0777 (octal). On some systems, mode is ignored.
|
||||||
Where it is used, the current umask value is first masked out.
|
Where it is used, the current umask value is first masked out.
|
||||||
|
|
||||||
@param path: name of the folder to create.
|
@param path: name of the folder to create
|
||||||
@type path: string
|
@type path: str
|
||||||
@param mode: permissions (posix-style) for the newly-created folder.
|
@param mode: permissions (posix-style) for the newly-created folder
|
||||||
@type mode: int
|
@type mode: int
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
|
@ -275,8 +275,8 @@ class SFTPClient (BaseSFTP):
|
||||||
"""
|
"""
|
||||||
Remove the folder named C{path}.
|
Remove the folder named C{path}.
|
||||||
|
|
||||||
@param path: name of the folder to remove.
|
@param path: name of the folder to remove
|
||||||
@type path: string
|
@type path: str
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
self._log(DEBUG, 'rmdir(%r)' % path)
|
self._log(DEBUG, 'rmdir(%r)' % path)
|
||||||
|
@ -296,9 +296,9 @@ class SFTPClient (BaseSFTP):
|
||||||
The fields supported are: C{st_mode}, C{st_size}, C{st_uid}, C{st_gid},
|
The fields supported are: C{st_mode}, C{st_size}, C{st_uid}, C{st_gid},
|
||||||
C{st_atime}, and C{st_mtime}.
|
C{st_atime}, and C{st_mtime}.
|
||||||
|
|
||||||
@param path: the filename to stat.
|
@param path: the filename to stat
|
||||||
@type path: string
|
@type path: str
|
||||||
@return: an object containing attributes about the given file.
|
@return: an object containing attributes about the given file
|
||||||
@rtype: SFTPAttributes
|
@rtype: SFTPAttributes
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
|
@ -314,9 +314,9 @@ class SFTPClient (BaseSFTP):
|
||||||
following symbolic links (shortcuts). This otherwise behaves exactly
|
following symbolic links (shortcuts). This otherwise behaves exactly
|
||||||
the same as L{stat}.
|
the same as L{stat}.
|
||||||
|
|
||||||
@param path: the filename to stat.
|
@param path: the filename to stat
|
||||||
@type path: string
|
@type path: str
|
||||||
@return: an object containing attributes about the given file.
|
@return: an object containing attributes about the given file
|
||||||
@rtype: SFTPAttributes
|
@rtype: SFTPAttributes
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
|
@ -331,10 +331,10 @@ class SFTPClient (BaseSFTP):
|
||||||
Create a symbolic link (shortcut) of the C{source} path at
|
Create a symbolic link (shortcut) of the C{source} path at
|
||||||
C{destination}.
|
C{destination}.
|
||||||
|
|
||||||
@param source: path of the original file.
|
@param source: path of the original file
|
||||||
@type source: string
|
@type source: str
|
||||||
@param dest: path of the newly created symlink.
|
@param dest: path of the newly created symlink
|
||||||
@type dest: string
|
@type dest: str
|
||||||
"""
|
"""
|
||||||
dest = self._adjust_cwd(dest)
|
dest = self._adjust_cwd(dest)
|
||||||
self._log(DEBUG, 'symlink(%r, %r)' % (source, dest))
|
self._log(DEBUG, 'symlink(%r, %r)' % (source, dest))
|
||||||
|
@ -348,9 +348,9 @@ class SFTPClient (BaseSFTP):
|
||||||
unix-style and identical to those used by python's C{os.chmod}
|
unix-style and identical to those used by python's C{os.chmod}
|
||||||
function.
|
function.
|
||||||
|
|
||||||
@param path: path of the file to change the permissions of.
|
@param path: path of the file to change the permissions of
|
||||||
@type path: string
|
@type path: str
|
||||||
@param mode: new permissions.
|
@param mode: new permissions
|
||||||
@type mode: int
|
@type mode: int
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
|
@ -366,8 +366,8 @@ class SFTPClient (BaseSFTP):
|
||||||
only want to change one, use L{stat} first to retrieve the current
|
only want to change one, use L{stat} first to retrieve the current
|
||||||
owner and group.
|
owner and group.
|
||||||
|
|
||||||
@param path: path of the file to change the owner and group of.
|
@param path: path of the file to change the owner and group of
|
||||||
@type path: string
|
@type path: str
|
||||||
@param uid: new owner's uid
|
@param uid: new owner's uid
|
||||||
@type uid: int
|
@type uid: int
|
||||||
@param gid: new group id
|
@param gid: new group id
|
||||||
|
@ -388,11 +388,11 @@ class SFTPClient (BaseSFTP):
|
||||||
modified times, respectively. This bizarre API is mimicked from python
|
modified times, respectively. This bizarre API is mimicked from python
|
||||||
for the sake of consistency -- I apologize.
|
for the sake of consistency -- I apologize.
|
||||||
|
|
||||||
@param path: path of the file to modify.
|
@param path: path of the file to modify
|
||||||
@type path: string
|
@type path: str
|
||||||
@param times: C{None} or a tuple of (access time, modified time) in
|
@param times: C{None} or a tuple of (access time, modified time) in
|
||||||
standard internet epoch time (seconds since 01 January 1970 GMT).
|
standard internet epoch time (seconds since 01 January 1970 GMT)
|
||||||
@type times: tuple of int
|
@type times: tuple(int)
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
if times is None:
|
if times is None:
|
||||||
|
@ -402,15 +402,32 @@ class SFTPClient (BaseSFTP):
|
||||||
attr.st_atime, attr.st_mtime = times
|
attr.st_atime, attr.st_mtime = times
|
||||||
self._request(CMD_SETSTAT, path, attr)
|
self._request(CMD_SETSTAT, path, attr)
|
||||||
|
|
||||||
|
def truncate(self, path, size):
|
||||||
|
"""
|
||||||
|
Change the size of the file specified by C{path}. This usually extends
|
||||||
|
or shrinks the size of the file, just like the C{truncate()} method on
|
||||||
|
python file objects.
|
||||||
|
|
||||||
|
@param path: path of the file to modify
|
||||||
|
@type path: str
|
||||||
|
@param size: the new size of the file
|
||||||
|
@type size: int or long
|
||||||
|
"""
|
||||||
|
path = self._adjust_cwd(path)
|
||||||
|
self._log(DEBUG, 'truncate(%r, %r)' % (path, size))
|
||||||
|
attr = SFTPAttributes()
|
||||||
|
attr.st_size = size
|
||||||
|
self._request(CMD_SETSTAT, path, attr)
|
||||||
|
|
||||||
def readlink(self, path):
|
def readlink(self, path):
|
||||||
"""
|
"""
|
||||||
Return the target of a symbolic link (shortcut). You can use
|
Return the target of a symbolic link (shortcut). You can use
|
||||||
L{symlink} to create these. The result may be either an absolute or
|
L{symlink} to create these. The result may be either an absolute or
|
||||||
relative pathname.
|
relative pathname.
|
||||||
|
|
||||||
@param path: path of the symbolic link file.
|
@param path: path of the symbolic link file
|
||||||
@type path: str
|
@type path: str
|
||||||
@return: target path.
|
@return: target path
|
||||||
@rtype: str
|
@rtype: str
|
||||||
"""
|
"""
|
||||||
path = self._adjust_cwd(path)
|
path = self._adjust_cwd(path)
|
||||||
|
@ -432,9 +449,9 @@ class SFTPClient (BaseSFTP):
|
||||||
server is considering to be the "current folder" (by passing C{'.'}
|
server is considering to be the "current folder" (by passing C{'.'}
|
||||||
as C{path}).
|
as C{path}).
|
||||||
|
|
||||||
@param path: path to be normalized.
|
@param path: path to be normalized
|
||||||
@type path: str
|
@type path: str
|
||||||
@return: normalized form of the given path.
|
@return: normalized form of the given path
|
||||||
@rtype: str
|
@rtype: str
|
||||||
|
|
||||||
@raise IOError: if the path can't be resolved on the server
|
@raise IOError: if the path can't be resolved on the server
|
||||||
|
|
|
@ -181,6 +181,71 @@ class SFTPFile (BufferedFile):
|
||||||
if t != CMD_ATTRS:
|
if t != CMD_ATTRS:
|
||||||
raise SFTPError('Expected attributes')
|
raise SFTPError('Expected attributes')
|
||||||
return SFTPAttributes._from_msg(msg)
|
return SFTPAttributes._from_msg(msg)
|
||||||
|
|
||||||
|
def chmod(self, mode):
|
||||||
|
"""
|
||||||
|
Change the mode (permissions) of this file. The permissions are
|
||||||
|
unix-style and identical to those used by python's C{os.chmod}
|
||||||
|
function.
|
||||||
|
|
||||||
|
@param mode: new permissions
|
||||||
|
@type mode: int
|
||||||
|
"""
|
||||||
|
self.sftp._log(DEBUG, 'chmod(%s, %r)' % (util.hexify(self.handle), mode))
|
||||||
|
attr = SFTPAttributes()
|
||||||
|
attr.st_mode = mode
|
||||||
|
self.sftp._request(CMD_FSETSTAT, self.handle, attr)
|
||||||
|
|
||||||
|
def chown(self, uid, gid):
|
||||||
|
"""
|
||||||
|
Change the owner (C{uid}) and group (C{gid}) of this file. As with
|
||||||
|
python's C{os.chown} function, you must pass both arguments, so if you
|
||||||
|
only want to change one, use L{stat} first to retrieve the current
|
||||||
|
owner and group.
|
||||||
|
|
||||||
|
@param uid: new owner's uid
|
||||||
|
@type uid: int
|
||||||
|
@param gid: new group id
|
||||||
|
@type gid: int
|
||||||
|
"""
|
||||||
|
self.sftp._log(DEBUG, 'chown(%s, %r, %r)' % (util.hexify(self.handle), uid, gid))
|
||||||
|
attr = SFTPAttributes()
|
||||||
|
attr.st_uid, attr.st_gid = uid, gid
|
||||||
|
self.sftp._request(CMD_FSETSTAT, self.handle, attr)
|
||||||
|
|
||||||
|
def utime(self, times):
|
||||||
|
"""
|
||||||
|
Set the access and modified times of this file. If
|
||||||
|
C{times} is C{None}, then the file's access and modified times are set
|
||||||
|
to the current time. Otherwise, C{times} must be a 2-tuple of numbers,
|
||||||
|
of the form C{(atime, mtime)}, which is used to set the access and
|
||||||
|
modified times, respectively. This bizarre API is mimicked from python
|
||||||
|
for the sake of consistency -- I apologize.
|
||||||
|
|
||||||
|
@param times: C{None} or a tuple of (access time, modified time) in
|
||||||
|
standard internet epoch time (seconds since 01 January 1970 GMT)
|
||||||
|
@type times: tuple(int)
|
||||||
|
"""
|
||||||
|
if times is None:
|
||||||
|
times = (time.time(), time.time())
|
||||||
|
self.sftp._log(DEBUG, 'utime(%s, %r)' % (util.hexify(self.handle), times))
|
||||||
|
attr = SFTPAttributes()
|
||||||
|
attr.st_atime, attr.st_mtime = times
|
||||||
|
self.sftp._request(CMD_FSETSTAT, self.handle, attr)
|
||||||
|
|
||||||
|
def truncate(self, size):
|
||||||
|
"""
|
||||||
|
Change the size of this file. This usually extends
|
||||||
|
or shrinks the size of the file, just like the C{truncate()} method on
|
||||||
|
python file objects.
|
||||||
|
|
||||||
|
@param size: the new size of the file
|
||||||
|
@type size: int or long
|
||||||
|
"""
|
||||||
|
self.sftp._log(DEBUG, 'truncate(%s, %r)' % (util.hexify(self.handle), size))
|
||||||
|
attr = SFTPAttributes()
|
||||||
|
attr.st_size = size
|
||||||
|
self.sftp._request(CMD_FSETSTAT, self.handle, attr)
|
||||||
|
|
||||||
def check(self, hash_algorithm, offset=0, length=0, block_size=0):
|
def check(self, hash_algorithm, offset=0, length=0, block_size=0):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -147,6 +147,8 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
||||||
os.chown(filename, attr.st_uid, attr.st_gid)
|
os.chown(filename, attr.st_uid, attr.st_gid)
|
||||||
if attr._flags & attr.FLAG_AMTIME:
|
if attr._flags & attr.FLAG_AMTIME:
|
||||||
os.utime(filename, (attr.st_atime, attr.st_mtime))
|
os.utime(filename, (attr.st_atime, attr.st_mtime))
|
||||||
|
if attr._flags & attr.FLAG_SIZE:
|
||||||
|
open(filename, 'w+').truncate(attr.st_size)
|
||||||
set_file_attr = staticmethod(set_file_attr)
|
set_file_attr = staticmethod(set_file_attr)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ class StubSFTPHandle (SFTPHandle):
|
||||||
# use the stored filename
|
# use the stored filename
|
||||||
try:
|
try:
|
||||||
SFTPServer.set_file_attr(self.filename, attr)
|
SFTPServer.set_file_attr(self.filename, attr)
|
||||||
|
return SFTP_OK
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
return SFTPServer.convert_errno(e.errno)
|
return SFTPServer.convert_errno(e.errno)
|
||||||
|
|
||||||
|
|
|
@ -273,28 +273,68 @@ class SFTPTest (unittest.TestCase):
|
||||||
|
|
||||||
def test_8_setstat(self):
|
def test_8_setstat(self):
|
||||||
"""
|
"""
|
||||||
verify that the setstat functions (chown, chmod, utime) work.
|
verify that the setstat functions (chown, chmod, utime, truncate) work.
|
||||||
"""
|
"""
|
||||||
f = sftp.open(FOLDER + '/special', 'w')
|
f = sftp.open(FOLDER + '/special', 'w')
|
||||||
try:
|
try:
|
||||||
|
f.write('x' * 1024)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
stat = sftp.stat(FOLDER + '/special')
|
stat = sftp.stat(FOLDER + '/special')
|
||||||
sftp.chmod(FOLDER + '/special', (stat.st_mode & ~0777) | 0600)
|
sftp.chmod(FOLDER + '/special', (stat.st_mode & ~0777) | 0600)
|
||||||
self.assertEqual(sftp.stat(FOLDER + '/special').st_mode & 0777, 0600)
|
stat = sftp.stat(FOLDER + '/special')
|
||||||
|
self.assertEqual(stat.st_mode & 0777, 0600)
|
||||||
|
self.assertEqual(stat.st_size, 1024)
|
||||||
|
|
||||||
mtime = stat.st_mtime - 3600
|
mtime = stat.st_mtime - 3600
|
||||||
atime = stat.st_atime - 1800
|
atime = stat.st_atime - 1800
|
||||||
sftp.utime(FOLDER + '/special', (atime, mtime))
|
sftp.utime(FOLDER + '/special', (atime, mtime))
|
||||||
nstat = sftp.stat(FOLDER + '/special')
|
stat = sftp.stat(FOLDER + '/special')
|
||||||
self.assertEqual(nstat.st_mtime, mtime)
|
self.assertEqual(stat.st_mtime, mtime)
|
||||||
self.assertEqual(nstat.st_atime, atime)
|
self.assertEqual(stat.st_atime, atime)
|
||||||
|
|
||||||
# can't really test chown, since we'd have to know a valid uid.
|
# can't really test chown, since we'd have to know a valid uid.
|
||||||
|
|
||||||
|
sftp.truncate(FOLDER + '/special', 512)
|
||||||
|
stat = sftp.stat(FOLDER + '/special')
|
||||||
|
self.assertEqual(stat.st_size, 512)
|
||||||
finally:
|
finally:
|
||||||
sftp.remove(FOLDER + '/special')
|
sftp.remove(FOLDER + '/special')
|
||||||
|
|
||||||
def test_9_readline_seek(self):
|
def test_9_fsetstat(self):
|
||||||
|
"""
|
||||||
|
verify that the fsetstat functions (chown, chmod, utime, truncate)
|
||||||
|
work on open files.
|
||||||
|
"""
|
||||||
|
f = sftp.open(FOLDER + '/special', 'w')
|
||||||
|
try:
|
||||||
|
f.write('x' * 1024)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
f = sftp.open(FOLDER + '/special', 'r+')
|
||||||
|
stat = f.stat()
|
||||||
|
f.chmod((stat.st_mode & ~0777) | 0600)
|
||||||
|
stat = f.stat()
|
||||||
|
self.assertEqual(stat.st_mode & 0777, 0600)
|
||||||
|
self.assertEqual(stat.st_size, 1024)
|
||||||
|
|
||||||
|
mtime = stat.st_mtime - 3600
|
||||||
|
atime = stat.st_atime - 1800
|
||||||
|
f.utime((atime, mtime))
|
||||||
|
stat = f.stat()
|
||||||
|
self.assertEqual(stat.st_mtime, mtime)
|
||||||
|
self.assertEqual(stat.st_atime, atime)
|
||||||
|
|
||||||
|
# can't really test chown, since we'd have to know a valid uid.
|
||||||
|
|
||||||
|
f.truncate(512)
|
||||||
|
stat = f.stat()
|
||||||
|
self.assertEqual(stat.st_size, 512)
|
||||||
|
f.close()
|
||||||
|
finally:
|
||||||
|
sftp.remove(FOLDER + '/special')
|
||||||
|
|
||||||
|
def test_A_readline_seek(self):
|
||||||
"""
|
"""
|
||||||
create a text file and write a bunch of text into it. then count the lines
|
create a text file and write a bunch of text into it. then count the lines
|
||||||
in the file, and seek around to retreive particular lines. this should
|
in the file, and seek around to retreive particular lines. this should
|
||||||
|
@ -324,7 +364,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.remove(FOLDER + '/duck.txt')
|
sftp.remove(FOLDER + '/duck.txt')
|
||||||
|
|
||||||
def test_A_write_seek(self):
|
def test_B_write_seek(self):
|
||||||
"""
|
"""
|
||||||
create a text file, seek back and change part of it, and verify that the
|
create a text file, seek back and change part of it, and verify that the
|
||||||
changes worked.
|
changes worked.
|
||||||
|
@ -344,7 +384,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.remove(FOLDER + '/testing.txt')
|
sftp.remove(FOLDER + '/testing.txt')
|
||||||
|
|
||||||
def test_B_symlink(self):
|
def test_C_symlink(self):
|
||||||
"""
|
"""
|
||||||
create a symlink and then check that lstat doesn't follow it.
|
create a symlink and then check that lstat doesn't follow it.
|
||||||
"""
|
"""
|
||||||
|
@ -387,7 +427,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_C_flush_seek(self):
|
def test_D_flush_seek(self):
|
||||||
"""
|
"""
|
||||||
verify that buffered writes are automatically flushed on seek.
|
verify that buffered writes are automatically flushed on seek.
|
||||||
"""
|
"""
|
||||||
|
@ -409,7 +449,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_D_lots_of_files(self):
|
def test_E_lots_of_files(self):
|
||||||
"""
|
"""
|
||||||
create a bunch of files over the same session.
|
create a bunch of files over the same session.
|
||||||
"""
|
"""
|
||||||
|
@ -440,7 +480,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_E_big_file(self):
|
def test_F_big_file(self):
|
||||||
"""
|
"""
|
||||||
write a 1MB file with no buffering.
|
write a 1MB file with no buffering.
|
||||||
"""
|
"""
|
||||||
|
@ -474,7 +514,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.remove('%s/hongry.txt' % FOLDER)
|
sftp.remove('%s/hongry.txt' % FOLDER)
|
||||||
|
|
||||||
def test_F_big_file_pipelined(self):
|
def test_G_big_file_pipelined(self):
|
||||||
"""
|
"""
|
||||||
write a 1MB file, with no linefeeds, using pipelining.
|
write a 1MB file, with no linefeeds, using pipelining.
|
||||||
"""
|
"""
|
||||||
|
@ -510,7 +550,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.remove('%s/hongry.txt' % FOLDER)
|
sftp.remove('%s/hongry.txt' % FOLDER)
|
||||||
|
|
||||||
def test_G_lots_of_prefetching(self):
|
def test_H_lots_of_prefetching(self):
|
||||||
"""
|
"""
|
||||||
prefetch a 1MB file a bunch of times, discarding the file object
|
prefetch a 1MB file a bunch of times, discarding the file object
|
||||||
without using it, to verify that paramiko doesn't get confused.
|
without using it, to verify that paramiko doesn't get confused.
|
||||||
|
@ -546,7 +586,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.remove('%s/hongry.txt' % FOLDER)
|
sftp.remove('%s/hongry.txt' % FOLDER)
|
||||||
|
|
||||||
def test_H_big_file_big_buffer(self):
|
def test_I_big_file_big_buffer(self):
|
||||||
"""
|
"""
|
||||||
write a 1MB file, with no linefeeds, and a big buffer.
|
write a 1MB file, with no linefeeds, and a big buffer.
|
||||||
"""
|
"""
|
||||||
|
@ -563,7 +603,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.remove('%s/hongry.txt' % FOLDER)
|
sftp.remove('%s/hongry.txt' % FOLDER)
|
||||||
|
|
||||||
def test_I_big_file_renegotiate(self):
|
def test_J_big_file_renegotiate(self):
|
||||||
"""
|
"""
|
||||||
write a 1MB file, forcing key renegotiation in the middle.
|
write a 1MB file, forcing key renegotiation in the middle.
|
||||||
"""
|
"""
|
||||||
|
@ -585,7 +625,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
sftp.remove('%s/hongry.txt' % FOLDER)
|
sftp.remove('%s/hongry.txt' % FOLDER)
|
||||||
t.packetizer.REKEY_BYTES = pow(2, 30)
|
t.packetizer.REKEY_BYTES = pow(2, 30)
|
||||||
|
|
||||||
def test_J_realpath(self):
|
def test_K_realpath(self):
|
||||||
"""
|
"""
|
||||||
test that realpath is returning something non-empty and not an
|
test that realpath is returning something non-empty and not an
|
||||||
error.
|
error.
|
||||||
|
@ -596,7 +636,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
self.assert_(len(f) > 0)
|
self.assert_(len(f) > 0)
|
||||||
self.assertEquals(os.path.join(pwd, FOLDER), f)
|
self.assertEquals(os.path.join(pwd, FOLDER), f)
|
||||||
|
|
||||||
def test_K_mkdir(self):
|
def test_L_mkdir(self):
|
||||||
"""
|
"""
|
||||||
verify that mkdir/rmdir work.
|
verify that mkdir/rmdir work.
|
||||||
"""
|
"""
|
||||||
|
@ -619,7 +659,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_L_chdir(self):
|
def test_M_chdir(self):
|
||||||
"""
|
"""
|
||||||
verify that chdir/getcwd work.
|
verify that chdir/getcwd work.
|
||||||
"""
|
"""
|
||||||
|
@ -656,7 +696,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_M_get_put(self):
|
def test_N_get_put(self):
|
||||||
"""
|
"""
|
||||||
verify that get/put work.
|
verify that get/put work.
|
||||||
"""
|
"""
|
||||||
|
@ -685,7 +725,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
os.unlink(localname)
|
os.unlink(localname)
|
||||||
sftp.unlink(FOLDER + '/bunny.txt')
|
sftp.unlink(FOLDER + '/bunny.txt')
|
||||||
|
|
||||||
def test_N_check(self):
|
def test_O_check(self):
|
||||||
"""
|
"""
|
||||||
verify that file.check() works against our own server.
|
verify that file.check() works against our own server.
|
||||||
(it's an sftp extension that we support, and may be the only ones who
|
(it's an sftp extension that we support, and may be the only ones who
|
||||||
|
@ -707,7 +747,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.unlink(FOLDER + '/kitty.txt')
|
sftp.unlink(FOLDER + '/kitty.txt')
|
||||||
|
|
||||||
def test_O_x_flag(self):
|
def test_P_x_flag(self):
|
||||||
"""
|
"""
|
||||||
verify that the 'x' flag works when opening a file.
|
verify that the 'x' flag works when opening a file.
|
||||||
"""
|
"""
|
||||||
|
@ -723,7 +763,7 @@ class SFTPTest (unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
sftp.unlink(FOLDER + '/unusual.txt')
|
sftp.unlink(FOLDER + '/unusual.txt')
|
||||||
|
|
||||||
def test_P_utf8(self):
|
def test_Q_utf8(self):
|
||||||
"""
|
"""
|
||||||
verify that unicode strings are encoded into utf8 correctly.
|
verify that unicode strings are encoded into utf8 correctly.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue