From 76ce3defea0e69c3e8130e7cfdcd22b64322aea2 Mon Sep 17 00:00:00 2001 From: Tim Byrne Date: Mon, 10 Jul 2023 14:43:17 -0500 Subject: [PATCH] Changes for black compliance --- test/conftest.py | 406 +++++++++----------- test/test_alt.py | 226 +++++------ test/test_alt_copy.py | 44 +-- test/test_assert_private_dirs.py | 46 +-- test/test_bootstrap.py | 38 +- test/test_clean.py | 6 +- test/test_clone.py | 282 +++++++------- test/test_config.py | 81 ++-- test/test_encryption.py | 373 ++++++++---------- test/test_enter.py | 140 +++---- test/test_ext_crypt.py | 36 +- test/test_git.py | 40 +- test/test_help.py | 10 +- test/test_hooks.py | 129 +++---- test/test_init.py | 66 ++-- test/test_introspect.py | 40 +- test/test_list.py | 38 +- test/test_perms.py | 86 ++--- test/test_syntax.py | 57 ++- test/test_unit_bootstrap_available.py | 10 +- test/test_unit_choose_template_cmd.py | 48 +-- test/test_unit_configure_paths.py | 94 ++--- test/test_unit_copy_perms.py | 34 +- test/test_unit_encryption.py | 80 ++-- test/test_unit_exclude_encrypted.py | 60 ++- test/test_unit_issue_legacy_path_warning.py | 33 +- test/test_unit_parse_encrypt.py | 177 +++++---- test/test_unit_private_dirs.py | 20 +- test/test_unit_query_distro.py | 28 +- test/test_unit_query_distro_family.py | 22 +- test/test_unit_record_score.py | 86 ++--- test/test_unit_record_template.py | 24 +- test/test_unit_relative_path.py | 6 +- test/test_unit_remove_stale_links.py | 28 +- test/test_unit_report_invalid_alts.py | 20 +- test/test_unit_score_file.py | 321 +++++++--------- test/test_unit_set_local_alt_values.py | 62 +-- test/test_unit_set_os.py | 38 +- test/test_unit_set_yadm_dir.py | 55 ++- test/test_unit_template_default.py | 74 ++-- test/test_unit_template_esh.py | 29 +- test/test_unit_template_j2.py | 33 +- test/test_unit_upgrade.py | 103 +++-- test/test_unit_x_program.py | 35 +- test/test_upgrade.py | 137 ++++--- test/test_version.py | 26 +- test/utils.py | 56 +-- 47 files changed, 1845 insertions(+), 2038 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index e05d5dc..b18cae4 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -23,169 +23,168 @@ def pytest_addoption(parser): ) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def shellcheck_version(): """Version of shellcheck supported""" - return '0.9.0' + return "0.9.0" -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def pylint_version(): """Version of pylint supported""" - return '2.17.0' + return "2.17.0" -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def isort_version(): """Version of isort supported""" - return '5.12.0' + return "5.12.0" -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def flake8_version(): """Version of flake8 supported""" - return '6.0.0' + return "6.0.0" -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def black_version(): """Version of black supported""" - return '23.1.0' + return "23.1.0" -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def yamllint_version(): """Version of yamllint supported""" - return '1.30.0' + return "1.30.0" -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tst_user(): """Test session's user id""" return pwd.getpwuid(os.getuid()).pw_name -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tst_host(): """Test session's short hostname value""" - return platform.node().split('.')[0] + return platform.node().split(".")[0] -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tst_distro(runner): """Test session's distro""" - distro = '' + distro = "" with contextlib.suppress(Exception): - run = runner(command=['lsb_release', '-si'], report=False) + run = runner(command=["lsb_release", "-si"], report=False) distro = run.out.strip() return distro -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tst_distro_family(runner): """Test session's distro_family""" - family = '' + family = "" with contextlib.suppress(Exception): - run = runner(command=[ - 'grep', '-oP', r'ID_LIKE=\K.+', '/etc/os-release'], report=False) + run = runner(command=["grep", "-oP", r"ID_LIKE=\K.+", "/etc/os-release"], report=False) family = run.out.strip() return family -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tst_sys(): """Test session's uname value""" return platform.system() -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tst_arch(): """Test session's uname value""" return platform.machine() -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def supported_commands(): """List of supported commands This list should be updated every time yadm learns a new command. """ return [ - 'alt', - 'bootstrap', - 'clean', - 'clone', - 'config', - 'decrypt', - 'encrypt', - 'enter', - 'git-crypt', - 'gitconfig', - 'help', - 'init', - 'introspect', - 'list', - 'perms', - 'transcrypt', - 'upgrade', - 'version', - ] + "alt", + "bootstrap", + "clean", + "clone", + "config", + "decrypt", + "encrypt", + "enter", + "git-crypt", + "gitconfig", + "help", + "init", + "introspect", + "list", + "perms", + "transcrypt", + "upgrade", + "version", + ] -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def supported_configs(): """List of supported config options This list should be updated every time yadm learns a new config. """ return [ - 'local.arch', - 'local.class', - 'local.hostname', - 'local.os', - 'local.user', - 'yadm.alt-copy', - 'yadm.auto-alt', - 'yadm.auto-exclude', - 'yadm.auto-perms', - 'yadm.auto-private-dirs', - 'yadm.cipher', - 'yadm.git-program', - 'yadm.gpg-perms', - 'yadm.gpg-program', - 'yadm.gpg-recipient', - 'yadm.openssl-ciphername', - 'yadm.openssl-old', - 'yadm.openssl-program', - 'yadm.ssh-perms', - ] + "local.arch", + "local.class", + "local.hostname", + "local.os", + "local.user", + "yadm.alt-copy", + "yadm.auto-alt", + "yadm.auto-exclude", + "yadm.auto-perms", + "yadm.auto-private-dirs", + "yadm.cipher", + "yadm.git-program", + "yadm.gpg-perms", + "yadm.gpg-program", + "yadm.gpg-recipient", + "yadm.openssl-ciphername", + "yadm.openssl-old", + "yadm.openssl-program", + "yadm.ssh-perms", + ] -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def supported_switches(): """List of supported switches This list should be updated every time yadm learns a new switch. """ return [ - '--yadm-archive', - '--yadm-bootstrap', - '--yadm-config', - '--yadm-data', - '--yadm-dir', - '--yadm-encrypt', - '--yadm-repo', - '-Y', - ] + "--yadm-archive", + "--yadm-bootstrap", + "--yadm-config", + "--yadm-data", + "--yadm-dir", + "--yadm-encrypt", + "--yadm-repo", + "-Y", + ] -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def supported_local_configs(supported_configs): """List of supported local config options""" - return [c for c in supported_configs if c.startswith('local.')] + return [c for c in supported_configs if c.startswith("local.")] -class Runner(): +class Runner: """Class for running commands Within yadm tests, this object should be used when running commands that @@ -198,17 +197,9 @@ class Runner(): Other instances of simply running commands should use os.system(). """ - def __init__( - self, - command, - inp=None, - shell=False, - cwd=None, - env=None, - expect=None, - report=True): + def __init__(self, command, inp=None, shell=False, cwd=None, env=None, expect=None, report=True): if shell: - self.command = ' '.join([str(cmd) for cmd in command]) + self.command = " ".join([str(cmd) for cmd in command]) else: self.command = command if env is None: @@ -239,56 +230,43 @@ class Runner(): self.report() def __repr__(self): - return f'Runner({self.command})' + return f"Runner({self.command})" def report(self): """Print code/stdout/stderr""" - print(f'{self}') - print(f' RUN: code:{self.code}') + print(f"{self}") + print(f" RUN: code:{self.code}") if self.inp: - print(f' RUN: input:\n{self.inp}') - print(f' RUN: stdout:\n{self.out}') - print(f' RUN: stderr:\n{self.err}') + print(f" RUN: input:\n{self.inp}") + print(f" RUN: stdout:\n{self.out}") + print(f" RUN: stderr:\n{self.err}") def wrap(self, expect): """Wrap command with expect""" if not expect: return - cmdline = ' '.join([f'"{w}"' for w in self.command]) - expect_script = f'set timeout 2\nspawn {cmdline}\n' + cmdline = " ".join([f'"{w}"' for w in self.command]) + expect_script = f"set timeout 2\nspawn {cmdline}\n" for question, answer in expect: - expect_script += ( - 'expect {\n' - f'"{question}" {{send "{answer}\\r"}}\n' - 'timeout {close;exit 128}\n' - '}\n') - expect_script += ( - 'expect eof\n' - 'foreach {pid spawnid os_error_flag value} [wait] break\n' - 'exit $value') + expect_script += "expect {\n" f'"{question}" {{send "{answer}\\r"}}\n' "timeout {close;exit 128}\n" "}\n" + expect_script += "expect eof\n" "foreach {pid spawnid os_error_flag value} [wait] break\n" "exit $value" self.inp = expect_script - print(f'EXPECT:{expect_script}') - self.command = ['expect'] + print(f"EXPECT:{expect_script}") + self.command = ["expect"] -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def runner(): """Class for running commands""" return Runner -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def config_git(): """Configure global git configuration, if missing""" - os.system( - 'git config init.defaultBranch || ' - 'git config --global init.defaultBranch master') - os.system( - 'git config user.name || ' - 'git config --global user.name "test"') - os.system( - 'git config user.email || ' - 'git config --global user.email "test@test.test"') + os.system("git config init.defaultBranch || git config --global init.defaultBranch master") + os.system('git config user.name || git config --global user.name "test"') + os.system('git config user.email || git config --global user.email "test@test.test"') @pytest.fixture() @@ -298,19 +276,19 @@ def repo_config(runner, paths): def query_func(key): """Query a yadm repo configuration value""" run = runner( - command=('git', 'config', '--local', key), - env={'GIT_DIR': paths.repo}, + command=("git", "config", "--local", key), + env={"GIT_DIR": paths.repo}, report=False, - ) + ) return run.out.rstrip() return query_func -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def yadm(): """Path to yadm program to be tested""" - full_path = os.path.realpath('yadm') + full_path = os.path.realpath("yadm") assert os.path.isfile(full_path), "yadm program file isn't present" return full_path @@ -319,38 +297,40 @@ def yadm(): def paths(tmpdir, yadm): """Function scoped test paths""" - dir_root = tmpdir.mkdir('root') - dir_remote = dir_root.mkdir('remote') - dir_work = dir_root.mkdir('work') - dir_xdg_data = dir_root.mkdir('xdg_data') - dir_xdg_home = dir_root.mkdir('xdg_home') - dir_data = dir_xdg_data.mkdir('yadm') - dir_yadm = dir_xdg_home.mkdir('yadm') - dir_hooks = dir_yadm.mkdir('hooks') - dir_repo = dir_data.mkdir('repo.git') - file_archive = dir_data.join('archive') - file_bootstrap = dir_yadm.join('bootstrap') - file_config = dir_yadm.join('config') - file_encrypt = dir_yadm.join('encrypt') + dir_root = tmpdir.mkdir("root") + dir_remote = dir_root.mkdir("remote") + dir_work = dir_root.mkdir("work") + dir_xdg_data = dir_root.mkdir("xdg_data") + dir_xdg_home = dir_root.mkdir("xdg_home") + dir_data = dir_xdg_data.mkdir("yadm") + dir_yadm = dir_xdg_home.mkdir("yadm") + dir_hooks = dir_yadm.mkdir("hooks") + dir_repo = dir_data.mkdir("repo.git") + file_archive = dir_data.join("archive") + file_bootstrap = dir_yadm.join("bootstrap") + file_config = dir_yadm.join("config") + file_encrypt = dir_yadm.join("encrypt") paths = collections.namedtuple( - 'Paths', [ - 'pgm', - 'root', - 'remote', - 'work', - 'xdg_data', - 'xdg_home', - 'data', - 'yadm', - 'hooks', - 'repo', - 'archive', - 'bootstrap', - 'config', - 'encrypt', - ]) - os.environ['XDG_CONFIG_HOME'] = str(dir_xdg_home) - os.environ['XDG_DATA_HOME'] = str(dir_xdg_data) + "Paths", + [ + "pgm", + "root", + "remote", + "work", + "xdg_data", + "xdg_home", + "data", + "yadm", + "hooks", + "repo", + "archive", + "bootstrap", + "config", + "encrypt", + ], + ) + os.environ["XDG_CONFIG_HOME"] = str(dir_xdg_home) + os.environ["XDG_DATA_HOME"] = str(dir_xdg_data) return paths( yadm, dir_root, @@ -366,15 +346,17 @@ def paths(tmpdir, yadm): file_bootstrap, file_config, file_encrypt, - ) + ) @pytest.fixture() def yadm_cmd(paths): """Generate custom command_list function""" + def command_list(*args): """Produce params for running yadm with -Y""" return [paths.pgm] + list(args) + return command_list @@ -382,7 +364,7 @@ class NoRelativePath(Exception): """Exception when finding relative paths""" -class DataFile(): +class DataFile: """Datafile object""" def __init__(self, path, tracked=True, private=False): @@ -401,7 +383,7 @@ class DataFile(): """Relative path property""" if self.__parent: return self.__parent.join(self.path) - raise NoRelativePath('Unable to provide relative path, no parent') + raise NoRelativePath("Unable to provide relative path, no parent") @property def tracked(self): @@ -418,7 +400,7 @@ class DataFile(): self.__parent = parent -class DataSet(): +class DataSet: """Dataset object""" def __init__(self): @@ -429,11 +411,7 @@ class DataSet(): self.__relpath = None def __repr__(self): - return ( - f'[DS with {len(self)} files; ' - f'{len(self.tracked)} tracked, ' - f'{len(self.private)} private]' - ) + return f"[DS with {len(self)} files; " f"{len(self.tracked)} tracked, " f"{len(self.private)} private]" def __iter__(self): return iter(self.__files) @@ -471,17 +449,17 @@ class DataSet(): @property def plain_dirs(self): """List of directories in DataSet not starting with '.'""" - return [d for d in self.dirs if not d.startswith('.')] + return [d for d in self.dirs if not d.startswith(".")] @property def hidden_dirs(self): """List of directories in DataSet starting with '.'""" - return [d for d in self.dirs if d.startswith('.')] + return [d for d in self.dirs if d.startswith(".")] @property def tracked_dirs(self): """List of directories in DataSet not starting with '.'""" - return [d for d in self.__tracked_dirs if not d.startswith('.')] + return [d for d in self.__tracked_dirs if not d.startswith(".")] @property def private_dirs(self): @@ -511,23 +489,23 @@ class DataSet(): datafile.relative_to(self.__relpath) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def ds1_dset(tst_sys): """Meta-data for dataset one files""" dset = DataSet() - dset.add_file('t1') - dset.add_file('d1/t2') - dset.add_file(f'test_alt_copy##os.{tst_sys}') - dset.add_file('u1', tracked=False) - dset.add_file('d2/u2', tracked=False) - dset.add_file('.ssh/p1', tracked=False, private=True) - dset.add_file('.ssh/.p2', tracked=False, private=True) - dset.add_file('.gnupg/p3', tracked=False, private=True) - dset.add_file('.gnupg/.p4', tracked=False, private=True) + dset.add_file("t1") + dset.add_file("d1/t2") + dset.add_file(f"test_alt_copy##os.{tst_sys}") + dset.add_file("u1", tracked=False) + dset.add_file("d2/u2", tracked=False) + dset.add_file(".ssh/p1", tracked=False, private=True) + dset.add_file(".ssh/.p2", tracked=False, private=True) + dset.add_file(".gnupg/p3", tracked=False, private=True) + dset.add_file(".gnupg/.p4", tracked=False, private=True) return dset -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def ds1_data(tmpdir_factory, config_git, ds1_dset, runner): """A set of test data, worktree & repo""" # pylint: disable=unused-argument @@ -535,44 +513,24 @@ def ds1_data(tmpdir_factory, config_git, ds1_dset, runner): # @pytest.mark.usefixtures('config_git') # cannot be applied to another fixture. - data = tmpdir_factory.mktemp('ds1') + data = tmpdir_factory.mktemp("ds1") - work = data.mkdir('work') + work = data.mkdir("work") for datafile in ds1_dset: work.join(datafile.path).write(datafile.path, ensure=True) - repo = data.mkdir('repo.git') + repo = data.mkdir("repo.git") env = os.environ.copy() - env['GIT_DIR'] = str(repo) - runner( - command=['git', 'init', '--shared=0600', '--bare', str(repo)], - report=False) - runner( - command=['git', 'config', 'core.bare', 'false'], - env=env, - report=False) - runner( - command=['git', 'config', 'status.showUntrackedFiles', 'no'], - env=env, - report=False) - runner( - command=['git', 'config', 'yadm.managed', 'true'], - env=env, - report=False) - runner( - command=['git', 'config', 'core.worktree', str(work)], - env=env, - report=False) - runner( - command=['git', 'add'] + - [str(work.join(f.path)) for f in ds1_dset if f.tracked], - env=env) - runner( - command=['git', 'commit', '--allow-empty', '-m', 'Initial commit'], - env=env, - report=False) + env["GIT_DIR"] = str(repo) + runner(command=["git", "init", "--shared=0600", "--bare", str(repo)], report=False) + runner(command=["git", "config", "core.bare", "false"], env=env, report=False) + runner(command=["git", "config", "status.showUntrackedFiles", "no"], env=env, report=False) + runner(command=["git", "config", "yadm.managed", "true"], env=env, report=False) + runner(command=["git", "config", "core.worktree", str(work)], env=env, report=False) + runner(command=["git", "add"] + [str(work.join(f.path)) for f in ds1_dset if f.tracked], env=env) + runner(command=["git", "commit", "--allow-empty", "-m", "Initial commit"], env=env, report=False) - data = collections.namedtuple('Data', ['work', 'repo']) + data = collections.namedtuple("Data", ["work", "repo"]) return data(work, repo) @@ -587,11 +545,8 @@ def ds1_repo_copy(runner, ds1_data, paths): """Function scoped copy of ds1_data.repo""" shutil.copytree(str(ds1_data.repo), str(paths.repo), dirs_exist_ok=True) env = os.environ.copy() - env['GIT_DIR'] = str(paths.repo) - runner( - command=['git', 'config', 'core.worktree', str(paths.work)], - env=env, - report=False) + env["GIT_DIR"] = str(paths.repo) + runner(command=["git", "config", "core.worktree", str(paths.work)], env=env, report=False) @pytest.fixture() @@ -616,30 +571,27 @@ def ds1(ds1_work_copy, paths, ds1_dset): return dscopy -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def gnupg(tmpdir_factory, runner): """Location of GNUPGHOME""" def register_gpg_password(password): """Publish a new GPG mock password""" - py.path.local('/tmp/mock-password').write(password) + py.path.local("/tmp/mock-password").write(password) - home = tmpdir_factory.mktemp('gnupghome') + home = tmpdir_factory.mktemp("gnupghome") home.chmod(0o700) - conf = home.join('gpg.conf') - conf.write('no-secmem-warning\n') + conf = home.join("gpg.conf") + conf.write("no-secmem-warning\n") conf.chmod(0o600) - agentconf = home.join('gpg-agent.conf') - agentconf.write( - f'pinentry-program {os.path.abspath("test/pinentry-mock")}\n' - 'max-cache-ttl 0\n' - ) + agentconf = home.join("gpg-agent.conf") + agentconf.write(f'pinentry-program {os.path.abspath("test/pinentry-mock")}\n' "max-cache-ttl 0\n") agentconf.chmod(0o600) - data = collections.namedtuple('GNUPG', ['home', 'pw']) + data = collections.namedtuple("GNUPG", ["home", "pw"]) env = os.environ.copy() - env['GNUPGHOME'] = home + env["GNUPGHOME"] = home # this pre-populates std files in the GNUPGHOME - runner(['gpg', '-k'], env=env) + runner(["gpg", "-k"], env=env) return data(home, register_gpg_password) diff --git a/test/test_alt.py b/test/test_alt.py index e57caee..c429ad4 100644 --- a/test/test_alt.py +++ b/test/test_alt.py @@ -9,34 +9,34 @@ import utils TEST_PATHS = [utils.ALT_FILE1, utils.ALT_FILE2, utils.ALT_DIR] -@pytest.mark.usefixtures('ds1_copy') -@pytest.mark.parametrize('yadm_alt', [True, False], ids=['alt', 'worktree']) +@pytest.mark.usefixtures("ds1_copy") +@pytest.mark.parametrize("yadm_alt", [True, False], ids=["alt", "worktree"]) @pytest.mark.parametrize( - 'tracked,encrypt,exclude', [ + "tracked,encrypt,exclude", + [ (False, False, False), (True, False, False), (False, True, False), (False, True, True), - ], ids=['untracked', 'tracked', 'encrypted', 'excluded']) -def test_alt_source( - runner, paths, - tracked, encrypt, exclude, - yadm_alt): + ], + ids=["untracked", "tracked", "encrypted", "excluded"], +) +def test_alt_source(runner, paths, tracked, encrypt, exclude, yadm_alt): """Test yadm alt operates on all expected sources of alternates""" yadm_dir, yadm_data = setup_standard_yadm_dir(paths) utils.create_alt_files( - paths, '##default', tracked=tracked, encrypt=encrypt, exclude=exclude, - yadm_alt=yadm_alt, yadm_dir=yadm_dir) - run = runner([paths.pgm, '-Y', yadm_dir, '--yadm-data', yadm_data, 'alt']) + paths, "##default", tracked=tracked, encrypt=encrypt, exclude=exclude, yadm_alt=yadm_alt, yadm_dir=yadm_dir + ) + run = runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"]) assert run.success - assert run.err == '' + assert run.err == "" linked = utils.parse_alt_output(run.out) - basepath = yadm_dir.join('alt') if yadm_alt else paths.work + basepath = yadm_dir.join("alt") if yadm_alt else paths.work for link_path in TEST_PATHS: - source_file_content = link_path + '##default' + source_file_content = link_path + "##default" source_file = basepath.join(source_file_content) link_file = paths.work.join(link_path) if tracked or (encrypt and not exclude): @@ -46,63 +46,69 @@ def test_alt_source( assert link_file.read() == source_file_content assert str(source_file) in linked else: - assert link_file.join( - utils.CONTAINED).read() == source_file_content + assert link_file.join(utils.CONTAINED).read() == source_file_content assert str(source_file) in linked else: assert not link_file.exists() assert str(source_file) not in linked -@pytest.mark.usefixtures('ds1_copy') -@pytest.mark.parametrize('yadm_alt', [True, False], ids=['alt', 'worktree']) +@pytest.mark.usefixtures("ds1_copy") +@pytest.mark.parametrize("yadm_alt", [True, False], ids=["alt", "worktree"]) def test_relative_link(runner, paths, yadm_alt): """Confirm links created are relative""" yadm_dir, yadm_data = setup_standard_yadm_dir(paths) utils.create_alt_files( - paths, '##default', tracked=True, encrypt=False, exclude=False, - yadm_alt=yadm_alt, yadm_dir=yadm_dir) - run = runner([paths.pgm, '-Y', yadm_dir, '--yadm-data', yadm_data, 'alt']) + paths, "##default", tracked=True, encrypt=False, exclude=False, yadm_alt=yadm_alt, yadm_dir=yadm_dir + ) + run = runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"]) assert run.success - assert run.err == '' + assert run.err == "" - basepath = yadm_dir.join('alt') if yadm_alt else paths.work + basepath = yadm_dir.join("alt") if yadm_alt else paths.work for link_path in TEST_PATHS: - source_file_content = link_path + '##default' + source_file_content = link_path + "##default" source_file = basepath.join(source_file_content) link_file = paths.work.join(link_path) link = link_file.readlink() - relpath = os.path.relpath( - source_file, start=os.path.dirname(link_file)) + relpath = os.path.relpath(source_file, start=os.path.dirname(link_file)) assert link == relpath -@pytest.mark.usefixtures('ds1_copy') -@pytest.mark.parametrize('suffix', [ - '##default', - '##default,e.txt', '##default,extension.txt', - '##a.$tst_arch', '##arch.$tst_arch', - '##o.$tst_sys', '##os.$tst_sys', - '##d.$tst_distro', '##distro.$tst_distro', - '##f.$tst_distro_family', '##distro_family.$tst_distro_family', - '##c.$tst_class', '##class.$tst_class', - '##h.$tst_host', '##hostname.$tst_host', - '##u.$tst_user', '##user.$tst_user', - ]) -def test_alt_conditions( - runner, paths, - tst_arch, tst_sys, tst_distro, tst_distro_family, tst_host, tst_user, - suffix): +@pytest.mark.usefixtures("ds1_copy") +@pytest.mark.parametrize( + "suffix", + [ + "##default", + "##default,e.txt", + "##default,extension.txt", + "##a.$tst_arch", + "##arch.$tst_arch", + "##o.$tst_sys", + "##os.$tst_sys", + "##d.$tst_distro", + "##distro.$tst_distro", + "##f.$tst_distro_family", + "##distro_family.$tst_distro_family", + "##c.$tst_class", + "##class.$tst_class", + "##h.$tst_host", + "##hostname.$tst_host", + "##u.$tst_user", + "##user.$tst_user", + ], +) +def test_alt_conditions(runner, paths, tst_arch, tst_sys, tst_distro, tst_distro_family, tst_host, tst_user, suffix): """Test conditions supported by yadm alt""" yadm_dir, yadm_data = setup_standard_yadm_dir(paths) # set the class - tst_class = 'testclass' - utils.set_local(paths, 'class', tst_class + ".before") - utils.set_local(paths, 'class', tst_class, add=True) - utils.set_local(paths, 'class', tst_class + ".after", add=True) + tst_class = "testclass" + utils.set_local(paths, "class", tst_class + ".before") + utils.set_local(paths, "class", tst_class, add=True) + utils.set_local(paths, "class", tst_class + ".after", add=True) suffix = string.Template(suffix).substitute( tst_arch=tst_arch, @@ -115,9 +121,9 @@ def test_alt_conditions( ) utils.create_alt_files(paths, suffix) - run = runner([paths.pgm, '-Y', yadm_dir, '--yadm-data', yadm_data, 'alt']) + run = runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"]) assert run.success - assert run.err == '' + assert run.err == "" linked = utils.parse_alt_output(run.out) for link_path in TEST_PATHS: @@ -128,27 +134,31 @@ def test_alt_conditions( assert paths.work.join(link_path).read() == source_file assert str(paths.work.join(source_file)) in linked else: - assert paths.work.join(link_path).join( - utils.CONTAINED).read() == source_file + assert paths.work.join(link_path).join(utils.CONTAINED).read() == source_file assert str(paths.work.join(source_file)) in linked -@pytest.mark.usefixtures('ds1_copy') +@pytest.mark.usefixtures("ds1_copy") +@pytest.mark.parametrize("kind", ["default", "", None, "envtpl", "j2cli", "j2", "esh"]) @pytest.mark.parametrize( - 'kind', ['default', '', None, 'envtpl', 'j2cli', 'j2', 'esh']) -@pytest.mark.parametrize('label', ['t', 'template', 'yadm', ]) -def test_alt_templates( - runner, paths, kind, label): + "label", + [ + "t", + "template", + "yadm", + ], +) +def test_alt_templates(runner, paths, kind, label): """Test templates supported by yadm alt""" yadm_dir, yadm_data = setup_standard_yadm_dir(paths) - suffix = f'##{label}.{kind}' + suffix = f"##{label}.{kind}" if kind is None: - suffix = f'##{label}' + suffix = f"##{label}" utils.create_alt_files(paths, suffix) - run = runner([paths.pgm, '-Y', yadm_dir, '--yadm-data', yadm_data, 'alt']) + run = runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "alt"]) assert run.success - assert run.err == '' + assert run.err == "" created = utils.parse_alt_output(run.out, linked=False) for created_path in TEST_PATHS: @@ -159,41 +169,39 @@ def test_alt_templates( assert str(paths.work.join(source_file)) in created -@pytest.mark.usefixtures('ds1_copy') -@pytest.mark.parametrize('autoalt', [None, 'true', 'false']) +@pytest.mark.usefixtures("ds1_copy") +@pytest.mark.parametrize("autoalt", [None, "true", "false"]) def test_auto_alt(runner, yadm_cmd, paths, autoalt): """Test auto alt""" # set the value of auto-alt if autoalt: - os.system(' '.join(yadm_cmd('config', 'yadm.auto-alt', autoalt))) + os.system(" ".join(yadm_cmd("config", "yadm.auto-alt", autoalt))) - utils.create_alt_files(paths, '##default') - run = runner(yadm_cmd('status')) + utils.create_alt_files(paths, "##default") + run = runner(yadm_cmd("status")) assert run.success - assert run.err == '' + assert run.err == "" linked = utils.parse_alt_output(run.out) for link_path in TEST_PATHS: - source_file = link_path + '##default' - if autoalt == 'false': + source_file = link_path + "##default" + if autoalt == "false": assert not paths.work.join(link_path).exists() else: assert paths.work.join(link_path).islink() - target = py.path.local( - os.path.realpath(paths.work.join(link_path))) + target = py.path.local(os.path.realpath(paths.work.join(link_path))) if target.isfile(): assert paths.work.join(link_path).read() == source_file # no linking output when run via auto-alt assert str(paths.work.join(source_file)) not in linked else: - assert paths.work.join(link_path).join( - utils.CONTAINED).read() == source_file + assert paths.work.join(link_path).join(utils.CONTAINED).read() == source_file # no linking output when run via auto-alt assert str(paths.work.join(source_file)) not in linked -@pytest.mark.usefixtures('ds1_copy') +@pytest.mark.usefixtures("ds1_copy") def test_stale_link_removal(runner, yadm_cmd, paths): """Stale links to alternative files are removed @@ -202,48 +210,47 @@ def test_stale_link_removal(runner, yadm_cmd, paths): """ # set the class - tst_class = 'testclass' - utils.set_local(paths, 'class', tst_class) + tst_class = "testclass" + utils.set_local(paths, "class", tst_class) # create files which match the test class - utils.create_alt_files(paths, f'##class.{tst_class}') + utils.create_alt_files(paths, f"##class.{tst_class}") # run alt to trigger linking - run = runner(yadm_cmd('alt')) + run = runner(yadm_cmd("alt")) assert run.success - assert run.err == '' + assert run.err == "" linked = utils.parse_alt_output(run.out) # assert the proper linking has occurred for stale_path in TEST_PATHS: - source_file = stale_path + '##class.' + tst_class + source_file = stale_path + "##class." + tst_class assert paths.work.join(stale_path).islink() target = py.path.local(os.path.realpath(paths.work.join(stale_path))) if target.isfile(): assert paths.work.join(stale_path).read() == source_file assert str(paths.work.join(source_file)) in linked else: - assert paths.work.join(stale_path).join( - utils.CONTAINED).read() == source_file + assert paths.work.join(stale_path).join(utils.CONTAINED).read() == source_file assert str(paths.work.join(source_file)) in linked # change the class so there are no valid alternates - utils.set_local(paths, 'class', 'changedclass') + utils.set_local(paths, "class", "changedclass") # run alt to trigger linking - run = runner(yadm_cmd('alt')) + run = runner(yadm_cmd("alt")) assert run.success - assert run.err == '' + assert run.err == "" linked = utils.parse_alt_output(run.out) # assert the linking is removed for stale_path in TEST_PATHS: - source_file = stale_path + '##class.' + tst_class + source_file = stale_path + "##class." + tst_class assert not paths.work.join(stale_path).exists() assert str(paths.work.join(source_file)) not in linked -@pytest.mark.usefixtures('ds1_repo_copy') +@pytest.mark.usefixtures("ds1_repo_copy") def test_template_overwrite_symlink(runner, yadm_cmd, paths, tst_sys): """Remove symlinks before processing a template @@ -252,45 +259,44 @@ def test_template_overwrite_symlink(runner, yadm_cmd, paths, tst_sys): be removed just before processing a template. """ - target = paths.work.join(f'test_link##os.{tst_sys}') - target.write('target') + target = paths.work.join(f"test_link##os.{tst_sys}") + target.write("target") - link = paths.work.join('test_link') + link = paths.work.join("test_link") link.mksymlinkto(target, absolute=1) - template = paths.work.join('test_link##template.default') - template.write('test-data') + template = paths.work.join("test_link##template.default") + template.write("test-data") - run = runner(yadm_cmd('add', target, template)) + run = runner(yadm_cmd("add", target, template)) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" assert not link.islink() - assert target.read().strip() == 'target' - assert link.read().strip() == 'test-data' + assert target.read().strip() == "target" + assert link.read().strip() == "test-data" -@pytest.mark.usefixtures('ds1_copy') -@pytest.mark.parametrize('style', ['symlink', 'template']) +@pytest.mark.usefixtures("ds1_copy") +@pytest.mark.parametrize("style", ["symlink", "template"]) def test_ensure_alt_path(runner, paths, style): """Test that directories are created before making alternates""" yadm_dir, yadm_data = setup_standard_yadm_dir(paths) - suffix = 'default' if style == 'symlink' else 'template' - filename = 'a/b/c/file' - source = yadm_dir.join(f'alt/{filename}##{suffix}') - source.write('test-data', ensure=True) - run = runner([ - paths.pgm, '-Y', yadm_dir, '--yadm-data', yadm_data, 'add', source]) + suffix = "default" if style == "symlink" else "template" + filename = "a/b/c/file" + source = yadm_dir.join(f"alt/{filename}##{suffix}") + source.write("test-data", ensure=True) + run = runner([paths.pgm, "-Y", yadm_dir, "--yadm-data", yadm_data, "add", source]) assert run.success - assert run.err == '' - assert run.out == '' - assert paths.work.join(filename).read().strip() == 'test-data' + assert run.err == "" + assert run.out == "" + assert paths.work.join(filename).read().strip() == "test-data" def setup_standard_yadm_dir(paths): """Configure a yadm home within the work tree""" - std_yadm_dir = paths.work.mkdir('.config').mkdir('yadm') - std_yadm_data = paths.work.mkdir('.local').mkdir('share').mkdir('yadm') - std_yadm_data.join('repo.git').mksymlinkto(paths.repo, absolute=1) - std_yadm_dir.join('encrypt').mksymlinkto(paths.encrypt, absolute=1) + std_yadm_dir = paths.work.mkdir(".config").mkdir("yadm") + std_yadm_data = paths.work.mkdir(".local").mkdir("share").mkdir("yadm") + std_yadm_data.join("repo.git").mksymlinkto(paths.repo, absolute=1) + std_yadm_dir.join("encrypt").mksymlinkto(paths.encrypt, absolute=1) return std_yadm_dir, std_yadm_data diff --git a/test/test_alt_copy.py b/test/test_alt_copy.py index eb19e3d..e1beece 100644 --- a/test/test_alt_copy.py +++ b/test/test_alt_copy.py @@ -6,41 +6,41 @@ import pytest @pytest.mark.parametrize( - 'setting, expect_link, pre_existing', [ + "setting, expect_link, pre_existing", + [ (None, True, None), (True, False, None), (False, True, None), - (True, False, 'link'), - (True, False, 'file'), + (True, False, "link"), + (True, False, "file"), ], ids=[ - 'unset', - 'true', - 'false', - 'pre-existing symlink', - 'pre-existing file', - ]) -@pytest.mark.usefixtures('ds1_copy') -def test_alt_copy( - runner, yadm_cmd, paths, tst_sys, - setting, expect_link, pre_existing): + "unset", + "true", + "false", + "pre-existing symlink", + "pre-existing file", + ], +) +@pytest.mark.usefixtures("ds1_copy") +def test_alt_copy(runner, yadm_cmd, paths, tst_sys, setting, expect_link, pre_existing): """Test yadm.alt-copy""" if setting is not None: - os.system(' '.join(yadm_cmd('config', 'yadm.alt-copy', str(setting)))) + os.system(" ".join(yadm_cmd("config", "yadm.alt-copy", str(setting)))) - expected_content = f'test_alt_copy##os.{tst_sys}' + expected_content = f"test_alt_copy##os.{tst_sys}" - alt_path = paths.work.join('test_alt_copy') - if pre_existing == 'symlink': + alt_path = paths.work.join("test_alt_copy") + if pre_existing == "symlink": alt_path.mklinkto(expected_content) - elif pre_existing == 'file': - alt_path.write('wrong content') + elif pre_existing == "file": + alt_path.write("wrong content") - run = runner(yadm_cmd('alt')) + run = runner(yadm_cmd("alt")) assert run.success - assert run.err == '' - assert 'Linking' in run.out + assert run.err == "" + assert "Linking" in run.out assert alt_path.read() == expected_content assert alt_path.islink() == expect_link diff --git a/test/test_assert_private_dirs.py b/test/test_assert_private_dirs.py index 440446b..0cba1f6 100644 --- a/test/test_assert_private_dirs.py +++ b/test/test_assert_private_dirs.py @@ -5,11 +5,11 @@ import re import pytest -pytestmark = pytest.mark.usefixtures('ds1_copy') -PRIVATE_DIRS = ['.gnupg', '.ssh'] +pytestmark = pytest.mark.usefixtures("ds1_copy") +PRIVATE_DIRS = [".gnupg", ".ssh"] -@pytest.mark.parametrize('home', [True, False], ids=['home', 'not-home']) +@pytest.mark.parametrize("home", [True, False], ids=["home", "not-home"]) def test_pdirs_missing(runner, yadm_cmd, paths, home): """Private dirs (private dirs missing) @@ -25,15 +25,15 @@ def test_pdirs_missing(runner, yadm_cmd, paths, home): path.remove() assert not path.exists() - env = {'DEBUG': 'yes'} + env = {"DEBUG": "yes"} if home: - env['HOME'] = paths.work + env["HOME"] = paths.work # run status - run = runner(command=yadm_cmd('status'), env=env) + run = runner(command=yadm_cmd("status"), env=env) assert run.success - assert run.err == '' - assert 'On branch master' in run.out + assert run.err == "" + assert "On branch master" in run.out # confirm directories are created # and are protected @@ -41,17 +41,15 @@ def test_pdirs_missing(runner, yadm_cmd, paths, home): path = paths.work.join(pdir) if home: assert path.exists() - assert oct(path.stat().mode).endswith('00'), ('Directory is ' - 'not secured') + assert oct(path.stat().mode).endswith("00"), "Directory is " "not secured" else: assert not path.exists() # confirm directories are created before command is run: if home: assert re.search( - (r'Creating.+\.(gnupg|ssh).+Creating.+\.(gnupg|ssh).+' - r'Running git command git status'), - run.out, re.DOTALL), 'directories created before command is run' + r"Creating.+\.(gnupg|ssh).+Creating.+\.(gnupg|ssh).+Running git command git status", run.out, re.DOTALL + ), "directories created before command is run" def test_pdirs_missing_apd_false(runner, yadm_cmd, paths): @@ -71,14 +69,13 @@ def test_pdirs_missing_apd_false(runner, yadm_cmd, paths): assert not path.exists() # set configuration - os.system(' '.join(yadm_cmd( - 'config', '--bool', 'yadm.auto-private-dirs', 'false'))) + os.system(" ".join(yadm_cmd("config", "--bool", "yadm.auto-private-dirs", "false"))) # run status - run = runner(command=yadm_cmd('status')) + run = runner(command=yadm_cmd("status")) assert run.success - assert run.err == '' - assert 'On branch master' in run.out + assert run.err == "" + assert "On branch master" in run.out # confirm directories are STILL missing for pdir in PRIVATE_DIRS: @@ -100,19 +97,18 @@ def test_pdirs_exist_apd_false(runner, yadm_cmd, paths): if not path.isdir(): path.mkdir() path.chmod(0o777) - assert oct(path.stat().mode).endswith('77'), 'Directory is secure.' + assert oct(path.stat().mode).endswith("77"), "Directory is secure." # set configuration - os.system(' '.join(yadm_cmd( - 'config', '--bool', 'yadm.auto-perms', 'false'))) + os.system(" ".join(yadm_cmd("config", "--bool", "yadm.auto-perms", "false"))) # run status - run = runner(command=yadm_cmd('status')) + run = runner(command=yadm_cmd("status")) assert run.success - assert run.err == '' - assert 'On branch master' in run.out + assert run.err == "" + assert "On branch master" in run.out # created directories are STILL permissive for pdir in PRIVATE_DIRS: path = paths.work.join(pdir) - assert oct(path.stat().mode).endswith('77'), 'Directory is secure' + assert oct(path.stat().mode).endswith("77"), "Directory is secure" diff --git a/test/test_bootstrap.py b/test/test_bootstrap.py index 4865ece..099dde8 100644 --- a/test/test_bootstrap.py +++ b/test/test_bootstrap.py @@ -4,32 +4,30 @@ import pytest @pytest.mark.parametrize( - 'exists, executable, code, expect', [ - (False, False, 1, 'Cannot execute bootstrap'), - (True, False, 1, 'is not an executable program'), - (True, True, 123, 'Bootstrap successful'), - ], ids=[ - 'missing', - 'not executable', - 'executable', - ]) -def test_bootstrap( - runner, yadm_cmd, paths, exists, executable, code, expect): + "exists, executable, code, expect", + [ + (False, False, 1, "Cannot execute bootstrap"), + (True, False, 1, "is not an executable program"), + (True, True, 123, "Bootstrap successful"), + ], + ids=[ + "missing", + "not executable", + "executable", + ], +) +def test_bootstrap(runner, yadm_cmd, paths, exists, executable, code, expect): """Test bootstrap command""" if exists: - paths.bootstrap.write('') + paths.bootstrap.write("") if executable: - paths.bootstrap.write( - '#!/bin/bash\n' - f'echo {expect}\n' - f'exit {code}\n' - ) + paths.bootstrap.write("#!/bin/bash\n" f"echo {expect}\n" f"exit {code}\n") paths.bootstrap.chmod(0o775) - run = runner(command=yadm_cmd('bootstrap')) + run = runner(command=yadm_cmd("bootstrap")) assert run.code == code if exists and executable: - assert run.err == '' + assert run.err == "" assert expect in run.out else: assert expect in run.err - assert run.out == '' + assert run.out == "" diff --git a/test/test_clean.py b/test/test_clean.py index 39e7e54..4eaf1e4 100644 --- a/test/test_clean.py +++ b/test/test_clean.py @@ -3,9 +3,9 @@ def test_clean_command(runner, yadm_cmd): """Run with clean command""" - run = runner(command=yadm_cmd('clean')) + run = runner(command=yadm_cmd("clean")) # do nothing, this is a dangerous Git command when managing dot files # report the command as disabled and exit as a failure assert run.failure - assert run.out == '' - assert 'disabled' in run.err + assert run.out == "" + assert "disabled" in run.err diff --git a/test/test_clone.py b/test/test_clone.py index 9268965..1cae929 100644 --- a/test/test_clone.py +++ b/test/test_clone.py @@ -6,27 +6,28 @@ import re import pytest BOOTSTRAP_CODE = 123 -BOOTSTRAP_MSG = 'Bootstrap successful' +BOOTSTRAP_MSG = "Bootstrap successful" -@pytest.mark.usefixtures('remote') +@pytest.mark.usefixtures("remote") @pytest.mark.parametrize( - 'good_remote, repo_exists, force, conflicts', [ + "good_remote, repo_exists, force, conflicts", + [ (False, False, False, False), (True, False, False, False), (True, True, False, False), (True, True, True, False), (True, False, False, True), - ], ids=[ - 'bad remote', - 'simple', - 'existing repo', - '-f', - 'conflicts', - ]) -def test_clone( - runner, paths, yadm_cmd, repo_config, ds1, - good_remote, repo_exists, force, conflicts): + ], + ids=[ + "bad remote", + "simple", + "existing repo", + "-f", + "conflicts", + ], +) +def test_clone(runner, paths, yadm_cmd, repo_config, ds1, good_remote, repo_exists, force, conflicts): """Test basic clone operation""" # clear out the work path @@ -34,74 +35,70 @@ def test_clone( paths.work.mkdir() # determine remote url - remote_url = f'file://{paths.remote}' + remote_url = f"file://{paths.remote}" if not good_remote: - remote_url = 'file://bad_remote' + remote_url = "file://bad_remote" old_repo = None if repo_exists: # put a repo in the way paths.repo.mkdir() - old_repo = paths.repo.join('old_repo') - old_repo.write('old_repo') + old_repo = paths.repo.join("old_repo") + old_repo.write("old_repo") if conflicts: - ds1.tracked[0].relative.write('conflict') + ds1.tracked[0].relative.write("conflict") assert ds1.tracked[0].relative.exists() # run the clone command - args = ['clone', '-w', paths.work] + args = ["clone", "-w", paths.work] if force: - args += ['-f'] + args += ["-f"] args += [remote_url] run = runner(command=yadm_cmd(*args)) if not good_remote: # clone should fail assert run.failure - assert run.out == '' - assert 'Unable to clone the repository' in run.err + assert run.out == "" + assert "Unable to clone the repository" in run.err assert not paths.repo.exists() elif repo_exists and not force: # can't overwrite data assert run.failure - assert run.out == '' - assert 'Git repo already exists' in run.err + assert run.out == "" + assert "Git repo already exists" in run.err else: # clone should succeed, and repo should be configured properly assert successful_clone(run, paths, repo_config) # these clones should have master as HEAD - verify_head(paths, 'master') + verify_head(paths, "master") # ensure conflicts are handled properly if conflicts: - assert 'NOTE' in run.out - assert 'Local files with content that differs' in run.out + assert "NOTE" in run.out + assert "Local files with content that differs" in run.out # confirm correct Git origin - run = runner( - command=('git', 'remote', '-v', 'show'), - env={'GIT_DIR': paths.repo}) + run = runner(command=("git", "remote", "-v", "show"), env={"GIT_DIR": paths.repo}) assert run.success - assert run.err == '' - assert f'origin\t{remote_url}' in run.out + assert run.err == "" + assert f"origin\t{remote_url}" in run.out # ensure conflicts are really preserved if conflicts: # test that the conflicts are preserved in the work tree - run = runner( - command=yadm_cmd('status', '-uno', '--porcelain'), - cwd=paths.work) + run = runner(command=yadm_cmd("status", "-uno", "--porcelain"), cwd=paths.work) assert run.success - assert run.err == '' + assert run.err == "" assert str(ds1.tracked[0].path) in run.out # verify content of the conflicts - run = runner(command=yadm_cmd('diff'), cwd=paths.work) + run = runner(command=yadm_cmd("diff"), cwd=paths.work) assert run.success - assert run.err == '' - assert '\n+conflict' in run.out, 'conflict overwritten' + assert run.err == "" + assert "\n+conflict" in run.out, "conflict overwritten" # another force-related assertion if old_repo: @@ -111,54 +108,56 @@ def test_clone( assert old_repo.exists() -@pytest.mark.usefixtures('remote') +@pytest.mark.usefixtures("remote") @pytest.mark.parametrize( - 'bs_exists, bs_param, answer', [ - (False, '--bootstrap', None), - (True, '--bootstrap', None), - (True, '--no-bootstrap', None), - (True, None, 'n'), - (True, None, 'y'), - ], ids=[ - 'force, missing', - 'force, existing', - 'prevent', - 'existing, answer n', - 'existing, answer y', - ]) -def test_clone_bootstrap( - runner, paths, yadm_cmd, repo_config, bs_exists, bs_param, answer): + "bs_exists, bs_param, answer", + [ + (False, "--bootstrap", None), + (True, "--bootstrap", None), + (True, "--no-bootstrap", None), + (True, None, "n"), + (True, None, "y"), + ], + ids=[ + "force, missing", + "force, existing", + "prevent", + "existing, answer n", + "existing, answer y", + ], +) +def test_clone_bootstrap(runner, paths, yadm_cmd, repo_config, bs_exists, bs_param, answer): """Test bootstrap clone features""" # establish a bootstrap create_bootstrap(paths, bs_exists) # run the clone command - args = ['clone', '-w', paths.work] + args = ["clone", "-w", paths.work] if bs_param: args += [bs_param] - args += [f'file://{paths.remote}'] + args += [f"file://{paths.remote}"] expect = [] if answer: - expect.append(('Would you like to execute it now', answer)) + expect.append(("Would you like to execute it now", answer)) run = runner(command=yadm_cmd(*args), expect=expect) if answer: - assert 'Would you like to execute it now' in run.out + assert "Would you like to execute it now" in run.out expected_code = 0 - if bs_exists and bs_param != '--no-bootstrap': + if bs_exists and bs_param != "--no-bootstrap": expected_code = BOOTSTRAP_CODE - if answer == 'y': + if answer == "y": expected_code = BOOTSTRAP_CODE assert BOOTSTRAP_MSG in run.out - elif answer == 'n': + elif answer == "n": expected_code = 0 assert BOOTSTRAP_MSG not in run.out assert successful_clone(run, paths, repo_config, expected_code) - verify_head(paths, 'master') + verify_head(paths, "master") if not bs_exists: assert BOOTSTRAP_MSG not in run.out @@ -167,108 +166,90 @@ def test_clone_bootstrap( def create_bootstrap(paths, exists): """Create bootstrap file for test""" if exists: - paths.bootstrap.write( - '#!/bin/sh\n' - f'echo {BOOTSTRAP_MSG}\n' - f'exit {BOOTSTRAP_CODE}\n') + paths.bootstrap.write("#!/bin/sh\n" f"echo {BOOTSTRAP_MSG}\n" f"exit {BOOTSTRAP_CODE}\n") paths.bootstrap.chmod(0o775) assert paths.bootstrap.exists() else: assert not paths.bootstrap.exists() -@pytest.mark.usefixtures('remote') +@pytest.mark.usefixtures("remote") @pytest.mark.parametrize( - 'private_type, in_repo, in_work', [ - ('ssh', False, True), - ('gnupg', False, True), - ('ssh', True, True), - ('gnupg', True, True), - ('ssh', True, False), - ('gnupg', True, False), - ], ids=[ - 'open ssh, not tracked', - 'open gnupg, not tracked', - 'open ssh, tracked', - 'open gnupg, tracked', - 'missing ssh, tracked', - 'missing gnupg, tracked', - ]) -def test_clone_perms( - runner, yadm_cmd, paths, repo_config, - private_type, in_repo, in_work): + "private_type, in_repo, in_work", + [ + ("ssh", False, True), + ("gnupg", False, True), + ("ssh", True, True), + ("gnupg", True, True), + ("ssh", True, False), + ("gnupg", True, False), + ], + ids=[ + "open ssh, not tracked", + "open gnupg, not tracked", + "open ssh, tracked", + "open gnupg, tracked", + "missing ssh, tracked", + "missing gnupg, tracked", + ], +) +def test_clone_perms(runner, yadm_cmd, paths, repo_config, private_type, in_repo, in_work): """Test clone permission-related functions""" # update remote repo to include private data if in_repo: - rpath = paths.work.mkdir(f'.{private_type}').join('related') - rpath.write('related') + rpath = paths.work.mkdir(f".{private_type}").join("related") + rpath.write("related") os.system(f'GIT_DIR="{paths.remote}" git add {rpath}') os.system(f'GIT_DIR="{paths.remote}" git commit -m "{rpath}"') rpath.remove() # ensure local private data is insecure at the start if in_work: - pdir = paths.work.join(f'.{private_type}') + pdir = paths.work.join(f".{private_type}") if not pdir.exists(): pdir.mkdir() - pfile = pdir.join('existing') - pfile.write('existing') + pfile = pdir.join("existing") + pfile.write("existing") pdir.chmod(0o777) pfile.chmod(0o777) else: paths.work.remove() paths.work.mkdir() - env = {'HOME': paths.work} - run = runner( - yadm_cmd('clone', '-d', '-w', paths.work, f'file://{paths.remote}'), - env=env - ) + env = {"HOME": paths.work} + run = runner(yadm_cmd("clone", "-d", "-w", paths.work, f"file://{paths.remote}"), env=env) assert successful_clone(run, paths, repo_config) - verify_head(paths, 'master') + verify_head(paths, "master") if in_work: # private directories which already exist, should be left as they are, # which in this test is "insecure". - assert re.search( - f'initial private dir perms drwxrwxrwx.+.{private_type}', - run.out) - assert re.search( - f'pre-checkout private dir perms drwxrwxrwx.+.{private_type}', - run.out) - assert re.search( - f'post-checkout private dir perms drwxrwxrwx.+.{private_type}', - run.out) + assert re.search(f"initial private dir perms drwxrwxrwx.+.{private_type}", run.out) + assert re.search(f"pre-checkout private dir perms drwxrwxrwx.+.{private_type}", run.out) + assert re.search(f"post-checkout private dir perms drwxrwxrwx.+.{private_type}", run.out) else: # private directories which are created, should be done prior to # checkout, and with secure permissions. - assert 'initial private dir perms' not in run.out - assert re.search( - f'pre-checkout private dir perms drwx------.+.{private_type}', - run.out) - assert re.search( - f'post-checkout private dir perms drwx------.+.{private_type}', - run.out) + assert "initial private dir perms" not in run.out + assert re.search(f"pre-checkout private dir perms drwx------.+.{private_type}", run.out) + assert re.search(f"post-checkout private dir perms drwx------.+.{private_type}", run.out) # standard perms still apply afterwards unless disabled with auto.perms - assert oct( - paths.work.join(f'.{private_type}').stat().mode).endswith('00'), ( - f'.{private_type} has not been secured by auto.perms') + assert oct(paths.work.join(f".{private_type}").stat().mode).endswith( + "00" + ), f".{private_type} has not been secured by auto.perms" -@pytest.mark.usefixtures('remote') -@pytest.mark.parametrize( - 'branch', ['master', 'default', 'valid', 'invalid']) +@pytest.mark.usefixtures("remote") +@pytest.mark.parametrize("branch", ["master", "default", "valid", "invalid"]) def test_alternate_branch(runner, paths, yadm_cmd, repo_config, branch): """Test cloning a branch other than master""" # add a "valid" branch to the remote os.system(f'GIT_DIR="{paths.remote}" git checkout -b valid') - os.system( - f'GIT_DIR="{paths.remote}" git commit ' - f'--allow-empty -m "This branch is valid"') - if branch != 'default': + os.system(f'GIT_DIR="{paths.remote}" git commit ' f'--allow-empty -m "This branch is valid"') + if branch != "default": # When branch == 'default', the "default" branch of the remote repo # will remain "valid" to validate identification the correct default # branch by inspecting the repo. Otherwise it will be set back to @@ -279,45 +260,43 @@ def test_alternate_branch(runner, paths, yadm_cmd, repo_config, branch): paths.work.remove() paths.work.mkdir() - remote_url = f'file://{paths.remote}' + remote_url = f"file://{paths.remote}" # run the clone command - args = ['clone', '-w', paths.work] - if branch not in ['master', 'default']: - args += ['-b', branch] + args = ["clone", "-w", paths.work] + if branch not in ["master", "default"]: + args += ["-b", branch] args += [remote_url] run = runner(command=yadm_cmd(*args)) - if branch == 'invalid': + if branch == "invalid": assert run.failure - assert 'ERROR: Unable to clone the repository' in run.err + assert "ERROR: Unable to clone the repository" in run.err assert f"Remote branch {branch} not found in upstream" in run.err else: assert successful_clone(run, paths, repo_config) # confirm correct Git origin - run = runner( - command=('git', 'remote', '-v', 'show'), - env={'GIT_DIR': paths.repo}) + run = runner(command=("git", "remote", "-v", "show"), env={"GIT_DIR": paths.repo}) assert run.success - assert run.err == '' - assert f'origin\t{remote_url}' in run.out - run = runner(command=yadm_cmd('show')) - if branch == 'master': - assert 'Initial commit' in run.out - verify_head(paths, 'master') + assert run.err == "" + assert f"origin\t{remote_url}" in run.out + run = runner(command=yadm_cmd("show")) + if branch == "master": + assert "Initial commit" in run.out + verify_head(paths, "master") else: - assert 'This branch is valid' in run.out - verify_head(paths, 'valid') + assert "This branch is valid" in run.out + verify_head(paths, "valid") def successful_clone(run, paths, repo_config, expected_code=0): """Assert clone is successful""" assert run.code == expected_code - assert oct(paths.repo.stat().mode).endswith('00'), 'Repo is not secured' - assert repo_config('core.bare') == 'false' - assert repo_config('status.showUntrackedFiles') == 'no' - assert repo_config('yadm.managed') == 'true' + assert oct(paths.repo.stat().mode).endswith("00"), "Repo is not secured" + assert repo_config("core.bare") == "false" + assert repo_config("status.showUntrackedFiles") == "no" + assert repo_config("yadm.managed") == "true" return True @@ -332,15 +311,18 @@ def remote(paths, ds1_repo_copy): paths.repo.move(paths.remote) -def test_no_repo(runner, yadm_cmd, ): +def test_no_repo( + runner, + yadm_cmd, +): """Test cloning without specifying a repo""" - run = runner(command=yadm_cmd('clone', '-f')) + run = runner(command=yadm_cmd("clone", "-f")) assert run.failure - assert run.out == '' - assert 'ERROR: Unable to clone the repository' in run.err - assert 'repository \'repo.git\' does not exist' in run.err + assert run.out == "" + assert "ERROR: Unable to clone the repository" in run.err + assert "repository 'repo.git' does not exist" in run.err def verify_head(paths, branch): """Assert the local repo has the correct head branch""" - assert paths.repo.join('HEAD').read() == f'ref: refs/heads/{branch}\n' + assert paths.repo.join("HEAD").read() == f"ref: refs/heads/{branch}\n" diff --git a/test/test_config.py b/test/test_config.py index d6a5e33..c43d81c 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -4,11 +4,11 @@ import os import pytest -TEST_SECTION = 'test' -TEST_ATTRIBUTE = 'attribute' -TEST_KEY = f'{TEST_SECTION}.{TEST_ATTRIBUTE}' -TEST_VALUE = 'testvalue' -TEST_FILE = f'[{TEST_SECTION}]\n\t{TEST_ATTRIBUTE} = {TEST_VALUE}' +TEST_SECTION = "test" +TEST_ATTRIBUTE = "attribute" +TEST_KEY = f"{TEST_SECTION}.{TEST_ATTRIBUTE}" +TEST_VALUE = "testvalue" +TEST_FILE = f"[{TEST_SECTION}]\n\t{TEST_ATTRIBUTE} = {TEST_VALUE}" def test_config_no_params(runner, yadm_cmd, supported_configs): @@ -19,11 +19,11 @@ def test_config_no_params(runner, yadm_cmd, supported_configs): Exit with 0 """ - run = runner(yadm_cmd('config')) + run = runner(yadm_cmd("config")) assert run.success - assert run.err == '' - assert 'Please read the CONFIGURATION section' in run.out + assert run.err == "" + assert "Please read the CONFIGURATION section" in run.out for config in supported_configs: assert config in run.out @@ -35,11 +35,11 @@ def test_config_read_missing(runner, yadm_cmd): Exit with 0 """ - run = runner(yadm_cmd('config', TEST_KEY)) + run = runner(yadm_cmd("config", TEST_KEY)) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" def test_config_write(runner, yadm_cmd, paths): @@ -50,11 +50,11 @@ def test_config_write(runner, yadm_cmd, paths): Exit with 0 """ - run = runner(yadm_cmd('config', TEST_KEY, TEST_VALUE)) + run = runner(yadm_cmd("config", TEST_KEY, TEST_VALUE)) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" assert paths.config.read().strip() == TEST_FILE @@ -66,10 +66,10 @@ def test_config_read(runner, yadm_cmd, paths): """ paths.config.write(TEST_FILE) - run = runner(yadm_cmd('config', TEST_KEY)) + run = runner(yadm_cmd("config", TEST_KEY)) assert run.success - assert run.err == '' + assert run.err == "" assert run.out.strip() == TEST_VALUE @@ -83,16 +83,16 @@ def test_config_update(runner, yadm_cmd, paths): paths.config.write(TEST_FILE) - run = runner(yadm_cmd('config', TEST_KEY, TEST_VALUE + 'extra')) + run = runner(yadm_cmd("config", TEST_KEY, TEST_VALUE + "extra")) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" - assert paths.config.read().strip() == TEST_FILE + 'extra' + assert paths.config.read().strip() == TEST_FILE + "extra" -@pytest.mark.usefixtures('ds1_repo_copy') +@pytest.mark.usefixtures("ds1_repo_copy") def test_config_local_read(runner, yadm_cmd, paths, supported_local_configs): """Read local attribute @@ -102,19 +102,17 @@ def test_config_local_read(runner, yadm_cmd, paths, supported_local_configs): # populate test values for config in supported_local_configs: - os.system( - f'GIT_DIR="{paths.repo}" ' - f'git config --local "{config}" "value_of_{config}"') + os.system(f'GIT_DIR="{paths.repo}" ' f'git config --local "{config}" "value_of_{config}"') # run yadm config for config in supported_local_configs: - run = runner(yadm_cmd('config', config)) + run = runner(yadm_cmd("config", config)) assert run.success - assert run.err == '' - assert run.out.strip() == f'value_of_{config}' + assert run.err == "" + assert run.out.strip() == f"value_of_{config}" -@pytest.mark.usefixtures('ds1_repo_copy') +@pytest.mark.usefixtures("ds1_repo_copy") def test_config_local_write(runner, yadm_cmd, paths, supported_local_configs): """Write local attribute @@ -125,19 +123,17 @@ def test_config_local_write(runner, yadm_cmd, paths, supported_local_configs): # run yadm config for config in supported_local_configs: - run = runner(yadm_cmd('config', config, f'value_of_{config}')) + run = runner(yadm_cmd("config", config, f"value_of_{config}")) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" # verify test values for config in supported_local_configs: - run = runner( - command=('git', 'config', config), - env={'GIT_DIR': paths.repo}) + run = runner(command=("git", "config", config), env={"GIT_DIR": paths.repo}) assert run.success - assert run.err == '' - assert run.out.strip() == f'value_of_{config}' + assert run.err == "" + assert run.out.strip() == f"value_of_{config}" def test_config_without_parent_directory(runner, yadm_cmd, paths): @@ -148,17 +144,16 @@ def test_config_without_parent_directory(runner, yadm_cmd, paths): Exit with 0 """ - config_file = paths.root + '/folder/does/not/exist/config' + config_file = paths.root + "/folder/does/not/exist/config" - run = runner( - yadm_cmd('--yadm-config', config_file, 'config', TEST_KEY, TEST_VALUE)) + run = runner(yadm_cmd("--yadm-config", config_file, "config", TEST_KEY, TEST_VALUE)) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" - run = runner(yadm_cmd('--yadm-config', config_file, 'config', TEST_KEY)) + run = runner(yadm_cmd("--yadm-config", config_file, "config", TEST_KEY)) assert run.success - assert run.err == '' + assert run.err == "" assert run.out.strip() == TEST_VALUE diff --git a/test/test_encryption.py b/test/test_encryption.py index 78bbf3a..8c64222 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -6,26 +6,26 @@ import time import pytest -KEY_FILE = 'test/test_key' -KEY_FINGERPRINT = 'F8BBFC746C58945442349BCEBA54FFD04C599B1A' -KEY_NAME = 'yadm-test1' -KEY_TRUST = 'test/ownertrust.txt' -PASSPHRASE = 'ExamplePassword' +KEY_FILE = "test/test_key" +KEY_FINGERPRINT = "F8BBFC746C58945442349BCEBA54FFD04C599B1A" +KEY_NAME = "yadm-test1" +KEY_TRUST = "test/ownertrust.txt" +PASSPHRASE = "ExamplePassword" -pytestmark = pytest.mark.usefixtures('config_git') +pytestmark = pytest.mark.usefixtures("config_git") def add_asymmetric_key(runner, gnupg): """Add asymmetric key""" env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home runner( - ['gpg', '--import', shlex.quote(KEY_FILE)], + ["gpg", "--import", shlex.quote(KEY_FILE)], env=env, shell=True, ) runner( - ['gpg', '--import-ownertrust', '<', shlex.quote(KEY_TRUST)], + ["gpg", "--import-ownertrust", "<", shlex.quote(KEY_TRUST)], env=env, shell=True, ) @@ -34,20 +34,14 @@ def add_asymmetric_key(runner, gnupg): def remove_asymmetric_key(runner, gnupg): """Remove asymmetric key""" env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home runner( - [ - 'gpg', '--batch', '--yes', - '--delete-secret-keys', shlex.quote(KEY_FINGERPRINT) - ], + ["gpg", "--batch", "--yes", "--delete-secret-keys", shlex.quote(KEY_FINGERPRINT)], env=env, shell=True, ) runner( - [ - 'gpg', '--batch', '--yes', - '--delete-key', shlex.quote(KEY_FINGERPRINT) - ], + ["gpg", "--batch", "--yes", "--delete-key", shlex.quote(KEY_FINGERPRINT)], env=env, shell=True, ) @@ -79,48 +73,48 @@ def encrypt_targets(yadm_cmd, paths): """ # init empty yadm repo - os.system(' '.join(yadm_cmd('init', '-w', str(paths.work), '-f'))) + os.system(" ".join(yadm_cmd("init", "-w", str(paths.work), "-f"))) expected = [] # standard files w/ dirs & spaces - paths.work.join('inc file1').write('inc file1') - expected.append('inc file1') - paths.encrypt.write('inc file1\n') - paths.work.join('inc dir').mkdir() - paths.work.join('inc dir/inc file2').write('inc file2') - expected.append('inc dir/inc file2') - paths.encrypt.write('inc dir/inc file2\n', mode='a') + paths.work.join("inc file1").write("inc file1") + expected.append("inc file1") + paths.encrypt.write("inc file1\n") + paths.work.join("inc dir").mkdir() + paths.work.join("inc dir/inc file2").write("inc file2") + expected.append("inc dir/inc file2") + paths.encrypt.write("inc dir/inc file2\n", mode="a") # standard globs w/ dirs & spaces - paths.work.join('globs file1').write('globs file1') - expected.append('globs file1') - paths.work.join('globs dir').mkdir() - paths.work.join('globs dir/globs file2').write('globs file2') - expected.append('globs dir/globs file2') - paths.encrypt.write('globs*\n', mode='a') + paths.work.join("globs file1").write("globs file1") + expected.append("globs file1") + paths.work.join("globs dir").mkdir() + paths.work.join("globs dir/globs file2").write("globs file2") + expected.append("globs dir/globs file2") + paths.encrypt.write("globs*\n", mode="a") # blank lines - paths.encrypt.write('\n \n\t\n', mode='a') + paths.encrypt.write("\n \n\t\n", mode="a") # comments - paths.work.join('commentfile1').write('commentfile1') - paths.encrypt.write('#commentfile1\n', mode='a') - paths.encrypt.write(' #commentfile1\n', mode='a') + paths.work.join("commentfile1").write("commentfile1") + paths.encrypt.write("#commentfile1\n", mode="a") + paths.encrypt.write(" #commentfile1\n", mode="a") # exclusions - paths.work.join('extest').mkdir() - paths.encrypt.write('extest/*\n', mode='a') # include within extest - paths.work.join('extest/inglob1').write('inglob1') - paths.work.join('extest/exglob1').write('exglob1') - paths.work.join('extest/exglob2').write('exglob2') - paths.encrypt.write('!extest/ex*\n', mode='a') # exclude the ex* - expected.append('extest/inglob1') # should be left with only in* + paths.work.join("extest").mkdir() + paths.encrypt.write("extest/*\n", mode="a") # include within extest + paths.work.join("extest/inglob1").write("inglob1") + paths.work.join("extest/exglob1").write("exglob1") + paths.work.join("extest/exglob2").write("exglob2") + paths.encrypt.write("!extest/ex*\n", mode="a") # exclude the ex* + expected.append("extest/inglob1") # should be left with only in* return expected -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def decrypt_targets(tmpdir_factory, runner, gnupg): """Fixture for setting data to decrypt @@ -129,234 +123,203 @@ def decrypt_targets(tmpdir_factory, runner, gnupg): * creates a list of expected decrypted files """ - tmpdir = tmpdir_factory.mktemp('decrypt_targets') - symmetric = tmpdir.join('symmetric.tar.gz.gpg') - asymmetric = tmpdir.join('asymmetric.tar.gz.gpg') + tmpdir = tmpdir_factory.mktemp("decrypt_targets") + symmetric = tmpdir.join("symmetric.tar.gz.gpg") + asymmetric = tmpdir.join("asymmetric.tar.gz.gpg") expected = [] - tmpdir.join('decrypt1').write('decrypt1') - expected.append('decrypt1') - tmpdir.join('decrypt2').write('decrypt2') - expected.append('decrypt2') - tmpdir.join('subdir').mkdir() - tmpdir.join('subdir/decrypt3').write('subdir/decrypt3') - expected.append('subdir/decrypt3') + tmpdir.join("decrypt1").write("decrypt1") + expected.append("decrypt1") + tmpdir.join("decrypt2").write("decrypt2") + expected.append("decrypt2") + tmpdir.join("subdir").mkdir() + tmpdir.join("subdir/decrypt3").write("subdir/decrypt3") + expected.append("subdir/decrypt3") gnupg.pw(PASSPHRASE) env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home run = runner( - ['tar', 'cvf', '-'] + - expected + - ['|', 'gpg', '--batch', '--yes', '-c'] + - ['--output', shlex.quote(str(symmetric))], + ["tar", "cvf", "-"] + + expected + + ["|", "gpg", "--batch", "--yes", "-c"] + + ["--output", shlex.quote(str(symmetric))], cwd=tmpdir, env=env, - shell=True) + shell=True, + ) assert run.success - gnupg.pw('') + gnupg.pw("") add_asymmetric_key(runner, gnupg) run = runner( - ['tar', 'cvf', '-'] + - expected + - ['|', 'gpg', '--batch', '--yes', '-e'] + - ['-r', shlex.quote(KEY_NAME)] + - ['--output', shlex.quote(str(asymmetric))], + ["tar", "cvf", "-"] + + expected + + ["|", "gpg", "--batch", "--yes", "-e"] + + ["-r", shlex.quote(KEY_NAME)] + + ["--output", shlex.quote(str(asymmetric))], cwd=tmpdir, env=env, - shell=True) + shell=True, + ) assert run.success remove_asymmetric_key(runner, gnupg) return { - 'asymmetric': asymmetric, - 'expected': expected, - 'symmetric': symmetric, + "asymmetric": asymmetric, + "expected": expected, + "symmetric": symmetric, } -@pytest.mark.parametrize( - 'bad_phrase', [False, True], - ids=['good_phrase', 'bad_phrase']) -@pytest.mark.parametrize( - 'missing_encrypt', [False, True], - ids=['encrypt_exists', 'encrypt_missing']) -@pytest.mark.parametrize( - 'overwrite', [False, True], - ids=['clean', 'overwrite']) -def test_symmetric_encrypt( - runner, yadm_cmd, paths, encrypt_targets, - gnupg, bad_phrase, overwrite, missing_encrypt): +@pytest.mark.parametrize("bad_phrase", [False, True], ids=["good_phrase", "bad_phrase"]) +@pytest.mark.parametrize("missing_encrypt", [False, True], ids=["encrypt_exists", "encrypt_missing"]) +@pytest.mark.parametrize("overwrite", [False, True], ids=["clean", "overwrite"]) +def test_symmetric_encrypt(runner, yadm_cmd, paths, encrypt_targets, gnupg, bad_phrase, overwrite, missing_encrypt): """Test symmetric encryption""" if missing_encrypt: paths.encrypt.remove() if bad_phrase: - gnupg.pw('') + gnupg.pw("") else: gnupg.pw(PASSPHRASE) if overwrite: - paths.archive.write('existing archive') + paths.archive.write("existing archive") env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home - run = runner(yadm_cmd('encrypt'), env=env) + env["GNUPGHOME"] = gnupg.home + run = runner(yadm_cmd("encrypt"), env=env) if missing_encrypt or bad_phrase: assert run.failure else: assert run.success - assert run.err == '' + assert run.err == "" if missing_encrypt: - assert 'does not exist' in run.err + assert "does not exist" in run.err elif bad_phrase: - assert 'Invalid IPC' in run.err + assert "Invalid IPC" in run.err else: - assert encrypted_data_valid( - runner, gnupg, paths.archive, encrypt_targets) + assert encrypted_data_valid(runner, gnupg, paths.archive, encrypt_targets) -@pytest.mark.parametrize( - 'bad_phrase', [False, True], - ids=['good_phrase', 'bad_phrase']) -@pytest.mark.parametrize( - 'archive_exists', [True, False], - ids=['archive_exists', 'archive_missing']) -@pytest.mark.parametrize( - 'dolist', [False, True], - ids=['decrypt', 'list']) -def test_symmetric_decrypt( - runner, yadm_cmd, paths, decrypt_targets, gnupg, - dolist, archive_exists, bad_phrase): +@pytest.mark.parametrize("bad_phrase", [False, True], ids=["good_phrase", "bad_phrase"]) +@pytest.mark.parametrize("archive_exists", [True, False], ids=["archive_exists", "archive_missing"]) +@pytest.mark.parametrize("dolist", [False, True], ids=["decrypt", "list"]) +def test_symmetric_decrypt(runner, yadm_cmd, paths, decrypt_targets, gnupg, dolist, archive_exists, bad_phrase): """Test decryption""" # init empty yadm repo - os.system(' '.join(yadm_cmd('init', '-w', str(paths.work), '-f'))) + os.system(" ".join(yadm_cmd("init", "-w", str(paths.work), "-f"))) if bad_phrase: - gnupg.pw('') + gnupg.pw("") time.sleep(1) # allow gpg-agent cache to expire else: gnupg.pw(PASSPHRASE) if archive_exists: - decrypt_targets['symmetric'].copy(paths.archive) + decrypt_targets["symmetric"].copy(paths.archive) # to test overwriting - paths.work.join('decrypt1').write('pre-existing file') + paths.work.join("decrypt1").write("pre-existing file") env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home args = [] if dolist: - args.append('-l') - run = runner(yadm_cmd('decrypt') + args, env=env) + args.append("-l") + run = runner(yadm_cmd("decrypt") + args, env=env) if archive_exists and not bad_phrase: assert run.success - assert 'encrypted with 1 passphrase' in run.err + assert "encrypted with 1 passphrase" in run.err if dolist: - for filename in decrypt_targets['expected']: - if filename != 'decrypt1': # this one should exist + for filename in decrypt_targets["expected"]: + if filename != "decrypt1": # this one should exist assert not paths.work.join(filename).exists() assert filename in run.out else: - for filename in decrypt_targets['expected']: + for filename in decrypt_targets["expected"]: assert paths.work.join(filename).read() == filename else: assert run.failure -@pytest.mark.usefixtures('asymmetric_key') -@pytest.mark.parametrize( - 'ask', [False, True], - ids=['no_ask', 'ask']) -@pytest.mark.parametrize( - 'key_exists', [True, False], - ids=['key_exists', 'key_missing']) -@pytest.mark.parametrize( - 'overwrite', [False, True], - ids=['clean', 'overwrite']) -def test_asymmetric_encrypt( - runner, yadm_cmd, paths, encrypt_targets, gnupg, - overwrite, key_exists, ask): +@pytest.mark.usefixtures("asymmetric_key") +@pytest.mark.parametrize("ask", [False, True], ids=["no_ask", "ask"]) +@pytest.mark.parametrize("key_exists", [True, False], ids=["key_exists", "key_missing"]) +@pytest.mark.parametrize("overwrite", [False, True], ids=["clean", "overwrite"]) +def test_asymmetric_encrypt(runner, yadm_cmd, paths, encrypt_targets, gnupg, overwrite, key_exists, ask): """Test asymmetric encryption""" # specify encryption recipient if ask: - os.system(' '.join(yadm_cmd('config', 'yadm.gpg-recipient', 'ASK'))) - expect = [('Enter the user ID', KEY_NAME), ('Enter the user ID', '')] + os.system(" ".join(yadm_cmd("config", "yadm.gpg-recipient", "ASK"))) + expect = [("Enter the user ID", KEY_NAME), ("Enter the user ID", "")] else: - os.system(' '.join(yadm_cmd('config', 'yadm.gpg-recipient', KEY_NAME))) + os.system(" ".join(yadm_cmd("config", "yadm.gpg-recipient", KEY_NAME))) expect = [] if overwrite: - paths.archive.write('existing archive') + paths.archive.write("existing archive") if not key_exists: remove_asymmetric_key(runner, gnupg) env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home - run = runner(yadm_cmd('encrypt'), env=env, expect=expect) + run = runner(yadm_cmd("encrypt"), env=env, expect=expect) if key_exists: assert run.success - assert encrypted_data_valid( - runner, gnupg, paths.archive, encrypt_targets) + assert encrypted_data_valid(runner, gnupg, paths.archive, encrypt_targets) else: assert run.failure - assert 'Unable to write' in run.out if expect else run.err + assert "Unable to write" in run.out if expect else run.err if ask: - assert 'Enter the user ID' in run.out + assert "Enter the user ID" in run.out -@pytest.mark.usefixtures('asymmetric_key') -@pytest.mark.usefixtures('encrypt_targets') +@pytest.mark.usefixtures("asymmetric_key") +@pytest.mark.usefixtures("encrypt_targets") def test_multi_key(runner, yadm_cmd, gnupg): """Test multiple recipients""" # specify two encryption recipient - os.system(' '.join(yadm_cmd( - 'config', 'yadm.gpg-recipient', f'"second-key {KEY_NAME}"'))) + os.system(" ".join(yadm_cmd("config", "yadm.gpg-recipient", f'"second-key {KEY_NAME}"'))) env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home - run = runner(yadm_cmd('encrypt'), env=env) + run = runner(yadm_cmd("encrypt"), env=env) assert run.failure - assert 'second-key: skipped: No public key' in run.err + assert "second-key: skipped: No public key" in run.err -@pytest.mark.usefixtures('asymmetric_key') -@pytest.mark.parametrize( - 'key_exists', [True, False], - ids=['key_exists', 'key_missing']) -@pytest.mark.parametrize( - 'dolist', [False, True], - ids=['decrypt', 'list']) -def test_asymmetric_decrypt( - runner, yadm_cmd, paths, decrypt_targets, gnupg, - dolist, key_exists): +@pytest.mark.usefixtures("asymmetric_key") +@pytest.mark.parametrize("key_exists", [True, False], ids=["key_exists", "key_missing"]) +@pytest.mark.parametrize("dolist", [False, True], ids=["decrypt", "list"]) +def test_asymmetric_decrypt(runner, yadm_cmd, paths, decrypt_targets, gnupg, dolist, key_exists): """Test decryption""" # init empty yadm repo - os.system(' '.join(yadm_cmd('init', '-w', str(paths.work), '-f'))) + os.system(" ".join(yadm_cmd("init", "-w", str(paths.work), "-f"))) - decrypt_targets['asymmetric'].copy(paths.archive) + decrypt_targets["asymmetric"].copy(paths.archive) # to test overwriting - paths.work.join('decrypt1').write('pre-existing file') + paths.work.join("decrypt1").write("pre-existing file") if not key_exists: remove_asymmetric_key(runner, gnupg) @@ -364,32 +327,28 @@ def test_asymmetric_decrypt( args = [] if dolist: - args.append('-l') + args.append("-l") env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home - run = runner(yadm_cmd('decrypt') + args, env=env) + env["GNUPGHOME"] = gnupg.home + run = runner(yadm_cmd("decrypt") + args, env=env) if key_exists: assert run.success if dolist: - for filename in decrypt_targets['expected']: - if filename != 'decrypt1': # this one should exist + for filename in decrypt_targets["expected"]: + if filename != "decrypt1": # this one should exist assert not paths.work.join(filename).exists() assert filename in run.out else: - for filename in decrypt_targets['expected']: + for filename in decrypt_targets["expected"]: assert paths.work.join(filename).read() == filename else: assert run.failure - assert 'Unable to extract encrypted files' in run.err + assert "Unable to extract encrypted files" in run.err -@pytest.mark.parametrize( - 'untracked', - [False, 'y', 'n'], - ids=['tracked', 'untracked_answer_y', 'untracked_answer_n']) -def test_offer_to_add( - runner, yadm_cmd, paths, encrypt_targets, gnupg, untracked): +@pytest.mark.parametrize("untracked", [False, "y", "n"], ids=["tracked", "untracked_answer_y", "untracked_answer_n"]) +def test_offer_to_add(runner, yadm_cmd, paths, encrypt_targets, gnupg, untracked): """Test offer to add encrypted archive All the other encryption tests use an archive outside of the work tree. @@ -397,85 +356,75 @@ def test_offer_to_add( should be an offer to add it to the repo if it is not tracked. """ - worktree_archive = paths.work.join('worktree-archive.tar.gpg') + worktree_archive = paths.work.join("worktree-archive.tar.gpg") expect = [] gnupg.pw(PASSPHRASE) env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home if untracked: - expect.append(('add it now', untracked)) + expect.append(("add it now", untracked)) else: - worktree_archive.write('exists') - os.system(' '.join(yadm_cmd('add', str(worktree_archive)))) + worktree_archive.write("exists") + os.system(" ".join(yadm_cmd("add", str(worktree_archive)))) - run = runner( - yadm_cmd('encrypt', '--yadm-archive', str(worktree_archive)), - env=env, - expect=expect - ) + run = runner(yadm_cmd("encrypt", "--yadm-archive", str(worktree_archive)), env=env, expect=expect) assert run.success - assert run.err == '' - assert encrypted_data_valid( - runner, gnupg, worktree_archive, encrypt_targets) + assert run.err == "" + assert encrypted_data_valid(runner, gnupg, worktree_archive, encrypt_targets) - run = runner( - yadm_cmd('status', '--porcelain', '-uall', str(worktree_archive))) + run = runner(yadm_cmd("status", "--porcelain", "-uall", str(worktree_archive))) assert run.success - assert run.err == '' + assert run.err == "" - if untracked == 'y': + if untracked == "y": # should be added to the index - assert f'A {worktree_archive.basename}' in run.out - elif untracked == 'n': + assert f"A {worktree_archive.basename}" in run.out + elif untracked == "n": # should NOT be added to the index - assert f'?? {worktree_archive.basename}' in run.out + assert f"?? {worktree_archive.basename}" in run.out else: # should appear modified in the index - assert f'AM {worktree_archive.basename}' in run.out + assert f"AM {worktree_archive.basename}" in run.out -@pytest.mark.usefixtures('ds1_copy') +@pytest.mark.usefixtures("ds1_copy") def test_encrypt_added_to_exclude(runner, yadm_cmd, paths, gnupg): """Confirm that .config/yadm/encrypt is added to exclude""" gnupg.pw(PASSPHRASE) env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home + env["GNUPGHOME"] = gnupg.home - exclude_file = paths.repo.join('info/exclude') - paths.encrypt.write('test-encrypt-data\n') - paths.work.join('test-encrypt-data').write('') - exclude_file.write('original-data', ensure=True) + exclude_file = paths.repo.join("info/exclude") + paths.encrypt.write("test-encrypt-data\n") + paths.work.join("test-encrypt-data").write("") + exclude_file.write("original-data", ensure=True) - run = runner(yadm_cmd('encrypt'), env=env) + run = runner(yadm_cmd("encrypt"), env=env) - assert 'test-encrypt-data' in paths.repo.join('info/exclude').read() - assert 'original-data' in paths.repo.join('info/exclude').read() + assert "test-encrypt-data" in paths.repo.join("info/exclude").read() + assert "original-data" in paths.repo.join("info/exclude").read() assert run.success - assert run.err == '' + assert run.err == "" def encrypted_data_valid(runner, gnupg, encrypted, expected): """Verify encrypted data matches expectations""" gnupg.pw(PASSPHRASE) env = os.environ.copy() - env['GNUPGHOME'] = gnupg.home - run = runner([ - 'gpg', - '-d', shlex.quote(str(encrypted)), - '2>/dev/null', - '|', 'tar', 't'], env=env, shell=True, report=False) + env["GNUPGHOME"] = gnupg.home + run = runner( + ["gpg", "-d", shlex.quote(str(encrypted)), "2>/dev/null", "|", "tar", "t"], env=env, shell=True, report=False + ) file_count = 0 for filename in run.out.splitlines(): - if filename.endswith('/'): + if filename.endswith("/"): continue file_count += 1 - assert filename in expected, ( - f'Unexpected file in archive: {filename}') - assert file_count == len(expected), ( - 'Number of files in archive does not match expected') + assert filename in expected, f"Unexpected file in archive: {filename}" + assert file_count == len(expected), "Number of files in archive does not match expected" return True diff --git a/test/test_enter.py b/test/test_enter.py index 5148e23..b0626ae 100644 --- a/test/test_enter.py +++ b/test/test_enter.py @@ -6,106 +6,112 @@ import pytest @pytest.mark.parametrize( - 'shell, success', [ - ('delete', True), # if there is no shell variable, bash creates it - ('', False), - ('/usr/bin/env', True), - ('noexec', False), - ], ids=[ - 'shell-missing', - 'shell-empty', - 'shell-env', - 'shell-noexec', - ]) -@pytest.mark.usefixtures('ds1_copy') + "shell, success", + [ + ("delete", True), # if there is no shell variable, bash creates it + ("", False), + ("/usr/bin/env", True), + ("noexec", False), + ], + ids=[ + "shell-missing", + "shell-empty", + "shell-env", + "shell-noexec", + ], +) +@pytest.mark.usefixtures("ds1_copy") def test_enter(runner, yadm_cmd, paths, shell, success): """Enter tests""" env = os.environ.copy() - if shell == 'delete': + if shell == "delete": # remove shell - if 'SHELL' in env: - del env['SHELL'] - elif shell == 'noexec': + if "SHELL" in env: + del env["SHELL"] + elif shell == "noexec": # specify a non-executable path - noexec = paths.root.join('noexec') - noexec.write('') + noexec = paths.root.join("noexec") + noexec.write("") noexec.chmod(0o664) - env['SHELL'] = str(noexec) + env["SHELL"] = str(noexec) else: - env['SHELL'] = shell + env["SHELL"] = shell - run = runner(command=yadm_cmd('enter'), env=env) + run = runner(command=yadm_cmd("enter"), env=env) assert run.success == success - prompt = f'yadm shell ({paths.repo})' + prompt = f"yadm shell ({paths.repo})" if success: - assert run.out.startswith('Entering yadm repo') - assert run.out.rstrip().endswith('Leaving yadm repo') - assert run.err == '' + assert run.out.startswith("Entering yadm repo") + assert run.out.rstrip().endswith("Leaving yadm repo") + assert run.err == "" else: - assert 'does not refer to an executable' in run.err - if 'env' in shell: - assert f'GIT_DIR={paths.repo}' in run.out - assert f'GIT_WORK_TREE={paths.work}' in run.out - assert f'PROMPT={prompt}' in run.out - assert f'PS1={prompt}' in run.out + assert "does not refer to an executable" in run.err + if "env" in shell: + assert f"GIT_DIR={paths.repo}" in run.out + assert f"GIT_WORK_TREE={paths.work}" in run.out + assert f"PROMPT={prompt}" in run.out + assert f"PS1={prompt}" in run.out @pytest.mark.parametrize( - 'shell, opts, path', [ - ('bash', '--norc', '\\w'), - ('csh', '-f', '%~'), - ('zsh', '-f', '%~'), - ], ids=[ - 'bash', - 'csh', - 'zsh', - ]) + "shell, opts, path", + [ + ("bash", "--norc", "\\w"), + ("csh", "-f", "%~"), + ("zsh", "-f", "%~"), + ], + ids=[ + "bash", + "csh", + "zsh", + ], +) @pytest.mark.parametrize( - 'cmd', - [False, 'cmd', 'cmd-bad-exit'], - ids=['no-cmd', 'cmd', 'cmd-bad-exit']) + "cmd", + [False, "cmd", "cmd-bad-exit"], + ids=["no-cmd", "cmd", "cmd-bad-exit"], +) @pytest.mark.parametrize( - 'term', ['', 'dumb'], - ids=['term-empty', 'term-dumb']) -@pytest.mark.usefixtures('ds1_copy') -def test_enter_shell_ops(runner, yadm_cmd, paths, shell, - opts, path, cmd, term): + "term", + ["", "dumb"], + ids=["term-empty", "term-dumb"], +) +@pytest.mark.usefixtures("ds1_copy") +def test_enter_shell_ops(runner, yadm_cmd, paths, shell, opts, path, cmd, term): """Enter tests for specific shell options""" - change_exit = '\nfalse' if cmd == 'cmd-bad-exit' else '' + change_exit = "\nfalse" if cmd == "cmd-bad-exit" else "" # Create custom shell to detect options passed custom_shell = paths.root.join(shell) - custom_shell.write( - f'#!/bin/sh\necho OPTS=$*\necho PROMPT=$PROMPT{change_exit}' - ) + custom_shell.write(f"#!/bin/sh\necho OPTS=$*\necho PROMPT=$PROMPT{change_exit}") custom_shell.chmod(0o775) - test_cmd = ['test1', 'test2', 'test3'] + test_cmd = ["test1", "test2", "test3"] - enter_cmd = ['enter'] + enter_cmd = ["enter"] if cmd: enter_cmd += test_cmd env = os.environ.copy() - env['TERM'] = term - env['SHELL'] = custom_shell + env["TERM"] = term + env["SHELL"] = custom_shell - if shell == 'zsh' and term == 'dumb': - opts += ' --no-zle' + if shell == "zsh" and term == "dumb": + opts += " --no-zle" run = runner(command=yadm_cmd(*enter_cmd), env=env) - if cmd == 'cmd-bad-exit': + if cmd == "cmd-bad-exit": assert run.failure else: assert run.success - assert run.err == '' - assert f'OPTS={opts}' in run.out - assert f'PROMPT=yadm shell ({paths.repo}) {path} >' in run.out + assert run.err == "" + assert f"OPTS={opts}" in run.out + assert f"PROMPT=yadm shell ({paths.repo}) {path} >" in run.out if cmd: - assert '-c ' + ' '.join(test_cmd) in run.out - assert 'Entering yadm repo' not in run.out - assert 'Leaving yadm repo' not in run.out + assert "-c " + " ".join(test_cmd) in run.out + assert "Entering yadm repo" not in run.out + assert "Leaving yadm repo" not in run.out else: - assert 'Entering yadm repo' in run.out - assert 'Leaving yadm repo' in run.out + assert "Entering yadm repo" in run.out + assert "Leaving yadm repo" in run.out diff --git a/test/test_ext_crypt.py b/test/test_ext_crypt.py index cb74afc..92f703f 100644 --- a/test/test_ext_crypt.py +++ b/test/test_ext_crypt.py @@ -4,28 +4,30 @@ import pytest @pytest.mark.parametrize( - 'crypt', - [False, 'installed', 'installed-but-failed'], - ids=['not-installed', 'installed', 'installed-but-failed'] + "crypt", + [False, "installed", "installed-but-failed"], + ids=["not-installed", "installed", "installed-but-failed"], ) @pytest.mark.parametrize( - 'cmd,var', [ - ['git_crypt', 'GIT_CRYPT_PROGRAM'], - ['transcrypt', 'TRANSCRYPT_PROGRAM'], - ], - ids=['git-crypt', 'transcrypt']) + "cmd,var", + [ + ["git_crypt", "GIT_CRYPT_PROGRAM"], + ["transcrypt", "TRANSCRYPT_PROGRAM"], + ], + ids=["git-crypt", "transcrypt"], +) def test_ext_encryption(runner, yadm, paths, tmpdir, crypt, cmd, var): """External encryption tests""" paths.repo.ensure(dir=True) - bindir = tmpdir.mkdir('bin') - pgm = bindir.join('test-ext-crypt') + bindir = tmpdir.mkdir("bin") + pgm = bindir.join("test-ext-crypt") if crypt: - pgm.write('#!/bin/sh\necho ext-crypt ran\n') + pgm.write("#!/bin/sh\necho ext-crypt ran\n") pgm.chmod(0o775) - if crypt == 'installed-but-failed': - pgm.write('false\n', mode='a') + if crypt == "installed-but-failed": + pgm.write("false\n", mode="a") script = f""" YADM_TEST=1 source {yadm} @@ -34,15 +36,15 @@ def test_ext_encryption(runner, yadm, paths, tmpdir, crypt, cmd, var): {cmd} "param1" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) if crypt: - if crypt == 'installed-but-failed': + if crypt == "installed-but-failed": assert run.failure else: assert run.success - assert run.out.strip() == 'ext-crypt ran' - assert run.err == '' + assert run.out.strip() == "ext-crypt ran" + assert run.err == "" else: assert run.failure assert f"command '{pgm}' cannot be located" in run.err diff --git a/test/test_git.py b/test/test_git.py index 41b102c..dea538d 100644 --- a/test/test_git.py +++ b/test/test_git.py @@ -5,7 +5,7 @@ import re import pytest -@pytest.mark.usefixtures('ds1_copy') +@pytest.mark.usefixtures("ds1_copy") def test_git(runner, yadm_cmd, paths): """Test series of passthrough git commands @@ -18,42 +18,42 @@ def test_git(runner, yadm_cmd, paths): """ # passthru unknown commands to Git - run = runner(command=yadm_cmd('bogus')) + run = runner(command=yadm_cmd("bogus")) assert run.failure assert "git: 'bogus' is not a git command." in run.err assert "See 'git --help'" in run.err - assert run.out == '' + assert run.out == "" # git command 'add' - badfile - run = runner(command=yadm_cmd('add', '-v', 'does_not_exist')) + run = runner(command=yadm_cmd("add", "-v", "does_not_exist")) assert run.code == 128 assert "pathspec 'does_not_exist' did not match any files" in run.err - assert run.out == '' + assert run.out == "" # git command 'add' - newfile = paths.work.join('test_git') - newfile.write('test_git') - run = runner(command=yadm_cmd('add', '-v', str(newfile))) + newfile = paths.work.join("test_git") + newfile.write("test_git") + run = runner(command=yadm_cmd("add", "-v", str(newfile))) assert run.success - assert run.err == '' + assert run.err == "" assert "add 'test_git'" in run.out # git command 'status' - run = runner(command=yadm_cmd('status')) + run = runner(command=yadm_cmd("status")) assert run.success - assert run.err == '' - assert re.search(r'new file:\s+test_git', run.out) + assert run.err == "" + assert re.search(r"new file:\s+test_git", run.out) # git command 'commit' - run = runner(command=yadm_cmd('commit', '-m', 'Add test_git')) + run = runner(command=yadm_cmd("commit", "-m", "Add test_git")) assert run.success - assert run.err == '' - assert '1 file changed' in run.out - assert '1 insertion' in run.out - assert re.search(r'create mode .+ test_git', run.out) + assert run.err == "" + assert "1 file changed" in run.out + assert "1 insertion" in run.out + assert re.search(r"create mode .+ test_git", run.out) # git command 'log' - run = runner(command=yadm_cmd('log', '--oneline')) + run = runner(command=yadm_cmd("log", "--oneline")) assert run.success - assert run.err == '' - assert 'Add test_git' in run.out + assert run.err == "" + assert "Add test_git" in run.out diff --git a/test/test_help.py b/test/test_help.py index 0d8f2c3..cbfabcc 100644 --- a/test/test_help.py +++ b/test/test_help.py @@ -6,14 +6,14 @@ def test_missing_command(runner, yadm_cmd): """Run without any command""" run = runner(command=yadm_cmd()) assert run.failure - assert run.err == '' - assert run.out.startswith('Usage: yadm') + assert run.err == "" + assert run.out.startswith("Usage: yadm") -@pytest.mark.parametrize('cmd', ['--help', 'help']) +@pytest.mark.parametrize("cmd", ["--help", "help"]) def test_help_command(runner, yadm_cmd, cmd): """Run with help command""" run = runner(command=yadm_cmd(cmd)) assert run.failure - assert run.err == '' - assert run.out.startswith('Usage: yadm') + assert run.err == "" + assert run.out.startswith("Usage: yadm") diff --git a/test/test_hooks.py b/test/test_hooks.py index 704636a..aff3daf 100644 --- a/test/test_hooks.py +++ b/test/test_hooks.py @@ -4,7 +4,8 @@ import pytest @pytest.mark.parametrize( - 'pre, pre_code, post, post_code', [ + "pre, pre_code, post, post_code", + [ (False, 0, False, 0), (True, 0, False, 0), (True, 5, False, 0), @@ -12,83 +13,83 @@ import pytest (False, 0, True, 5), (True, 0, True, 0), (True, 5, True, 5), - ], ids=[ - 'no-hooks', - 'pre-success', - 'pre-fail', - 'post-success', - 'post-fail', - 'pre-post-success', - 'pre-post-fail', - ]) -@pytest.mark.parametrize('cmd', ['--version', 'version']) -def test_hooks( - runner, yadm_cmd, paths, cmd, - pre, pre_code, post, post_code): + ], + ids=[ + "no-hooks", + "pre-success", + "pre-fail", + "post-success", + "post-fail", + "pre-post-success", + "pre-post-fail", + ], +) +@pytest.mark.parametrize("cmd", ["--version", "version"]) +def test_hooks(runner, yadm_cmd, paths, cmd, pre, pre_code, post, post_code): """Test pre/post hook""" # generate hooks if pre: - create_hook(paths, 'pre_version', pre_code) + create_hook(paths, "pre_version", pre_code) if post: - create_hook(paths, 'post_version', post_code) + create_hook(paths, "post_version", post_code) # run yadm run = runner(yadm_cmd(cmd)) # when a pre hook fails, yadm should exit with the hook's code assert run.code == pre_code - assert run.err == '' + assert run.err == "" if pre: - assert 'HOOK:pre_version' in run.out + assert "HOOK:pre_version" in run.out # if pre hook is missing or successful, yadm itself should exit 0 if run.success: if post: - assert 'HOOK:post_version' in run.out + assert "HOOK:post_version" in run.out else: # when a pre hook fails, yadm should not run the command - assert 'version will not be run' in run.out + assert "version will not be run" in run.out # when a pre hook fails, yadm should not run the post hook - assert 'HOOK:post_version' not in run.out + assert "HOOK:post_version" not in run.out # repo fixture is needed to test the population of YADM_HOOK_WORK -@pytest.mark.usefixtures('ds1_repo_copy') +@pytest.mark.usefixtures("ds1_repo_copy") def test_hook_env(runner, yadm_cmd, paths): """Test hook environment""" # test will be done with a non existent "git" passthru command # which should exit with a failing code - cmd = 'passthrucmd' + cmd = "passthrucmd" # write the hook - hook = paths.hooks.join(f'post_{cmd}') - hook.write('#!/bin/bash\nenv\ndeclare\n') + hook = paths.hooks.join(f"post_{cmd}") + hook.write("#!/bin/bash\nenv\ndeclare\n") hook.chmod(0o755) - run = runner(yadm_cmd(cmd, 'extra_args')) + run = runner(yadm_cmd(cmd, "extra_args")) # expect passthru to fail assert run.failure assert f"'{cmd}' is not a git command" in run.err # verify hook environment - assert 'YADM_HOOK_EXIT=1\n' in run.out - assert f'YADM_HOOK_COMMAND={cmd}\n' in run.out - assert f'YADM_HOOK_DIR={paths.yadm}\n' in run.out - assert f'YADM_HOOK_FULL_COMMAND={cmd} extra_args\n' in run.out - assert f'YADM_HOOK_REPO={paths.repo}\n' in run.out - assert f'YADM_HOOK_WORK={paths.work}\n' in run.out - assert 'YADM_ENCRYPT_INCLUDE_FILES=\n' in run.out + assert "YADM_HOOK_EXIT=1\n" in run.out + assert f"YADM_HOOK_COMMAND={cmd}\n" in run.out + assert f"YADM_HOOK_DIR={paths.yadm}\n" in run.out + assert f"YADM_HOOK_FULL_COMMAND={cmd} extra_args\n" in run.out + assert f"YADM_HOOK_REPO={paths.repo}\n" in run.out + assert f"YADM_HOOK_WORK={paths.work}\n" in run.out + assert "YADM_ENCRYPT_INCLUDE_FILES=\n" in run.out # verify the hook environment contains certain exported functions for func in [ - 'builtin_dirname', - 'relative_path', - 'unix_path', - 'mixed_path', + "builtin_dirname", + "relative_path", + "unix_path", + "mixed_path", ]: - assert f'BASH_FUNC_{func}' in run.out + assert f"BASH_FUNC_{func}" in run.out # verify the hook environment contains the list of encrypted files script = f""" @@ -98,10 +99,10 @@ def test_hook_env(runner, yadm_cmd, paths): ENCRYPT_INCLUDE_FILES=(a b c) invoke_hook "post" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'YADM_ENCRYPT_INCLUDE_FILES=a\nb\nc\n' in run.out + assert run.err == "" + assert "YADM_ENCRYPT_INCLUDE_FILES=a\nb\nc\n" in run.out def test_escaped(runner, yadm_cmd, paths): @@ -109,35 +110,33 @@ def test_escaped(runner, yadm_cmd, paths): # test will be done with a non existent "git" passthru command # which should exit with a failing code - cmd = 'passthrucmd' + cmd = "passthrucmd" # write the hook - hook = paths.hooks.join(f'post_{cmd}') - hook.write('#!/bin/bash\nenv\n') + hook = paths.hooks.join(f"post_{cmd}") + hook.write("#!/bin/bash\nenv\n") hook.chmod(0o755) - run = runner(yadm_cmd(cmd, 'a b', 'c\td', 'e\\f')) + run = runner(yadm_cmd(cmd, "a b", "c\td", "e\\f")) # expect passthru to fail assert run.failure # verify escaped values - assert ( - f'YADM_HOOK_FULL_COMMAND={cmd} ' - 'a\\ b c\\\td e\\\\f\n') in run.out + assert f"YADM_HOOK_FULL_COMMAND={cmd} a\\ b c\\\td e\\\\f\n" in run.out -@pytest.mark.parametrize('condition', ['exec', 'no-exec', 'mingw']) +@pytest.mark.parametrize("condition", ["exec", "no-exec", "mingw"]) def test_executable(runner, paths, condition): """Verify hook must be exectuable""" - cmd = 'version' - hook = paths.hooks.join(f'pre_{cmd}') - hook.write('#!/bin/sh\necho HOOK\n') + cmd = "version" + hook = paths.hooks.join(f"pre_{cmd}") + hook.write("#!/bin/sh\necho HOOK\n") hook.chmod(0o644) - if condition == 'exec': + if condition == "exec": hook.chmod(0o755) - mingw = 'OPERATING_SYSTEM="MINGWx"' if condition == 'mingw' else '' + mingw = 'OPERATING_SYSTEM="MINGWx"' if condition == "mingw" else "" script = f""" YADM_TEST=1 source {paths.pgm} YADM_HOOKS="{paths.hooks}" @@ -145,27 +144,23 @@ def test_executable(runner, paths, condition): {mingw} invoke_hook "pre" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) - if condition != 'mingw': + if condition != "mingw": assert run.success - assert run.err == '' + assert run.err == "" else: assert run.failure - assert 'Permission denied' in run.err + assert "Permission denied" in run.err - if condition == 'exec': - assert 'HOOK' in run.out - elif condition == 'no-exec': - assert 'HOOK' not in run.out + if condition == "exec": + assert "HOOK" in run.out + elif condition == "no-exec": + assert "HOOK" not in run.out def create_hook(paths, name, code): """Create hook""" hook = paths.hooks.join(name) - hook.write( - '#!/bin/sh\n' - f'echo HOOK:{name}\n' - f'exit {code}\n' - ) + hook.write("#!/bin/sh\n" f"echo HOOK:{name}\n" f"exit {code}\n") hook.chmod(0o755) diff --git a/test/test_init.py b/test/test_init.py index 3d149d6..a8ba493 100644 --- a/test/test_init.py +++ b/test/test_init.py @@ -4,22 +4,24 @@ import pytest @pytest.mark.parametrize( - 'alt_work, repo_present, force', [ + "alt_work, repo_present, force", + [ (False, False, False), (True, False, False), (False, True, False), (False, True, True), (True, True, True), - ], ids=[ - 'simple', - '-w', - 'existing repo', - '-f', - '-w & -f', - ]) -@pytest.mark.usefixtures('ds1_work_copy') -def test_init( - runner, yadm_cmd, paths, repo_config, alt_work, repo_present, force): + ], + ids=[ + "simple", + "-w", + "existing repo", + "-f", + "-w & -f", + ], +) +@pytest.mark.usefixtures("ds1_work_copy") +def test_init(runner, yadm_cmd, paths, repo_config, alt_work, repo_present, force): """Test init Repos should have attribs: @@ -31,56 +33,54 @@ def test_init( """ # these tests will assume this for $HOME - home = str(paths.root.mkdir('HOME')) + home = str(paths.root.mkdir("HOME")) # ds1_work_copy comes WITH an empty repo dir present. - old_repo = paths.repo.join('old_repo') + old_repo = paths.repo.join("old_repo") if repo_present: # Let's put some data in it, so we can confirm that data is gone when # forced to be overwritten. - old_repo.write('old repo data') + old_repo.write("old repo data") assert old_repo.isfile() else: paths.repo.remove() # command args - args = ['init'] + args = ["init"] cwd = None if alt_work: if force: cwd = paths.work.dirname - args.extend(['-w', paths.work.basename]) + args.extend(["-w", paths.work.basename]) else: - args.extend(['-w', paths.work]) + args.extend(["-w", paths.work]) if force: - args.append('-f') + args.append("-f") # run init - runner(['git', 'config', '--global', 'init.defaultBranch', 'master'], - env={'HOME': home}, cwd=cwd) - run = runner(yadm_cmd(*args), env={'HOME': home}, cwd=cwd) + runner(["git", "config", "--global", "init.defaultBranch", "master"], env={"HOME": home}, cwd=cwd) + run = runner(yadm_cmd(*args), env={"HOME": home}, cwd=cwd) if repo_present and not force: assert run.failure - assert 'repo already exists' in run.err - assert old_repo.isfile(), 'Missing original repo' + assert "repo already exists" in run.err + assert old_repo.isfile(), "Missing original repo" else: assert run.success - assert 'Initialized empty shared Git repository' in run.out + assert "Initialized empty shared Git repository" in run.out if repo_present: - assert not old_repo.isfile(), 'Original repo still exists' + assert not old_repo.isfile(), "Original repo still exists" else: - assert run.err == '' + assert run.err == "" if alt_work: - assert repo_config('core.worktree') == paths.work + assert repo_config("core.worktree") == paths.work else: - assert repo_config('core.worktree') == home + assert repo_config("core.worktree") == home # uniform repo assertions - assert oct(paths.repo.stat().mode).endswith('00'), ( - 'Repo is not secure') - assert repo_config('core.bare') == 'false' - assert repo_config('status.showUntrackedFiles') == 'no' - assert repo_config('yadm.managed') == 'true' + assert oct(paths.repo.stat().mode).endswith("00"), "Repo is not secure" + assert repo_config("core.bare") == "false" + assert repo_config("status.showUntrackedFiles") == "no" + assert repo_config("yadm.managed") == "true" diff --git a/test/test_introspect.py b/test/test_introspect.py index b292bd4..3a4fb46 100644 --- a/test/test_introspect.py +++ b/test/test_introspect.py @@ -4,38 +4,38 @@ import pytest @pytest.mark.parametrize( - 'name', [ - '', - 'invalid', - 'commands', - 'configs', - 'repo', - 'switches', - ]) -def test_introspect_category( - runner, yadm_cmd, paths, name, - supported_commands, supported_configs, supported_switches): + "name", + [ + "", + "invalid", + "commands", + "configs", + "repo", + "switches", + ], +) +def test_introspect_category(runner, yadm_cmd, paths, name, supported_commands, supported_configs, supported_switches): """Validate introspection category""" if name: - run = runner(command=yadm_cmd('introspect', name)) + run = runner(command=yadm_cmd("introspect", name)) else: - run = runner(command=yadm_cmd('introspect')) + run = runner(command=yadm_cmd("introspect")) assert run.success - assert run.err == '' + assert run.err == "" expected = [] - if name == 'commands': + if name == "commands": expected = supported_commands - elif name == 'configs': + elif name == "configs": expected = supported_configs - elif name == 'switches': + elif name == "switches": expected = supported_switches # assert values - if name in ('', 'invalid'): - assert run.out == '' - if name == 'repo': + if name in ("", "invalid"): + assert run.out == "" + if name == "repo": assert run.out.rstrip() == paths.repo # make sure every expected value is present diff --git a/test/test_list.py b/test/test_list.py index d7d09a6..afcea6f 100644 --- a/test/test_list.py +++ b/test/test_list.py @@ -6,27 +6,29 @@ import pytest @pytest.mark.parametrize( - 'location', [ - 'work', - 'outside', - 'subdir', - ]) -@pytest.mark.usefixtures('ds1_copy') + "location", + [ + "work", + "outside", + "subdir", + ], +) +@pytest.mark.usefixtures("ds1_copy") def test_list(runner, yadm_cmd, paths, ds1, location): """List tests""" - if location == 'work': + if location == "work": run_dir = paths.work - elif location == 'outside': - run_dir = paths.work.join('..') - elif location == 'subdir': + elif location == "outside": + run_dir = paths.work.join("..") + elif location == "subdir": # first directory with tracked data run_dir = paths.work.join(ds1.tracked_dirs[0]) with run_dir.as_cwd(): # test with '-a' # should get all tracked files, relative to the work path - run = runner(command=yadm_cmd('list', '-a')) + run = runner(command=yadm_cmd("list", "-a")) assert run.success - assert run.err == '' + assert run.err == "" returned_files = set(run.out.splitlines()) expected_files = {e.path for e in ds1 if e.tracked} assert returned_files == expected_files @@ -34,16 +36,14 @@ def test_list(runner, yadm_cmd, paths, ds1, location): # should get all tracked files, relative to the work path unless in a # subdir, then those should be a limited set of files, relative to the # subdir - run = runner(command=yadm_cmd('list')) + run = runner(command=yadm_cmd("list")) assert run.success - assert run.err == '' + assert run.err == "" returned_files = set(run.out.splitlines()) - if location == 'subdir': + if location == "subdir": basepath = os.path.basename(os.getcwd()) # only expect files within the subdir # names should be relative to subdir - expected_files = { - e.path[len(basepath)+1:] - for e in ds1 if e.tracked and e.path.startswith(basepath) - } + index = len(basepath) + 1 + expected_files = {e.path[index:] for e in ds1 if e.tracked and e.path.startswith(basepath)} assert returned_files == expected_files diff --git a/test/test_perms.py b/test/test_perms.py index a49d897..1491c16 100644 --- a/test/test_perms.py +++ b/test/test_perms.py @@ -5,18 +5,17 @@ import os import pytest -@pytest.mark.parametrize('autoperms', ['notest', 'unset', 'true', 'false']) -@pytest.mark.usefixtures('ds1_copy') +@pytest.mark.parametrize("autoperms", ["notest", "unset", "true", "false"]) +@pytest.mark.usefixtures("ds1_copy") def test_perms(runner, yadm_cmd, paths, ds1, autoperms): """Test perms""" # set the value of auto-perms - if autoperms != 'notest': - if autoperms != 'unset': - os.system(' '.join( - yadm_cmd('config', 'yadm.auto-perms', autoperms))) + if autoperms != "notest": + if autoperms != "unset": + os.system(" ".join(yadm_cmd("config", "yadm.auto-perms", autoperms))) # privatepaths will hold all paths that should become secured - privatepaths = [paths.work.join('.ssh'), paths.work.join('.gnupg')] + privatepaths = [paths.work.join(".ssh"), paths.work.join(".gnupg")] privatepaths += [paths.work.join(private.path) for private in ds1.private] # create an archive file @@ -24,82 +23,71 @@ def test_perms(runner, yadm_cmd, paths, ds1, autoperms): privatepaths.append(paths.archive) # create encrypted file test data - efile1 = paths.work.join('efile1') - efile1.write('efile1') - efile2 = paths.work.join('efile2') - efile2.write('efile2') - paths.encrypt.write('efile1\nefile2\n!efile1\n') + efile1 = paths.work.join("efile1") + efile1.write("efile1") + efile2 = paths.work.join("efile2") + efile2.write("efile2") + paths.encrypt.write("efile1\nefile2\n!efile1\n") insecurepaths = [efile1] privatepaths.append(efile2) # assert these paths begin unsecured for private in privatepaths + insecurepaths: - assert not oct(private.stat().mode).endswith('00'), ( - 'Path started secured') + assert not oct(private.stat().mode).endswith("00"), "Path started secured" - cmd = 'perms' - if autoperms != 'notest': - cmd = 'status' - run = runner(yadm_cmd(cmd), env={'HOME': paths.work}) + cmd = "perms" + if autoperms != "notest": + cmd = "status" + run = runner(yadm_cmd(cmd), env={"HOME": paths.work}) assert run.success - assert run.err == '' - if cmd == 'perms': - assert run.out == '' + assert run.err == "" + if cmd == "perms": + assert run.out == "" # these paths should be secured if processing perms for private in privatepaths: - if autoperms == 'false': - assert not oct(private.stat().mode).endswith('00'), ( - 'Path should not be secured') + if autoperms == "false": + assert not oct(private.stat().mode).endswith("00"), "Path should not be secured" else: - assert oct(private.stat().mode).endswith('00'), ( - 'Path has not been secured') + assert oct(private.stat().mode).endswith("00"), "Path has not been secured" # these paths should never be secured for private in insecurepaths: - assert not oct(private.stat().mode).endswith('00'), ( - 'Path should not be secured') + assert not oct(private.stat().mode).endswith("00"), "Path should not be secured" -@pytest.mark.parametrize('sshperms', [None, 'true', 'false']) -@pytest.mark.parametrize('gpgperms', [None, 'true', 'false']) -@pytest.mark.usefixtures('ds1_copy') +@pytest.mark.parametrize("sshperms", [None, "true", "false"]) +@pytest.mark.parametrize("gpgperms", [None, "true", "false"]) +@pytest.mark.usefixtures("ds1_copy") def test_perms_control(runner, yadm_cmd, paths, ds1, sshperms, gpgperms): """Test fine control of perms""" # set the value of ssh-perms if sshperms: - os.system(' '.join(yadm_cmd('config', 'yadm.ssh-perms', sshperms))) + os.system(" ".join(yadm_cmd("config", "yadm.ssh-perms", sshperms))) # set the value of gpg-perms if gpgperms: - os.system(' '.join(yadm_cmd('config', 'yadm.gpg-perms', gpgperms))) + os.system(" ".join(yadm_cmd("config", "yadm.gpg-perms", gpgperms))) # privatepaths will hold all paths that should become secured - privatepaths = [paths.work.join('.ssh'), paths.work.join('.gnupg')] + privatepaths = [paths.work.join(".ssh"), paths.work.join(".gnupg")] privatepaths += [paths.work.join(private.path) for private in ds1.private] # assert these paths begin unsecured for private in privatepaths: - assert not oct(private.stat().mode).endswith('00'), ( - 'Path started secured') + assert not oct(private.stat().mode).endswith("00"), "Path started secured" - run = runner(yadm_cmd('perms'), env={'HOME': paths.work}) + run = runner(yadm_cmd("perms"), env={"HOME": paths.work}) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" # these paths should be secured if processing perms for private in privatepaths: - if ( - (sshperms == 'false' and 'ssh' in str(private)) - or - (gpgperms == 'false' and 'gnupg' in str(private)) - ): - assert not oct(private.stat().mode).endswith('00'), ( - 'Path should not be secured') + if (sshperms == "false" and "ssh" in str(private)) or (gpgperms == "false" and "gnupg" in str(private)): + assert not oct(private.stat().mode).endswith("00"), "Path should not be secured" else: - assert oct(private.stat().mode).endswith('00'), ( - 'Path has not been secured') + assert oct(private.stat().mode).endswith("00"), "Path has not been secured" # verify permissions aren't changed for the worktree - assert oct(paths.work.stat().mode).endswith('0755') + assert oct(paths.work.stat().mode).endswith("0755") diff --git a/test/test_syntax.py b/test/test_syntax.py index aadafde..6549822 100644 --- a/test/test_syntax.py +++ b/test/test_syntax.py @@ -7,80 +7,77 @@ import pytest def test_yadm_syntax(runner, yadm): """Is syntactically valid""" - run = runner(command=['bash', '-n', yadm]) + run = runner(command=["bash", "-n", yadm]) assert run.success def test_shellcheck(pytestconfig, runner, yadm, shellcheck_version): """Passes shellcheck""" if not pytestconfig.getoption("--force-linters"): - run = runner(command=['shellcheck', '-V'], report=False) - if f'version: {shellcheck_version}' not in run.out: - pytest.skip('Unsupported shellcheck version') - run = runner(command=['shellcheck', '-s', 'bash', yadm]) + run = runner(command=["shellcheck", "-V"], report=False) + if f"version: {shellcheck_version}" not in run.out: + pytest.skip("Unsupported shellcheck version") + run = runner(command=["shellcheck", "-s", "bash", yadm]) assert run.success def test_pylint(pytestconfig, runner, pylint_version): """Passes pylint""" if not pytestconfig.getoption("--force-linters"): - run = runner(command=['pylint', '--version'], report=False) - if f'pylint {pylint_version}' not in run.out: - pytest.skip('Unsupported pylint version') + run = runner(command=["pylint", "--version"], report=False) + if f"pylint {pylint_version}" not in run.out: + pytest.skip("Unsupported pylint version") pyfiles = [] - for tfile in os.listdir('test'): - if tfile.endswith('.py'): - pyfiles.append(f'test/{tfile}') - run = runner(command=['pylint'] + pyfiles) + for tfile in os.listdir("test"): + if tfile.endswith(".py"): + pyfiles.append(f"test/{tfile}") + run = runner(command=["pylint"] + pyfiles) assert run.success def test_isort(pytestconfig, runner, isort_version): """Passes isort""" if not pytestconfig.getoption("--force-linters"): - run = runner(command=['isort', '--version'], report=False) + run = runner(command=["isort", "--version"], report=False) if isort_version not in run.out: - pytest.skip('Unsupported isort version') - run = runner(command=['isort', '-c', 'test']) + pytest.skip("Unsupported isort version") + run = runner(command=["isort", "-c", "test"]) assert run.success def test_flake8(pytestconfig, runner, flake8_version): """Passes flake8""" if not pytestconfig.getoption("--force-linters"): - run = runner(command=['flake8', '--version'], report=False) + run = runner(command=["flake8", "--version"], report=False) if not run.out.startswith(flake8_version): - pytest.skip('Unsupported flake8 version') - run = runner(command=['flake8', 'test']) + pytest.skip("Unsupported flake8 version") + run = runner(command=["flake8", "test"]) assert run.success def test_black(pytestconfig, runner, black_version): """Passes black""" if not pytestconfig.getoption("--force-linters"): - run = runner(command=['black', '--version'], report=False) + run = runner(command=["black", "--version"], report=False) if black_version not in run.out: - pytest.skip('Unsupported black version') - run = runner(command=['black', '--check', 'test']) + pytest.skip("Unsupported black version") + run = runner(command=["black", "--check", "test"]) assert run.success def test_yamllint(pytestconfig, runner, yamllint_version): """Passes yamllint""" if not pytestconfig.getoption("--force-linters"): - run = runner(command=['yamllint', '--version'], report=False) + run = runner(command=["yamllint", "--version"], report=False) if not run.out.strip().endswith(yamllint_version): - pytest.skip('Unsupported yamllint version') - run = runner( - command=['yamllint', '-s', '$(find . -name \\*.yml)'], - shell=True) + pytest.skip("Unsupported yamllint version") + run = runner(command=["yamllint", "-s", "$(find . -name \\*.yml)"], shell=True) assert run.success def test_man(runner): """Check for warnings from man""" - run = runner( - command=['man.REAL', '--warnings', './yadm.1']) + run = runner(command=["man.REAL", "--warnings", "./yadm.1"]) assert run.success - assert run.err == '' - assert 'yadm - Yet Another Dotfiles Manager' in run.out + assert run.err == "" + assert "yadm - Yet Another Dotfiles Manager" in run.out diff --git a/test/test_unit_bootstrap_available.py b/test/test_unit_bootstrap_available.py index f37ac08..6ab8df8 100644 --- a/test/test_unit_bootstrap_available.py +++ b/test/test_unit_bootstrap_available.py @@ -8,14 +8,14 @@ def test_bootstrap_missing(runner, paths): def test_bootstrap_no_exec(runner, paths): """Test result of bootstrap_available, when bootstrap not executable""" - paths.bootstrap.write('') + paths.bootstrap.write("") paths.bootstrap.chmod(0o644) run_test(runner, paths, False) def test_bootstrap_exec(runner, paths): """Test result of bootstrap_available, when bootstrap executable""" - paths.bootstrap.write('') + paths.bootstrap.write("") paths.bootstrap.chmod(0o775) run_test(runner, paths, True) @@ -27,7 +27,7 @@ def run_test(runner, paths, success): YADM_BOOTSTRAP='{paths.bootstrap}' bootstrap_available """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success == success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" diff --git a/test/test_unit_choose_template_cmd.py b/test/test_unit_choose_template_cmd.py index 536735d..cf7600b 100644 --- a/test/test_unit_choose_template_cmd.py +++ b/test/test_unit_choose_template_cmd.py @@ -2,20 +2,20 @@ import pytest -@pytest.mark.parametrize('label', ['', 'default', 'other']) -@pytest.mark.parametrize('awk', [True, False], ids=['awk', 'no-awk']) +@pytest.mark.parametrize("label", ["", "default", "other"]) +@pytest.mark.parametrize("awk", [True, False], ids=["awk", "no-awk"]) def test_kind_default(runner, yadm, awk, label): """Test kind: default""" - expected = 'template_default' - awk_avail = 'true' + expected = "template_default" + awk_avail = "true" if not awk: - awk_avail = 'false' - expected = '' + awk_avail = "false" + expected = "" - if label == 'other': - expected = '' + if label == "other": + expected = "" script = f""" YADM_TEST=1 source {yadm} @@ -23,30 +23,30 @@ def test_kind_default(runner, yadm, awk, label): template="$(choose_template_cmd "{label}")" echo "TEMPLATE:$template" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert f'TEMPLATE:{expected}\n' in run.out + assert run.err == "" + assert f"TEMPLATE:{expected}\n" in run.out -@pytest.mark.parametrize('label', ['envtpl', 'j2cli', 'j2', 'other']) -@pytest.mark.parametrize('envtpl', [True, False], ids=['envtpl', 'no-envtpl']) -@pytest.mark.parametrize('j2cli', [True, False], ids=['j2cli', 'no-j2cli']) +@pytest.mark.parametrize("label", ["envtpl", "j2cli", "j2", "other"]) +@pytest.mark.parametrize("envtpl", [True, False], ids=["envtpl", "no-envtpl"]) +@pytest.mark.parametrize("j2cli", [True, False], ids=["j2cli", "no-j2cli"]) def test_kind_j2cli_envtpl(runner, yadm, envtpl, j2cli, label): """Test kind: j2 (both j2cli & envtpl) j2cli is preferred over envtpl if available. """ - envtpl_avail = 'true' if envtpl else 'false' - j2cli_avail = 'true' if j2cli else 'false' + envtpl_avail = "true" if envtpl else "false" + j2cli_avail = "true" if j2cli else "false" - if label in ('j2cli', 'j2') and j2cli: - expected = 'template_j2cli' - elif label in ('envtpl', 'j2') and envtpl: - expected = 'template_envtpl' + if label in ("j2cli", "j2") and j2cli: + expected = "template_j2cli" + elif label in ("envtpl", "j2") and envtpl: + expected = "template_envtpl" else: - expected = '' + expected = "" script = f""" YADM_TEST=1 source {yadm} @@ -55,7 +55,7 @@ def test_kind_j2cli_envtpl(runner, yadm, envtpl, j2cli, label): template="$(choose_template_cmd "{label}")" echo "TEMPLATE:$template" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert f'TEMPLATE:{expected}\n' in run.out + assert run.err == "" + assert f"TEMPLATE:{expected}\n" in run.out diff --git a/test/test_unit_configure_paths.py b/test/test_unit_configure_paths.py index 8ecd0ea..d2a680e 100644 --- a/test/test_unit_configure_paths.py +++ b/test/test_unit_configure_paths.py @@ -2,52 +2,56 @@ import pytest -ARCHIVE = 'archive' -BOOTSTRAP = 'bootstrap' -CONFIG = 'config' -ENCRYPT = 'encrypt' -HOME = '/testhome' -REPO = 'repo.git' -YDIR = '.config/yadm' -YDATA = '.local/share/yadm' +ARCHIVE = "archive" +BOOTSTRAP = "bootstrap" +CONFIG = "config" +ENCRYPT = "encrypt" +HOME = "/testhome" +REPO = "repo.git" +YDIR = ".config/yadm" +YDATA = ".local/share/yadm" @pytest.mark.parametrize( - 'override, expect', [ + "override, expect", + [ (None, {}), - ('-Y', {'yadm': 'YADM_DIR'}), - ('--yadm-data', {'data': 'YADM_DATA'}), - ('--yadm-repo', {'repo': 'YADM_REPO', 'git': 'GIT_DIR'}), - ('--yadm-config', {'config': 'YADM_CONFIG'}), - ('--yadm-encrypt', {'encrypt': 'YADM_ENCRYPT'}), - ('--yadm-archive', {'archive': 'YADM_ARCHIVE'}), - ('--yadm-bootstrap', {'bootstrap': 'YADM_BOOTSTRAP'}), - ], ids=[ - 'default', - 'override yadm dir', - 'override yadm data', - 'override repo', - 'override config', - 'override encrypt', - 'override archive', - 'override bootstrap', - ]) + ("-Y", {"yadm": "YADM_DIR"}), + ("--yadm-data", {"data": "YADM_DATA"}), + ("--yadm-repo", {"repo": "YADM_REPO", "git": "GIT_DIR"}), + ("--yadm-config", {"config": "YADM_CONFIG"}), + ("--yadm-encrypt", {"encrypt": "YADM_ENCRYPT"}), + ("--yadm-archive", {"archive": "YADM_ARCHIVE"}), + ("--yadm-bootstrap", {"bootstrap": "YADM_BOOTSTRAP"}), + ], + ids=[ + "default", + "override yadm dir", + "override yadm data", + "override repo", + "override config", + "override encrypt", + "override archive", + "override bootstrap", + ], +) @pytest.mark.parametrize( - 'path', ['.', './override', 'override', '.override', '/override'], ids=[ - 'cwd', './relative', 'relative', 'hidden relative', 'absolute' - ]) + "path", + [".", "./override", "override", ".override", "/override"], + ids=["cwd", "./relative", "relative", "hidden relative", "absolute"], +) def test_config(runner, paths, override, expect, path): """Test configure_paths""" - if path.startswith('/'): + if path.startswith("/"): expected_path = path else: expected_path = str(paths.root.join(path)) args = [override, path] if override else [] - if override == '-Y': + if override == "-Y": matches = match_map(expected_path) - elif override == '--yadm-data': + elif override == "--yadm-data": matches = match_map(None, expected_path) else: matches = match_map() @@ -61,23 +65,23 @@ def test_config(runner, paths, override, expect, path): def match_map(yadm_dir=None, yadm_data=None): """Create a dictionary of matches, relative to yadm_dir""" if not yadm_dir: - yadm_dir = '/'.join([HOME, YDIR]) + yadm_dir = "/".join([HOME, YDIR]) if not yadm_data: - yadm_data = '/'.join([HOME, YDATA]) + yadm_data = "/".join([HOME, YDATA]) return { - 'yadm': f'YADM_DIR="{yadm_dir}"', - 'repo': f'YADM_REPO="{yadm_data}/{REPO}"', - 'config': f'YADM_CONFIG="{yadm_dir}/{CONFIG}"', - 'encrypt': f'YADM_ENCRYPT="{yadm_dir}/{ENCRYPT}"', - 'archive': f'YADM_ARCHIVE="{yadm_data}/{ARCHIVE}"', - 'bootstrap': f'YADM_BOOTSTRAP="{yadm_dir}/{BOOTSTRAP}"', - 'git': f'GIT_DIR="{yadm_data}/{REPO}"', - } + "yadm": f'YADM_DIR="{yadm_dir}"', + "repo": f'YADM_REPO="{yadm_data}/{REPO}"', + "config": f'YADM_CONFIG="{yadm_dir}/{CONFIG}"', + "encrypt": f'YADM_ENCRYPT="{yadm_dir}/{ENCRYPT}"', + "archive": f'YADM_ARCHIVE="{yadm_data}/{ARCHIVE}"', + "bootstrap": f'YADM_BOOTSTRAP="{yadm_dir}/{BOOTSTRAP}"', + "git": f'GIT_DIR="{yadm_data}/{REPO}"', + } def run_test(runner, paths, args, expected_matches, cwd=None): """Run proces global args, and run configure_paths""" - argstring = ' '.join(['"'+a+'"' for a in args]) + argstring = " ".join(['"' + a + '"' for a in args]) script = f""" YADM_TEST=1 HOME="{HOME}" source {paths.pgm} process_global_args {argstring} @@ -87,8 +91,8 @@ def run_test(runner, paths, args, expected_matches, cwd=None): configure_paths declare -p | grep -E '(YADM|GIT)_' """ - run = runner(command=['bash'], inp=script, cwd=cwd) + run = runner(command=["bash"], inp=script, cwd=cwd) assert run.success - assert run.err == '' + assert run.err == "" for match in expected_matches: assert match in run.out diff --git a/test/test_unit_copy_perms.py b/test/test_unit_copy_perms.py index b043878..c0ea04f 100644 --- a/test/test_unit_copy_perms.py +++ b/test/test_unit_copy_perms.py @@ -3,42 +3,40 @@ import os import pytest -OCTAL = '7654' -NON_OCTAL = '9876' +OCTAL = "7654" +NON_OCTAL = "9876" -@pytest.mark.parametrize( - 'stat_broken', [True, False], ids=['normal', 'stat broken']) +@pytest.mark.parametrize("stat_broken", [True, False], ids=["normal", "stat broken"]) def test_copy_perms(runner, yadm, tmpdir, stat_broken): """Test function copy_perms""" src_mode = 0o754 dst_mode = 0o644 - source = tmpdir.join('source') - source.write('test', ensure=True) + source = tmpdir.join("source") + source.write("test", ensure=True) source.chmod(src_mode) - dest = tmpdir.join('dest') - dest.write('test', ensure=True) + dest = tmpdir.join("dest") + dest.write("test", ensure=True) dest.chmod(dst_mode) - override_stat = '' + override_stat = "" if stat_broken: - override_stat = 'function stat() { echo broken; }' + override_stat = "function stat() { echo broken; }" script = f""" YADM_TEST=1 source {yadm} {override_stat} copy_perms "{source}" "{dest}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert run.out == '' + assert run.err == "" + assert run.out == "" expected = dst_mode if stat_broken else src_mode assert oct(os.stat(dest).st_mode)[-3:] == oct(expected)[-3:] -@pytest.mark.parametrize( - 'stat_output', [OCTAL, NON_OCTAL], ids=['octal', 'non-octal']) +@pytest.mark.parametrize("stat_output", [OCTAL, NON_OCTAL], ids=["octal", "non-octal"]) def test_get_mode(runner, yadm, stat_output): """Test function get_mode""" script = f""" @@ -47,8 +45,8 @@ def test_get_mode(runner, yadm, stat_output): mode=$(get_mode abc) echo "MODE:$mode" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" expected = OCTAL if stat_output == OCTAL else "" - assert f'MODE:{expected}\n' in run.out + assert f"MODE:{expected}\n" in run.out diff --git a/test/test_unit_encryption.py b/test/test_unit_encryption.py index ab03c62..098d5f6 100644 --- a/test/test_unit_encryption.py +++ b/test/test_unit_encryption.py @@ -3,12 +3,12 @@ import pytest -@pytest.mark.parametrize('condition', ['default', 'override']) +@pytest.mark.parametrize("condition", ["default", "override"]) def test_get_cipher(runner, paths, condition): """Test _get_cipher()""" - if condition == 'override': - paths.config.write('[yadm]\n\tcipher = override-cipher') + if condition == "override": + paths.config.write("[yadm]\n\tcipher = override-cipher") script = f""" YADM_TEST=1 source {paths.pgm} @@ -19,18 +19,18 @@ def test_get_cipher(runner, paths, condition): echo "output_archive:$output_archive" echo "yadm_cipher:$yadm_cipher" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'output_archive:test-archive' in run.out - if condition == 'override': - assert 'yadm_cipher:override-cipher' in run.out + assert run.err == "" + assert "output_archive:test-archive" in run.out + if condition == "override": + assert "yadm_cipher:override-cipher" in run.out else: - assert 'yadm_cipher:gpg' in run.out + assert "yadm_cipher:gpg" in run.out -@pytest.mark.parametrize('cipher', ['gpg', 'openssl', 'bad']) -@pytest.mark.parametrize('mode', ['_encrypt_to', '_decrypt_from']) +@pytest.mark.parametrize("cipher", ["gpg", "openssl", "bad"]) +@pytest.mark.parametrize("mode", ["_encrypt_to", "_decrypt_from"]) def test_encrypt_decrypt(runner, paths, cipher, mode): """Test _encrypt_to() & _decrypt_from""" @@ -49,24 +49,24 @@ def test_encrypt_decrypt(runner, paths, cipher, mode): GPG_PROGRAM=mock_gpg {mode} {paths.archive} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) - if cipher != 'bad': + if cipher != "bad": assert run.success assert run.out.startswith(cipher) assert str(paths.archive) in run.out - assert run.err == '' + assert run.err == "" else: assert run.failure - assert 'Unknown cipher' in run.err + assert "Unknown cipher" in run.err -@pytest.mark.parametrize('condition', ['default', 'override']) +@pytest.mark.parametrize("condition", ["default", "override"]) def test_get_openssl_ciphername(runner, paths, condition): """Test _get_openssl_ciphername()""" - if condition == 'override': - paths.config.write('[yadm]\n\topenssl-ciphername = override-cipher') + if condition == "override": + paths.config.write("[yadm]\n\topenssl-ciphername = override-cipher") script = f""" YADM_TEST=1 source {paths.pgm} @@ -76,21 +76,21 @@ def test_get_openssl_ciphername(runner, paths, condition): result=$(_get_openssl_ciphername) echo "result:$result" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if condition == 'override': - assert run.out.strip() == 'result:override-cipher' + assert run.err == "" + if condition == "override": + assert run.out.strip() == "result:override-cipher" else: - assert run.out.strip() == 'result:aes-256-cbc' + assert run.out.strip() == "result:aes-256-cbc" -@pytest.mark.parametrize('condition', ['old', 'not-old']) +@pytest.mark.parametrize("condition", ["old", "not-old"]) def test_set_openssl_options(runner, paths, condition): """Test _set_openssl_options()""" - if condition == 'old': - paths.config.write('[yadm]\n\topenssl-old = true') + if condition == "old": + paths.config.write("[yadm]\n\topenssl-old = true") script = f""" YADM_TEST=1 source {paths.pgm} @@ -101,20 +101,20 @@ def test_set_openssl_options(runner, paths, condition): _set_openssl_options echo "result:${{OPENSSL_OPTS[@]}}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if condition == 'old': - assert '-testcipher -salt -md md5' in run.out + assert run.err == "" + if condition == "old": + assert "-testcipher -salt -md md5" in run.out else: - assert '-testcipher -salt -pbkdf2 -iter 100000 -md sha512' in run.out + assert "-testcipher -salt -pbkdf2 -iter 100000 -md sha512" in run.out -@pytest.mark.parametrize('recipient', ['ASK', 'present', '']) +@pytest.mark.parametrize("recipient", ["ASK", "present", ""]) def test_set_gpg_options(runner, paths, recipient): """Test _set_gpg_options()""" - paths.config.write(f'[yadm]\n\tgpg-recipient = {recipient}') + paths.config.write(f"[yadm]\n\tgpg-recipient = {recipient}") script = f""" YADM_TEST=1 source {paths.pgm} @@ -124,12 +124,12 @@ def test_set_gpg_options(runner, paths, recipient): _set_gpg_options echo "result:${{GPG_OPTS[@]}}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if recipient == 'ASK': - assert run.out.strip() == 'result:--no-default-recipient -e' - elif recipient != '': - assert run.out.strip() == f'result:-e -r {recipient}' + assert run.err == "" + if recipient == "ASK": + assert run.out.strip() == "result:--no-default-recipient -e" + elif recipient != "": + assert run.out.strip() == f"result:-e -r {recipient}" else: - assert run.out.strip() == 'result:-c' + assert run.out.strip() == "result:-c" diff --git a/test/test_unit_exclude_encrypted.py b/test/test_unit_exclude_encrypted.py index 9d9a074..8937a8b 100644 --- a/test/test_unit_exclude_encrypted.py +++ b/test/test_unit_exclude_encrypted.py @@ -2,38 +2,28 @@ import pytest -@pytest.mark.parametrize( - 'exclude', ['missing', 'outdated', 'up-to-date']) -@pytest.mark.parametrize( - 'encrypt_exists', [True, False], ids=['encrypt', 'no-encrypt']) -@pytest.mark.parametrize( - 'auto_exclude', [True, False], ids=['enabled', 'disabled']) -def test_exclude_encrypted( - runner, tmpdir, yadm, encrypt_exists, auto_exclude, exclude): +@pytest.mark.parametrize("exclude", ["missing", "outdated", "up-to-date"]) +@pytest.mark.parametrize("encrypt_exists", [True, False], ids=["encrypt", "no-encrypt"]) +@pytest.mark.parametrize("auto_exclude", [True, False], ids=["enabled", "disabled"]) +def test_exclude_encrypted(runner, tmpdir, yadm, encrypt_exists, auto_exclude, exclude): """Test exclude_encrypted()""" - header = ( - "# yadm-auto-excludes\n" - "# This section is managed by yadm.\n" - "# Any edits below will be lost.\n" - ) + header = "# yadm-auto-excludes\n# This section is managed by yadm.\n# Any edits below will be lost.\n" config_function = 'function config() { echo "false";}' if auto_exclude: - config_function = 'function config() { return; }' + config_function = "function config() { return; }" - encrypt_file = tmpdir.join('encrypt_file') - repo_dir = tmpdir.join('repodir') - exclude_file = repo_dir.join('info/exclude') + encrypt_file = tmpdir.join("encrypt_file") + repo_dir = tmpdir.join("repodir") + exclude_file = repo_dir.join("info/exclude") if encrypt_exists: - encrypt_file.write('test-encrypt-data\n', ensure=True) - if exclude == 'outdated': - exclude_file.write( - f'original-exclude\n{header}outdated\n', ensure=True) - elif exclude == 'up-to-date': - exclude_file.write( - f'original-exclude\n{header}test-encrypt-data\n', ensure=True) + encrypt_file.write("test-encrypt-data\n", ensure=True) + if exclude == "outdated": + exclude_file.write(f"original-exclude\n{header}outdated\n", ensure=True) + elif exclude == "up-to-date": + exclude_file.write(f"original-exclude\n{header}test-encrypt-data\n", ensure=True) script = f""" YADM_TEST=1 source {yadm} @@ -43,24 +33,22 @@ def test_exclude_encrypted( YADM_REPO="{repo_dir}" exclude_encrypted """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" if auto_exclude: if encrypt_exists: assert exclude_file.exists() - if exclude == 'missing': - assert exclude_file.read() == f'{header}test-encrypt-data\n' + if exclude == "missing": + assert exclude_file.read() == f"{header}test-encrypt-data\n" else: - assert exclude_file.read() == ( - 'original-exclude\n' - f'{header}test-encrypt-data\n') - if exclude != 'up-to-date': - assert f'Updating {exclude_file}' in run.out + assert exclude_file.read() == ("original-exclude\n" f"{header}test-encrypt-data\n") + if exclude != "up-to-date": + assert f"Updating {exclude_file}" in run.out else: - assert run.out == '' + assert run.out == "" else: - assert run.out == '' + assert run.out == "" else: - assert run.out == '' + assert run.out == "" diff --git a/test/test_unit_issue_legacy_path_warning.py b/test/test_unit_issue_legacy_path_warning.py index e43228b..faae7fa 100644 --- a/test/test_unit_issue_legacy_path_warning.py +++ b/test/test_unit_issue_legacy_path_warning.py @@ -3,25 +3,24 @@ import pytest @pytest.mark.parametrize( - 'legacy_path', [ + "legacy_path", + [ None, - 'repo.git', - 'files.gpg', - ], - ) -@pytest.mark.parametrize( - 'override', [True, False], ids=['override', 'no-override']) -@pytest.mark.parametrize( - 'upgrade', [True, False], ids=['upgrade', 'no-upgrade']) + "repo.git", + "files.gpg", + ], +) +@pytest.mark.parametrize("override", [True, False], ids=["override", "no-override"]) +@pytest.mark.parametrize("upgrade", [True, False], ids=["upgrade", "no-upgrade"]) def test_legacy_warning(tmpdir, runner, yadm, upgrade, override, legacy_path): """Use issue_legacy_path_warning""" - home = tmpdir.mkdir('home') + home = tmpdir.mkdir("home") if legacy_path: - home.ensure(f'.config/yadm/{str(legacy_path)}') + home.ensure(f".config/yadm/{str(legacy_path)}") - override = 'YADM_OVERRIDE_REPO=override' if override else '' - main_args = 'MAIN_ARGS=("upgrade")' if upgrade else '' + override = "YADM_OVERRIDE_REPO=override" if override else "" + main_args = 'MAIN_ARGS=("upgrade")' if upgrade else "" script = f""" XDG_CONFIG_HOME= XDG_DATA_HOME= @@ -32,10 +31,10 @@ def test_legacy_warning(tmpdir, runner, yadm, upgrade, override, legacy_path): set_yadm_dirs issue_legacy_path_warning """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.out == '' + assert run.out == "" if legacy_path and (not upgrade) and (not override): - assert 'Legacy paths have been detected' in run.err + assert "Legacy paths have been detected" in run.err else: - assert 'Legacy paths have been detected' not in run.err + assert "Legacy paths have been detected" not in run.err diff --git a/test/test_unit_parse_encrypt.py b/test/test_unit_parse_encrypt.py index ec3a6ee..6a5c23b 100644 --- a/test/test_unit_parse_encrypt.py +++ b/test/test_unit_parse_encrypt.py @@ -7,136 +7,137 @@ def test_not_called(runner, paths): """Test parse_encrypt (not called)""" run = run_parse_encrypt(runner, paths, skip_parse=True) assert run.success - assert run.err == '' - assert 'EIF:unparsed' in run.out, 'EIF should be unparsed' - assert 'EIF_COUNT:1' in run.out, 'Only value of EIF should be unparsed' + assert run.err == "" + assert "EIF:unparsed" in run.out, "EIF should be unparsed" + assert "EIF_COUNT:1" in run.out, "Only value of EIF should be unparsed" def test_short_circuit(runner, paths): """Test parse_encrypt (short-circuit)""" run = run_parse_encrypt(runner, paths, twice=True) assert run.success - assert run.err == '' - assert 'PARSE_ENCRYPT_SHORT=parse_encrypt() not reprocessed' in run.out, ( - 'parse_encrypt() should short-circuit') + assert run.err == "" + assert "PARSE_ENCRYPT_SHORT=parse_encrypt() not reprocessed" in run.out, "parse_encrypt() should short-circuit" @pytest.mark.parametrize( - 'encrypt', [ - ('missing'), - ('empty'), - ]) + "encrypt", + [ + ("missing"), + ("empty"), + ], +) def test_empty(runner, paths, encrypt): """Test parse_encrypt (file missing/empty)""" # write encrypt file - if encrypt == 'missing': - assert not paths.encrypt.exists(), 'Encrypt should be missing' + if encrypt == "missing": + assert not paths.encrypt.exists(), "Encrypt should be missing" else: - paths.encrypt.write('') - assert paths.encrypt.exists(), 'Encrypt should exist' - assert paths.encrypt.size() == 0, 'Encrypt should be empty' + paths.encrypt.write("") + assert paths.encrypt.exists(), "Encrypt should exist" + assert paths.encrypt.size() == 0, "Encrypt should be empty" # run parse_encrypt run = run_parse_encrypt(runner, paths) assert run.success - assert run.err == '' + assert run.err == "" # validate parsing result - assert 'EIF_COUNT:0' in run.out, 'EIF should be empty' + assert "EIF_COUNT:0" in run.out, "EIF should be empty" def create_test_encrypt_data(paths): """Generate test data for testing encrypt""" - edata = '' + edata = "" expected = set() # empty line - edata += '\n' + edata += "\n" # simple comments - edata += '# a simple comment\n' - edata += ' # a comment with leading space\n' + edata += "# a simple comment\n" + edata += " # a comment with leading space\n" # unreferenced directory - paths.work.join('unreferenced').mkdir() + paths.work.join("unreferenced").mkdir() # simple files - edata += 'simple_file\n' - edata += 'simple.file\n' - paths.work.join('simple_file').write('') - paths.work.join('simple.file').write('') - paths.work.join('simple_file2').write('') - paths.work.join('simple.file2').write('') - expected.add('simple_file') - expected.add('simple.file') + edata += "simple_file\n" + edata += "simple.file\n" + paths.work.join("simple_file").write("") + paths.work.join("simple.file").write("") + paths.work.join("simple_file2").write("") + paths.work.join("simple.file2").write("") + expected.add("simple_file") + expected.add("simple.file") # simple files in directories - edata += 'simple_dir/simple_file\n' - paths.work.join('simple_dir/simple_file').write('', ensure=True) - paths.work.join('simple_dir/simple_file2').write('', ensure=True) - expected.add('simple_dir/simple_file') + edata += "simple_dir/simple_file\n" + paths.work.join("simple_dir/simple_file").write("", ensure=True) + paths.work.join("simple_dir/simple_file2").write("", ensure=True) + expected.add("simple_dir/simple_file") # paths with spaces - edata += 'with space/with space\n' - paths.work.join('with space/with space').write('', ensure=True) - paths.work.join('with space/with space2').write('', ensure=True) - expected.add('with space/with space') + edata += "with space/with space\n" + paths.work.join("with space/with space").write("", ensure=True) + paths.work.join("with space/with space2").write("", ensure=True) + expected.add("with space/with space") # hidden files - edata += '.hidden\n' - paths.work.join('.hidden').write('') - expected.add('.hidden') + edata += ".hidden\n" + paths.work.join(".hidden").write("") + expected.add(".hidden") # hidden files in directories - edata += '.hidden_dir/.hidden_file\n' - paths.work.join('.hidden_dir/.hidden_file').write('', ensure=True) - expected.add('.hidden_dir/.hidden_file') + edata += ".hidden_dir/.hidden_file\n" + paths.work.join(".hidden_dir/.hidden_file").write("", ensure=True) + expected.add(".hidden_dir/.hidden_file") # wildcards - edata += 'wild*\n' - paths.work.join('wildcard1').write('', ensure=True) - paths.work.join('wildcard2').write('', ensure=True) - expected.add('wildcard1') - expected.add('wildcard2') + edata += "wild*\n" + paths.work.join("wildcard1").write("", ensure=True) + paths.work.join("wildcard2").write("", ensure=True) + expected.add("wildcard1") + expected.add("wildcard2") - edata += 'dirwild*\n' - paths.work.join('dirwildcard/file1').write('', ensure=True) - paths.work.join('dirwildcard/file2').write('', ensure=True) - expected.add('dirwildcard') + edata += "dirwild*\n" + paths.work.join("dirwildcard/file1").write("", ensure=True) + paths.work.join("dirwildcard/file2").write("", ensure=True) + expected.add("dirwildcard") # excludes - edata += 'exclude*\n' - edata += 'ex ex/*\n' - paths.work.join('exclude_file1').write('') - paths.work.join('exclude_file2.ex').write('') - paths.work.join('exclude_file3.ex3').write('') - expected.add('exclude_file1') - expected.add('exclude_file3.ex3') - edata += '!*.ex\n' - edata += '!ex ex/*.txt\n' - paths.work.join('ex ex/file4').write('', ensure=True) - paths.work.join('ex ex/file5.txt').write('', ensure=True) - paths.work.join('ex ex/file6.text').write('', ensure=True) - expected.add('ex ex/file4') - expected.add('ex ex/file6.text') + edata += "exclude*\n" + edata += "ex ex/*\n" + paths.work.join("exclude_file1").write("") + paths.work.join("exclude_file2.ex").write("") + paths.work.join("exclude_file3.ex3").write("") + expected.add("exclude_file1") + expected.add("exclude_file3.ex3") + edata += "!*.ex\n" + edata += "!ex ex/*.txt\n" + paths.work.join("ex ex/file4").write("", ensure=True) + paths.work.join("ex ex/file5.txt").write("", ensure=True) + paths.work.join("ex ex/file6.text").write("", ensure=True) + expected.add("ex ex/file4") + expected.add("ex ex/file6.text") # double star - edata += 'doublestar/**/file*\n' - edata += '!**/file3\n' - paths.work.join('doublestar/a/b/file1').write('', ensure=True) - paths.work.join('doublestar/c/d/file2').write('', ensure=True) - paths.work.join('doublestar/e/f/file3').write('', ensure=True) - paths.work.join('doublestar/g/h/nomatch').write('', ensure=True) - expected.add('doublestar/a/b/file1') - expected.add('doublestar/c/d/file2') + edata += "doublestar/**/file*\n" + edata += "!**/file3\n" + paths.work.join("doublestar/a/b/file1").write("", ensure=True) + paths.work.join("doublestar/c/d/file2").write("", ensure=True) + paths.work.join("doublestar/e/f/file3").write("", ensure=True) + paths.work.join("doublestar/g/h/nomatch").write("", ensure=True) + expected.add("doublestar/a/b/file1") + expected.add("doublestar/c/d/file2") # doublestar/e/f/file3 is excluded return edata, expected -@pytest.mark.usefixtures('ds1_repo_copy') +@pytest.mark.usefixtures("ds1_repo_copy") def test_file_parse_encrypt(runner, paths): """Test parse_encrypt @@ -147,39 +148,35 @@ def test_file_parse_encrypt(runner, paths): edata, expected = create_test_encrypt_data(paths) # write encrypt file - print(f'ENCRYPT:\n---\n{edata}---\n') + print(f"ENCRYPT:\n---\n{edata}---\n") paths.encrypt.write(edata) assert paths.encrypt.isfile() # run parse_encrypt run = run_parse_encrypt(runner, paths) assert run.success - assert run.err == '' + assert run.err == "" - assert f'EIF_COUNT:{len(expected)}' in run.out, 'EIF count wrong' + assert f"EIF_COUNT:{len(expected)}" in run.out, "EIF count wrong" for expected_file in expected: - assert f'EIF:{expected_file}\n' in run.out + assert f"EIF:{expected_file}\n" in run.out - sorted_expectations = '\n'.join( - [f'EIF:{exp}' for exp in sorted(expected)]) + sorted_expectations = "\n".join([f"EIF:{exp}" for exp in sorted(expected)]) assert sorted_expectations in run.out -def run_parse_encrypt( - runner, paths, - skip_parse=False, - twice=False): +def run_parse_encrypt(runner, paths, skip_parse=False, twice=False): """Run parse_encrypt A count of ENCRYPT_INCLUDE_FILES will be reported as EIF_COUNT:X. All values of ENCRYPT_INCLUDE_FILES will be reported as individual EIF:value lines. """ - parse_cmd = 'parse_encrypt' + parse_cmd = "parse_encrypt" if skip_parse: - parse_cmd = '' + parse_cmd = "" if twice: - parse_cmd = 'parse_encrypt; parse_encrypt' + parse_cmd = "parse_encrypt; parse_encrypt" script = f""" YADM_TEST=1 source {paths.pgm} YADM_ENCRYPT={paths.encrypt} @@ -197,5 +194,5 @@ def run_parse_encrypt( echo "EIF:$value" done """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) return run diff --git a/test/test_unit_private_dirs.py b/test/test_unit_private_dirs.py index 4f182da..58bd39c 100644 --- a/test/test_unit_private_dirs.py +++ b/test/test_unit_private_dirs.py @@ -3,15 +3,15 @@ import pytest @pytest.mark.parametrize( - 'gnupghome', + "gnupghome", [True, False], - ids=['gnupghome-set', 'gnupghome-unset'], + ids=["gnupghome-set", "gnupghome-unset"], ) -@pytest.mark.parametrize('param', ['all', 'gnupg']) +@pytest.mark.parametrize("param", ["all", "gnupg"]) def test_relative_path(runner, paths, gnupghome, param): """Test translate_to_relative""" - alt_gnupghome = 'alt/gnupghome' + alt_gnupghome = "alt/gnupghome" env_gnupghome = paths.work.join(alt_gnupghome) script = f""" @@ -22,13 +22,13 @@ def test_relative_path(runner, paths, gnupghome, param): env = {} if gnupghome: - env['GNUPGHOME'] = env_gnupghome + env["GNUPGHOME"] = env_gnupghome - expected = alt_gnupghome if gnupghome else '.gnupg' - if param == 'all': - expected = f'.ssh {expected}' + expected = alt_gnupghome if gnupghome else ".gnupg" + if param == "all": + expected = f".ssh {expected}" - run = runner(command=['bash'], inp=script, env=env) + run = runner(command=["bash"], inp=script, env=env) assert run.success - assert run.err == '' + assert run.err == "" assert run.out.strip() == expected diff --git a/test/test_unit_query_distro.py b/test/test_unit_query_distro.py index 4f46501..c32760b 100644 --- a/test/test_unit_query_distro.py +++ b/test/test_unit_query_distro.py @@ -2,18 +2,16 @@ import pytest -@pytest.mark.parametrize( - 'condition', ['lsb_release', 'os-release', 'os-release-quotes', 'missing']) +@pytest.mark.parametrize("condition", ["lsb_release", "os-release", "os-release-quotes", "missing"]) def test_query_distro(runner, yadm, tst_distro, tmp_path, condition): """Match lsb_release -si when present""" - test_release = 'testrelease' - lsb_release = '' - os_release = tmp_path.joinpath('os-release') - if 'os-release' in condition: - quotes = '"' if 'quotes' in condition else '' - os_release.write_text( - f"testing\nID={quotes}{test_release}{quotes}\nrelease") - if condition != 'lsb_release': + test_release = "testrelease" + lsb_release = "" + os_release = tmp_path.joinpath("os-release") + if "os-release" in condition: + quotes = '"' if "quotes" in condition else "" + os_release.write_text(f"testing\nID={quotes}{test_release}{quotes}\nrelease") + if condition != "lsb_release": lsb_release = 'LSB_RELEASE_PROGRAM="missing_lsb_release"' script = f""" YADM_TEST=1 source {yadm} @@ -21,12 +19,12 @@ def test_query_distro(runner, yadm, tst_distro, tmp_path, condition): OS_RELEASE="{os_release}" query_distro """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if condition == 'lsb_release': + assert run.err == "" + if condition == "lsb_release": assert run.out.rstrip() == tst_distro - elif 'os-release' in condition: + elif "os-release" in condition: assert run.out.rstrip() == test_release else: - assert run.out.rstrip() == '' + assert run.out.rstrip() == "" diff --git a/test/test_unit_query_distro_family.py b/test/test_unit_query_distro_family.py index bf68319..1935bf6 100644 --- a/test/test_unit_query_distro_family.py +++ b/test/test_unit_query_distro_family.py @@ -2,25 +2,23 @@ import pytest -@pytest.mark.parametrize( - 'condition', ['os-release', 'os-release-quotes', 'missing']) +@pytest.mark.parametrize("condition", ["os-release", "os-release-quotes", "missing"]) def test_query_distro_family(runner, yadm, tmp_path, condition): """Match ID_LIKE when present""" - test_family = 'testfamily' - os_release = tmp_path.joinpath('os-release') - if 'os-release' in condition: - quotes = '"' if 'quotes' in condition else '' - os_release.write_text( - f"testing\nID_LIKE={quotes}{test_family}{quotes}\nfamily") + test_family = "testfamily" + os_release = tmp_path.joinpath("os-release") + if "os-release" in condition: + quotes = '"' if "quotes" in condition else "" + os_release.write_text(f"testing\nID_LIKE={quotes}{test_family}{quotes}\nfamily") script = f""" YADM_TEST=1 source {yadm} OS_RELEASE="{os_release}" query_distro_family """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if 'os-release' in condition: + assert run.err == "" + if "os-release" in condition: assert run.out.rstrip() == test_family else: - assert run.out.rstrip() == '' + assert run.out.rstrip() == "" diff --git a/test/test_unit_record_score.py b/test/test_unit_record_score.py index 78596e1..a82046c 100644 --- a/test/test_unit_record_score.py +++ b/test/test_unit_record_score.py @@ -30,13 +30,13 @@ def test_dont_record_zeros(runner, yadm): record_score "0" "testtgt" "testsrc" {REPORT_RESULTS} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:0\n' in run.out - assert 'SCORES:\n' in run.out - assert 'TARGETS:\n' in run.out - assert 'SOURCES:\n' in run.out + assert run.err == "" + assert "SIZE:0\n" in run.out + assert "SCORES:\n" in run.out + assert "TARGETS:\n" in run.out + assert "SOURCES:\n" in run.out def test_new_scores(runner, yadm): @@ -50,29 +50,29 @@ def test_new_scores(runner, yadm): record_score "4" "tgt_three" "src_three" {REPORT_RESULTS} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:3\n' in run.out - assert 'SCORES:1 2 4\n' in run.out - assert 'TARGETS:tgt_one tgt_two tgt_three\n' in run.out - assert 'SOURCES:src_one src_two src_three\n' in run.out + assert run.err == "" + assert "SIZE:3\n" in run.out + assert "SCORES:1 2 4\n" in run.out + assert "TARGETS:tgt_one tgt_two tgt_three\n" in run.out + assert "SOURCES:src_one src_two src_three\n" in run.out -@pytest.mark.parametrize('difference', ['lower', 'equal', 'higher']) +@pytest.mark.parametrize("difference", ["lower", "equal", "higher"]) def test_existing_scores(runner, yadm, difference): """Test existing scores""" - expected_score = '2' - expected_src = 'existing_src' - if difference == 'lower': - score = '1' - elif difference == 'equal': - score = '2' + expected_score = "2" + expected_src = "existing_src" + if difference == "lower": + score = "1" + elif difference == "equal": + score = "2" else: - score = '4' - expected_score = '4' - expected_src = 'new_src' + score = "4" + expected_score = "4" + expected_src = "new_src" script = f""" YADM_TEST=1 source {yadm} @@ -83,13 +83,13 @@ def test_existing_scores(runner, yadm, difference): record_score "{score}" "testtgt" "new_src" {REPORT_RESULTS} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:1\n' in run.out - assert f'SCORES:{expected_score}\n' in run.out - assert 'TARGETS:testtgt\n' in run.out - assert f'SOURCES:{expected_src}\n' in run.out + assert run.err == "" + assert "SIZE:1\n" in run.out + assert f"SCORES:{expected_score}\n" in run.out + assert "TARGETS:testtgt\n" in run.out + assert f"SOURCES:{expected_src}\n" in run.out def test_existing_template(runner, yadm): @@ -105,19 +105,19 @@ def test_existing_template(runner, yadm): record_score "2" "testtgt" "new_src" {REPORT_RESULTS} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:1\n' in run.out - assert 'SCORES:1\n' in run.out - assert 'TARGETS:testtgt\n' in run.out - assert 'SOURCES:\n' in run.out + assert run.err == "" + assert "SIZE:1\n" in run.out + assert "SCORES:1\n" in run.out + assert "TARGETS:testtgt\n" in run.out + assert "SOURCES:\n" in run.out def test_config_first(runner, yadm): """Verify YADM_CONFIG is always processed first""" - config = 'yadm_config_file' + config = "yadm_config_file" script = f""" YADM_TEST=1 source {yadm} {INIT_VARS} @@ -130,12 +130,12 @@ def test_config_first(runner, yadm): echo "CMD_VALUE:${{alt_template_cmds[@]}}" echo "CMD_INDEX:${{!alt_template_cmds[@]}}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:3\n' in run.out - assert 'SCORES:2 1 3\n' in run.out - assert f'TARGETS:{config} tgt_before tgt_tmp tgt_after\n' in run.out - assert 'SOURCES:src_config src_before src_tmp src_after\n' in run.out - assert 'CMD_VALUE:cmd_tmp\n' in run.out - assert 'CMD_INDEX:2\n' in run.out + assert run.err == "" + assert "SIZE:3\n" in run.out + assert "SCORES:2 1 3\n" in run.out + assert f"TARGETS:{config} tgt_before tgt_tmp tgt_after\n" in run.out + assert "SOURCES:src_config src_before src_tmp src_after\n" in run.out + assert "CMD_VALUE:cmd_tmp\n" in run.out + assert "CMD_INDEX:2\n" in run.out diff --git a/test/test_unit_record_template.py b/test/test_unit_record_template.py index 6bfd012..4f3c3e8 100644 --- a/test/test_unit_record_template.py +++ b/test/test_unit_record_template.py @@ -25,13 +25,13 @@ def test_new_template(runner, yadm): record_template "tgt_three" "cmd_three" "src_three" {REPORT_RESULTS} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:3\n' in run.out - assert 'TARGETS:tgt_one tgt_two tgt_three\n' in run.out - assert 'CMDS:cmd_one cmd_two cmd_three\n' in run.out - assert 'SOURCES:src_one src_two src_three\n' in run.out + assert run.err == "" + assert "SIZE:3\n" in run.out + assert "TARGETS:tgt_one tgt_two tgt_three\n" in run.out + assert "CMDS:cmd_one cmd_two cmd_three\n" in run.out + assert "SOURCES:src_one src_two src_three\n" in run.out def test_existing_template(runner, yadm): @@ -46,10 +46,10 @@ def test_existing_template(runner, yadm): record_template "testtgt" "new_cmd" "new_src" {REPORT_RESULTS} """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert 'SIZE:1\n' in run.out - assert 'TARGETS:testtgt\n' in run.out - assert 'CMDS:new_cmd\n' in run.out - assert 'SOURCES:new_src\n' in run.out + assert run.err == "" + assert "SIZE:1\n" in run.out + assert "TARGETS:testtgt\n" in run.out + assert "CMDS:new_cmd\n" in run.out + assert "SOURCES:new_src\n" in run.out diff --git a/test/test_unit_relative_path.py b/test/test_unit_relative_path.py index f723c84..e0b32f5 100644 --- a/test/test_unit_relative_path.py +++ b/test/test_unit_relative_path.py @@ -3,7 +3,7 @@ import pytest @pytest.mark.parametrize( - 'base,full_path,expected', + "base,full_path,expected", [ ("/A/B/C", "/A", "../.."), ("/A/B/C", "/A/B", ".."), @@ -25,7 +25,7 @@ def test_relative_path(runner, paths, base, full_path, expected): relative_path "{base}" "{full_path}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert run.out.strip() == expected diff --git a/test/test_unit_remove_stale_links.py b/test/test_unit_remove_stale_links.py index 4fcf1a1..f389ed8 100644 --- a/test/test_unit_remove_stale_links.py +++ b/test/test_unit_remove_stale_links.py @@ -4,21 +4,21 @@ import os import pytest -@pytest.mark.parametrize('linked', [True, False]) -@pytest.mark.parametrize('kind', ['file', 'symlink']) +@pytest.mark.parametrize("linked", [True, False]) +@pytest.mark.parametrize("kind", ["file", "symlink"]) def test_remove_stale_links(runner, yadm, tmpdir, kind, linked): """Test remove_stale_links()""" - source_file = tmpdir.join('source_file') - source_file.write('source file', ensure=True) - link = tmpdir.join('link') + source_file = tmpdir.join("source_file") + source_file.write("source file", ensure=True) + link = tmpdir.join("link") - if kind == 'file': - link.write('link file', ensure=True) + if kind == "file": + link.write("link file", ensure=True) else: - os.system(f'ln -s {source_file} {link}') + os.system(f"ln -s {source_file} {link}") - alt_linked = '' + alt_linked = "" if linked: alt_linked = source_file @@ -30,9 +30,9 @@ def test_remove_stale_links(runner, yadm, tmpdir, kind, linked): remove_stale_links """ - run = runner(command=['bash'], inp=script) - assert run.err == '' - if kind == 'symlink' and not linked: - assert f'rm -f {link}' in run.out + run = runner(command=["bash"], inp=script) + assert run.err == "" + if kind == "symlink" and not linked: + assert f"rm -f {link}" in run.out else: - assert run.out == '' + assert run.out == "" diff --git a/test/test_unit_report_invalid_alts.py b/test/test_unit_report_invalid_alts.py index 8730d61..996b1ef 100644 --- a/test/test_unit_report_invalid_alts.py +++ b/test/test_unit_report_invalid_alts.py @@ -2,15 +2,15 @@ import pytest -@pytest.mark.parametrize('valid', [True, False], ids=['valid', 'no_valid']) -@pytest.mark.parametrize('previous', [True, False], ids=['prev', 'no_prev']) +@pytest.mark.parametrize("valid", [True, False], ids=["valid", "no_valid"]) +@pytest.mark.parametrize("previous", [True, False], ids=["prev", "no_prev"]) def test_report_invalid_alts(runner, yadm, valid, previous): """Use report_invalid_alts""" - lwi = '' - alts = 'INVALID_ALT=()' + lwi = "" + alts = "INVALID_ALT=()" if previous: - lwi = 'LEGACY_WARNING_ISSUED=1' + lwi = "LEGACY_WARNING_ISSUED=1" if not valid: alts = 'INVALID_ALT=("file##invalid")' @@ -20,11 +20,11 @@ def test_report_invalid_alts(runner, yadm, valid, previous): {alts} report_invalid_alts """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.out == '' + assert run.out == "" if not valid and not previous: - assert 'WARNING' in run.err - assert 'file##invalid' in run.err + assert "WARNING" in run.err + assert "file##invalid" in run.err else: - assert run.err == '' + assert run.err == "" diff --git a/test/test_unit_score_file.py b/test/test_unit_score_file.py index dd2f0b7..c84fb1e 100644 --- a/test/test_unit_score_file.py +++ b/test/test_unit_score_file.py @@ -2,40 +2,40 @@ import pytest CONDITION = { - 'default': { - 'labels': ['default'], - 'modifier': 0, - }, - 'arch': { - 'labels': ['a', 'arch'], - 'modifier': 1, - }, - 'system': { - 'labels': ['o', 'os'], - 'modifier': 2, - }, - 'distro': { - 'labels': ['d', 'distro'], - 'modifier': 4, - }, - 'distro_family': { - 'labels': ['f', 'distro_family'], - 'modifier': 8, - }, - 'class': { - 'labels': ['c', 'class'], - 'modifier': 16, - }, - 'hostname': { - 'labels': ['h', 'hostname'], - 'modifier': 32, - }, - 'user': { - 'labels': ['u', 'user'], - 'modifier': 64, - }, - } -TEMPLATE_LABELS = ['t', 'template', 'yadm'] + "default": { + "labels": ["default"], + "modifier": 0, + }, + "arch": { + "labels": ["a", "arch"], + "modifier": 1, + }, + "system": { + "labels": ["o", "os"], + "modifier": 2, + }, + "distro": { + "labels": ["d", "distro"], + "modifier": 4, + }, + "distro_family": { + "labels": ["f", "distro_family"], + "modifier": 8, + }, + "class": { + "labels": ["c", "class"], + "modifier": 16, + }, + "hostname": { + "labels": ["h", "hostname"], + "modifier": 32, + }, + "user": { + "labels": ["u", "user"], + "modifier": 64, + }, +} +TEMPLATE_LABELS = ["t", "template", "yadm"] def calculate_score(filename): @@ -43,48 +43,48 @@ def calculate_score(filename): # pylint: disable=too-many-branches score = 0 - _, conditions = filename.split('##', 1) + _, conditions = filename.split("##", 1) - for condition in conditions.split(','): + for condition in conditions.split(","): label = condition value = None - if '.' in condition: - label, value = condition.split('.', 1) - if label in CONDITION['default']['labels']: + if "." in condition: + label, value = condition.split(".", 1) + if label in CONDITION["default"]["labels"]: score += 1000 - elif label in CONDITION['arch']['labels']: - if value == 'testarch': - score += 1000 + CONDITION['arch']['modifier'] + elif label in CONDITION["arch"]["labels"]: + if value == "testarch": + score += 1000 + CONDITION["arch"]["modifier"] else: score = 0 break - elif label in CONDITION['system']['labels']: - if value == 'testsystem': - score += 1000 + CONDITION['system']['modifier'] + elif label in CONDITION["system"]["labels"]: + if value == "testsystem": + score += 1000 + CONDITION["system"]["modifier"] else: score = 0 break - elif label in CONDITION['distro']['labels']: - if value == 'testdistro': - score += 1000 + CONDITION['distro']['modifier'] + elif label in CONDITION["distro"]["labels"]: + if value == "testdistro": + score += 1000 + CONDITION["distro"]["modifier"] else: score = 0 break - elif label in CONDITION['class']['labels']: - if value == 'testclass': - score += 1000 + CONDITION['class']['modifier'] + elif label in CONDITION["class"]["labels"]: + if value == "testclass": + score += 1000 + CONDITION["class"]["modifier"] else: score = 0 break - elif label in CONDITION['hostname']['labels']: - if value == 'testhost': - score += 1000 + CONDITION['hostname']['modifier'] + elif label in CONDITION["hostname"]["labels"]: + if value == "testhost": + score += 1000 + CONDITION["hostname"]["modifier"] else: score = 0 break - elif label in CONDITION['user']['labels']: - if value == 'testuser': - score += 1000 + CONDITION['user']['modifier'] + elif label in CONDITION["user"]["labels"]: + if value == "testuser": + score += 1000 + CONDITION["user"]["modifier"] else: score = 0 break @@ -94,111 +94,85 @@ def calculate_score(filename): return score -@pytest.mark.parametrize( - 'default', ['default', None], ids=['default', 'no-default']) -@pytest.mark.parametrize( - 'arch', ['arch', None], ids=['arch', 'no-arch']) -@pytest.mark.parametrize( - 'system', ['system', None], ids=['system', 'no-system']) -@pytest.mark.parametrize( - 'distro', ['distro', None], ids=['distro', 'no-distro']) -@pytest.mark.parametrize( - 'cla', ['class', None], ids=['class', 'no-class']) -@pytest.mark.parametrize( - 'host', ['hostname', None], ids=['hostname', 'no-host']) -@pytest.mark.parametrize( - 'user', ['user', None], ids=['user', 'no-user']) -def test_score_values( - runner, yadm, default, arch, system, distro, cla, host, user): +@pytest.mark.parametrize("default", ["default", None], ids=["default", "no-default"]) +@pytest.mark.parametrize("arch", ["arch", None], ids=["arch", "no-arch"]) +@pytest.mark.parametrize("system", ["system", None], ids=["system", "no-system"]) +@pytest.mark.parametrize("distro", ["distro", None], ids=["distro", "no-distro"]) +@pytest.mark.parametrize("cla", ["class", None], ids=["class", "no-class"]) +@pytest.mark.parametrize("host", ["hostname", None], ids=["hostname", "no-host"]) +@pytest.mark.parametrize("user", ["user", None], ids=["user", "no-user"]) +def test_score_values(runner, yadm, default, arch, system, distro, cla, host, user): """Test score results""" # pylint: disable=too-many-branches - local_class = 'testclass' - local_arch = 'testarch' - local_system = 'testsystem' - local_distro = 'testdistro' - local_host = 'testhost' - local_user = 'testuser' - filenames = {'filename##': 0} + local_class = "testclass" + local_arch = "testarch" + local_system = "testsystem" + local_distro = "testdistro" + local_host = "testhost" + local_user = "testuser" + filenames = {"filename##": 0} if default: for filename in list(filenames): - for label in CONDITION[default]['labels']: + for label in CONDITION[default]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' + if not newfile.endswith("##"): + newfile += "," newfile += label filenames[newfile] = calculate_score(newfile) if arch: for filename in list(filenames): for match in [True, False]: - for label in CONDITION[arch]['labels']: + for label in CONDITION[arch]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([ - label, - local_arch if match else 'badarch' - ]) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, local_arch if match else "badarch"]) filenames[newfile] = calculate_score(newfile) if system: for filename in list(filenames): for match in [True, False]: - for label in CONDITION[system]['labels']: + for label in CONDITION[system]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([ - label, - local_system if match else 'badsys' - ]) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, local_system if match else "badsys"]) filenames[newfile] = calculate_score(newfile) if distro: for filename in list(filenames): for match in [True, False]: - for label in CONDITION[distro]['labels']: + for label in CONDITION[distro]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([ - label, - local_distro if match else 'baddistro' - ]) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, local_distro if match else "baddistro"]) filenames[newfile] = calculate_score(newfile) if cla: for filename in list(filenames): for match in [True, False]: - for label in CONDITION[cla]['labels']: + for label in CONDITION[cla]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([ - label, - local_class if match else 'badclass' - ]) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, local_class if match else "badclass"]) filenames[newfile] = calculate_score(newfile) if host: for filename in list(filenames): for match in [True, False]: - for label in CONDITION[host]['labels']: + for label in CONDITION[host]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([ - label, - local_host if match else 'badhost' - ]) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, local_host if match else "badhost"]) filenames[newfile] = calculate_score(newfile) if user: for filename in list(filenames): for match in [True, False]: - for label in CONDITION[user]['labels']: + for label in CONDITION[user]["labels"]: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([ - label, - local_user if match else 'baduser' - ]) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, local_user if match else "baduser"]) filenames[newfile] = calculate_score(newfile) script = f""" @@ -212,29 +186,29 @@ def test_score_values( local_host={local_host} local_user={local_user} """ - expected = '' + expected = "" for filename, score in filenames.items(): script += f""" score_file "{filename}" echo "{filename}" echo "$score" """ - expected += filename + '\n' - expected += str(score) + '\n' - run = runner(command=['bash'], inp=script) + expected += filename + "\n" + expected += str(score) + "\n" + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert run.out == expected -@pytest.mark.parametrize('ext', [None, 'e', 'extension']) +@pytest.mark.parametrize("ext", [None, "e", "extension"]) def test_extensions(runner, yadm, ext): """Verify extensions do not effect scores""" - local_user = 'testuser' - filename = f'filename##u.{local_user}' + local_user = "testuser" + filename = f"filename##u.{local_user}" if ext: - filename += f',{ext}.xyz' - expected = '' + filename += f",{ext}.xyz" + expected = "" script = f""" YADM_TEST=1 source {yadm} score=0 @@ -243,28 +217,28 @@ def test_extensions(runner, yadm, ext): echo "$score" """ expected = f'{1000 + CONDITION["user"]["modifier"]}\n' - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert run.out == expected def test_score_values_templates(runner, yadm): """Test score results""" - local_class = 'testclass' - local_arch = 'arch' - local_system = 'testsystem' - local_distro = 'testdistro' - local_host = 'testhost' - local_user = 'testuser' - filenames = {'filename##': 0} + local_class = "testclass" + local_arch = "arch" + local_system = "testsystem" + local_distro = "testdistro" + local_host = "testhost" + local_user = "testuser" + filenames = {"filename##": 0} for filename in list(filenames): for label in TEMPLATE_LABELS: newfile = filename - if not newfile.endswith('##'): - newfile += ',' - newfile += '.'.join([label, 'testtemplate']) + if not newfile.endswith("##"): + newfile += "," + newfile += ".".join([label, "testtemplate"]) filenames[newfile] = calculate_score(newfile) script = f""" @@ -277,33 +251,30 @@ def test_score_values_templates(runner, yadm): local_host={local_host} local_user={local_user} """ - expected = '' + expected = "" for filename, score in filenames.items(): script += f""" score_file "{filename}" echo "{filename}" echo "$score" """ - expected += filename + '\n' - expected += str(score) + '\n' - run = runner(command=['bash'], inp=script) + expected += filename + "\n" + expected += str(score) + "\n" + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert run.out == expected -@pytest.mark.parametrize( - 'cmd_generated', - [True, False], - ids=['supported-template', 'unsupported-template']) +@pytest.mark.parametrize("cmd_generated", [True, False], ids=["supported-template", "unsupported-template"]) def test_template_recording(runner, yadm, cmd_generated): """Template should be recorded if choose_template_cmd outputs a command""" - mock = 'function choose_template_cmd() { return; }' - expected = '' + mock = "function choose_template_cmd() { return; }" + expected = "" if cmd_generated: mock = 'function choose_template_cmd() { echo "test_cmd"; }' - expected = 'template recorded' + expected = "template recorded" script = f""" YADM_TEST=1 source {yadm} @@ -311,24 +282,24 @@ def test_template_recording(runner, yadm, cmd_generated): {mock} score_file "testfile##template.kind" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert run.out.rstrip() == expected def test_underscores_in_distro_and_family(runner, yadm): """Test replacing spaces in distro / distro_family with underscores""" - local_distro = 'test distro' - local_distro_family = 'test family' + local_distro = "test distro" + local_distro_family = "test family" filenames = { - 'filename##distro.test distro': 1004, - 'filename##distro.test-distro': 0, - 'filename##distro.test_distro': 1004, - 'filename##distro_family.test family': 1008, - 'filename##distro_family.test-family': 0, - 'filename##distro_family.test_family': 1008, - } + "filename##distro.test distro": 1004, + "filename##distro.test-distro": 0, + "filename##distro.test_distro": 1004, + "filename##distro_family.test family": 1008, + "filename##distro_family.test-family": 0, + "filename##distro_family.test_family": 1008, + } script = f""" YADM_TEST=1 source {yadm} @@ -336,16 +307,16 @@ def test_underscores_in_distro_and_family(runner, yadm): local_distro="{local_distro}" local_distro_family="{local_distro_family}" """ - expected = '' + expected = "" for filename, score in filenames.items(): script += f""" score_file "{filename}" echo "{filename}" echo "$score" """ - expected += filename + '\n' - expected += str(score) + '\n' - run = runner(command=['bash'], inp=script) + expected += filename + "\n" + expected += str(score) + "\n" + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert run.out == expected diff --git a/test/test_unit_set_local_alt_values.py b/test/test_unit_set_local_alt_values.py index 449850c..fa5749d 100644 --- a/test/test_unit_set_local_alt_values.py +++ b/test/test_unit_set_local_alt_values.py @@ -4,26 +4,26 @@ import utils @pytest.mark.parametrize( - 'override', [ + "override", + [ False, - 'class', - 'arch', - 'os', - 'hostname', - 'user', - ], + "class", + "arch", + "os", + "hostname", + "user", + ], ids=[ - 'no-override', - 'override-class', - 'override-arch', - 'override-os', - 'override-hostname', - 'override-user', - ] - ) -@pytest.mark.usefixtures('ds1_copy') -def test_set_local_alt_values( - runner, yadm, paths, tst_arch, tst_sys, tst_host, tst_user, override): + "no-override", + "override-class", + "override-arch", + "override-os", + "override-hostname", + "override-user", + ], +) +@pytest.mark.usefixtures("ds1_copy") +def test_set_local_alt_values(runner, yadm, paths, tst_arch, tst_sys, tst_host, tst_user, override): """Use issue_legacy_path_warning""" script = f""" YADM_TEST=1 source {yadm} && @@ -37,37 +37,37 @@ def test_set_local_alt_values( echo "user='$local_user'" """ - if override == 'class': - utils.set_local(paths, override, 'first') - utils.set_local(paths, override, 'override', add=True) + if override == "class": + utils.set_local(paths, override, "first") + utils.set_local(paths, override, "override", add=True) elif override: - utils.set_local(paths, override, 'override') + utils.set_local(paths, override, "override") - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" - if override == 'class': + if override == "class": assert "class='override'" in run.out else: assert "class=''" in run.out - if override == 'arch': + if override == "arch": assert "arch='override'" in run.out else: assert f"arch='{tst_arch}'" in run.out - if override == 'os': + if override == "os": assert "os='override'" in run.out else: assert f"os='{tst_sys}'" in run.out - if override == 'hostname': + if override == "hostname": assert "host='override'" in run.out else: assert f"host='{tst_host}'" in run.out - if override == 'user': + if override == "user": assert "user='override'" in run.out else: assert f"user='{tst_user}'" in run.out @@ -85,8 +85,8 @@ def test_distro_and_family(runner, yadm): echo "distro='$local_distro'" echo "distro_family='$local_distro_family'" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert "distro='testdistro'" in run.out assert "distro_family='testfamily'" in run.out diff --git a/test/test_unit_set_os.py b/test/test_unit_set_os.py index 936986f..ac61de2 100644 --- a/test/test_unit_set_os.py +++ b/test/test_unit_set_os.py @@ -4,25 +4,27 @@ import pytest @pytest.mark.parametrize( - 'proc_value, expected_os', [ - ('missing', 'uname'), - ('has microsoft inside', 'WSL'), # case insensitive - ('has Microsoft inside', 'WSL'), # case insensitive - ('another value', 'uname'), - ], ids=[ - '/proc/version missing', - '/proc/version includes ms', - '/proc/version excludes Ms', - 'another value', - ]) -def test_set_operating_system( - runner, paths, tst_sys, proc_value, expected_os): + "proc_value, expected_os", + [ + ("missing", "uname"), + ("has microsoft inside", "WSL"), # case insensitive + ("has Microsoft inside", "WSL"), # case insensitive + ("another value", "uname"), + ], + ids=[ + "/proc/version missing", + "/proc/version includes ms", + "/proc/version excludes Ms", + "another value", + ], +) +def test_set_operating_system(runner, paths, tst_sys, proc_value, expected_os): """Run set_operating_system and test result""" # Normally /proc/version (set in PROC_VERSION) is inspected to identify # WSL. During testing, we will override that value. - proc_version = paths.root.join('proc_version') - if proc_value != 'missing': + proc_version = paths.root.join("proc_version") + if proc_value != "missing": proc_version.write(proc_value) script = f""" YADM_TEST=1 source {paths.pgm} @@ -30,9 +32,9 @@ def test_set_operating_system( set_operating_system echo $OPERATING_SYSTEM """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if expected_os == 'uname': + assert run.err == "" + if expected_os == "uname": expected_os = tst_sys assert run.out.rstrip() == expected_os diff --git a/test/test_unit_set_yadm_dir.py b/test/test_unit_set_yadm_dir.py index 32af8bf..b56c98d 100644 --- a/test/test_unit_set_yadm_dir.py +++ b/test/test_unit_set_yadm_dir.py @@ -3,25 +3,20 @@ import pytest @pytest.mark.parametrize( - 'condition', [ - 'basic', - 'override', - 'override_data', - 'xdg_config_home', - 'xdg_data_home' - ], - ) + "condition", + ["basic", "override", "override_data", "xdg_config_home", "xdg_data_home"], +) def test_set_yadm_dirs(runner, yadm, condition): """Test set_yadm_dirs""" - setup = '' - if condition == 'override': - setup = 'YADM_DIR=/override' - elif condition == 'override_data': - setup = 'YADM_DATA=/override' - elif condition == 'xdg_config_home': - setup = 'XDG_CONFIG_HOME=/xdg' - elif condition == 'xdg_data_home': - setup = 'XDG_DATA_HOME=/xdg' + setup = "" + if condition == "override": + setup = "YADM_DIR=/override" + elif condition == "override_data": + setup = "YADM_DATA=/override" + elif condition == "xdg_config_home": + setup = "XDG_CONFIG_HOME=/xdg" + elif condition == "xdg_data_home": + setup = "XDG_DATA_HOME=/xdg" script = f""" HOME=/testhome YADM_TEST=1 source {yadm} @@ -32,17 +27,17 @@ def test_set_yadm_dirs(runner, yadm, condition): echo "YADM_DIR=$YADM_DIR" echo "YADM_DATA=$YADM_DATA" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if condition == 'basic': - assert 'YADM_DIR=/testhome/.config/yadm' in run.out - assert 'YADM_DATA=/testhome/.local/share/yadm' in run.out - elif condition == 'override': - assert 'YADM_DIR=/override' in run.out - elif condition == 'override_data': - assert 'YADM_DATA=/override' in run.out - elif condition == 'xdg_config_home': - assert 'YADM_DIR=/xdg/yadm' in run.out - elif condition == 'xdg_data_home': - assert 'YADM_DATA=/xdg/yadm' in run.out + assert run.err == "" + if condition == "basic": + assert "YADM_DIR=/testhome/.config/yadm" in run.out + assert "YADM_DATA=/testhome/.local/share/yadm" in run.out + elif condition == "override": + assert "YADM_DIR=/override" in run.out + elif condition == "override_data": + assert "YADM_DATA=/override" in run.out + elif condition == "xdg_config_home": + assert "YADM_DIR=/xdg/yadm" in run.out + elif condition == "xdg_data_home": + assert "YADM_DATA=/xdg/yadm" in run.out diff --git a/test/test_unit_template_default.py b/test/test_unit_template_default.py index 729784e..7243877 100644 --- a/test/test_unit_template_default.py +++ b/test/test_unit_template_default.py @@ -12,7 +12,7 @@ LOCAL_HOST = "default_Test+@-!^Host" LOCAL_USER = "default_Test+@-!^User" LOCAL_DISTRO = "default_Test+@-!^Distro" LOCAL_DISTRO_FAMILY = "default_Test+@-!^Family" -TEMPLATE = f''' +TEMPLATE = f""" start of template default class = >{{{{yadm.class}}}}< default arch = >{{{{yadm.arch}}}}< @@ -98,8 +98,8 @@ Included section for distro_family = \ wrong family 2 {{% endif %}} end of template -''' -EXPECTED = f''' +""" +EXPECTED = f""" start of template default class = >{LOCAL_CLASS}< default arch = >{LOCAL_ARCH}< @@ -122,17 +122,17 @@ Included section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again) Included section for distro_family = \ {LOCAL_DISTRO_FAMILY} ({LOCAL_DISTRO_FAMILY} again) end of template -''' +""" -INCLUDE_BASIC = 'basic\n' -INCLUDE_VARIABLES = '''\ +INCLUDE_BASIC = "basic\n" +INCLUDE_VARIABLES = """\ included <{{ yadm.class }}> file empty line above -''' -INCLUDE_NESTED = 'no newline at the end' +""" +INCLUDE_NESTED = "no newline at the end" -TEMPLATE_INCLUDE = '''\ +TEMPLATE_INCLUDE = """\ The first line {% include empty %} An empty file removes the line above @@ -141,8 +141,8 @@ An empty file removes the line above {% include dir/nested %} Include basic again: {% include basic %} -''' -EXPECTED_INCLUDE = f'''\ +""" +EXPECTED_INCLUDE = f"""\ The first line An empty file removes the line above basic @@ -152,21 +152,21 @@ empty line above no newline at the end Include basic again: basic -''' +""" def test_template_default(runner, yadm, tmpdir): """Test template_default""" - input_file = tmpdir.join('input') + input_file = tmpdir.join("input") input_file.write(TEMPLATE, ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") # ensure overwrite works when file exists as read-only (there is some # special processing when this is encountered because some environments do # not properly overwrite read-only files) - output_file.write('existing') + output_file.write("existing") output_file.chmod(0o400) script = f""" @@ -182,9 +182,9 @@ def test_template_default(runner, yadm, tmpdir): local_distro_family="{LOCAL_DISTRO_FAMILY}" template_default "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read() == EXPECTED assert os.stat(output_file).st_mode == os.stat(input_file).st_mode @@ -192,19 +192,19 @@ def test_template_default(runner, yadm, tmpdir): def test_source(runner, yadm, tmpdir): """Test yadm.source""" - input_file = tmpdir.join('input') - input_file.write('{{yadm.source}}', ensure=True) + input_file = tmpdir.join("input") + input_file.write("{{yadm.source}}", ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") script = f""" YADM_TEST=1 source {yadm} set_awk template_default "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read().strip() == str(input_file) assert os.stat(output_file).st_mode == os.stat(input_file).st_mode @@ -212,22 +212,22 @@ def test_source(runner, yadm, tmpdir): def test_include(runner, yadm, tmpdir): """Test include""" - empty_file = tmpdir.join('empty') - empty_file.write('', ensure=True) + empty_file = tmpdir.join("empty") + empty_file.write("", ensure=True) - basic_file = tmpdir.join('basic') + basic_file = tmpdir.join("basic") basic_file.write(INCLUDE_BASIC) - variables_file = tmpdir.join(f'variables.{LOCAL_SYSTEM}') + variables_file = tmpdir.join(f"variables.{LOCAL_SYSTEM}") variables_file.write(INCLUDE_VARIABLES) - nested_file = tmpdir.join('dir').join('nested') + nested_file = tmpdir.join("dir").join("nested") nested_file.write(INCLUDE_NESTED, ensure=True) - input_file = tmpdir.join('input') + input_file = tmpdir.join("input") input_file.write(TEMPLATE_INCLUDE) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") script = f""" YADM_TEST=1 source {yadm} @@ -236,9 +236,9 @@ def test_include(runner, yadm, tmpdir): local_system="{LOCAL_SYSTEM}" template_default "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read() == EXPECTED_INCLUDE assert os.stat(output_file).st_mode == os.stat(input_file).st_mode @@ -246,17 +246,17 @@ def test_include(runner, yadm, tmpdir): def test_env(runner, yadm, tmpdir): """Test env""" - input_file = tmpdir.join('input') - input_file.write('{{env.PWD}}', ensure=True) + input_file = tmpdir.join("input") + input_file.write("{{env.PWD}}", ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") script = f""" YADM_TEST=1 source {yadm} set_awk template_default "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - assert output_file.read().strip() == os.environ['PWD'] + assert run.err == "" + assert output_file.read().strip() == os.environ["PWD"] diff --git a/test/test_unit_template_esh.py b/test/test_unit_template_esh.py index 7f2f2b9..2c91c20 100644 --- a/test/test_unit_template_esh.py +++ b/test/test_unit_template_esh.py @@ -11,7 +11,7 @@ LOCAL_HOST = "esh_Test+@-!^Host" LOCAL_USER = "esh_Test+@-!^User" LOCAL_DISTRO = "esh_Test+@-!^Distro" LOCAL_DISTRO_FAMILY = "esh_Test+@-!^Family" -TEMPLATE = f''' +TEMPLATE = f""" start of template esh class = ><%=$YADM_CLASS%>< esh arch = ><%=$YADM_ARCH%>< @@ -90,8 +90,8 @@ Included esh section for distro_family = \ wrong family 2 <% fi -%> end of template -''' -EXPECTED = f''' +""" +EXPECTED = f""" start of template esh class = >{LOCAL_CLASS}< esh arch = >{LOCAL_ARCH}< @@ -111,21 +111,22 @@ Included esh section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again) Included esh section for distro_family = \ {LOCAL_DISTRO_FAMILY} ({LOCAL_DISTRO_FAMILY} again) end of template -''' +""" def test_template_esh(runner, yadm, tmpdir): """Test processing by esh""" + # pylint: disable=duplicate-code - input_file = tmpdir.join('input') + input_file = tmpdir.join("input") input_file.write(TEMPLATE, ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") # ensure overwrite works when file exists as read-only (there is some # special processing when this is encountered because some environments do # not properly overwrite read-only files) - output_file.write('existing') + output_file.write("existing") output_file.chmod(0o400) script = f""" @@ -140,9 +141,9 @@ def test_template_esh(runner, yadm, tmpdir): local_distro_family="{LOCAL_DISTRO_FAMILY}" template_esh "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read().strip() == str(EXPECTED).strip() assert os.stat(output_file).st_mode == os.stat(input_file).st_mode @@ -150,17 +151,17 @@ def test_template_esh(runner, yadm, tmpdir): def test_source(runner, yadm, tmpdir): """Test YADM_SOURCE""" - input_file = tmpdir.join('input') - input_file.write('<%= $YADM_SOURCE %>', ensure=True) + input_file = tmpdir.join("input") + input_file.write("<%= $YADM_SOURCE %>", ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") script = f""" YADM_TEST=1 source {yadm} template_esh "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read().strip() == str(input_file) assert os.stat(output_file).st_mode == os.stat(input_file).st_mode diff --git a/test/test_unit_template_j2.py b/test/test_unit_template_j2.py index 84afc2d..750ee8c 100644 --- a/test/test_unit_template_j2.py +++ b/test/test_unit_template_j2.py @@ -13,7 +13,7 @@ LOCAL_HOST = "j2_Test+@-!^Host" LOCAL_USER = "j2_Test+@-!^User" LOCAL_DISTRO = "j2_Test+@-!^Distro" LOCAL_DISTRO_FAMILY = "j2_Test+@-!^Family" -TEMPLATE = f''' +TEMPLATE = f""" start of template j2 class = >{{{{YADM_CLASS}}}}< j2 arch = >{{{{YADM_ARCH}}}}< @@ -94,8 +94,8 @@ Included j2 section for distro_family = \ wrong family 2 {{%- endif %}} end of template -''' -EXPECTED = f''' +""" +EXPECTED = f""" start of template j2 class = >{LOCAL_CLASS}< j2 arch = >{LOCAL_ARCH}< @@ -116,22 +116,23 @@ Included j2 section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again) Included j2 section for distro_family = \ {LOCAL_DISTRO_FAMILY} ({LOCAL_DISTRO_FAMILY} again) end of template -''' +""" -@pytest.mark.parametrize('processor', ('j2cli', 'envtpl')) +@pytest.mark.parametrize("processor", ("j2cli", "envtpl")) def test_template_j2(runner, yadm, tmpdir, processor): """Test processing by j2cli & envtpl""" + # pylint: disable=duplicate-code - input_file = tmpdir.join('input') + input_file = tmpdir.join("input") input_file.write(TEMPLATE, ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") # ensure overwrite works when file exists as read-only (there is some # special processing when this is encountered because some environments do # not properly overwrite read-only files) - output_file.write('existing') + output_file.write("existing") output_file.chmod(0o400) script = f""" @@ -146,28 +147,28 @@ def test_template_j2(runner, yadm, tmpdir, processor): local_distro_family="{LOCAL_DISTRO_FAMILY}" template_{processor} "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read() == EXPECTED assert os.stat(output_file).st_mode == os.stat(input_file).st_mode -@pytest.mark.parametrize('processor', ('j2cli', 'envtpl')) +@pytest.mark.parametrize("processor", ("j2cli", "envtpl")) def test_source(runner, yadm, tmpdir, processor): """Test YADM_SOURCE""" - input_file = tmpdir.join('input') - input_file.write('{{YADM_SOURCE}}', ensure=True) + input_file = tmpdir.join("input") + input_file.write("{{YADM_SOURCE}}", ensure=True) input_file.chmod(FILE_MODE) - output_file = tmpdir.join('output') + output_file = tmpdir.join("output") script = f""" YADM_TEST=1 source {yadm} template_{processor} "{input_file}" "{output_file}" """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' + assert run.err == "" assert output_file.read().strip() == str(input_file) assert os.stat(output_file).st_mode == os.stat(input_file).st_mode diff --git a/test/test_unit_upgrade.py b/test/test_unit_upgrade.py index 3463740..cf4f6f4 100644 --- a/test/test_unit_upgrade.py +++ b/test/test_unit_upgrade.py @@ -2,21 +2,21 @@ import pytest -@pytest.mark.parametrize('condition', ['override', 'equal', 'existing_repo']) +@pytest.mark.parametrize("condition", ["override", "equal", "existing_repo"]) def test_upgrade_errors(tmpdir, runner, yadm, condition): """Test upgrade() error conditions""" - home = tmpdir.mkdir('home') - yadm_dir = home.join('.config/yadm') - yadm_data = home.join('.local/share/yadm') - override = '' - if condition == 'override': - override = 'override' - if condition == 'equal': + home = tmpdir.mkdir("home") + yadm_dir = home.join(".config/yadm") + yadm_data = home.join(".local/share/yadm") + override = "" + if condition == "override": + override = "override" + if condition == "equal": yadm_data = yadm_dir - if condition == 'existing_repo': - yadm_dir.ensure_dir('repo.git') - yadm_data.ensure_dir('repo.git') + if condition == "existing_repo": + yadm_dir.ensure_dir("repo.git") + yadm_data.ensure_dir("repo.git") script = f""" YADM_TEST=1 source {yadm} @@ -27,17 +27,16 @@ def test_upgrade_errors(tmpdir, runner, yadm, condition): YADM_OVERRIDE_REPO="{override}" upgrade """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.failure - assert 'Unable to upgrade' in run.err - if condition in ['override', 'equal']: - assert 'Paths have been overridden' in run.err - elif condition == 'existing_repo': - assert 'already exists' in run.err + assert "Unable to upgrade" in run.err + if condition in ["override", "equal"]: + assert "Paths have been overridden" in run.err + elif condition == "existing_repo": + assert "already exists" in run.err -@pytest.mark.parametrize( - 'condition', ['no-paths', 'untracked', 'tracked', 'submodules']) +@pytest.mark.parametrize("condition", ["no-paths", "untracked", "tracked", "submodules"]) def test_upgrade(tmpdir, runner, yadm, condition): """Test upgrade() @@ -45,21 +44,21 @@ def test_upgrade(tmpdir, runner, yadm, condition): mock for git. echo will return true, simulating a positive result from "git ls-files". Also echo will report the parameters for "git mv". """ - legacy_paths = ('config', 'encrypt', 'bootstrap', 'hooks/pre_cmd') - home = tmpdir.mkdir('home') - yadm_dir = home.join('.config/yadm') - yadm_data = home.join('.local/share/yadm') - yadm_legacy = home.join('.yadm') + legacy_paths = ("config", "encrypt", "bootstrap", "hooks/pre_cmd") + home = tmpdir.mkdir("home") + yadm_dir = home.join(".config/yadm") + yadm_data = home.join(".local/share/yadm") + yadm_legacy = home.join(".yadm") - if condition != 'no-paths': - yadm_dir.join('repo.git/config').write('test-repo', ensure=True) - yadm_dir.join('files.gpg').write('files.gpg', ensure=True) + if condition != "no-paths": + yadm_dir.join("repo.git/config").write("test-repo", ensure=True) + yadm_dir.join("files.gpg").write("files.gpg", ensure=True) for path in legacy_paths: yadm_legacy.join(path).write(path, ensure=True) mock_git = "" - if condition != 'no-paths': - mock_git = f''' + if condition != "no-paths": + mock_git = f""" function git() {{ echo "$@" if [[ "$*" = *"submodule status" ]]; then @@ -71,7 +70,7 @@ def test_upgrade(tmpdir, runner, yadm, condition): fi return 0 }} - ''' + """ script = f""" YADM_TEST=1 source {yadm} @@ -85,38 +84,30 @@ def test_upgrade(tmpdir, runner, yadm, condition): function cd {{ echo "$@";}} upgrade """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success - assert run.err == '' - if condition == 'no-paths': - assert 'Upgrade is not necessary' in run.out + assert run.err == "" + if condition == "no-paths": + assert "Upgrade is not necessary" in run.out else: - for (lpath, npath) in [ - ('repo.git', 'repo.git'), ('files.gpg', 'archive')]: - expected = ( - f'Moving {yadm_dir.join(lpath)} ' - f'to {yadm_data.join(npath)}') + for lpath, npath in [("repo.git", "repo.git"), ("files.gpg", "archive")]: + expected = f"Moving {yadm_dir.join(lpath)} " f"to {yadm_data.join(npath)}" assert expected in run.out for path in legacy_paths: - expected = ( - f'Moving {yadm_legacy.join(path)} ' - f'to {yadm_dir.join(path)}') + expected = f"Moving {yadm_legacy.join(path)} " f"to {yadm_dir.join(path)}" assert expected in run.out - if condition == 'untracked': - assert 'test-repo' in yadm_data.join('repo.git/config').read() - assert 'files.gpg' in yadm_data.join('archive').read() + if condition == "untracked": + assert "test-repo" in yadm_data.join("repo.git/config").read() + assert "files.gpg" in yadm_data.join("archive").read() for path in legacy_paths: assert path in yadm_dir.join(path).read() - elif condition in ['tracked', 'submodules']: - expected = ( - f'mv {yadm_dir.join("files.gpg")} ' - f'{yadm_data.join("archive")}') + elif condition in ["tracked", "submodules"]: + expected = f'mv {yadm_dir.join("files.gpg")} ' f'{yadm_data.join("archive")}' assert expected in run.out - assert 'files tracked by yadm have been renamed' in run.out - if condition == 'submodules': - assert 'submodule deinit -- mymodule' in run.out - assert 'submodule update --init --recursive -- mymodule' \ - in run.out + assert "files tracked by yadm have been renamed" in run.out + if condition == "submodules": + assert "submodule deinit -- mymodule" in run.out + assert "submodule update --init --recursive -- mymodule" in run.out else: - assert 'submodule deinit' not in run.out - assert 'submodule update --init --recursive' not in run.out + assert "submodule deinit" not in run.out + assert "submodule update --init --recursive" not in run.out diff --git a/test/test_unit_x_program.py b/test/test_unit_x_program.py index 883c9af..33b8473 100644 --- a/test/test_unit_x_program.py +++ b/test/test_unit_x_program.py @@ -6,24 +6,25 @@ import pytest @pytest.mark.parametrize( - 'executable, success, value, match', [ - (None, True, 'program', None), - ('cat', True, 'cat', None), - ('badprogram', False, None, 'badprogram'), - ], ids=[ - 'executable missing', - 'valid alternative', - 'invalid alternative', - ]) -@pytest.mark.parametrize('program', ['git', 'gpg']) -def test_x_program( - runner, yadm_cmd, paths, program, executable, success, value, match): + "executable, success, value, match", + [ + (None, True, "program", None), + ("cat", True, "cat", None), + ("badprogram", False, None, "badprogram"), + ], + ids=[ + "executable missing", + "valid alternative", + "invalid alternative", + ], +) +@pytest.mark.parametrize("program", ["git", "gpg"]) +def test_x_program(runner, yadm_cmd, paths, program, executable, success, value, match): """Set yadm.X-program, and test result of require_X""" # set configuration if executable: - os.system(' '.join(yadm_cmd( - 'config', f'yadm.{program}-program', executable))) + os.system(" ".join(yadm_cmd("config", f"yadm.{program}-program", executable))) # test require_[git,gpg] script = f""" @@ -33,11 +34,11 @@ def test_x_program( require_{program} echo ${program.upper()}_PROGRAM """ - run = runner(command=['bash'], inp=script) + run = runner(command=["bash"], inp=script) assert run.success == success # [GIT,GPG]_PROGRAM set correctly - if value == 'program': + if value == "program": assert run.out.rstrip() == program elif value: assert run.out.rstrip() == value @@ -46,4 +47,4 @@ def test_x_program( if match: assert match in run.err else: - assert run.err == '' + assert run.err == "" diff --git a/test/test_upgrade.py b/test/test_upgrade.py index 1805882..8ab1e94 100644 --- a/test/test_upgrade.py +++ b/test/test_upgrade.py @@ -6,129 +6,126 @@ import pytest @pytest.mark.parametrize( - 'versions', [ - ('1.12.0', '2.5.0'), - ('1.12.0',), - ('2.5.0',), - ], ids=[ - '1.12.0 -> 2.5.0 -> latest', - '1.12.0 -> latest', - '2.5.0 -> latest', - ]) -@pytest.mark.parametrize( - 'submodule', [False, True], - ids=['no submodule', 'with submodules']) + "versions", + [ + ("1.12.0", "2.5.0"), + ("1.12.0",), + ("2.5.0",), + ], + ids=[ + "1.12.0 -> 2.5.0 -> latest", + "1.12.0 -> latest", + "2.5.0 -> latest", + ], +) +@pytest.mark.parametrize("submodule", [False, True], ids=["no submodule", "with submodules"]) def test_upgrade(tmpdir, runner, versions, submodule): """Upgrade tests""" # pylint: disable=too-many-statements - home = tmpdir.mkdir('HOME') - env = {'HOME': str(home)} - runner(['git', 'config', '--global', 'init.defaultBranch', 'master'], - env=env) - runner(['git', 'config', '--global', 'protocol.file.allow', 'always'], - env=env) + home = tmpdir.mkdir("HOME") + env = {"HOME": str(home)} + runner(["git", "config", "--global", "init.defaultBranch", "master"], env=env) + runner(["git", "config", "--global", "protocol.file.allow", "always"], env=env) if submodule: - ext_repo = tmpdir.mkdir('ext_repo') - ext_repo.join('afile').write('some data') + ext_repo = tmpdir.mkdir("ext_repo") + ext_repo.join("afile").write("some data") - for cmd in (('init',), ('add', 'afile'), ('commit', '-m', 'test')): - run = runner(['git', '-C', str(ext_repo), *cmd]) + for cmd in (("init",), ("add", "afile"), ("commit", "-m", "test")): + run = runner(["git", "-C", str(ext_repo), *cmd]) assert run.success - os.environ.pop('XDG_CONFIG_HOME', None) - os.environ.pop('XDG_DATA_HOME', None) + os.environ.pop("XDG_CONFIG_HOME", None) + os.environ.pop("XDG_DATA_HOME", None) def run_version(version, *args, check_stderr=True): - yadm = f'yadm-{version}' if version else '/yadm/yadm' + yadm = f"yadm-{version}" if version else "/yadm/yadm" run = runner([yadm, *args], shell=True, cwd=str(home), env=env) assert run.success if check_stderr: - assert run.err == '' + assert run.err == "" return run # Initialize the repo with the first version first = versions[0] - run_version(first, 'init') + run_version(first, "init") - home.join('file').write('some data') - run_version(first, 'add', 'file') - run_version(first, 'commit', '-m', '"First commit"') + home.join("file").write("some data") + run_version(first, "add", "file") + run_version(first, "commit", "-m", '"First commit"') if submodule: # When upgrading via 2.5.0 we can't have a submodule that's been added # after being cloned as 2.5.0 fails the upgrade in that case. - can_upgrade_cloned_submodule = '2.5.0' not in versions[1:] + can_upgrade_cloned_submodule = "2.5.0" not in versions[1:] if can_upgrade_cloned_submodule: # Check out a repo and then add it as a submodule - run = runner(['git', '-C', str(home), 'clone', str(ext_repo), 'b']) + run = runner(["git", "-C", str(home), "clone", str(ext_repo), "b"]) assert run.success - run_version(first, 'submodule', 'add', str(ext_repo), 'b') + run_version(first, "submodule", "add", str(ext_repo), "b") # Add submodule without first checking it out - run_version(first, 'submodule', 'add', str(ext_repo), 'a', - check_stderr=False) - run_version(first, 'submodule', 'add', str(ext_repo), 'c', - check_stderr=False) + run_version(first, "submodule", "add", str(ext_repo), "a", check_stderr=False) + run_version(first, "submodule", "add", str(ext_repo), "c", check_stderr=False) - run_version(first, 'commit', '-m', '"Add submodules"') + run_version(first, "commit", "-m", '"Add submodules"') - for path in ('.yadm', '.config/yadm'): + for path in (".yadm", ".config/yadm"): yadm_dir = home.join(path) if yadm_dir.exists(): break - yadm_dir.join('bootstrap').write('init stuff') - run_version(first, 'add', yadm_dir.join('bootstrap')) - run_version(first, 'commit', '-m', 'bootstrap') + yadm_dir.join("bootstrap").write("init stuff") + run_version(first, "add", yadm_dir.join("bootstrap")) + run_version(first, "commit", "-m", "bootstrap") - yadm_dir.join('encrypt').write('secret') + yadm_dir.join("encrypt").write("secret") - hooks_dir = yadm_dir.mkdir('hooks') - hooks_dir.join('pre_status').write('status') - hooks_dir.join('post_commit').write('commit') + hooks_dir = yadm_dir.mkdir("hooks") + hooks_dir.join("pre_status").write("status") + hooks_dir.join("post_commit").write("commit") - run_version(first, 'config', 'local.class', 'test') - run_version(first, 'config', 'foo.bar', 'true') + run_version(first, "config", "local.class", "test") + run_version(first, "config", "foo.bar", "true") # Run upgrade with intermediate versions and latest latest = None for version in versions[1:] + (latest,): - run = run_version(version, 'upgrade', check_stderr=not submodule) + run = run_version(version, "upgrade", check_stderr=not submodule) if submodule: lines = run.err.splitlines() if can_upgrade_cloned_submodule: - assert 'Migrating git directory of' in lines[0] - assert str(home.join('b/.git')) in lines[1] - assert str(yadm_dir.join('repo.git/modules/b')) in lines[2] + assert "Migrating git directory of" in lines[0] + assert str(home.join("b/.git")) in lines[1] + assert str(yadm_dir.join("repo.git/modules/b")) in lines[2] del lines[:3] for line in lines: - assert line.startswith('Submodule') - assert 'registered for path' in line + assert line.startswith("Submodule") + assert "registered for path" in line # Verify result for the final upgrade - run_version(latest, 'status') + run_version(latest, "status") - run = run_version(latest, 'show', 'HEAD:file') - assert run.out == 'some data' + run = run_version(latest, "show", "HEAD:file") + assert run.out == "some data" if submodule: if can_upgrade_cloned_submodule: - assert home.join('b/afile').read() == 'some data' - assert home.join('a/afile').read() == 'some data' - assert home.join('c/afile').read() == 'some data' + assert home.join("b/afile").read() == "some data" + assert home.join("a/afile").read() == "some data" + assert home.join("c/afile").read() == "some data" - yadm_dir = home.join('.config/yadm') + yadm_dir = home.join(".config/yadm") - assert yadm_dir.join('bootstrap').read() == 'init stuff' - assert yadm_dir.join('encrypt').read() == 'secret' + assert yadm_dir.join("bootstrap").read() == "init stuff" + assert yadm_dir.join("encrypt").read() == "secret" - hooks_dir = yadm_dir.join('hooks') - assert hooks_dir.join('pre_status').read() == 'status' - assert hooks_dir.join('post_commit').read() == 'commit' + hooks_dir = yadm_dir.join("hooks") + assert hooks_dir.join("pre_status").read() == "status" + assert hooks_dir.join("post_commit").read() == "commit" - run = run_version(latest, 'config', 'local.class') - assert run.out.rstrip() == 'test' + run = run_version(latest, "config", "local.class") + assert run.out.rstrip() == "test" - run = run_version(latest, 'config', 'foo.bar') - assert run.out.rstrip() == 'true' + run = run_version(latest, "config", "foo.bar") + assert run.out.rstrip() == "true" diff --git a/test/test_version.py b/test/test_version.py index aee6f33..52b18ab 100644 --- a/test/test_version.py +++ b/test/test_version.py @@ -5,34 +5,32 @@ import re import pytest -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def expected_version(yadm): """ Expected semantic version number. This is taken directly out of yadm, searching for the VERSION= string. """ - with open(yadm, encoding='utf-8') as source_file: - yadm_version = re.findall(r'VERSION=([^\n]+)', source_file.read()) + with open(yadm, encoding="utf-8") as source_file: + yadm_version = re.findall(r"VERSION=([^\n]+)", source_file.read()) if yadm_version: return yadm_version[0] - pytest.fail(f'version not found in {yadm}') - return 'not found' + pytest.fail(f"version not found in {yadm}") + return "not found" def test_semantic_version(expected_version): """Version is semantic""" # semantic version conforms to MAJOR.MINOR.PATCH - assert re.search(r'^\d+\.\d+\.\d+$', expected_version), ( - 'does not conform to MAJOR.MINOR.PATCH') + assert re.search(r"^\d+\.\d+\.\d+$", expected_version), "does not conform to MAJOR.MINOR.PATCH" -@pytest.mark.parametrize('cmd', ['--version', 'version']) -def test_reported_version( - runner, yadm_cmd, cmd, expected_version): +@pytest.mark.parametrize("cmd", ["--version", "version"]) +def test_reported_version(runner, yadm_cmd, cmd, expected_version): """Report correct version and bash/git versions""" run = runner(command=yadm_cmd(cmd)) assert run.success - assert run.err == '' - assert 'bash version' in run.out - assert 'git version' in run.out - assert run.out.endswith(f'\nyadm version {expected_version}\n') + assert run.err == "" + assert "bash version" in run.out + assert "git version" in run.out + assert run.out.endswith(f"\nyadm version {expected_version}\n") diff --git a/test/utils.py b/test/utils.py index f71a758..c36ecac 100644 --- a/test/utils.py +++ b/test/utils.py @@ -6,35 +6,39 @@ This module holds values/functions common to multiple tests. import os import re -ALT_FILE1 = 'test_alt' -ALT_FILE2 = 'test alt/test alt' -ALT_DIR = 'test alt/test alt dir' +ALT_FILE1 = "test_alt" +ALT_FILE2 = "test alt/test alt" +ALT_DIR = "test alt/test alt dir" # Directory based alternates must have a tracked contained file. # This will be the test contained file name -CONTAINED = 'contained_file' +CONTAINED = "contained_file" # These variables are used for making include files which will be processed # within jinja templates -INCLUDE_FILE = 'inc_file' -INCLUDE_DIRS = ['', 'test alt'] -INCLUDE_CONTENT = '8780846c02e34c930d0afd127906668f' +INCLUDE_FILE = "inc_file" +INCLUDE_DIRS = ["", "test alt"] +INCLUDE_CONTENT = "8780846c02e34c930d0afd127906668f" def set_local(paths, variable, value, add=False): """Set local override""" add = "--add" if add else "" - os.system( - f'GIT_DIR={str(paths.repo)} ' - f'git config --local {add} "local.{variable}" "{value}"' - ) + os.system(f"GIT_DIR={str(paths.repo)} " f'git config --local {add} "local.{variable}" "{value}"') -def create_alt_files(paths, suffix, - preserve=False, tracked=True, - encrypt=False, exclude=False, - content=None, includefile=False, - yadm_alt=False, yadm_dir=None): +def create_alt_files( + paths, + suffix, + preserve=False, + tracked=True, + encrypt=False, + exclude=False, + content=None, + includefile=False, + yadm_alt=False, + yadm_dir=None, +): """Create new files, and add to the repo This is used for testing alternate files. In each case, a suffix is @@ -42,7 +46,7 @@ def create_alt_files(paths, suffix, repo handling are dependent upon the function arguments. """ - basepath = yadm_dir.join('alt') if yadm_alt else paths.work + basepath = yadm_dir.join("alt") if yadm_alt else paths.work if not preserve: for remove_path in (ALT_FILE1, ALT_FILE2, ALT_DIR): @@ -60,27 +64,27 @@ def create_alt_files(paths, suffix, # Do not test directory support for jinja alternates test_paths = [new_file1, new_file2] test_names = [ALT_FILE1, ALT_FILE2] - if not re.match(r'##(t$|t\.|template|yadm)', suffix): + if not re.match(r"##(t$|t\.|template|yadm)", suffix): test_paths += [new_dir] test_names += [ALT_DIR] for test_path in test_paths: if content: - test_path.write('\n' + content, mode='a', ensure=True) + test_path.write("\n" + content, mode="a", ensure=True) assert test_path.exists() _create_includefiles(includefile, test_paths, basepath) _create_tracked(tracked, test_paths, paths) - prefix = '.config/yadm/alt/' if yadm_alt else '' + prefix = ".config/yadm/alt/" if yadm_alt else "" _create_encrypt(encrypt, test_names, suffix, paths, exclude, prefix) def parse_alt_output(output, linked=True): """Parse output of 'alt', and return list of linked files""" - regex = r'Creating (.+) from template (.+)$' + regex = r"Creating (.+) from template (.+)$" if linked: - regex = r'Linking (.+) to (.+)$' + regex = r"Linking (.+) to (.+)$" parsed_list = {} for line in output.splitlines(): match = re.match(regex, line) @@ -95,7 +99,7 @@ def parse_alt_output(output, linked=True): def _create_includefiles(includefile, test_paths, basepath): if includefile: for dpath in INCLUDE_DIRS: - incfile = basepath.join(dpath + '/' + INCLUDE_FILE) + incfile = basepath.join(dpath + "/" + INCLUDE_FILE) incfile.write(INCLUDE_CONTENT, ensure=True) test_paths += [incfile] @@ -110,8 +114,6 @@ def _create_tracked(tracked, test_paths, paths): def _create_encrypt(encrypt, test_names, suffix, paths, exclude, prefix): if encrypt: for encrypt_name in test_names: - paths.encrypt.write( - f'{prefix + encrypt_name + suffix}\n', mode='a') + paths.encrypt.write(f"{prefix + encrypt_name + suffix}\n", mode="a") if exclude: - paths.encrypt.write( - f'!{prefix + encrypt_name + suffix}\n', mode='a') + paths.encrypt.write(f"!{prefix + encrypt_name + suffix}\n", mode="a")