def test_create_both_sd_same_dir_diff_file(test_name, sd1, sd2, sd3, prefix): """14. Create different files in same dir in both SDs. Create at the same time on one client a directory with file A, and on the other client the same directory with file B. Check that both files are propagated ok. """ # create both dirs with different files os.mkdir(os.path.join(sd1.rootdir, 'dir')) os.mkdir(os.path.join(sd2.rootdir, 'dir')) open(os.path.join(sd1.rootdir, 'dir', 'file1.txt'), 'w').close() open(os.path.join(sd2.rootdir, 'dir', 'file2.txt'), 'w').close() debug(prefix, "Dir and files created in both SDs") # wait for both to settle, and get the files in both yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) files1 = walk_and_list_dir(os.path.join(sd1.rootdir, 'dir')) files2 = walk_and_list_dir(os.path.join(sd2.rootdir, 'dir')) # both files should be on both assert "file1.txt" in files1, "file 1 should be in SD1: %s" % (files1,) assert "file2.txt" in files1, "file 2 should be in SD1: %s" % (files1,) assert "file1.txt" in files2, "file 1 should be in SD2: %s" % (files2,) assert "file2.txt" in files2, "file 2 should be in SD2: %s" % (files2,)
def test_create_tree_and_rename(test_name, sd1, sd2, sd3, prefix): """15. Create a tree and rename parent. Create a directory, with one subdir, and other subdir under the later, and a file as a leaf (root/a/b/c.txt). Wait for nirvana. Rename the first subdir (a). Check. """ # create the tree and wait for it to finish os.makedirs(os.path.join(sd1.rootdir, 'a', 'b')) open(os.path.join(sd1.rootdir, 'a', 'b', 'c.txt'), 'w').close() debug(prefix, "Dir and files created in SD1") yield sd1.sdt.wait_for_nirvana(.5) # rename the parent, wait for both to settle, and get the files in both os.rename( os.path.join(sd1.rootdir, 'a'), os.path.join(sd1.rootdir, 'nuevo')) debug(prefix, "Parent renamed") yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) files1 = walk_and_list_dir(sd1.rootdir) files2 = walk_and_list_dir(sd2.rootdir) # both trees should be on both, and old 'a' on neither of them assert "nuevo/b/c.txt" in files1, "tree not in SD1: %s" % (files1,) assert "nuevo/b/c.txt" in files2, "tree not in SD2: %s" % (files2,) assert 'a' not in files1, "'a' should not be in SD1: %s" % (files1,) assert 'a' not in files2, "'a' should not be in SD1: %s" % (files2,)
def test_create_both_sd_different_content(test_name, sd1, sd2, sd3, prefix): """11. Create files with different content in both SDs. Create at the same time on each client two files with same name and different content. Check that one of both gets conflicted. """ # create both files with content c1 = os.urandom(1000) c2 = c1[::-1] create_file_and_add_content( os.path.join(sd1.rootdir, 'file.txt'), content=c1) create_file_and_add_content( os.path.join(sd2.rootdir, 'file.txt'), content=c2) debug(prefix, "Files with different content created in both SDs") # wait for both to settle, and get the files in both yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) files1 = walk_and_list_dir(sd1.rootdir) debug(prefix, "Files in SD1", files1) files2 = walk_and_list_dir(sd2.rootdir) debug(prefix, "Files in SD2", files2) # file.txt should be on both assert "file.txt" in files1, "the file.txt should be in SD1" assert "file.txt" in files2, "the file.txt should be in SD2" # one of them should have a conflict, and the other should not conflict1 = "file.txt.u1conflict" in files1 conflict2 = "file.txt.u1conflict" in files2 assert conflict1 and not conflict2 or conflict2 and not conflict1, \ "Only one of both should have conflict!"
def test_remove_udf(udf_name, sd1, sd2, sd3, prefix): """Test 8: Remove an UDF, assert correct deletion on both clients.""" yield create_udf(udf_name, sd1, prefix) yield sd2.sdt.wait_for_nirvana(.5) assert os.path.exists(os.path.join(sd2.homedir, udf_name)) actual1 = walk_and_list_dir(os.path.join(sd1.homedir, udf_name)) actual2 = walk_and_list_dir(os.path.join(sd2.homedir, udf_name)) debug(prefix, "contents for SD1", actual1) assert actual1 == actual2 debug(prefix, "Removing the UDF:", udf_name) shutil.rmtree(os.path.join(sd1.homedir, udf_name)) yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) events = [event['event_name'] for event in sd2.events] assert 'VM_VOLUME_DELETED' in events, 'VM_UDF_DELETED in sd2.events' debug(prefix, "VM_VOLUME_DELETED found on SD2") msg = 'UDF\'s contents must be deleted from file system on SD2.' udf_content = os.listdir(os.path.join(sd2.homedir, udf_name)) debug(prefix, 'contents for SD2', udf_content) assert udf_content == [], msg
def test_remove_udf(udf_name, sd1, sd2, sd3, prefix): """Test 8: Remove an UDF, assert correct deletion on both clients.""" yield create_udf(udf_name, sd1, prefix) yield sd2.sdt.wait_for_nirvana(.5) assert os.path.exists(os.path.join(sd2.homedir, udf_name)) actual1 = walk_and_list_dir(os.path.join(sd1.homedir, udf_name)) actual2 = walk_and_list_dir(os.path.join(sd2.homedir, udf_name)) debug(prefix, "contents for SD1", actual1) assert actual1 == actual2 debug(prefix, "Removing the UDF:", udf_name) shutil.rmtree(os.path.join(sd1.homedir, udf_name)) yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) events = [event['event_name'] for event in sd2.events] assert 'VM_VOLUME_DELETED' in events, 'VM_UDF_DELETED in sd2.events' debug(prefix, "VM_VOLUME_DELETED found on SD2") msg = 'UDF\'s contents must be deleted from file system on SD2.' udf_content = os.listdir(os.path.join(sd2.homedir, udf_name)) debug(prefix, 'contents for SD2', udf_content) assert udf_content == [], msg
def test_delete_tree_touched_ok(test_name, sd1, sd2, sd3, prefix): """19. Delete a tree on one side that has a deleted file in the other. Create a directory, with a subdir and a file in the later. Wait for nirvana. At the same time on one client unlink the file, and on the other client remove everything. Check that all is deleted ok. """ # create the tree and wait os.makedirs(os.path.join(sd1.rootdir, 'dir1', 'dir2')) create_file_and_add_content( os.path.join(sd1.rootdir, 'dir1', 'dir2', 'file.txt')) yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, "Tree created and propagated") # remove everything on one side, and unlink on the other shutil.rmtree(os.path.join(sd2.rootdir, 'dir1')) os.remove(os.path.join(sd1.rootdir, 'dir1', 'dir2', 'file.txt')) debug(prefix, "Deletes executed") # wait yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) debug(prefix, "Nirvana reached on both") # check files files1 = walk_and_list_dir(sd1.rootdir) files2 = walk_and_list_dir(sd2.rootdir) assert files1 == [], "Bad files in SD1: %s" % (files1,) assert files2 == [], "Bad files in SD2: %s" % (files2,)
def test_create_both_sd_same_content(test_name, sd1, sd2, sd3, prefix): """13. Create files with same content in both SDs. Create at the same time on each client two files with same name and same content. Check. """ # create both files with same content data = os.urandom(1000) create_file_and_add_content( os.path.join(sd1.rootdir, 'file.txt'), content=data) create_file_and_add_content( os.path.join(sd2.rootdir, 'file.txt'), content=data) debug(prefix, "Files with same content created in both SDs") # wait for both to settle, and get the files in both yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) files1 = walk_and_list_dir(sd1.rootdir) files2 = walk_and_list_dir(sd2.rootdir) # file.txt should be on both, and no conflict at all assert "file.txt" in files1, "the file should be in SD1: %s" % (files1,) assert "file.txt.u1conflict" not in files1, "conflict SD1: %s" % (files1,) assert "file.txt" in files2, "the file should be in SD2: %s" % (files2,) assert "file.txt.u1conflict" not in files2, "conflict SD2: %s" % (files2,)
def test_disconnect_modify_connect(udf_name, sd1, sd2, sd3, prefix): """Test 13: Create UDF, disconnect SD, do stuff, and then reconnect.""" folder = yield create_udf(udf_name, sd1, prefix) folder_path = folder['path'] other_dir = os.path.join(folder_path, 'other_dir') os.mkdir(other_dir) third_dir = os.path.join(folder_path, 'third_dir') os.mkdir(third_dir) yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, 'Disconnecting SD1.') yield sd1.sdt.disconnect() # disconnect SD1 debug(prefix, 'Doing stuff in the file system of SD1.') # do stuff in the file system xyz_dir = os.path.join(folder_path, 'x', 'y', 'z') os.makedirs(xyz_dir) create_file_and_add_content(os.path.join(xyz_dir, 'new.txt')) # move a file within the UDF os.rename(os.path.join(folder_path, 'a_dir', 'a_file.txt'), os.path.join(xyz_dir, 'renamed_file.txt')) # move a folder outside the UDF to the root dir os.rename(os.path.join(folder_path, 'other_dir'), os.path.join(sd1.rootdir, udf_name + 'renamed_other_dir')) # move a folder outside the UDF to the home dir renamed_third_dir = os.path.join(sd1.homedir, 'renamed_third_dir') os.rename(os.path.join(folder_path, 'third_dir'), renamed_third_dir) expected = set(walk_and_list_dir(sd1.homedir)) debug(prefix, "Expected to have", expected) debug(prefix, 'Re connecting SD1.') yield sd1.sdt.connect() # re-connect SD1 yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, 'Waiting for nirvana for SD2.') yield sd2.sdt.wait_for_nirvana(.5) # wait for SD2 to get all the changes actual = set(walk_and_list_dir(sd2.homedir)) debug(prefix, "Currently found", actual) debug(prefix, 'expected sym diff actual', expected.symmetric_difference(actual)) assert expected.difference(actual) == set(['renamed_third_dir']), \ 'SD1 home must have the same as SD2 except for renamed_third_dir.' assert actual.difference(expected) == set([]), \ 'SD2 home must have nothing extra than the SD1\'s.'
def test_disconnect_modify_connect(udf_name, sd1, sd2, sd3, prefix): """Test 13: Create UDF, disconnect SD, do stuff, and then reconnect.""" folder = yield create_udf(udf_name, sd1, prefix) folder_path = folder['path'] other_dir = os.path.join(folder_path, 'other_dir') os.mkdir(other_dir) third_dir = os.path.join(folder_path, 'third_dir') os.mkdir(third_dir) yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, 'Disconnecting SD1.') yield sd1.sdt.disconnect() # disconnect SD1 debug(prefix, 'Doing stuff in the file system of SD1.') # do stuff in the file system xyz_dir = os.path.join(folder_path, 'x', 'y', 'z') os.makedirs(xyz_dir) create_file_and_add_content(os.path.join(xyz_dir, 'new.txt')) # move a file within the UDF os.rename(os.path.join(folder_path, 'a_dir', 'a_file.txt'), os.path.join(xyz_dir, 'renamed_file.txt')) # move a folder outside the UDF to the root dir os.rename(os.path.join(folder_path, 'other_dir'), os.path.join(sd1.rootdir, udf_name + 'renamed_other_dir')) # move a folder outside the UDF to the home dir renamed_third_dir = os.path.join(sd1.homedir, 'renamed_third_dir') os.rename(os.path.join(folder_path, 'third_dir'), renamed_third_dir) expected = set(walk_and_list_dir(sd1.homedir)) debug(prefix, "Expected to have", expected) debug(prefix, 'Re connecting SD1.') yield sd1.sdt.connect() # re-connect SD1 yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, 'Waiting for nirvana for SD2.') yield sd2.sdt.wait_for_nirvana(.5) # wait for SD2 to get all the changes actual = set(walk_and_list_dir(sd2.homedir)) debug(prefix, "Currently found", actual) debug(prefix, 'expected sym diff actual', expected.symmetric_difference(actual)) assert expected.difference(actual) == set(['renamed_third_dir']), \ 'SD1 home must have the same as SD2 except for renamed_third_dir.' assert actual.difference(expected) == set([]), \ 'SD2 home must have nothing extra than the SD1\'s.'
def test_rename_dir_create_same_name(test_name, sd1, sd2, sd3, prefix): """17. Create directory, rename it and create other with same name. Create a directory with a file A in it. Wait for nirvana. Rename the directory and immediately after create other directory with same name, and file B in it. Check. """ # create the directory, file, and wait os.mkdir(os.path.join(sd1.rootdir, 'direct')) open(os.path.join(sd1.rootdir, 'direct', 'fileA.txt'), 'w').close() debug(prefix, "Directory with file A created") yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, "Nirvana reached") # rename the directory, create again, and a new file os.rename( os.path.join(sd1.rootdir, 'direct'), os.path.join(sd1.rootdir, 'newdir')) os.mkdir(os.path.join(sd1.rootdir, 'direct')) open(os.path.join(sd1.rootdir, 'direct', 'fileB.txt'), 'w').close() debug(prefix, "Directory renamed and created new one with file B") yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) debug(prefix, "Nirvana reached on both") # check in sd2 files = walk_and_list_dir(sd2.rootdir) shouldbe = ['direct', 'direct/fileB.txt', 'newdir', 'newdir/fileA.txt'] assert files == shouldbe, "Bad files in SD2: %s" % (files,)
def test_unsuscribe_delete_subscribe(udf_name, sd1, sd2, sd3, prefix): """Test 14: unsubscribe and subsc., removing everything in the middle.""" # create udf folder = yield create_udf(udf_name, sd1, prefix) folder_id = folder["volume_id"] udf_path = folder["path"] debug(prefix, 'create_folder completed!', folder) assert folder['subscribed'], 'sd1 must be subscribed' yield sd1.sdt.wait_for_nirvana(.5) # un-subscribe and check yield sd1.sdt.unsubscribe_folder(folder_id) folders = yield sd1.sdt.get_folders() assert len(folders) == 1, "SD1 has udfs != 1 (%d)" % len(folders) assert not folders[0]['subscribed'], 'sd1 must NOT be subscribed' debug(prefix, 'unsubscribed!') # remove everything shutil.rmtree(udf_path) debug(prefix, 'everything removed from disk') yield sd1.sdt.wait_for_nirvana(.5) # subscribe and wait yield sd1.sdt.subscribe_folder(folder_id) folders = yield sd1.sdt.get_folders() assert len(folders) == 1, "SD1 has udfs != 1 (%d)" % len(folders) assert folders[0]['subscribed'], 'sd1 must be subscribed' yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, 'subscribed!') # check stuff in disk for sd1 in_disk = walk_and_list_dir(udf_path) expected = ['a_dir', os.path.join('a_dir', 'a_file.txt')] assert in_disk == expected, \ "Wrong stuff in disk: %s (expected: %s)" % (in_disk, expected)
def test_create_tree_internal_move(test_name, sd1, sd2, sd3, prefix): """18. Create tree and do internal move. Create a directory, with a subdir and a file in the later; immediately after move the file one dir up. Check. """ # create the tree and do the move os.makedirs(os.path.join(sd1.rootdir, 'dir1', 'dir2')) content = create_file_and_add_content( os.path.join(sd1.rootdir, 'dir1', 'dir2', 'file.txt')) os.rename(os.path.join(sd1.rootdir, 'dir1', 'dir2', 'file.txt'), os.path.join(sd1.rootdir, 'dir1', 'file.txt')) debug(prefix, "Tree created and file moved") yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) debug(prefix, "Nirvana reached on both") # check files in sd2 files = walk_and_list_dir(sd2.rootdir) shouldbe = ['dir1', 'dir1/dir2', 'dir1/file.txt'] assert files == shouldbe, "Bad files in SD2: %s" % (files,) # check content is ok fname = os.path.join(sd2.rootdir, 'dir1', 'file.txt') with open(fname) as f: assert content == f.read()
def test_unsuscribe_delete_subscribe(udf_name, sd1, sd2, sd3, prefix): """Test 14: unsubscribe and subsc., removing everything in the middle.""" # create udf folder = yield create_udf(udf_name, sd1, prefix) folder_id = folder["volume_id"] udf_path = folder["path"] debug(prefix, 'create_folder completed!', folder) assert folder['subscribed'], 'sd1 must be subscribed' yield sd1.sdt.wait_for_nirvana(.5) # un-subscribe and check yield sd1.sdt.unsubscribe_folder(folder_id) folders = yield sd1.sdt.get_folders() assert len(folders) == 1, "SD1 has udfs != 1 (%d)" % len(folders) assert not folders[0]['subscribed'], 'sd1 must NOT be subscribed' debug(prefix, 'unsubscribed!') # remove everything shutil.rmtree(udf_path) debug(prefix, 'everything removed from disk') yield sd1.sdt.wait_for_nirvana(.5) # subscribe and wait yield sd1.sdt.subscribe_folder(folder_id) folders = yield sd1.sdt.get_folders() assert len(folders) == 1, "SD1 has udfs != 1 (%d)" % len(folders) assert folders[0]['subscribed'], 'sd1 must be subscribed' yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, 'subscribed!') # check stuff in disk for sd1 in_disk = walk_and_list_dir(udf_path) expected = ['a_dir', os.path.join('a_dir', 'a_file.txt')] assert in_disk == expected, \ "Wrong stuff in disk: %s (expected: %s)" % (in_disk, expected)
def test_merge_directories_no_overlap(udf_name, sd1, sd2, sd3, prefix): """Test 4: Assert directories are correctly merged if no overlapping.""" folderdir1 = os.path.join(sd1.homedir, udf_name) folderdir2 = os.path.join(sd2.homedir, udf_name) expected = [] os.mkdir(folderdir1) # add folders and files to folderdir1 on_sd1 = [] for d in ('a', 'b', 'c'): dirpath = os.path.join(folderdir1, d) os.makedirs(dirpath) expected.append(d) for f in ('foo1.txt', 'bar1.txt', 'syncdaemon1.log'): # flip a coin if random.random() < 0.5: filepath = os.path.join(dirpath, f) open(filepath, 'w').close() on_sd1.append(os.path.join(d, f)) debug(prefix, "created in sd1", on_sd1) expected.extend(on_sd1) os.mkdir(folderdir2) on_sd2 = [] # add folders and files to folderdir2 for d in ('z', 'y', 'x'): dirpath = os.path.join(folderdir2, d) os.makedirs(dirpath) expected.append(d) for f in ('foo2.txt', 'bar2.txt', 'syncdaemon2.log'): # flip a coin if random.random() < 0.5: filepath = os.path.join(dirpath, f) open(filepath, 'w').close() on_sd2.append(os.path.join(d, f)) debug(prefix, "created in sd2", on_sd2) expected.extend(on_sd2) expected.sort() debug(prefix, "Expected", expected) # create the folder on sd1 and wait sd2 to finish working yield sd1.sdt.create_folder(path=folderdir1) yield sd1.sdt.wait_for_nirvana(.5) folders = yield sd1.sdt.get_folders() debug(prefix, 'get_folders completed!', folders) assert len(folders) == 1 # UDF was reported as expected yield sd2.sdt.wait_for_nirvana(.5) actual = walk_and_list_dir(folderdir2) debug(prefix, 'Found in SD2', actual) assert expected == actual, 'directory merge successful'
def test_merge_directories_no_overlap(udf_name, sd1, sd2, sd3, prefix): """Test 4: Assert directories are correctly merged if no overlapping.""" folderdir1 = os.path.join(sd1.homedir, udf_name) folderdir2 = os.path.join(sd2.homedir, udf_name) expected = [] os.mkdir(folderdir1) # add folders and files to folderdir1 on_sd1 = [] for d in ('a', 'b', 'c'): dirpath = os.path.join(folderdir1, d) os.makedirs(dirpath) expected.append(d) for f in ('foo1.txt', 'bar1.txt', 'syncdaemon1.log'): # flip a coin if random.random() < 0.5: filepath = os.path.join(dirpath, f) open(filepath, 'w').close() on_sd1.append(os.path.join(d, f)) debug(prefix, "created in sd1", on_sd1) expected.extend(on_sd1) os.mkdir(folderdir2) on_sd2 = [] # add folders and files to folderdir2 for d in ('z', 'y', 'x'): dirpath = os.path.join(folderdir2, d) os.makedirs(dirpath) expected.append(d) for f in ('foo2.txt', 'bar2.txt', 'syncdaemon2.log'): # flip a coin if random.random() < 0.5: filepath = os.path.join(dirpath, f) open(filepath, 'w').close() on_sd2.append(os.path.join(d, f)) debug(prefix, "created in sd2", on_sd2) expected.extend(on_sd2) expected.sort() debug(prefix, "Expected", expected) # create the folder on sd1 and wait sd2 to finish working yield sd1.sdt.create_folder(path=folderdir1) yield sd1.sdt.wait_for_nirvana(.5) folders = yield sd1.sdt.get_folders() debug(prefix, 'get_folders completed!', folders) assert len(folders) == 1 # UDF was reported as expected yield sd2.sdt.wait_for_nirvana(.5) actual = walk_and_list_dir(folderdir2) debug(prefix, 'Found in SD2', actual) assert expected == actual, 'directory merge successful'
def test_create_folder(udf_name, sd1, sd2, sd3, prefix): """Test 1: Assert correct folder creation.""" wait_for_udf_created = sd2.wait_for_event('VM_UDF_CREATED') yield create_udf(udf_name, sd1, prefix) yield wait_for_udf_created yield sd2.sdt.wait_for_nirvana(.5) folderdir1 = os.path.join(sd1.homedir, udf_name) folderdir2 = os.path.join(sd2.homedir, udf_name) expected = walk_and_list_dir(folderdir1) actual = walk_and_list_dir(folderdir2) debug(prefix, 'expected', expected) debug(prefix, 'actual', actual) assert expected == actual, 'UDF must be replicated correctly' with open(os.path.join(folderdir1, expected[-1])) as fd: content1 = fd.read() with open(os.path.join(folderdir1, actual[-1])) as fd: content2 = fd.read() assert content1 == content2, 'file content macth'
def test_create_folder(udf_name, sd1, sd2, sd3, prefix): """Test 1: Assert correct folder creation.""" wait_for_udf_created = sd2.wait_for_event('VM_UDF_CREATED') yield create_udf(udf_name, sd1, prefix) yield wait_for_udf_created yield sd2.sdt.wait_for_nirvana(.5) folderdir1 = os.path.join(sd1.homedir, udf_name) folderdir2 = os.path.join(sd2.homedir, udf_name) expected = walk_and_list_dir(folderdir1) actual = walk_and_list_dir(folderdir2) debug(prefix, 'expected', expected) debug(prefix, 'actual', actual) assert expected == actual, 'UDF must be replicated correctly' with open(os.path.join(folderdir1, expected[-1])) as fd: content1 = fd.read() with open(os.path.join(folderdir1, actual[-1])) as fd: content2 = fd.read() assert content1 == content2, 'file content macth'
def test_create_both_sd_empty(test_name, sd1, sd2, sd3, prefix): """12. Create empty files in both SDs. Create at the same time on each client two empty files with the same name. Check. """ # create two empty files in the SDs open(os.path.join(sd1.rootdir, 'file.txt'), 'w').close() open(os.path.join(sd2.rootdir, 'file.txt'), 'w').close() debug(prefix, "Empty files created in both SDs") # wait for both to settle, and get the files in both yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) files1 = walk_and_list_dir(sd1.rootdir) files2 = walk_and_list_dir(sd2.rootdir) # file.txt should be on both, and no conflict at all assert "file.txt" in files1, "the file should be in SD1: %s" % (files1,) assert "file.txt.u1conflict" not in files1, "conflict SD1: %s" % (files1,) assert "file.txt" in files2, "the file should be in SD2: %s" % (files2,) assert "file.txt.u1conflict" not in files2, "conflict SD2: %s" % (files2,)
def test_delete_tree_touched_conflict(test_name, sd1, sd2, sd3, prefix): """20. Delete a tree on one side that has a renamed file in the other. Create a directory, with a subdir and a file in the later. Wait for nirvana. Disconnect SD1 and remove everything in SD2. Write something to the file in SD1 and connect again. Check that in SD2 all is gone, but in SD1 the directory is not deleted but conflicted. """ # create the tree and wait os.makedirs(os.path.join(sd1.rootdir, 'dir1', 'dir2')) create_file_and_add_content( os.path.join(sd1.rootdir, 'dir1', 'dir2', 'file.txt')) yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) yield sd1.sdt.disconnect() debug(prefix, "Tree created and propagated; sd1 disconnected") # remove everything on one side shutil.rmtree(os.path.join(sd2.rootdir, 'dir1')) yield sd2.sdt.wait_for_nirvana(.5) debug(prefix, "Delete executed") # change sd1 and reconnect fname = os.path.join(sd1.rootdir, 'dir1', 'dir2', 'file.txt') with open(fname, 'w') as fh: fh.write(os.urandom(10)) yield sd1.sdt.connect() yield sd1.sdt.wait_for_nirvana(.5) debug(prefix, "Wrote in SD1 and reconnected") # check files files2 = walk_and_list_dir(sd2.rootdir) assert files2 == [], "Bad files in SD2: %s" % (files2,) files1 = walk_and_list_dir(sd1.rootdir) shouldbe = ['dir1.u1conflict', 'dir1.u1conflict/dir2.u1conflict', 'dir1.u1conflict/dir2.u1conflict/file.txt.u1conflict'] assert files1 == shouldbe, "Bad files in SD1: %s" % (files1,)
def test_create_tree_and_remove_it(test_name, sd1, sd2, sd3, prefix): """16. Create tree and remove it. Create a tree structure with some dirs and some files in some of them. Wait for nirvana. Remove everything as fast as possible. Check. """ # create some tree structure with files deepdir = os.path.join(sd1.rootdir, *'abcd') os.makedirs(deepdir) create_file_and_add_content(os.path.join(deepdir, 'file1.txt')) create_file_and_add_content(os.path.join(deepdir, 'file2.txt')) open(os.path.join(deepdir, 'file2.txt'), 'w').close() deepdir = os.path.join(sd1.rootdir, *'abjk') os.makedirs(deepdir) create_file_and_add_content(os.path.join(deepdir, 'file3.txt')) open(os.path.join(deepdir, 'file4.txt'), 'w').close() deepdir = os.path.join(sd1.rootdir, 'a') create_file_and_add_content(os.path.join(deepdir, 'file5.txt')) open(os.path.join(deepdir, 'file6.txt'), 'w').close() debug(prefix, "Tree structure created with files in it") # wait for both to settle, and remove everything yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) shutil.rmtree(os.path.join(sd1.rootdir, 'a')) debug(prefix, "rmtree finished") # wait for everything to finish, get both files list and check yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) files1 = walk_and_list_dir(sd1.rootdir) files2 = walk_and_list_dir(sd2.rootdir) assert files1 == [], "bad info in SD1: %s" % (files1,) assert files2 == [], "bad info in SD1: %s" % (files2,)
def test_unsusc_lotofchanges_subsc(udf_name, sd1, sd2, sd3, prefix): """Test 19: Merge should be done correctly.""" # some dirs and files udf_dir = os.path.join(sd1.homedir, udf_name) dir_a = os.path.join(udf_dir, "a") file_1 = os.path.join(dir_a, "file1") file_2 = os.path.join(dir_a, "file2") file_3 = os.path.join(dir_a, "file3") dir_b = os.path.join(udf_dir, "b") dir_c = os.path.join(udf_dir, "c") dir_d = os.path.join(udf_dir, "d") # we create an UDF and put: # - dir_a, with: # - file_1 # - file_2 # - dir_b # - dir_c folder, = yield sd1.sdt.create_folder(path=udf_dir) folder_id = folder["volume_id"] for d in (dir_a, dir_b, dir_c): os.mkdir(d) for f in (file_1, file_2): open(f, "w").close() debug(prefix, 'initial UDF completed!') yield sd1.sdt.wait_for_nirvana(.5) # unsubscribe yield sd1.sdt.unsubscribe_folder(folder_id) debug(prefix, 'unsubscribed!') # some changes: os.rmdir(dir_c) os.mkdir(dir_d) os.remove(file_2) open(file_3, "w").close() debug(prefix, 'changes made!') yield sd1.sdt.wait_for_nirvana(1) # subscribe again yield sd1.sdt.subscribe_folder(folder_id) debug(prefix, 'subscribed!') yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) debug(prefix, 'changes propagated') # what the merge should do: # - dir_c is back from the server # - dir_d uploaded # - file_2 is back from the server # - file_3 uploaded to the server # - the rest should remain unchanged # to check, we verify everything in both clients expected = ['a', 'a/file1', 'a/file2', 'a/file3', 'b', 'c', 'd'] for which, sd in enumerate((sd1, sd2)): debug(prefix, 'check SD', sd) udf_dir = os.path.join(sd.homedir, udf_name) in_disk = walk_and_list_dir(udf_dir) assert in_disk == expected, "sd %s has bad stuff in "\ "disk: %s" % (which, in_disk)
def test_merge_directories_with_overlap(udf_name, sd1, sd2, sd3, prefix): """Test 5: Assert directories are correctly merge with overlapping.""" # Structure to start # # client 1: # .../a # .../a/conflict.txt (content random) # .../a/noconflict.txt (same content that 2) # .../a/bar.txt # .../b # # client 2: # .../a # .../a/conflict.txt (content random) # .../a/noconflict.txt (same content that 1) # .../a/beer.txt # .../c # # Result after UDF creation and merge: # # .../a/bar.txt and .../b are synced to client 2 # .../a/beer.txt and .../c are synced to client 1 # .../a/conflict.txt stays the same in one client, and in the other it # goes to conflict (depending on which got first to the server) # .../a/noconflict.txt stays ok in both clients # folderdir1 = os.path.join(sd1.homedir, udf_name) folderdir2 = os.path.join(sd2.homedir, udf_name) os.mkdir(folderdir1) # add folders and files to folderdir1 dirpath = os.path.join(folderdir1, 'a') os.makedirs(dirpath) filepath = os.path.join(dirpath, 'conflict.txt') create_file_and_add_content(filepath, content='content from SD1') filepath = os.path.join(dirpath, 'noconflict.txt') with open(filepath, "w") as fh: fh.write("same content") filepath = os.path.join(dirpath, 'bar.txt') create_file_and_add_content(filepath) dirpath = os.path.join(folderdir1, 'b') os.makedirs(dirpath) os.mkdir(folderdir2) # add folders and files to folderdir2 dirpath = os.path.join(folderdir2, 'a') os.makedirs(dirpath) filepath = os.path.join(dirpath, 'conflict.txt') create_file_and_add_content(filepath, content='content from SD2') filepath = os.path.join(dirpath, 'noconflict.txt') with open(filepath, "w") as fh: fh.write("same content") filepath = os.path.join(dirpath, 'beer.txt') create_file_and_add_content(filepath) dirpath = os.path.join(folderdir1, 'c') os.makedirs(dirpath) # wait for all changes to settle down yield sd2.sdt.wait_for_nirvana(.5) yield sd1.sdt.wait_for_nirvana(.5) # prepare the info to compare expected_no_conflict = [ 'a', 'b', 'c', os.path.join('a', 'bar.txt'), os.path.join('a', 'beer.txt'), os.path.join('a', 'noconflict.txt'), os.path.join('a', 'conflict.txt') ] expected_no_conflict.sort() debug(prefix, 'expected without conflict', expected_no_conflict) expected_with_conflict = copy(expected_no_conflict) expected_with_conflict.append(os.path.join('a', 'conflict.txt.u1conflict')) expected_with_conflict.sort() debug(prefix, 'expected with conflict', expected_with_conflict) # create the UDF and wait everything to stop yield sd1.sdt.create_folder(path=folderdir1) yield sd2.sdt.wait_for_nirvana(.5) yield sd1.sdt.wait_for_nirvana(.5) actual1 = walk_and_list_dir(folderdir1) debug(prefix, 'actual content from SD1', actual1) actual2 = walk_and_list_dir(folderdir2) debug(prefix, 'actual content from SD2', actual2) # we don't know which client will enter in conflict, so we # tested both ways. if actual1 != expected_no_conflict: assert actual1 == expected_with_conflict, \ 'directory merge must be correct for SD1' assert actual2 == expected_no_conflict, \ 'directory merge must be correct for SD2' else: assert actual1 == expected_no_conflict, \ 'directory merge must be correct for SD1' assert actual2 == expected_with_conflict, \ 'directory merge must be correct for SD2'
def test_merge_directories_with_overlap(udf_name, sd1, sd2, sd3, prefix): """Test 5: Assert directories are correctly merge with overlapping.""" # Structure to start # # client 1: # .../a # .../a/conflict.txt (content random) # .../a/noconflict.txt (same content that 2) # .../a/bar.txt # .../b # # client 2: # .../a # .../a/conflict.txt (content random) # .../a/noconflict.txt (same content that 1) # .../a/beer.txt # .../c # # Result after UDF creation and merge: # # .../a/bar.txt and .../b are synced to client 2 # .../a/beer.txt and .../c are synced to client 1 # .../a/conflict.txt stays the same in one client, and in the other it # goes to conflict (depending on which got first to the server) # .../a/noconflict.txt stays ok in both clients # folderdir1 = os.path.join(sd1.homedir, udf_name) folderdir2 = os.path.join(sd2.homedir, udf_name) os.mkdir(folderdir1) # add folders and files to folderdir1 dirpath = os.path.join(folderdir1, 'a') os.makedirs(dirpath) filepath = os.path.join(dirpath, 'conflict.txt') create_file_and_add_content(filepath, content='content from SD1') filepath = os.path.join(dirpath, 'noconflict.txt') with open(filepath, "w") as fh: fh.write("same content") filepath = os.path.join(dirpath, 'bar.txt') create_file_and_add_content(filepath) dirpath = os.path.join(folderdir1, 'b') os.makedirs(dirpath) os.mkdir(folderdir2) # add folders and files to folderdir2 dirpath = os.path.join(folderdir2, 'a') os.makedirs(dirpath) filepath = os.path.join(dirpath, 'conflict.txt') create_file_and_add_content(filepath, content='content from SD2') filepath = os.path.join(dirpath, 'noconflict.txt') with open(filepath, "w") as fh: fh.write("same content") filepath = os.path.join(dirpath, 'beer.txt') create_file_and_add_content(filepath) dirpath = os.path.join(folderdir1, 'c') os.makedirs(dirpath) # wait for all changes to settle down yield sd2.sdt.wait_for_nirvana(.5) yield sd1.sdt.wait_for_nirvana(.5) # prepare the info to compare expected_no_conflict = ['a', 'b', 'c', os.path.join('a', 'bar.txt'), os.path.join('a', 'beer.txt'), os.path.join('a', 'noconflict.txt'), os.path.join('a', 'conflict.txt')] expected_no_conflict.sort() debug(prefix, 'expected without conflict', expected_no_conflict) expected_with_conflict = copy(expected_no_conflict) expected_with_conflict.append(os.path.join('a', 'conflict.txt.u1conflict')) expected_with_conflict.sort() debug(prefix, 'expected with conflict', expected_with_conflict) # create the UDF and wait everything to stop yield sd1.sdt.create_folder(path=folderdir1) yield sd2.sdt.wait_for_nirvana(.5) yield sd1.sdt.wait_for_nirvana(.5) actual1 = walk_and_list_dir(folderdir1) debug(prefix, 'actual content from SD1', actual1) actual2 = walk_and_list_dir(folderdir2) debug(prefix, 'actual content from SD2', actual2) # we don't know which client will enter in conflict, so we # tested both ways. if actual1 != expected_no_conflict: assert actual1 == expected_with_conflict, \ 'directory merge must be correct for SD1' assert actual2 == expected_no_conflict, \ 'directory merge must be correct for SD2' else: assert actual1 == expected_no_conflict, \ 'directory merge must be correct for SD1' assert actual2 == expected_with_conflict, \ 'directory merge must be correct for SD2'
def test_unsusc_lotofchanges_subsc(udf_name, sd1, sd2, sd3, prefix): """Test 19: Merge should be done correctly.""" # some dirs and files udf_dir = os.path.join(sd1.homedir, udf_name) dir_a = os.path.join(udf_dir, "a") file_1 = os.path.join(dir_a, "file1") file_2 = os.path.join(dir_a, "file2") file_3 = os.path.join(dir_a, "file3") dir_b = os.path.join(udf_dir, "b") dir_c = os.path.join(udf_dir, "c") dir_d = os.path.join(udf_dir, "d") # we create an UDF and put: # - dir_a, with: # - file_1 # - file_2 # - dir_b # - dir_c folder, = yield sd1.sdt.create_folder(path=udf_dir) folder_id = folder["volume_id"] for d in (dir_a, dir_b, dir_c): os.mkdir(d) for f in (file_1, file_2): open(f, "w").close() debug(prefix, 'initial UDF completed!') yield sd1.sdt.wait_for_nirvana(.5) # unsubscribe yield sd1.sdt.unsubscribe_folder(folder_id) debug(prefix, 'unsubscribed!') # some changes: os.rmdir(dir_c) os.mkdir(dir_d) os.remove(file_2) open(file_3, "w").close() debug(prefix, 'changes made!') yield sd1.sdt.wait_for_nirvana(1) # subscribe again yield sd1.sdt.subscribe_folder(folder_id) debug(prefix, 'subscribed!') yield sd1.sdt.wait_for_nirvana(.5) yield sd2.sdt.wait_for_nirvana(.5) debug(prefix, 'changes propagated') # what the merge should do: # - dir_c is back from the server # - dir_d uploaded # - file_2 is back from the server # - file_3 uploaded to the server # - the rest should remain unchanged # to check, we verify everything in both clients expected = ['a', 'a/file1', 'a/file2', 'a/file3', 'b', 'c', 'd'] for which, sd in enumerate((sd1, sd2)): debug(prefix, 'check SD', sd) udf_dir = os.path.join(sd.homedir, udf_name) in_disk = walk_and_list_dir(udf_dir) assert in_disk == expected, "sd %s has bad stuff in "\ "disk: %s" % (which, in_disk)