def test_same_file_moved(remote, AB): # old test 08 """ Same file moved to different locations""" if AB == 'A': BA = 'B' else: BA = 'A' testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_moved_deleted_same' + AB) try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='file0') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) config.move_conflict = AB testutil.init(config) # Apply actions testutil.move('A/file0', 'A/fileA') testutil.move('B/file0', 'B/fileB') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/file' + AB) == 'file0' assert not testutil.exists('A/file' + BA) # Finally assert len(testutil.compare_tree()) == 0
def test_file_replaced_deleted_other_prev_attr(remote): """ file0 is replaced by file1 on A and file1 is deleted on B with a prev_attr of just path """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_file_replaced_deleted_other') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='file0') testutil.write('A/file1', text='file1') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) config.prev_attributesA = ['path'] # config.move_attributesA = ['path'] testutil.init(config) # Apply actions testutil.remove('B/file1') testutil.move('A/file1', 'A/file0') # Sync testutil.run(config, silent=True) # Check it -- Only need to check A # Content of file0 assert not testutil.exists('A/file1'), 'deleted' # Finally assert len(testutil.compare_tree()) == 0
def test_moved_new_in_loc(remote): # old test 05 """ File moved by A. New file placed by B in same location. see test_movedmod_new_in_loc""" testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'moved_new_in_loc') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='file0') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) config.compress_file_list = True testutil.init(config) # Apply actions testutil.move('A/file0', 'A/file1') testutil.write('B/file1', text='file_onB') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/file0') == 'file0' # Transferred back assert testutil.read('A/file1') == 'file_onB' # Overwritten by B # Expected outcome file0 on B will not be allowed to move. # file1 was ONLY moved and not modified so it will be overwritten by B # See test 14 for a similar case # Finally assert len(testutil.compare_tree()) == 0
def test_replace_deleted_with_new(remote): #old test 20 """file deleted both sides but a new one is placed there (May be hard to test well if inodes are reused) """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs','test_replace_deleted_with_new') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0',text='A0') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.remove('A/file0') testutil.remove('B/file0') testutil.write('A/file0',text='A1') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/file0') == 'A1' log_path = glob(os.path.join(testpath,'A','.PyFiSync','logs','20*.log')) log_txt = open(log_path[-1]).read() assert len(re.findall('WARNING: *File deleted on B but move.*\n.*\n.*\n *File: *file0?',log_txt,re.MULTILINE)) == 1 # Finally assert len(testutil.compare_tree()) == 0
def test_moved_deleted_same(remote): # old test 07 """ Moved on one side and deleted on the other""" testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs','test_moved_deleted_same') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0',text='file0') testutil.write('A/file3',text='file3') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.move('A/file0','A/file1') testutil.remove('B/file0') testutil.remove('A/file3') testutil.move('B/file3','B/file4') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/file1') == 'file0' assert testutil.read('A/file4') == 'file3' # Finally assert len(testutil.compare_tree()) == 0
def test_new_and_deleted_file(remote): # Old test 10 """File is created (one on both sides) each different""" testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_new_and_deleted_file') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='file0') testutil.write('A/file1', text='file1') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.write('A/fileA', text='fileA') testutil.write('B/fileB', text='fileB') testutil.remove('A/file0') testutil.remove('A/file1') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/fileA') == 'fileA', 'copy A' assert testutil.read('A/fileB') == 'fileB', 'copy B' assert not testutil.exists('A/file0') assert not testutil.exists('A/file1') # Finally assert len(testutil.compare_tree()) == 0
def test_move(): # This used to be test 01 """ File Moved. inode and birthtime tracking """ name = 'test_move' testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'move_tests', name) try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('file1.txt', text='test1') prev_attr = ['ino', 'path'] move_attr = ['ino', 'birthtime'] # Get and inject configs config = testutil.get_config() PyFiSync.config = config # old list files_old = DictTable(_file_list(testpath, config)) # Apply actions testutil.move('file1.txt', 'file2.txt') # new list and track files_new = DictTable(_file_list(testpath, config)) PyFiSync.file_track(files_old, files_new, prev_attr, move_attr) # Check assert { 'path': 'file2.txt', 'moved': True, 'prev_path': 'file1.txt' } in files_new
def test_mod_files(remote): # old test 02 """ Different Files are modified both in A and B """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs','mod_files') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file1',text='test02.a') testutil.write('A/file2',text='test02.b') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # raw_input('a') # Apply actions testutil.write('A/file1',text='test02.a',mode='a') # append it testutil.write('B/file2',text='test02.b',mode='a') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/file1') == 'test02.a\ntest02.a','file1' assert testutil.read('A/file2') == 'test02.b\ntest02.b','file2' # Finally assert len(testutil.compare_tree()) == 0
def test_untouched(): """ File is not touched """ name = 'test_untouched' testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'move_tests', name) try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('file1.txt', text='test1') prev_attr = ['ino', 'path'] move_attr = ['ino', 'birthtime'] # Get and inject configs config = testutil.get_config() PyFiSync.config = config # old list files_old = ldtable(_file_list(testpath, config)) # Apply actions # new list and track files_new = ldtable(_file_list(testpath, config)) PyFiSync.file_track(files_old, files_new, prev_attr, move_attr) # Check assert { 'path': 'file1.txt', 'untouched': True, 'prev_path': 'file1.txt' } in files_new
def test_same_file_created(remote): # Old test 11 """ Same file is created with the same content """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs','test_same_file_created') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/other',text='other') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.write('A/file',text='file',time_adj=1) testutil.write('B/file',text='file',time_adj=5) # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.exists('A/file.machineA') assert testutil.exists('B/file.machineA') assert testutil.exists('A/file.machineB') assert testutil.exists('B/file.machineB') # Finally assert len(testutil.compare_tree()) == 0
def test_file_deleted_replaced_with_move(remote): # Original test 19 """ file1 is deleted on B then file2 --> file1 on B w/o modification (see test 09) """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_file_deleted_replaced_with_move') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='file0') testutil.write('A/file1', text='file1') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.remove('B/file1') testutil.move('B/file0', 'B/file1') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.read('A/file1') == 'file0', 'content' assert not testutil.exists('A/file0'), 'deleted' # Finally assert len(testutil.compare_tree()) == 0
def test_delete_file_in_folder(remote): # Old test 12 """ file is deleted. Folder should remain """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs','test_delete_file_in_folder') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/dir/file',text='file') testutil.write('A/dir2/file2',text='file') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.remove('A/dir/file') testutil.remove('B/dir2/file2') # Sync testutil.run(config) # Check it -- should be there assert testutil.exists('A/dir/') assert testutil.exists('B/dir2/') # Should not be there assert not testutil.exists('A/dir2/') assert not testutil.exists('B/dir/')
def test_move_same_file(remote): # old test 04 """ File moved by both A and B to the same location """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs','move_same_file') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file',text='file') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.move('A/file','A/file_new') testutil.move('B/file','B/file_new') # Sync testutil.run(config) # Check it -- Only need to check A assert testutil.exists('A/file_new') assert not testutil.exists('A/file') # Finally assert len(testutil.compare_tree()) == 0
def test_git_exclude(remote, level): """ Test with git exclusions at different levels level 0: git root is outside of the sync root level 1: git root is the same as the sync root level 2: git root is below the sync root """ import subprocess testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_git_exclude/out0/') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/sub2/InGit1.txt', text='in1') testutil.write('A/sub2/InGit2.txt', text='in2') testutil.write('A/sub2/OutGit1.txt', text='out1') testutil.write('A/sub2/OutGit2.txt', text='out2') # Add some more exclusions outside of git testutil.write('A/allow.txt', text='a') testutil.write('A/exclude1.txt', text='a') testutil.write('A/exclude2.txt', text='a') # Init the git directory if level == 0: # Above the sync dirs # Copy then create the git repo testutil.copy_tree() gitroot = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_git_exclude/out0') elif level == 1: # Inside of the dirs gitroot = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_git_exclude/out0/A') elif level == 2: gitroot = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_git_exclude/out0/A/sub2') else: raise ValueError('Not Valid level') cmd = [ 'cd {}', 'echo "Out*.txt">.gitignore', 'git init .', 'git add .', 'git commit -am"first"' ] cmd = ';'.join(cmd).format(gitroot) subprocess.call(cmd, shell=True) # copy over if not level 0 if level > 0: testutil.copy_tree() # # Start it config = testutil.get_config(remote=remote) config.git_exclude = True config.excludes += ['[ae]xclude1.txt', 'exclude2.txt'] testutil.init(config) # Apply actions testutil.write('A/sub2/InGit1.txt', text='in1-updatedA') testutil.write('A/sub2/OutGit1.txt', text='out1-updatedA') testutil.write('B/sub2/InGit2.txt', text='in1-updatedB') testutil.write('B/sub2/OutGit2.txt', text='out1-updatedB') testutil.write('A/exclude2.txt', text='aa') testutil.write('B/exclude1.txt', text='bb') # Sync testutil.run(config) # Check it -- Only need to check A diffs = testutil.compare_tree() # The files should disagree assert ('disagree', 'sub2/InGit1.txt') in diffs assert testutil.read('A/sub2/InGit1.txt') == 'in1-updatedA' assert ('disagree', 'sub2/InGit2.txt') in diffs assert testutil.read('B/sub2/InGit2.txt') == 'in1-updatedB' assert (u'disagree', u'exclude1.txt') in diffs assert (u'disagree', u'exclude2.txt') in diffs # No other differences assert len(diffs) == 4
def test_symlinks(remote, symlinks): """ test symlinked files and folders """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_symlinks') print('symlinks', symlinks) try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='A0') # just to have a file # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) config.copy_symlinks_as_links = not symlinks # config.symlinks = symlinks testutil.init(config) # Apply actions # Create symlinks OUTSIDE of the sync dir!!!! testutil.write('source/file1', text='S1') testutil.write('source/dir/file2', text='S2') testutil.write('source/dir/file3', text='S3') os.symlink(os.path.join(testpath, 'source/file1'), os.path.join(testpath, 'A/file1_link')) os.symlink(os.path.join(testpath, 'source/dir'), os.path.join(testpath, 'A/dir_link')) # Sync testutil.run(config) ## Check # Make sure the linked files are there in A assert testutil.read('A/file1_link') == 'S1', 'linked file' assert testutil.read('A/dir_link/file2') == 'S2', 'linked file' assert testutil.read('A/dir_link/file3') == 'S3', 'linked file' # Missing files will be caught in the dir equivalence test diff = testutil.compare_tree() assert len(diff) == 0 if symlinks: # Make sure the file got copies assert not os.path.islink(os.path.join(testpath, 'B', 'file1_link')) else: # Make sure the link got copied assert os.path.islink(os.path.join(testpath, 'B', 'file1_link')) # NOTE: directories are ALWAYS followed. Just make sure: assert os.path.islink(os.path.join(testpath, 'A', 'dir_link')) assert not os.path.islink(os.path.join(testpath, 'B', 'dir_link')) # Again, directories are always followed and the files within are treated as new. assert not os.path.islink(os.path.join(testpath, 'A', 'dir_link', 'file2')) assert not os.path.islink(os.path.join(testpath, 'A', 'dir_link', 'file3')) assert not os.path.islink(os.path.join(testpath, 'B', 'dir_link', 'file2')) assert not os.path.islink(os.path.join(testpath, 'B', 'dir_link', 'file3')) assert not os.stat(os.path.join( testpath, 'A', 'dir_link', 'file2')).st_ino == os.stat( os.path.join(testpath, 'B', 'dir_link', 'file2')).st_ino
def test_moved_file_size_track(remote): # Old test 17 """ test moved files with size tracking rather than birthtime on one side with modifications""" testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'test_moved_file_size_track') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/file0', text='F0') testutil.write('A/file1', text='F1') testutil.write('A/file2', text='F2') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) # Set A to be birthtime and B to be size config.move_attributesA = ['ino', 'birthtime'] config.move_attributesB = ['ino', 'size'] testutil.init(config) # Apply actions testutil.write('A/file0', text='F0', mode='a') testutil.move('A/file0', 'A/file00') # Should move with ino tracking testutil.write('B/file1', text='F1', mode='a') testutil.move('B/file1', 'B/file11') # Should register as delete and new testutil.move('B/file2', 'B/file22') # Should move since it didn't change size # Sync testutil.run(config) # Check it -- Only need to check A log_path = glob(os.path.join(testpath, 'A', '.PyFiSync', 'logs', '20*.log')) log_txt = open(log_path[-1]).read() # Should move assert len(re.findall('move: *file2 *--> *file22', log_txt)) == 1 assert len(re.findall('move: *file0 *--> *file00', log_txt)) == 1 # Not found assert len(re.findall('move: *file1 *--> *file11', log_txt)) == 0 # Make sure it was deleted. (and that this regex didn't capture too much assert len(re.findall('delete.*?: file1', log_txt)) == 1 assert len(re.findall('delete.*?: file1', log_txt)[0]) <= 50 # Should transfer assert len(re.findall('Transfer *file11', log_txt)) == 1 assert len(re.findall('Transfer *file00', log_txt)) == 1 # Should NOT transfer assert len(re.findall('Transfer *file22', log_txt)) == 0 # Finally assert len(testutil.compare_tree()) == 0
def test_move_overwrite(remote, AB, all_): """ A file move that will overwrite on recieveing end. Check backups """ testpath = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'test_dirs', 'pp', 'test_move_overwrite') try: shutil.rmtree(testpath) except: pass os.makedirs(testpath) testutil = testutils.Testutils(testpath=testpath) # Init testutil.write('A/fileA0', text='fileA0') testutil.write('A/fileB0', text='fileB0') # copy over testutil.copy_tree() # Start it config = testutil.get_config(remote=remote) testutil.init(config) # Apply actions testutil.write('A/fileA1', text='fileA1') testutil.move('A/fileA0', 'A/fileB1') testutil.write('B/fileB1', text='fileB1') testutil.move('B/fileB0', 'B/fileA1') # Sync if AB == 'A': mode = 'push' else: mode = 'pull' if all_: mode += '_all' testutil.run(config, mode=mode) # Check it -- Only need to check A diff = testutil.compare_tree() if AB == 'A': # Check backups in B backB = glob(os.path.join(testpath, 'B', '.PyFiSync', 'backups', '20*'))[0] if all_: # This file gets backed up before move but then the later upload # tries to overwrite. fileB1 is not changed so it doesn't happen # when not using --all assert open(os.path.join(backB, 'fileB1.0')).read().strip() == 'fileA0' # Overwritten file should be backed up assert open(os.path.join(backB, 'fileB1')).read().strip() == 'fileB1' # Backed up file on transfer assert open(os.path.join(backB, 'fileA1')).read().strip() == 'fileB0' else: backA = glob(os.path.join(testpath, 'A', '.PyFiSync', 'backups', '20*'))[0] if all_: # This file gets backed up before move but then the later upload # tries to overwrite. fileA1 is not changed so it doesn't happen # when not using --all assert open(os.path.join(backA, 'fileA1.0')).read().strip() == 'fileB0' # Overwritten file should be backed up assert open(os.path.join(backA, 'fileA1')).read().strip() == 'fileA1' # Backed up file on transfer assert open(os.path.join(backA, 'fileB1')).read().strip() == 'fileA0'