Exemple #1
0
def test_log(mocker):
    os.chdir(TEST_DIR)
    mocker_print = mocker.patch("sys.stdout")

    args = ["yarsync", "log"]
    ys = YARsync(args)

    # call _log
    res = ys()
    call = mocker.call
    assert res == 0
    assert mocker_print.mock_calls == [
        call.write('# no syncronization information found'),
        call.write('\n'),
        call.write('commit 3 is missing'),
        call.write('\n'),
        call.write('log 3\n'),
        call.write(''),
        call.write('\n'),
        call.write('commit 2'),
        call.write('\n'),
        call.write('When: Thu, 01 Jan 1970 03:00:02 MSK\nWhere: user@host\n'),
        call.write(''),
        call.write('\n'),
        call.write('commit 1'),
        call.write('\n'),
        call.write('Log is missing\nWhen: Thu, 01 Jan 1970 03:00:01 MSK\n'),
        call.write(''),
    ]

    mocker_print.reset_mock()
    # yarsync log -n 1 -r
    args = ["yarsync", "log", "--max-count", "1", "--reverse"]
    ys = YARsync(args)
    res = ys()
    call = mocker.call
    assert res == 0
    assert mocker_print.mock_calls == [
        call.write('# no syncronization information found'),
        # call.write('\n'),
        # call.write('commit 3 is missing'),
        # call.write('\n'),
        # call.write('log 3\n'),
        # call.write(''),
        # call.write('\n'),
        # call.write('commit 2'),
        # call.write('\n'),
        # call.write('When: Thu, 01 Jan 1970 03:00:02 MSK\nWhere: user@host\n'),
        # call.write(''),
        call.write('\n'),
        call.write('commit 1'),
        call.write('\n'),
        call.write('Log is missing\nWhen: Thu, 01 Jan 1970 03:00:01 MSK\n'),
        call.write(''),
    ]
Exemple #2
0
def test_log_error():
    """Test a not-yarsync directory."""
    os.chdir(TEST_DIR_NO_PERMS)

    args = ["yarsync", "log"]
    with pytest.raises(OSError) as err:
        ys = YARsync(args)
Exemple #3
0
def test_init_non_existent(mocker):
    def _os_path_exists(filepath):
        return False

    m = mocker.mock_open()
    if sys.version[0] == "2":
        mocker.patch("__builtin__.open", m)
    else:
        mocker.patch("builtins.open", m)
    mocker.patch("os.path.exists", _os_path_exists)
    mkdir = mocker.patch("os.mkdir")

    args = "yarsync init myhost".split()
    ys = YARsync(args)
    conffile = ys.CONFIGFILE
    repofile = ys.REPOFILE

    res = ys()
    assert res == 0
    call = mocker.call
    assert mkdir.mock_calls == [call(YSDIR, ys.DIRMODE)]
    assert m.mock_calls == [
        # mkdir is recorded separately
        call(conffile, "w"),
        call().__enter__(),
        call().write(''),
        call().write(''),
        call().__exit__(None, None, None),
        call(repofile, "w"),
        call().__enter__(),
        call().write("myhost"),
        call().write(''),  # this write is because of print(end='').
        call().__exit__(None, None, None)
    ]
Exemple #4
0
def test_status_existing_commits(mocker):
    os.chdir(TEST_DIR)
    mocker_print = mocker.patch("sys.stdout")

    args = ["yarsync", "status"]
    ys = YARsync(args)
    res = ys()
    # filter is needed, because not only .ys can be excluded
    filter_str = ys._get_filter(include_commits=False)[1]
    call = mocker.call
    assert res == 0
    assert mocker_print.mock_calls == [
        call.write(
            "rsync -aun --delete -i --exclude=/.ys {} {}/ {}/commits/2"\
            .format(filter_str, ys.root_dir, ys.config_dir)
        ),
        call.write('\n'),
        call.write('# changed since last commit:\n'),
        call.write('\n'),
        call.write('# no syncronization information found'),
        call.write('\n'),
    ]
Exemple #5
0
def test_error():
    if not os.path.exists(TEST_DIR_NO_PERMS):
        # git doesn't preserve permissions,
        # so we recreate this ourselves.
        # It's safe to call mkdir on non-Linux systems.
        # Docs write that permissions are ignored in that case
        # (however the test shall then fail)
        os.mkdir(TEST_DIR_NO_PERMS, 0o555)
    os.chdir(TEST_DIR_NO_PERMS)
    ys = YARsync(["yarsync", "init"])
    returncode = ys()
    print("if this test fails, check that permissions are correct")
    assert returncode == 8
Exemple #6
0
def test_status_no_commits(mocker):
    os.chdir(TEST_DIR_EMPTY)
    # StringIO uses only utf-8
    mocker_print = mocker.patch("sys.stdout")  #, new_callable=StringIO)

    args = ["yarsync", "status"]
    ys = YARsync(args)
    res = ys()
    call = mocker.call
    assert res == 0
    assert mocker_print.mock_calls == [
        call.write('No commits found'),
        call.write('\n')
    ]
Exemple #7
0
def test_print(mocker):
    # ys must be initialized with some settings.
    os.chdir(TEST_DIR)

    mocker_print = mocker.patch("sys.stdout")
    call = mocker.call

    args = ["yarsync", "log"]
    ys = YARsync(args)  # command is not called
    ys.DEBUG = True

    ys._print("debug", debug=True)
    assert mocker_print.mock_calls == [call.write('debug'), call.write('\n')]

    ys.DEBUG = False

    mocker_print.reset_mock()
    # will print unconditionally
    ys._print("general")
    assert mocker_print.mock_calls == [call.write('general'), call.write('\n')]

    mocker_print.reset_mock()
    ys._print("debug unavailable", debug=True)
    assert mocker_print.mock_calls == []
Exemple #8
0
def test_log_empty(mocker):
    os.chdir(TEST_DIR_EMPTY)
    mocker_print = mocker.patch("sys.stdout")

    args = ["yarsync", "log"]
    ys = YARsync(args)

    # call _log
    res = ys()
    call = mocker.call
    assert res == 0
    assert mocker_print.mock_calls == [
        call.write('# no syncronization information found'),
        call.write('\n'),
        call.write('No commits found'),
        call.write('\n')
    ]
Exemple #9
0
def test_status_error(mocker):
    """Test a not-yarsync directory."""
    os.chdir(TEST_DIR_NO_PERMS)
    mocker_print = mocker.patch("sys.stdout")
    call = mocker.call

    args = ["yarsync", "status"]
    with pytest.raises(OSError) as err:
        ys = YARsync(args)
    assert repr(err.value) == repr(OSError('.ys not found'))
    assert mocker_print.mock_calls == [
        call.write('!'),
        call.write(' '),
        call.write("fatal: no yarsync configuration "
                   ".ys found"),
        call.write('\n')
    ]
Exemple #10
0
def test_init_mixed(mocker):
    """Mock OS functions and check that they are called properly."""

    # os.chdir(TEST_DIR_EMPTY)

    ## Mock mixed existing directory and non-existent files ###

    def _os_path_exists(filepath):
        if filepath == YSDIR:
            return True
        elif filepath.startswith(YSDIR):
            print(filepath)
            return False
        else:
            return False  # won't get access to real os.path.exists(filepath)

    m = mocker.mock_open()
    if sys.version[0] == "2":
        mocker.patch("__builtin__.open", m)
    else:
        mocker.patch("builtins.open", m)
    mocker.patch("os.path.exists", _os_path_exists)

    args = "yarsync init myhost".split()
    ys = YARsync(args)
    conffile = ys.CONFIGFILE
    repofile = ys.REPOFILE
    # call _init
    res = ys()
    assert res == 0

    call = mocker.call
    assert m.mock_calls == [
        call(conffile, "w"),
        call().__enter__(),
        call().write(''),
        call().write(''),
        call().__exit__(None, None, None),
        call(repofile, "w"),
        call().__enter__(),
        call().write("myhost"),
        call().write(''),  # this write is because of print(end='').
        call().__exit__(None, None, None)
    ]
    old_calls = m.mock_calls[:]
Exemple #11
0
def test_commit_rsync_error(mocker):
    os.chdir(TEST_DIR_EMPTY)

    popen = mocker.patch("subprocess.Popen")
    subprocess_mock = mocker.Mock()
    attrs = {'communicate.return_value': ('output', 'error')}
    subprocess_mock.configure_mock(**attrs)
    # some error occurred in rsync
    subprocess_mock.configure_mock(returncode=1)
    popen.return_value = subprocess_mock

    # just in case. Now it won't be called, but to make code more stable.
    mocker.patch("os.mkdir")

    args = ["yarsync", "commit"]
    ys = YARsync(args)
    res = ys()

    assert res == 1
Exemple #12
0
def test_existent_commit_exception(mocker):
    os.chdir(TEST_DIR_EMPTY)
    mocker.patch("time.time", lambda: 2)

    def _os_path_exists(filepath):
        if YSDIR in filepath:
            return True
        return False

    mocker.patch("os.path.exists", _os_path_exists)

    args = "yarsync commit".split()
    ys = YARsync(args)

    with pytest.raises(RuntimeError) as err:
        res = ys()
    # can't compare them directly
    assert repr(err.value) == repr(RuntimeError(
        "commit {} exists".format(os.path.join(ys.COMMITDIR, "2"))
    ))
Exemple #13
0
def test_existent_tmp_commit_exception(mocker):
    os.chdir(TEST_DIR_EMPTY)
    mocker.patch("time.time", lambda: 2)

    def _os_path_exists(filepath):
        if YSDIR in filepath:
            # print("path = ", filepath)
            return "_tmp" in filepath
        return False

    # initialization is fine, because the config file is present
    args = "yarsync commit".split()
    ys = YARsync(args)

    mocker.patch("os.path.exists", _os_path_exists)
    mocker.patch("os.mkdir")

    with pytest.raises(RuntimeError) as err:
        res = ys()
    assert repr(err.value) == repr(RuntimeError(
        "temporary commit {} exists".format(os.path.join(ys.COMMITDIR, "2_tmp"))
    ))
Exemple #14
0
def test_init_existent(mocker):
    def _os_path_exists(filepath):
        # assume only files within YSDIR exist,
        # otherwise you'll have problems with gettext
        if os.path.commonprefix([filepath, YSDIR]) == YSDIR:
            return True
        # os.path.exists(filepath) would cause infinite recursion here!
        return False

    m = mocker.mock_open()
    if sys.version[0] == "2":
        mocker.patch("__builtin__.open", m)
    else:
        mocker.patch("builtins.open", m)
    mocker.patch("os.path.exists", _os_path_exists)
    mkdir = mocker.patch("os.mkdir")

    args = "yarsync init myhost".split()
    ys = YARsync(args)

    res = ys()
    assert res == 0
    assert mkdir.mock_calls == []
    assert m.mock_calls == []
Exemple #15
0
def test_commit(mocker):
    """Test commit creation and logging."""
    os.chdir(TEST_DIR_EMPTY)

    # important that it goes before patches, we need normal initialization
    commit_msg = "initial commit"
    args = ["yarsync", "commit", "-m", commit_msg]
    ys = YARsync(args)

    # time.localtime uses time.time
    time_3 = time.localtime(3)
    def loctime(sec=None):
        return time_3
    mocker.patch("time.localtime", loctime)
    # hope this will work in another time zone.
    mocker.patch("time.tzname", "MSK")
    # time.time is called a slight instant after time.localtime
    # their order is not important though.
    commit_time = 2
    mocker.patch("time.time", lambda: commit_time)
    rename = mocker.patch("os.rename")
    mkdir = mocker.patch("os.mkdir")
    mocker.patch("socket.gethostname", lambda: "host")
    mocker.patch("getpass.getuser", lambda: "user")

    m = mocker.mock_open()
    if sys.version[0] == "2":
        mocker.patch("__builtin__.open", m)
    else:
        mocker.patch("builtins.open", m)

    popen = mocker.patch("subprocess.Popen")
    subprocess_mock = mocker.Mock()
    attrs = {'communicate.return_value': ('output', 'error')}
    subprocess_mock.configure_mock(**attrs)
    subprocess_mock.configure_mock(**{"returncode": 0})
    popen.return_value = subprocess_mock

    commit_name = str(int(commit_time))
    commit_dir = os.path.join(ys.COMMITDIR, commit_name)
    commit_dir_tmp = commit_dir + "_tmp"
    commit_log_path = os.path.join(ys.LOGDIR, commit_name + ".txt")
    commit_time_str = time.strftime(ys.DATEFMT, time.localtime())

    # call _commit
    res = ys()
    filter_ = ys._get_filter(include_commits=False)[0]
    call = mocker.call

    assert res == 0
    assert mkdir.mock_calls == [
        call(ys.COMMITDIR, ys.DIRMODE),
        call(ys.LOGDIR, ys.DIRMODE),
    ]
    assert rename.mock_calls == [
        call(commit_dir_tmp, commit_dir),
    ]
    assert popen.mock_calls == [
        call(["rsync", "-a", "--link-dest=../../..", "--exclude=/.ys"]
             + filter_ +
             [ys.root_dir + '/', os.path.join(ys.COMMITDIR, "2_tmp")],
             stdout=-1, stderr=-1),
        call().communicate(),
    ]
    assert m.mock_calls == [
        call(commit_log_path, "w"), call().__enter__(),
        call().write(commit_msg + "\n\n"
                     "When: Thu, 01 Jan 1970 03:00:03 MSK\n"
                     "Where: user@host"),
        call().write('\n'),
        call().__exit__(None, None, None),
    ]
Exemple #16
0
def test_make_commit_log_list():
    commits = [1, 3]
    logs = [2]
    ys = YARsync(["yarsync", "log"])  # the function is not called
    mcl = ys._make_commit_list
    assert mcl(commits, logs) == [(1, None), (None, 2), (3, None)]
Exemple #17
0
def test_init():
    os.chdir(TEST_DIR)
    init_utf8 = YARsync("yarsync init источник".split())
    assert init_utf8.reponame == "источник"