Changes for black compliance

This commit is contained in:
Tim Byrne 2023-07-10 14:43:17 -05:00
parent e704175201
commit 76ce3defea
No known key found for this signature in database
GPG Key ID: 14DB4FC2465A4B12
47 changed files with 1845 additions and 2038 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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 == ""

View File

@ -3,9 +3,9 @@
def test_clean_command(runner, yadm_cmd):