pre-commit: run black with string normalization

This commit is contained in:
Erik Sundell
2021-11-03 23:55:34 +01:00
parent 2ba942ba76
commit e0aaa4f995
31 changed files with 700 additions and 692 deletions

View File

@@ -17,7 +17,7 @@ def tljh_dir(tmpdir):
reload(tljh)
for name in dir(tljh):
mod = getattr(tljh, name)
if isinstance(mod, types.ModuleType) and mod.__name__.startswith('tljh.'):
if isinstance(mod, types.ModuleType) and mod.__name__.startswith("tljh."):
reload(mod)
assert tljh.config.INSTALL_PREFIX == tljh_dir
os.makedirs(tljh.config.STATE_DIR)

View File

@@ -8,18 +8,18 @@ import subprocess
import tempfile
@pytest.fixture(scope='module')
@pytest.fixture(scope="module")
def prefix():
"""
Provide a temporary directory with a mambaforge conda environment
"""
# see https://github.com/conda-forge/miniforge/releases
mambaforge_version = '4.10.3-7'
if os.uname().machine == 'aarch64':
mambaforge_version = "4.10.3-7"
if os.uname().machine == "aarch64":
installer_sha256 = (
"ac95f137b287b3408e4f67f07a284357b1119ee157373b788b34e770ef2392b2"
)
elif os.uname().machine == 'x86_64':
elif os.uname().machine == "x86_64":
installer_sha256 = (
"fc872522ec427fcab10167a93e802efaf251024b58cc27b084b915a9a73c4474"
)
@@ -31,7 +31,7 @@ def prefix():
installer_url, installer_sha256
) as installer_path:
conda.install_miniconda(installer_path, tmpdir)
conda.ensure_conda_packages(tmpdir, ['conda==4.10.3'])
conda.ensure_conda_packages(tmpdir, ["conda==4.10.3"])
yield tmpdir
@@ -39,29 +39,29 @@ def test_ensure_packages(prefix):
"""
Test installing packages in conda environment
"""
conda.ensure_conda_packages(prefix, ['numpy'])
conda.ensure_conda_packages(prefix, ["numpy"])
# Throws an error if this fails
subprocess.check_call([os.path.join(prefix, 'bin', 'python'), '-c', 'import numpy'])
subprocess.check_call([os.path.join(prefix, "bin", "python"), "-c", "import numpy"])
def test_ensure_pip_packages(prefix):
"""
Test installing pip packages in conda environment
"""
conda.ensure_conda_packages(prefix, ['pip'])
conda.ensure_pip_packages(prefix, ['numpy'])
conda.ensure_conda_packages(prefix, ["pip"])
conda.ensure_pip_packages(prefix, ["numpy"])
# Throws an error if this fails
subprocess.check_call([os.path.join(prefix, 'bin', 'python'), '-c', 'import numpy'])
subprocess.check_call([os.path.join(prefix, "bin", "python"), "-c", "import numpy"])
def test_ensure_pip_requirements(prefix):
"""
Test installing pip packages with requirements.txt in conda environment
"""
conda.ensure_conda_packages(prefix, ['pip'])
conda.ensure_conda_packages(prefix, ["pip"])
with tempfile.NamedTemporaryFile() as f:
# Sample small package to test
f.write(b'there')
f.write(b"there")
f.flush()
conda.ensure_pip_requirements(prefix, f.name)
subprocess.check_call([os.path.join(prefix, 'bin', 'python'), '-c', 'import there'])
subprocess.check_call([os.path.join(prefix, "bin", "python"), "-c", "import there"])

View File

@@ -14,25 +14,25 @@ from tljh import config, configurer
def test_set_no_mutate():
conf = {}
new_conf = config.set_item_in_config(conf, 'a.b', 'c')
assert new_conf['a']['b'] == 'c'
new_conf = config.set_item_in_config(conf, "a.b", "c")
assert new_conf["a"]["b"] == "c"
assert conf == {}
def test_set_one_level():
conf = {}
new_conf = config.set_item_in_config(conf, 'a', 'b')
assert new_conf['a'] == 'b'
new_conf = config.set_item_in_config(conf, "a", "b")
assert new_conf["a"] == "b"
def test_set_multi_level():
conf = {}
new_conf = config.set_item_in_config(conf, 'a.b', 'c')
new_conf = config.set_item_in_config(new_conf, 'a.d', 'e')
new_conf = config.set_item_in_config(new_conf, 'f', 'g')
assert new_conf == {'a': {'b': 'c', 'd': 'e'}, 'f': 'g'}
new_conf = config.set_item_in_config(conf, "a.b", "c")
new_conf = config.set_item_in_config(new_conf, "a.d", "e")
new_conf = config.set_item_in_config(new_conf, "f", "g")
assert new_conf == {"a": {"b": "c", "d": "e"}, "f": "g"}
def test_set_overwrite():
@@ -41,124 +41,124 @@ def test_set_overwrite():
This might be surprising destructive behavior to some :D
"""
conf = {'a': 'b'}
conf = {"a": "b"}
new_conf = config.set_item_in_config(conf, 'a', 'c')
assert new_conf == {'a': 'c'}
new_conf = config.set_item_in_config(conf, "a", "c")
assert new_conf == {"a": "c"}
new_conf = config.set_item_in_config(new_conf, 'a.b', 'd')
assert new_conf == {'a': {'b': 'd'}}
new_conf = config.set_item_in_config(new_conf, "a.b", "d")
assert new_conf == {"a": {"b": "d"}}
new_conf = config.set_item_in_config(new_conf, 'a', 'hi')
assert new_conf == {'a': 'hi'}
new_conf = config.set_item_in_config(new_conf, "a", "hi")
assert new_conf == {"a": "hi"}
def test_unset_no_mutate():
conf = {'a': 'b'}
conf = {"a": "b"}
new_conf = config.unset_item_from_config(conf, 'a')
assert conf == {'a': 'b'}
new_conf = config.unset_item_from_config(conf, "a")
assert conf == {"a": "b"}
def test_unset_one_level():
conf = {'a': 'b'}
conf = {"a": "b"}
new_conf = config.unset_item_from_config(conf, 'a')
new_conf = config.unset_item_from_config(conf, "a")
assert new_conf == {}
def test_unset_multi_level():
conf = {'a': {'b': 'c', 'd': 'e'}, 'f': 'g'}
conf = {"a": {"b": "c", "d": "e"}, "f": "g"}
new_conf = config.unset_item_from_config(conf, 'a.b')
assert new_conf == {'a': {'d': 'e'}, 'f': 'g'}
new_conf = config.unset_item_from_config(new_conf, 'a.d')
assert new_conf == {'f': 'g'}
new_conf = config.unset_item_from_config(new_conf, 'f')
new_conf = config.unset_item_from_config(conf, "a.b")
assert new_conf == {"a": {"d": "e"}, "f": "g"}
new_conf = config.unset_item_from_config(new_conf, "a.d")
assert new_conf == {"f": "g"}
new_conf = config.unset_item_from_config(new_conf, "f")
assert new_conf == {}
def test_unset_and_clean_empty_configs():
conf = {'a': {'b': {'c': {'d': {'e': 'f'}}}}}
conf = {"a": {"b": {"c": {"d": {"e": "f"}}}}}
new_conf = config.unset_item_from_config(conf, 'a.b.c.d.e')
new_conf = config.unset_item_from_config(conf, "a.b.c.d.e")
assert new_conf == {}
def test_unset_config_error():
with pytest.raises(ValueError):
config.unset_item_from_config({}, 'a')
config.unset_item_from_config({}, "a")
with pytest.raises(ValueError):
config.unset_item_from_config({'a': 'b'}, 'b')
config.unset_item_from_config({"a": "b"}, "b")
with pytest.raises(ValueError):
config.unset_item_from_config({'a': {'b': 'c'}}, 'a.z')
config.unset_item_from_config({"a": {"b": "c"}}, "a.z")
def test_add_to_config_one_level():
conf = {}
new_conf = config.add_item_to_config(conf, 'a.b', 'c')
assert new_conf == {'a': {'b': ['c']}}
new_conf = config.add_item_to_config(conf, "a.b", "c")
assert new_conf == {"a": {"b": ["c"]}}
def test_add_to_config_zero_level():
conf = {}
new_conf = config.add_item_to_config(conf, 'a', 'b')
assert new_conf == {'a': ['b']}
new_conf = config.add_item_to_config(conf, "a", "b")
assert new_conf == {"a": ["b"]}
def test_add_to_config_multiple():
conf = {}
new_conf = config.add_item_to_config(conf, 'a.b.c', 'd')
assert new_conf == {'a': {'b': {'c': ['d']}}}
new_conf = config.add_item_to_config(conf, "a.b.c", "d")
assert new_conf == {"a": {"b": {"c": ["d"]}}}
new_conf = config.add_item_to_config(new_conf, 'a.b.c', 'e')
assert new_conf == {'a': {'b': {'c': ['d', 'e']}}}
new_conf = config.add_item_to_config(new_conf, "a.b.c", "e")
assert new_conf == {"a": {"b": {"c": ["d", "e"]}}}
def test_remove_from_config():
conf = {}
new_conf = config.add_item_to_config(conf, 'a.b.c', 'd')
new_conf = config.add_item_to_config(new_conf, 'a.b.c', 'e')
assert new_conf == {'a': {'b': {'c': ['d', 'e']}}}
new_conf = config.add_item_to_config(conf, "a.b.c", "d")
new_conf = config.add_item_to_config(new_conf, "a.b.c", "e")
assert new_conf == {"a": {"b": {"c": ["d", "e"]}}}
new_conf = config.remove_item_from_config(new_conf, 'a.b.c', 'e')
assert new_conf == {'a': {'b': {'c': ['d']}}}
new_conf = config.remove_item_from_config(new_conf, "a.b.c", "e")
assert new_conf == {"a": {"b": {"c": ["d"]}}}
def test_remove_from_config_error():
with pytest.raises(ValueError):
config.remove_item_from_config({}, 'a.b.c', 'e')
config.remove_item_from_config({}, "a.b.c", "e")
with pytest.raises(ValueError):
config.remove_item_from_config({'a': 'b'}, 'a.b', 'e')
config.remove_item_from_config({"a": "b"}, "a.b", "e")
with pytest.raises(ValueError):
config.remove_item_from_config({'a': ['b']}, 'a', 'e')
config.remove_item_from_config({"a": ["b"]}, "a", "e")
def test_reload_hub():
with mock.patch('tljh.systemd.restart_service') as restart_service, mock.patch(
'tljh.systemd.check_service_active'
) as check_active, mock.patch('tljh.config.check_hub_ready') as check_ready:
config.reload_component('hub')
assert restart_service.called_with('jupyterhub')
assert check_active.called_with('jupyterhub')
with mock.patch("tljh.systemd.restart_service") as restart_service, mock.patch(
"tljh.systemd.check_service_active"
) as check_active, mock.patch("tljh.config.check_hub_ready") as check_ready:
config.reload_component("hub")
assert restart_service.called_with("jupyterhub")
assert check_active.called_with("jupyterhub")
def test_reload_proxy(tljh_dir):
with mock.patch("tljh.systemd.restart_service") as restart_service, mock.patch(
"tljh.systemd.check_service_active"
) as check_active:
config.reload_component('proxy')
assert restart_service.called_with('traefik')
assert check_active.called_with('traefik')
assert os.path.exists(os.path.join(config.STATE_DIR, 'traefik.toml'))
config.reload_component("proxy")
assert restart_service.called_with("traefik")
assert check_active.called_with("traefik")
assert os.path.exists(os.path.join(config.STATE_DIR, "traefik.toml"))
def test_cli_no_command(capsys):
@@ -172,41 +172,41 @@ def test_cli_no_command(capsys):
def test_cli_set_bool(tljh_dir, arg, value):
config.main(["set", "https.enabled", arg])
cfg = configurer.load_config()
assert cfg['https']['enabled'] == value
assert cfg["https"]["enabled"] == value
def test_cli_set_int(tljh_dir):
config.main(["set", "https.port", "123"])
cfg = configurer.load_config()
assert cfg['https']['port'] == 123
assert cfg["https"]["port"] == 123
def test_cli_unset(tljh_dir):
config.main(["set", "foo.bar", "1"])
config.main(["set", "foo.bar2", "2"])
cfg = configurer.load_config()
assert cfg['foo'] == {'bar': 1, 'bar2': 2}
assert cfg["foo"] == {"bar": 1, "bar2": 2}
config.main(["unset", "foo.bar"])
cfg = configurer.load_config()
assert cfg['foo'] == {'bar2': 2}
assert cfg["foo"] == {"bar2": 2}
def test_cli_add_float(tljh_dir):
config.main(["add-item", "foo.bar", "1.25"])
cfg = configurer.load_config()
assert cfg['foo']['bar'] == [1.25]
assert cfg["foo"]["bar"] == [1.25]
def test_cli_remove_int(tljh_dir):
config.main(["add-item", "foo.bar", "1"])
config.main(["add-item", "foo.bar", "2"])
cfg = configurer.load_config()
assert cfg['foo']['bar'] == [1, 2]
assert cfg["foo"]["bar"] == [1, 2]
config.main(["remove-item", "foo.bar", "1"])
cfg = configurer.load_config()
assert cfg['foo']['bar'] == [2]
assert cfg["foo"]["bar"] == [2]
@pytest.mark.parametrize(

View File

@@ -25,15 +25,15 @@ def test_default_base_url():
Test default JupyterHub base_url
"""
c = apply_mock_config({})
assert c.JupyterHub.base_url == '/'
assert c.JupyterHub.base_url == "/"
def test_set_base_url():
"""
Test set JupyterHub base_url
"""
c = apply_mock_config({'base_url': '/custom-base'})
assert c.JupyterHub.base_url == '/custom-base'
c = apply_mock_config({"base_url": "/custom-base"})
assert c.JupyterHub.base_url == "/custom-base"
def test_default_memory_limit():
@@ -48,8 +48,8 @@ def test_set_memory_limit():
"""
Test setting per user memory limit
"""
c = apply_mock_config({'limits': {'memory': '42G'}})
assert c.Spawner.mem_limit == '42G'
c = apply_mock_config({"limits": {"memory": "42G"}})
assert c.Spawner.mem_limit == "42G"
def test_app_default():
@@ -58,23 +58,23 @@ def test_app_default():
"""
c = apply_mock_config({})
# default_url is not set, so JupyterHub will pick default.
assert 'default_url' not in c.Spawner
assert "default_url" not in c.Spawner
def test_app_jupyterlab():
"""
Test setting JupyterLab as default application
"""
c = apply_mock_config({'user_environment': {'default_app': 'jupyterlab'}})
assert c.Spawner.default_url == '/lab'
c = apply_mock_config({"user_environment": {"default_app": "jupyterlab"}})
assert c.Spawner.default_url == "/lab"
def test_app_nteract():
"""
Test setting nteract as default application
"""
c = apply_mock_config({'user_environment': {'default_app': 'nteract'}})
assert c.Spawner.default_url == '/nteract'
c = apply_mock_config({"user_environment": {"default_app": "nteract"}})
assert c.Spawner.default_url == "/nteract"
def test_auth_default():
@@ -85,7 +85,7 @@ def test_auth_default():
assert (
c.JupyterHub.authenticator_class
== 'firstuseauthenticator.FirstUseAuthenticator'
== "firstuseauthenticator.FirstUseAuthenticator"
)
# Do not auto create users who haven't been manually added by default
assert not c.FirstUseAuthenticator.create_users
@@ -96,10 +96,10 @@ def test_auth_dummy():
Test setting Dummy Authenticator & password
"""
c = apply_mock_config(
{'auth': {'type': 'dummy', 'DummyAuthenticator': {'password': 'test'}}}
{"auth": {"type": "dummy", "DummyAuthenticator": {"password": "test"}}}
)
assert c.JupyterHub.authenticator_class == 'dummy'
assert c.DummyAuthenticator.password == 'test'
assert c.JupyterHub.authenticator_class == "dummy"
assert c.DummyAuthenticator.password == "test"
def test_user_groups():
@@ -108,8 +108,8 @@ def test_user_groups():
"""
c = apply_mock_config(
{
'users': {
'extra_user_groups': {"g1": ["u1", "u2"], "g2": ["u3", "u4"]},
"users": {
"extra_user_groups": {"g1": ["u1", "u2"], "g2": ["u3", "u4"]},
}
}
)
@@ -122,15 +122,15 @@ def test_auth_firstuse():
"""
c = apply_mock_config(
{
'auth': {
'type': 'firstuseauthenticator.FirstUseAuthenticator',
'FirstUseAuthenticator': {'create_users': True},
"auth": {
"type": "firstuseauthenticator.FirstUseAuthenticator",
"FirstUseAuthenticator": {"create_users": True},
}
}
)
assert (
c.JupyterHub.authenticator_class
== 'firstuseauthenticator.FirstUseAuthenticator'
== "firstuseauthenticator.FirstUseAuthenticator"
)
assert c.FirstUseAuthenticator.create_users
@@ -141,20 +141,20 @@ def test_auth_github():
"""
c = apply_mock_config(
{
'auth': {
'type': 'oauthenticator.github.GitHubOAuthenticator',
'GitHubOAuthenticator': {
'client_id': 'something',
'client_secret': 'something-else',
"auth": {
"type": "oauthenticator.github.GitHubOAuthenticator",
"GitHubOAuthenticator": {
"client_id": "something",
"client_secret": "something-else",
},
}
}
)
assert (
c.JupyterHub.authenticator_class == 'oauthenticator.github.GitHubOAuthenticator'
c.JupyterHub.authenticator_class == "oauthenticator.github.GitHubOAuthenticator"
)
assert c.GitHubOAuthenticator.client_id == 'something'
assert c.GitHubOAuthenticator.client_secret == 'something-else'
assert c.GitHubOAuthenticator.client_id == "something"
assert c.GitHubOAuthenticator.client_secret == "something-else"
def test_traefik_api_default():
@@ -163,7 +163,7 @@ def test_traefik_api_default():
"""
c = apply_mock_config({})
assert c.TraefikTomlProxy.traefik_api_username == 'api_admin'
assert c.TraefikTomlProxy.traefik_api_username == "api_admin"
assert len(c.TraefikTomlProxy.traefik_api_password) == 0
@@ -172,10 +172,10 @@ def test_set_traefik_api():
Test setting per traefik api credentials
"""
c = apply_mock_config(
{'traefik_api': {'username': 'some_user', 'password': '1234'}}
{"traefik_api": {"username": "some_user", "password": "1234"}}
)
assert c.TraefikTomlProxy.traefik_api_username == 'some_user'
assert c.TraefikTomlProxy.traefik_api_password == '1234'
assert c.TraefikTomlProxy.traefik_api_username == "some_user"
assert c.TraefikTomlProxy.traefik_api_password == "1234"
def test_cull_service_default():
@@ -186,18 +186,18 @@ def test_cull_service_default():
cull_cmd = [
sys.executable,
'-m',
'jupyterhub_idle_culler',
'--timeout=600',
'--cull-every=60',
'--concurrency=5',
'--max-age=0',
"-m",
"jupyterhub_idle_culler",
"--timeout=600",
"--cull-every=60",
"--concurrency=5",
"--max-age=0",
]
assert c.JupyterHub.services == [
{
'name': 'cull-idle',
'admin': True,
'command': cull_cmd,
"name": "cull-idle",
"admin": True,
"command": cull_cmd,
}
]
@@ -207,23 +207,23 @@ def test_set_cull_service():
Test setting cull service options
"""
c = apply_mock_config(
{'services': {'cull': {'every': 10, 'users': True, 'max_age': 60}}}
{"services": {"cull": {"every": 10, "users": True, "max_age": 60}}}
)
cull_cmd = [
sys.executable,
'-m',
'jupyterhub_idle_culler',
'--timeout=600',
'--cull-every=10',
'--concurrency=5',
'--max-age=60',
'--cull-users',
"-m",
"jupyterhub_idle_culler",
"--timeout=600",
"--cull-every=10",
"--concurrency=5",
"--max-age=60",
"--cull-users",
]
assert c.JupyterHub.services == [
{
'name': 'cull-idle',
'admin': True,
'command': cull_cmd,
"name": "cull-idle",
"admin": True,
"command": cull_cmd,
}
]
@@ -232,11 +232,11 @@ def test_load_secrets(tljh_dir):
"""
Test loading secret files
"""
with open(os.path.join(tljh_dir, 'state', 'traefik-api.secret'), 'w') as f:
with open(os.path.join(tljh_dir, "state", "traefik-api.secret"), "w") as f:
f.write("traefik-password")
tljh_config = configurer.load_config()
assert tljh_config['traefik_api']['password'] == "traefik-password"
assert tljh_config["traefik_api"]["password"] == "traefik-password"
c = apply_mock_config(tljh_config)
assert c.TraefikTomlProxy.traefik_api_password == "traefik-password"
@@ -247,13 +247,13 @@ def test_auth_native():
"""
c = apply_mock_config(
{
'auth': {
'type': 'nativeauthenticator.NativeAuthenticator',
'NativeAuthenticator': {
'open_signup': True,
"auth": {
"type": "nativeauthenticator.NativeAuthenticator",
"NativeAuthenticator": {
"open_signup": True,
},
}
}
)
assert c.JupyterHub.authenticator_class == 'nativeauthenticator.NativeAuthenticator'
assert c.JupyterHub.authenticator_class == "nativeauthenticator.NativeAuthenticator"
assert c.NativeAuthenticator.open_signup == True

View File

@@ -13,16 +13,16 @@ def test_ensure_config_yaml(tljh_dir):
installer.ensure_config_yaml(pm)
assert os.path.exists(installer.CONFIG_FILE)
assert os.path.isdir(installer.CONFIG_DIR)
assert os.path.isdir(os.path.join(installer.CONFIG_DIR, 'jupyterhub_config.d'))
assert os.path.isdir(os.path.join(installer.CONFIG_DIR, "jupyterhub_config.d"))
# verify that old config doesn't exist
assert not os.path.exists(os.path.join(tljh_dir, 'config.yaml'))
assert not os.path.exists(os.path.join(tljh_dir, "config.yaml"))
@pytest.mark.parametrize(
"admins, expected_config",
[
([['a1'], ['a2'], ['a3']], ['a1', 'a2', 'a3']),
([['a1:p1'], ['a2']], ['a1', 'a2']),
([["a1"], ["a2"], ["a3"]], ["a1", "a2", "a3"]),
([["a1:p1"], ["a2"]], ["a1", "a2"]),
],
)
def test_ensure_admins(tljh_dir, admins, expected_config):
@@ -35,4 +35,4 @@ def test_ensure_admins(tljh_dir, admins, expected_config):
config = yaml.load(f)
# verify the list was flattened
assert config['users']['admin'] == expected_config
assert config["users"]["admin"] == expected_config

View File

@@ -10,13 +10,13 @@ def test_generate_username():
"""
usernames = {
# Very short
'jupyter-test': 'jupyter-test',
"jupyter-test": "jupyter-test",
# Very long
'jupyter-aelie9sohjeequ9iemeipuimuoshahz4aitugiuteeg4ohioh5yuiha6aei7te5z': 'jupyter-aelie9sohjeequ9iem-4b726',
"jupyter-aelie9sohjeequ9iemeipuimuoshahz4aitugiuteeg4ohioh5yuiha6aei7te5z": "jupyter-aelie9sohjeequ9iem-4b726",
# 26 characters, just below our cutoff for hashing
'jupyter-abcdefghijklmnopq': 'jupyter-abcdefghijklmnopq',
"jupyter-abcdefghijklmnopq": "jupyter-abcdefghijklmnopq",
# 27 characters, just above our cutoff for hashing
'jupyter-abcdefghijklmnopqr': 'jupyter-abcdefghijklmnopqr-e375e',
"jupyter-abcdefghijklmnopqr": "jupyter-abcdefghijklmnopqr-e375e",
}
for hub_user, system_user in usernames.items():
assert generate_system_username(hub_user) == system_user

View File

@@ -16,7 +16,7 @@ def test_ensure_user():
Test user creation & removal
"""
# Use a prefix to make sure we never start with a number
username = 'u' + str(uuid.uuid4())[:8]
username = "u" + str(uuid.uuid4())[:8]
# Validate that no user exists
with pytest.raises(KeyError):
pwd.getpwnam(username)
@@ -57,7 +57,7 @@ def test_ensure_group():
Test group creation & removal
"""
# Use a prefix to make sure we never start with a number
groupname = 'g' + str(uuid.uuid4())[:8]
groupname = "g" + str(uuid.uuid4())[:8]
# Validate that no group exists
with pytest.raises(KeyError):
@@ -83,8 +83,8 @@ def test_group_membership():
"""
Test group memberships can be added / removed
"""
username = 'u' + str(uuid.uuid4())[:8]
groupname = 'g' + str(uuid.uuid4())[:8]
username = "u" + str(uuid.uuid4())[:8]
groupname = "g" + str(uuid.uuid4())[:8]
# Validate that no group exists
with pytest.raises(KeyError):

View File

@@ -5,15 +5,15 @@ import logging
def test_run_subprocess_exception(mocker):
logger = logging.getLogger('tljh')
mocker.patch.object(logger, 'error')
logger = logging.getLogger("tljh")
mocker.patch.object(logger, "error")
with pytest.raises(subprocess.CalledProcessError):
utils.run_subprocess(['/bin/bash', '-c', 'echo error; exit 1'])
logger.error.assert_called_with('error\n')
utils.run_subprocess(["/bin/bash", "-c", "echo error; exit 1"])
logger.error.assert_called_with("error\n")
def test_run_subprocess(mocker):
logger = logging.getLogger('tljh')
mocker.patch.object(logger, 'debug')
utils.run_subprocess(['/bin/bash', '-c', 'echo success'])
logger.debug.assert_called_with('success\n')
logger = logging.getLogger("tljh")
mocker.patch.object(logger, "debug")
utils.run_subprocess(["/bin/bash", "-c", "echo success"])
logger.debug.assert_called_with("success\n")