示例#1
0
    def test_openDirectoryMemory(self):
        """openDirectory works on MemoryTransport."""
        transport = MemoryTransport()
        transport.put_bytes('hello', 'hello')
        sftp_server = TransportSFTPServer(AsyncTransport(transport))
        deferred = sftp_server.openDirectory('.')

        def check_directory(directory):
            with closing(directory):
                names = [entry[0] for entry in directory]
            self.assertEqual(['hello'], names)

        return deferred.addCallback(check_directory)
示例#2
0
    def test_openDirectoryMemory(self):
        """openDirectory works on MemoryTransport."""
        transport = MemoryTransport()
        transport.put_bytes('hello', 'hello')
        sftp_server = TransportSFTPServer(AsyncTransport(transport))
        deferred = sftp_server.openDirectory('.')

        def check_directory(directory):
            with closing(directory):
                names = [entry[0] for entry in directory]
            self.assertEqual(['hello'], names)

        return deferred.addCallback(check_directory)
示例#3
0
class TestSFTPServer(TestCaseInTempDir, SFTPTestMixin):
    """Tests for `TransportSFTPServer` and `TransportSFTPFile`."""

    run_tests_with = AsynchronousDeferredRunTest

    def setUp(self):
        TestCaseInTempDir.setUp(self)
        SFTPTestMixin.setUp(self)
        transport = AsyncTransport(
            FatLocalTransport(urlutils.local_path_to_url('.')))
        self.sftp_server = TransportSFTPServer(transport)

    def test_serverSetAttrs(self):
        # setAttrs on the TransportSFTPServer doesn't do anything either.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename, 'bar')])
        self.sftp_server.setAttrs(filename, {})

    def test_serverGetAttrs(self):
        # getAttrs on the TransportSFTPServer also returns a dictionary
        # consistent with the results of os.stat.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename, 'bar')])
        stat_value = os.stat(filename)
        deferred = self.sftp_server.getAttrs(filename, False)
        return deferred.addCallback(self.checkAttrs, stat_value)

    def test_serverGetAttrsError(self):
        # Errors in getAttrs on the TransportSFTPServer are translated into
        # SFTPErrors.
        nonexistent_file = self.getPathSegment()
        deferred = self.sftp_server.getAttrs(nonexistent_file, False)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_removeFile(self):
        # removeFile removes the file.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename, 'bar')])
        deferred = self.sftp_server.removeFile(filename)

        def assertFileRemoved(ignored):
            self.assertFalse(file_exists(filename))

        return deferred.addCallback(assertFileRemoved)

    def test_removeFileError(self):
        # Errors in removeFile are translated into SFTPErrors.
        filename = self.getPathSegment()
        deferred = self.sftp_server.removeFile(filename)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_removeFile_directory(self):
        # Errors in removeFile are translated into SFTPErrors.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename + '/',)])
        deferred = self.sftp_server.removeFile(filename)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_renameFile(self):
        # renameFile renames the file.
        orig_filename = self.getPathSegment()
        new_filename = self.getPathSegment()
        self.build_tree_contents([(orig_filename, 'bar')])
        deferred = self.sftp_server.renameFile(orig_filename, new_filename)

        def assertFileRenamed(ignored):
            self.assertFalse(file_exists(orig_filename))
            self.assertTrue(file_exists(new_filename))

        return deferred.addCallback(assertFileRenamed)

    def test_renameFileError(self):
        # Errors in renameFile are translated into SFTPErrors.
        orig_filename = self.getPathSegment()
        new_filename = self.getPathSegment()
        deferred = self.sftp_server.renameFile(orig_filename, new_filename)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_makeDirectory(self):
        # makeDirectory makes the directory.
        directory = self.getPathSegment()
        deferred = self.sftp_server.makeDirectory(
            directory, {'permissions': 0o777})

        def assertDirectoryExists(ignored):
            self.assertTrue(
                os.path.isdir(directory), '%r is not a directory' % directory)
            self.assertEqual(0o40777, os.stat(directory).st_mode)

        return deferred.addCallback(assertDirectoryExists)

    def test_makeDirectoryError(self):
        # Errors in makeDirectory are translated into SFTPErrors.
        nonexistent = self.getPathSegment()
        nonexistent_child = '%s/%s' % (nonexistent, self.getPathSegment())
        deferred = self.sftp_server.makeDirectory(
            nonexistent_child, {'permissions': 0o777})
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_removeDirectory(self):
        # removeDirectory removes the directory.
        directory = self.getPathSegment()
        os.mkdir(directory)
        deferred = self.sftp_server.removeDirectory(directory)

        def assertDirectoryRemoved(ignored):
            self.assertFalse(file_exists(directory))

        return deferred.addCallback(assertDirectoryRemoved)

    def test_removeDirectoryError(self):
        # Errors in removeDirectory are translated into SFTPErrors.
        directory = self.getPathSegment()
        deferred = self.sftp_server.removeDirectory(directory)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_gotVersion(self):
        # gotVersion returns an empty dictionary.
        extended = self.sftp_server.gotVersion('version', {})
        self.assertEqual({}, extended)

    def test_extendedRequest(self):
        # We don't support any extensions.
        self.assertRaises(
            NotImplementedError, self.sftp_server.extendedRequest,
            'foo', 'bar')

    def test_realPath(self):
        # realPath returns the absolute path of the file.
        src, dst = self.getPathSegment(), self.getPathSegment()
        os.symlink(src, dst)
        deferred = self.sftp_server.realPath(dst)
        return deferred.addCallback(self.assertEqual, os.path.abspath(src))

    def test_makeLink(self):
        # makeLink is not supported.
        self.assertRaises(
            NotImplementedError, self.sftp_server.makeLink,
            self.getPathSegment(), self.getPathSegment())

    def test_readLink(self):
        # readLink is not supported.
        self.assertRaises(
            NotImplementedError, self.sftp_server.readLink,
            self.getPathSegment())

    def test_openDirectory(self):
        # openDirectory returns an iterator that iterates over the contents of
        # the directory.
        parent_dir = self.getPathSegment()
        child_dir = self.getPathSegment()
        child_file = self.getPathSegment()
        self.build_tree([
            parent_dir + '/',
            '%s/%s/' % (parent_dir, child_dir),
            '%s/%s' % (parent_dir, child_file)])
        deferred = self.sftp_server.openDirectory(parent_dir)

        def check_entry(entries, filename):
            t = get_transport('.')
            stat = t.stat(urlutils.escape('%s/%s' % (parent_dir, filename)))
            named_entries = [
                entry for entry in entries if entry[0] == filename]
            self.assertEqual(1, len(named_entries))
            name, longname, attrs = named_entries[0]
            self.assertEqual(lsLine(name, stat), longname)
            self.assertEqual(self.sftp_server._translate_stat(stat), attrs)

        def check_open_directory(directory):
            entries = list(directory)
            directory.close()
            names = [entry[0] for entry in entries]
            self.assertEqual(set(names), set([child_dir, child_file]))
            check_entry(entries, child_dir)
            check_entry(entries, child_file)

        return deferred.addCallback(check_open_directory)

    def test_openDirectoryError(self):
        # Errors in openDirectory are translated into SFTPErrors.
        nonexistent = self.getPathSegment()
        deferred = self.sftp_server.openDirectory(nonexistent)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_openDirectoryMemory(self):
        """openDirectory works on MemoryTransport."""
        transport = MemoryTransport()
        transport.put_bytes('hello', 'hello')
        sftp_server = TransportSFTPServer(AsyncTransport(transport))
        deferred = sftp_server.openDirectory('.')

        def check_directory(directory):
            with closing(directory):
                names = [entry[0] for entry in directory]
            self.assertEqual(['hello'], names)

        return deferred.addCallback(check_directory)

    def test__format_directory_entries_with_MemoryStat(self):
        """format_directory_entries works with MemoryStat.

        MemoryStat lacks many fields, but format_directory_entries works
        around that.
        """
        t = MemoryTransport()
        stat_result = t.stat('.')
        entries = self.sftp_server._format_directory_entries(
            [stat_result], ['filename'])
        self.assertEqual(list(entries), [
            ('filename', 'drwxr-xr-x    0 0        0               0 '
             'Jan 01  1970 filename',
             {'atime': 0,
              'gid': 0,
              'mtime': 0,
              'permissions': 16877,
              'size': 0,
              'uid': 0})])
        self.assertIs(None, getattr(stat_result, 'st_mtime', None))

    def do_translation_test(self, exception, sftp_code, method_name=None):
        """Test that `exception` is translated into the correct SFTPError."""
        result = self.assertRaises(filetransfer.SFTPError,
            self.sftp_server.translateError,
            failure.Failure(exception), method_name)
        self.assertEqual(sftp_code, result.code)
        self.assertEqual(str(exception), result.message)

    def test_translatePermissionDenied(self):
        exception = bzr_errors.PermissionDenied(self.getPathSegment())
        self.do_translation_test(exception, filetransfer.FX_PERMISSION_DENIED)

    def test_translateTransportNotPossible(self):
        exception = bzr_errors.TransportNotPossible(self.getPathSegment())
        self.do_translation_test(exception, filetransfer.FX_PERMISSION_DENIED)

    def test_translateNoSuchFile(self):
        exception = bzr_errors.NoSuchFile(self.getPathSegment())
        self.do_translation_test(exception, filetransfer.FX_NO_SUCH_FILE)

    def test_translateFileExists(self):
        exception = bzr_errors.FileExists(self.getPathSegment())
        self.do_translation_test(
            exception, filetransfer.FX_FILE_ALREADY_EXISTS)

    def test_translateFileIsADirectory(self):
        exception = FileIsADirectory(self.getPathSegment())
        self.do_translation_test(
            exception, filetransfer.FX_FILE_IS_A_DIRECTORY)

    def test_translateDirectoryNotEmpty(self):
        exception = bzr_errors.DirectoryNotEmpty(self.getPathSegment())
        self.do_translation_test(
            exception, filetransfer.FX_FAILURE)

    def test_translateRandomError(self):
        # translateError re-raises unrecognized errors.
        exception = KeyboardInterrupt()
        result = self.assertRaises(KeyboardInterrupt,
            self.sftp_server.translateError,
            failure.Failure(exception), 'methodName')
        self.assertIs(result, exception)
示例#4
0
class TestSFTPServer(TestCaseInTempDir, SFTPTestMixin):
    """Tests for `TransportSFTPServer` and `TransportSFTPFile`."""

    run_tests_with = AsynchronousDeferredRunTest

    def setUp(self):
        TestCaseInTempDir.setUp(self)
        SFTPTestMixin.setUp(self)
        transport = AsyncTransport(
            FatLocalTransport(urlutils.local_path_to_url('.')))
        self.sftp_server = TransportSFTPServer(transport)

    def test_serverSetAttrs(self):
        # setAttrs on the TransportSFTPServer doesn't do anything either.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename, 'bar')])
        self.sftp_server.setAttrs(filename, {})

    def test_serverGetAttrs(self):
        # getAttrs on the TransportSFTPServer also returns a dictionary
        # consistent with the results of os.stat.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename, 'bar')])
        stat_value = os.stat(filename)
        deferred = self.sftp_server.getAttrs(filename, False)
        return deferred.addCallback(self.checkAttrs, stat_value)

    def test_serverGetAttrsError(self):
        # Errors in getAttrs on the TransportSFTPServer are translated into
        # SFTPErrors.
        nonexistent_file = self.getPathSegment()
        deferred = self.sftp_server.getAttrs(nonexistent_file, False)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_removeFile(self):
        # removeFile removes the file.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename, 'bar')])
        deferred = self.sftp_server.removeFile(filename)

        def assertFileRemoved(ignored):
            self.assertFalse(file_exists(filename))

        return deferred.addCallback(assertFileRemoved)

    def test_removeFileError(self):
        # Errors in removeFile are translated into SFTPErrors.
        filename = self.getPathSegment()
        deferred = self.sftp_server.removeFile(filename)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_removeFile_directory(self):
        # Errors in removeFile are translated into SFTPErrors.
        filename = self.getPathSegment()
        self.build_tree_contents([(filename + '/',)])
        deferred = self.sftp_server.removeFile(filename)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_renameFile(self):
        # renameFile renames the file.
        orig_filename = self.getPathSegment()
        new_filename = self.getPathSegment()
        self.build_tree_contents([(orig_filename, 'bar')])
        deferred = self.sftp_server.renameFile(orig_filename, new_filename)

        def assertFileRenamed(ignored):
            self.assertFalse(file_exists(orig_filename))
            self.assertTrue(file_exists(new_filename))

        return deferred.addCallback(assertFileRenamed)

    def test_renameFileError(self):
        # Errors in renameFile are translated into SFTPErrors.
        orig_filename = self.getPathSegment()
        new_filename = self.getPathSegment()
        deferred = self.sftp_server.renameFile(orig_filename, new_filename)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_makeDirectory(self):
        # makeDirectory makes the directory.
        directory = self.getPathSegment()
        deferred = self.sftp_server.makeDirectory(
            directory, {'permissions': 0777})

        def assertDirectoryExists(ignored):
            self.assertTrue(
                os.path.isdir(directory), '%r is not a directory' % directory)
            self.assertEqual(040777, os.stat(directory).st_mode)

        return deferred.addCallback(assertDirectoryExists)

    def test_makeDirectoryError(self):
        # Errors in makeDirectory are translated into SFTPErrors.
        nonexistent = self.getPathSegment()
        nonexistent_child = '%s/%s' % (nonexistent, self.getPathSegment())
        deferred = self.sftp_server.makeDirectory(
            nonexistent_child, {'permissions': 0777})
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_removeDirectory(self):
        # removeDirectory removes the directory.
        directory = self.getPathSegment()
        os.mkdir(directory)
        deferred = self.sftp_server.removeDirectory(directory)

        def assertDirectoryRemoved(ignored):
            self.assertFalse(file_exists(directory))

        return deferred.addCallback(assertDirectoryRemoved)

    def test_removeDirectoryError(self):
        # Errors in removeDirectory are translated into SFTPErrors.
        directory = self.getPathSegment()
        deferred = self.sftp_server.removeDirectory(directory)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_gotVersion(self):
        # gotVersion returns an empty dictionary.
        extended = self.sftp_server.gotVersion('version', {})
        self.assertEqual({}, extended)

    def test_extendedRequest(self):
        # We don't support any extensions.
        self.assertRaises(
            NotImplementedError, self.sftp_server.extendedRequest,
            'foo', 'bar')

    def test_realPath(self):
        # realPath returns the absolute path of the file.
        src, dst = self.getPathSegment(), self.getPathSegment()
        os.symlink(src, dst)
        deferred = self.sftp_server.realPath(dst)
        return deferred.addCallback(self.assertEqual, os.path.abspath(src))

    def test_makeLink(self):
        # makeLink is not supported.
        self.assertRaises(
            NotImplementedError, self.sftp_server.makeLink,
            self.getPathSegment(), self.getPathSegment())

    def test_readLink(self):
        # readLink is not supported.
        self.assertRaises(
            NotImplementedError, self.sftp_server.readLink,
            self.getPathSegment())

    def test_openDirectory(self):
        # openDirectory returns an iterator that iterates over the contents of
        # the directory.
        parent_dir = self.getPathSegment()
        child_dir = self.getPathSegment()
        child_file = self.getPathSegment()
        self.build_tree([
            parent_dir + '/',
            '%s/%s/' % (parent_dir, child_dir),
            '%s/%s' % (parent_dir, child_file)])
        deferred = self.sftp_server.openDirectory(parent_dir)

        def check_entry(entries, filename):
            t = get_transport('.')
            stat = t.stat(urlutils.escape('%s/%s' % (parent_dir, filename)))
            named_entries = [
                entry for entry in entries if entry[0] == filename]
            self.assertEqual(1, len(named_entries))
            name, longname, attrs = named_entries[0]
            self.assertEqual(lsLine(name, stat), longname)
            self.assertEqual(self.sftp_server._translate_stat(stat), attrs)

        def check_open_directory(directory):
            entries = list(directory)
            directory.close()
            names = [entry[0] for entry in entries]
            self.assertEqual(set(names), set([child_dir, child_file]))
            check_entry(entries, child_dir)
            check_entry(entries, child_file)

        return deferred.addCallback(check_open_directory)

    def test_openDirectoryError(self):
        # Errors in openDirectory are translated into SFTPErrors.
        nonexistent = self.getPathSegment()
        deferred = self.sftp_server.openDirectory(nonexistent)
        return assert_fails_with(deferred, filetransfer.SFTPError)

    def test_openDirectoryMemory(self):
        """openDirectory works on MemoryTransport."""
        transport = MemoryTransport()
        transport.put_bytes('hello', 'hello')
        sftp_server = TransportSFTPServer(AsyncTransport(transport))
        deferred = sftp_server.openDirectory('.')

        def check_directory(directory):
            with closing(directory):
                names = [entry[0] for entry in directory]
            self.assertEqual(['hello'], names)

        return deferred.addCallback(check_directory)

    def test__format_directory_entries_with_MemoryStat(self):
        """format_directory_entries works with MemoryStat.

        MemoryStat lacks many fields, but format_directory_entries works
        around that.
        """
        t = MemoryTransport()
        stat_result = t.stat('.')
        entries = self.sftp_server._format_directory_entries(
            [stat_result], ['filename'])
        self.assertEqual(list(entries), [
            ('filename', 'drwxr-xr-x    0 0        0               0 '
             'Jan 01  1970 filename',
             {'atime': 0,
              'gid': 0,
              'mtime': 0,
              'permissions': 16877,
              'size': 0,
              'uid': 0})])
        self.assertIs(None, getattr(stat_result, 'st_mtime', None))

    def do_translation_test(self, exception, sftp_code, method_name=None):
        """Test that `exception` is translated into the correct SFTPError."""
        result = self.assertRaises(filetransfer.SFTPError,
            self.sftp_server.translateError,
            failure.Failure(exception), method_name)
        self.assertEqual(sftp_code, result.code)
        self.assertEqual(str(exception), result.message)

    def test_translatePermissionDenied(self):
        exception = bzr_errors.PermissionDenied(self.getPathSegment())
        self.do_translation_test(exception, filetransfer.FX_PERMISSION_DENIED)

    def test_translateTransportNotPossible(self):
        exception = bzr_errors.TransportNotPossible(self.getPathSegment())
        self.do_translation_test(exception, filetransfer.FX_PERMISSION_DENIED)

    def test_translateNoSuchFile(self):
        exception = bzr_errors.NoSuchFile(self.getPathSegment())
        self.do_translation_test(exception, filetransfer.FX_NO_SUCH_FILE)

    def test_translateFileExists(self):
        exception = bzr_errors.FileExists(self.getPathSegment())
        self.do_translation_test(
            exception, filetransfer.FX_FILE_ALREADY_EXISTS)

    def test_translateFileIsADirectory(self):
        exception = FileIsADirectory(self.getPathSegment())
        self.do_translation_test(
            exception, filetransfer.FX_FILE_IS_A_DIRECTORY)

    def test_translateDirectoryNotEmpty(self):
        exception = bzr_errors.DirectoryNotEmpty(self.getPathSegment())
        self.do_translation_test(
            exception, filetransfer.FX_FAILURE)

    def test_translateRandomError(self):
        # translateError re-raises unrecognized errors.
        exception = KeyboardInterrupt()
        result = self.assertRaises(KeyboardInterrupt,
            self.sftp_server.translateError,
            failure.Failure(exception), 'methodName')
        self.assertIs(result, exception)