Files
the-littlest-jupyterhub/tests/test_config.py
Min RK a4427068cc tests and fixes in tljh-config
- add remove-item to cli
- fix setting non-string values (int, bool, float)
- show help when no action is given
- test coverage for cli
2018-07-31 13:25:30 +02:00

224 lines
5.2 KiB
Python

"""
Test configuration commandline tools
"""
from importlib import reload
import os
import tempfile
from unittest import mock
import pytest
from tljh import config, configurer
@pytest.fixture
def tljh_dir(tmpdir):
"""Fixture for setting up a temporary tljh dir"""
tljh_dir = str(tmpdir.join("tljh").mkdir())
with mock.patch.dict(
os.environ,
{"TLJH_INSTALL_PREFIX": tljh_dir}
):
reload(config)
reload(configurer)
assert config.INSTALL_PREFIX == tljh_dir
os.makedirs(config.STATE_DIR)
yield tljh_dir
def test_set_no_mutate():
conf = {}
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'
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'
}
def test_set_overwrite():
"""
We can overwrite already existing config items.
This might be surprising destructive behavior to some :D
"""
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(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'}
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']}
}
def test_add_to_config_zero_level():
conf = {}
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(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.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')
with pytest.raises(ValueError):
config.remove_item_from_config({'a': 'b'}, 'a.b', 'e')
with pytest.raises(ValueError):
config.remove_item_from_config({'a': ['b']}, 'a', 'e')
def test_reload_hub():
with mock.patch('tljh.systemd.restart_service') as restart_service:
config.reload_component('hub')
assert restart_service.called_with('jupyterhub')
def test_reload_proxy(tljh_dir):
with mock.patch('tljh.systemd.restart_service') as restart_service:
config.reload_component('proxy')
assert restart_service.called_with('configurable-http-proxy')
assert restart_service.called_with('traefik')
assert os.path.exists(os.path.join(config.STATE_DIR, 'traefik.toml'))
def test_cli_no_command(capsys):
config.main([])
captured = capsys.readouterr()
assert "usage:" in captured.out
assert "positional arguments:" in captured.out
@pytest.mark.parametrize(
"arg, value",
[
("true", True),
("FALSE", False),
],
)
def test_cli_set_bool(tljh_dir, arg, value):
config.main(["set", "https.enabled", arg])
cfg = configurer.load_config()
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
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]
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]
config.main(["remove-item", "foo.bar", "1"])
cfg = configurer.load_config()
assert cfg['foo']['bar'] == [2]
@pytest.mark.parametrize(
"value, expected",
[
("1", 1),
("1.25", 1.25),
("x", "x"),
("1x", "1x"),
("1.2x", "1.2x"),
(None, None),
("", ""),
],
)
def test_parse_value(value, expected):
assert config.parse_value(value) == expected
def test_show_config(capsys):
"""
Test stdout output when showing config
"""
conf = """
# Just some test YAML
a:
b:
- h
- 1
""".strip()
with tempfile.NamedTemporaryFile() as tmp:
tmp.write(conf.encode())
tmp.flush()
config.show_config(tmp.name)
out = capsys.readouterr().out
assert out.strip() == conf