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(''), ]
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)
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) ]
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'), ]
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
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') ]
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 == []
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') ]
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') ]
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[:]
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
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")) ))
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")) ))
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 == []
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), ]
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)]
def test_init(): os.chdir(TEST_DIR) init_utf8 = YARsync("yarsync init источник".split()) assert init_utf8.reponame == "источник"