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(join(sd1.rootdir, 'a', 'b'))
    open(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(join(sd1.rootdir, 'a'), 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_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(join(sd1.rootdir, 'dir1', 'dir2'))
    create_file_and_add_content(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(join(sd2.rootdir, 'dir1'))
    os.remove(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_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(join(sd1.rootdir, 'dir'))
    os.mkdir(join(sd2.rootdir, 'dir'))
    open(join(sd1.rootdir, 'dir', 'file1.txt'), 'w').close()
    open(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(join(sd1.rootdir, 'dir'))
    files2 = walk_and_list_dir(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_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(join(sd1.rootdir, 'file.txt'), content=c1)
    create_file_and_add_content(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_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(join(sd1.rootdir, 'dir1', 'dir2'))
    content = create_file_and_add_content(join(sd1.rootdir, 'dir1',
                                               'dir2', 'file.txt'))
    os.rename(join(sd1.rootdir, 'dir1', 'dir2', 'file.txt'),
              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
    assert content == open(join(sd2.rootdir, 'dir1', 'file.txt')).read()
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(join(sd1.rootdir, 'direct'))
    open(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(join(sd1.rootdir, 'direct'), join(sd1.rootdir, 'newdir'))
    os.mkdir(join(sd1.rootdir, 'direct'))
    open(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_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(join(sd1.rootdir, 'file.txt'), 'w').close()
    open(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_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(join(sd1.rootdir, 'file.txt'), content=data)
    create_file_and_add_content(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_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(join(sd1.rootdir, 'dir1', 'dir2'))
    create_file_and_add_content(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(join(sd2.rootdir, 'dir1'))
    yield sd2.sdt.wait_for_nirvana(.5)
    debug(prefix, "Delete executed")

    # change sd1 and reconnect
    with open(join(sd1.rootdir, 'dir1', 'dir2', 'file.txt'), '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 = join(sd1.rootdir, *'abcd')
    os.makedirs(deepdir)
    create_file_and_add_content(join(deepdir, 'file1.txt'))
    create_file_and_add_content(join(deepdir, 'file2.txt'))
    open(join(deepdir, 'file2.txt'), 'w').close()

    deepdir = join(sd1.rootdir, *'abjk')
    os.makedirs(deepdir)
    create_file_and_add_content(join(deepdir, 'file3.txt'))
    open(join(deepdir, 'file4.txt'), 'w').close()

    deepdir = join(sd1.rootdir, 'a')
    create_file_and_add_content(join(deepdir, 'file5.txt'))
    open(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(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,)