def test_conditional_upload(self): """Test conditional ASCII mode upload.""" local_source = '__test_source' data = ascii_data() self.generate_ascii_file(data, local_source) # Target is newer, so don't upload host = test_base.ftp_host_factory( ftp_host_class=FailingUploadAndDownloadFTPHost) flag = host.upload_if_newer(local_source, '/home/newer') self.assertEqual(flag, False) # Target is older, so upload host = test_base.ftp_host_factory() flag = host.upload_if_newer(local_source, '/home/older') self.assertEqual(flag, True) # Check uploaded content # The data which was uploaded has its line endings converted # so the conversion must also be applied to 'data'. data = data.replace('\n', '\r\n') remote_file_content = mock_ftplib.content_of('older') self.assertEqual(data, remote_file_content) # Target doesn't exist, so upload host = test_base.ftp_host_factory() flag = host.upload_if_newer(local_source, '/home/notthere') self.assertEqual(flag, True) remote_file_content = mock_ftplib.content_of('notthere') self.assertEqual(data, remote_file_content) # Clean up os.unlink(local_source)
def test_exists(self): """Test if "abnormal" FTP errors come through `path.exists`.""" # Regular use of `exists` testdir = '/home/sschwarzer' host = test_base.ftp_host_factory() host.chdir(testdir) self.assertEqual(host.path.exists("index.html"), True) self.assertEqual(host.path.exists("notthere"), False) # "Abnormal" failure host = test_base.ftp_host_factory(ftp_host_class=FailingFTPHost) self.assertRaises(ftp_error.FTPOSError, host.path.exists, "index.html")
def test_conditional_download_with_newer_target(self): """Test conditional binary mode download with older source file.""" local_target = '__test_target' # Make target file open(local_target, 'w').close() # Source is older, so don't download host = test_base.ftp_host_factory( session_factory=BinaryDownloadMockSession) host = test_base.ftp_host_factory( ftp_host_class=FailingUploadAndDownloadFTPHost, session_factory=BinaryDownloadMockSession) flag = host.download_if_newer('/home/older', local_target, 'b') self.assertEqual(flag, False) # Remove target file os.unlink(local_target)
def test_caching(self): """Test whether `_FTPFile` cache of `FTPHost` object works.""" host = test_base.ftp_host_factory() self.assertEqual(len(host._children), 0) path1 = 'path1' path2 = 'path2' # Open one file and inspect cache file1 = host.file(path1, 'w') child1 = host._children[0] self.assertEqual(len(host._children), 1) self.failIf(child1._file.closed) # Open another file file2 = host.file(path2, 'w') child2 = host._children[1] self.assertEqual(len(host._children), 2) self.failIf(child2._file.closed) # Close first file file1.close() self.assertEqual(len(host._children), 2) self.failUnless(child1._file.closed) self.failIf(child2._file.closed) # Re-open first child's file file1 = host.file(path1, 'w') child1_1 = file1._host # Check if it's reused self.failUnless(child1 is child1_1) self.failIf(child1._file.closed) self.failIf(child2._file.closed) # Close second file file2.close() self.failUnless(child2._file.closed)
def test_plain_listing(self): host = test_base.ftp_host_factory( session_factory=RecursiveListingForDotAsPathSession) lines = host._dir("") self.assertEqual(lines[0], "total 10") self.failUnless(lines[1].startswith("lrwxrwxrwx 1 staff")) self.failUnless(lines[2].startswith("d--x--x--x 2 staff")) host.close()
def test_conditional_download_without_target(self): "Test conditional binary mode download when no target file exists." local_target = '__test_target' # Target does not exist, so download host = test_base.ftp_host_factory( session_factory=BinaryDownloadMockSession) flag = host.download_if_newer('/home/newer', local_target, 'b') self.assertEqual(flag, True) self.compare_and_delete_downloaded_data(local_target)
def test_client_code_exception(self): try: with test_base.ftp_host_factory() as host: self.assertEqual(host.closed, False) raise ClientCodeException() except ClientCodeException: self.assertEqual(host.closed, True) else: raise self.failureException("ClientCodeException not raised")
def test_normal_operation(self): with test_base.ftp_host_factory(session_factory=ReadMockSession) \ as host: with host.file('dummy', 'r') as f: self.assertEqual(f.closed, False) data = f.readline() self.assertEqual(data, 'line 1\n') self.assertEqual(f.closed, False) self.assertEqual(f.closed, True)
def test_abnormal_isdir_isfile_islink(self): """Test abnormal `FTPHost._Path.isdir/isfile/islink`.""" testdir = '/home/sschwarzer' host = test_base.ftp_host_factory(ftp_host_class=FailingFTPHost) host.chdir(testdir) # Test a path which isn't there self.assertRaises(ftp_error.FTPOSError, host.path.isdir, "index.html") self.assertRaises(ftp_error.FTPOSError, host.path.isfile, "index.html") self.assertRaises(ftp_error.FTPOSError, host.path.islink, "index.html")
def test_ascii_readlines(self): """Read ASCII text with `readlines`.""" host = test_base.ftp_host_factory(session_factory=ReadMockSession) input_ = host.file('dummy', 'r') data = input_.read(3) self.assertEqual(data, 'lin') data = input_.readlines() self.assertEqual(data, ['e 1\n', 'another line\n', 'yet another line']) input_.close()
def test_ascii_iterator(self): """Test the iterator interface of `FTPFile` objects.""" host = test_base.ftp_host_factory(session_factory=ReadMockSession) input_ = host.file('dummy', 'rb') input_iterator = iter(input_) self.assertEqual(input_iterator.next(), "line 1\r\n") self.assertEqual(input_iterator.next(), "another line\r\n") self.assertEqual(input_iterator.next(), "yet another line") self.assertRaises(StopIteration, input_iterator.next) input_.close()
def test_workaround_for_spaces(self): """Test whether the workaround for space-containing paths is used.""" testdir = '/home/sschwarzer' host = test_base.ftp_host_factory() host.chdir(testdir) # Test a file name containing spaces testfile = '/home/dir with spaces/file with spaces' self.failIf(host.path.isdir(testfile)) self.failUnless(host.path.isfile(testfile)) self.failIf(host.path.islink(testfile))
def test_ascii_write(self): """Write ASCII text with `write`.""" host = test_base.ftp_host_factory() data = ' \nline 2\nline 3' output = host.file('dummy', 'w') output.write(data) output.close() child_data = mock_ftplib.content_of('dummy') expected_data = ' \r\nline 2\r\nline 3' self.assertEqual(child_data, expected_data)
def test_binary_write(self): """Write binary data with `write`.""" host = test_base.ftp_host_factory() data = '\000a\001b\r\n\002c\003\n\004\r\005' output = host.file('dummy', 'wb') output.write(data) output.close() child_data = mock_ftplib.content_of('dummy') expected_data = data self.assertEqual(child_data, expected_data)
def test_ftputil_exception(self): try: with test_base.ftp_host_factory(FailOnLoginSession) as host: pass except ftp_error.FTPOSError: # We arrived here, that's fine. Because the `FTPHost` object # wasn't successfully constructed the assignment to `host` # shouldn't have happened. self.failIf('host' in locals()) else: raise self.failureException("ftp_error.FTPOSError not raised")
def test_client_code_exception(self): with test_base.ftp_host_factory(session_factory=ReadMockSession) \ as host: try: with host.file('dummy', 'r') as f: self.assertEqual(f.closed, False) raise ClientCodeException() except ClientCodeException: self.assertEqual(f.closed, True) else: raise self.failureException("ClientCodeException not raised")
def test_conditional_download_with_older_target(self): """Test conditional binary mode download with newer source file.""" local_target = '__test_target' # Make target file open(local_target, 'w').close() # Source is newer, so download host = test_base.ftp_host_factory( session_factory=BinaryDownloadMockSession) flag = host.download_if_newer('/home/newer', local_target, 'b') self.assertEqual(flag, True) self.compare_and_delete_downloaded_data(local_target)
def test_command_not_implemented_error(self): """ Test if we get the anticipated exception if a command isn't implemented by the server. """ host = test_base.ftp_host_factory() self.assertRaises(ftp_error.PermanentError, host.chmod, "nonexistent", 0644) # `CommandNotImplementedError` is a subclass of `PermanentError` self.assertRaises(ftp_error.CommandNotImplementedError, host.chmod, "nonexistent", 0644)
def test_synchronize_times(self): """Test time synchronization with server.""" host = test_base.ftp_host_factory(ftp_host_class=TimeShiftFTPHost, session_factory=TimeShiftMockSession) # Valid time shift host.path.set_mtime(time.time() + 3630) host.synchronize_times() self.assertEqual(host.time_shift(), 3600) # Invalid time shift host.path.set_mtime(time.time() + 3600 + 10 * 60) self.assertRaises(ftp_error.TimeShiftError, host.synchronize_times)
def test_synchronize_times(self): """Test time synchronization with server.""" host = test_base.ftp_host_factory(ftp_host_class=TimeShiftFTPHost, session_factory=TimeShiftMockSession) # Valid time shift host.path.set_mtime(time.time() + 3630) host.synchronize_times() self.assertEqual(host.time_shift(), 3600) # Invalid time shift host.path.set_mtime(time.time() + 3600+10*60) self.assertRaises(ftp_error.TimeShiftError, host.synchronize_times)
def test_rounded_time_shift(self): """Test if time shift is rounded correctly.""" host = test_base.ftp_host_factory(session_factory=TimeShiftMockSession) # Use private bound method rounded_time_shift = host._FTPHost__rounded_time_shift # Pairs consisting of original value and expected result test_data = [ (0, 0), (0.1, 0), (-0.1, 0), (1500, 0), (-1500, 0), (1800, 3600), (-1800, -3600), (2000, 3600), (-2000, -3600), (5*3600-100, 5*3600), (-5*3600+100, -5*3600)] for time_shift, expected_time_shift in test_data: calculated_time_shift = rounded_time_shift(time_shift) self.assertEqual(calculated_time_shift, expected_time_shift)
def test_ascii_writelines(self): """Write ASCII text with `writelines`.""" host = test_base.ftp_host_factory() data = [' \n', 'line 2\n', 'line 3'] backup_data = data[:] output = host.file('dummy', 'w') output.writelines(data) output.close() child_data = mock_ftplib.content_of('dummy') expected_data = ' \r\nline 2\r\nline 3' self.assertEqual(child_data, expected_data) # Ensure that the original data was not modified self.assertEqual(data, backup_data)
def test_binary_download(self): """Test binary mode download.""" local_target = '__test_target' host = test_base.ftp_host_factory( session_factory=BinaryDownloadMockSession) # Download host.download('dummy', local_target, 'b') # Read file and compare data = open(local_target, 'rb').read() remote_file_content = mock_ftplib.content_of('dummy') self.assertEqual(data, remote_file_content) # Clean up os.unlink(local_target)
def test_set_parser(self): """Test if the selected parser is used.""" # This test isn't very practical but should help at least a bit ... host = test_base.ftp_host_factory() # Implicitly fix at Unix format files = host.listdir("/home/sschwarzer") self.assertEqual(files, ['chemeng', 'download', 'image', 'index.html', 'os2', 'osup', 'publications', 'python', 'scios2']) host.set_parser(ftp_stat.MSParser()) files = host.listdir("/home/msformat/XPLaunch") self.assertEqual(files, ['WindowsXP', 'XPLaunch', 'empty', 'abcd.exe', 'O2KKeys.exe']) self.assertEqual(host._stat._allow_parser_switching, False)
def test_rounded_time_shift(self): """Test if time shift is rounded correctly.""" host = test_base.ftp_host_factory(session_factory=TimeShiftMockSession) # Use private bound method rounded_time_shift = host._FTPHost__rounded_time_shift # Pairs consisting of original value and expected result test_data = [(0, 0), (0.1, 0), (-0.1, 0), (1500, 0), (-1500, 0), (1800, 3600), (-1800, -3600), (2000, 3600), (-2000, -3600), (5 * 3600 - 100, 5 * 3600), (-5 * 3600 + 100, -5 * 3600)] for time_shift, expected_time_shift in test_data: calculated_time_shift = rounded_time_shift(time_shift) self.assertEqual(calculated_time_shift, expected_time_shift)
def test_ftputil_exception(self): with test_base.ftp_host_factory( session_factory=InaccessibleDirSession) as host: try: # This should fail since the directory isn't accessible # by definition. with host.file('/inaccessible/new_file', 'w') as f: pass except ftp_error.FTPIOError: # The file construction didn't succeed, so `f` should # be absent from the namespace. self.failIf('f' in locals()) else: raise self.failureException("ftp_error.FTPIOError not raised")
def test_ascii_read(self): """Read ASCII text with plain `read`.""" host = test_base.ftp_host_factory(session_factory=ReadMockSession) input_ = host.file('dummy', 'r') data = input_.read(0) self.assertEqual(data, '') data = input_.read(3) self.assertEqual(data, 'lin') data = input_.read(7) self.assertEqual(data, 'e 1\nano') data = input_.read() self.assertEqual(data, 'ther line\nyet another line') data = input_.read() self.assertEqual(data, '') input_.close() # Try it again with a more "problematic" string which # makes several reads in the `read` method necessary. host = test_base.ftp_host_factory(session_factory=AsciiReadMockSession) expected_data = AsciiReadMockSession.mock_file_content.\ replace('\r\n', '\n') input_ = host.file('dummy', 'r') data = input_.read(len(expected_data)) self.assertEqual(data, expected_data)
def _test_time_shift(self, supposed_time_shift, deviation=0.0): """ Check if the stat parser considers the time shift value correctly. `deviation` is the difference between the actual time shift and the supposed time shift, which is rounded to full hours. """ host = test_base.ftp_host_factory() # Explicitly use Unix format parser host._stat._parser = ftp_stat.UnixParser() host.set_time_shift(supposed_time_shift) server_time = time.time() + supposed_time_shift + deviation stat_result = host._stat._parser.parse_line(self.dir_line(server_time), host.time_shift()) self.assert_equal_times(stat_result.st_mtime, server_time)
def test_set_parser(self): """Test if the selected parser is used.""" # This test isn't very practical but should help at least a bit ... host = test_base.ftp_host_factory() # Implicitly fix at Unix format files = host.listdir("/home/sschwarzer") self.assertEqual(files, [ 'chemeng', 'download', 'image', 'index.html', 'os2', 'osup', 'publications', 'python', 'scios2' ]) host.set_parser(ftp_stat.MSParser()) files = host.listdir("/home/msformat/XPLaunch") self.assertEqual( files, ['WindowsXP', 'XPLaunch', 'empty', 'abcd.exe', 'O2KKeys.exe']) self.assertEqual(host._stat._allow_parser_switching, False)
def test_ascii_upload(self): """Test ASCII mode upload.""" local_source = '__test_source' data = ascii_data() self.generate_ascii_file(data, local_source) # Upload host = test_base.ftp_host_factory() host.upload(local_source, 'dummy') # Check uploaded content # The data which was uploaded has its line endings converted # so the conversion must also be applied to `data`. data = data.replace('\n', '\r\n') remote_file_content = mock_ftplib.content_of('dummy') self.assertEqual(data, remote_file_content) # Clean up os.unlink(local_source)
def test_assert_valid_time_shift(self): """Test time shift sanity checks.""" host = test_base.ftp_host_factory(session_factory=TimeShiftMockSession) # Use private bound method assert_time_shift = host._FTPHost__assert_valid_time_shift # Valid time shifts test_data = [23*3600, -23*3600, 3600+30, -3600+30] for time_shift in test_data: self.failUnless(assert_time_shift(time_shift) is None) # Invalid time shift (exceeds one day) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, 25*3600) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, -25*3600) # Invalid time shift (deviation from full hours unacceptable) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, 10*60) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, -3600-10*60)
def test_binary_readline(self): """Read binary data with `readline`.""" host = test_base.ftp_host_factory(session_factory=ReadMockSession) input_ = host.file('dummy', 'rb') data = input_.readline(3) self.assertEqual(data, 'lin') data = input_.readline(10) self.assertEqual(data, 'e 1\r\n') data = input_.readline(13) self.assertEqual(data, 'another line\r') data = input_.readline() self.assertEqual(data, '\n') data = input_.readline() self.assertEqual(data, 'yet another line') data = input_.readline() self.assertEqual(data, '') input_.close()
def test_assert_valid_time_shift(self): """Test time shift sanity checks.""" host = test_base.ftp_host_factory(session_factory=TimeShiftMockSession) # Use private bound method assert_time_shift = host._FTPHost__assert_valid_time_shift # Valid time shifts test_data = [23 * 3600, -23 * 3600, 3600 + 30, -3600 + 30] for time_shift in test_data: self.failUnless(assert_time_shift(time_shift) is None) # Invalid time shift (exceeds one day) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, 25 * 3600) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, -25 * 3600) # Invalid time shift (deviation from full hours unacceptable) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, 10 * 60) self.assertRaises(ftp_error.TimeShiftError, assert_time_shift, -3600 - 10 * 60)
def test_regular_isdir_isfile_islink(self): """Test regular `FTPHost._Path.isdir/isfile/islink`.""" testdir = '/home/sschwarzer' host = test_base.ftp_host_factory() host.chdir(testdir) # Test a path which isn't there self.failIf(host.path.isdir('notthere')) self.failIf(host.path.isfile('notthere')) self.failIf(host.path.islink('notthere')) # Test a directory self.failUnless(host.path.isdir(testdir)) self.failIf(host.path.isfile(testdir)) self.failIf(host.path.islink(testdir)) # Test a file testfile = '/home/sschwarzer/index.html' self.failIf(host.path.isdir(testfile)) self.failUnless(host.path.isfile(testfile)) self.failIf(host.path.islink(testfile)) # Test a link testlink = '/home/sschwarzer/osup' self.failIf(host.path.isdir(testlink)) self.failIf(host.path.isfile(testlink)) self.failUnless(host.path.islink(testlink))