You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
6.0 KiB
150 lines
6.0 KiB
# pylint: disable=redefined-outer-name
|
|
from copy import deepcopy
|
|
import pytest
|
|
import preserve
|
|
import configspec
|
|
|
|
|
|
@pytest.fixture
|
|
def example_spec():
|
|
confspec = configspec.ConfigSpecification()
|
|
confspec.add_spec("bool_a",
|
|
configspec.BoolSpec(False, False, "Bool A"))
|
|
confspec.add_spec("boollist_a",
|
|
configspec.BoolListSpec(False, False, "Bool A"))
|
|
confspec.add_spec("int_a",
|
|
configspec.IntSpec(0, -4, 4, False, "Int A"))
|
|
confspec.add_spec("intlist_a",
|
|
configspec.IntListSpec(0, -4, 4, False, "Int A"))
|
|
confspec.add_spec("string_a",
|
|
configspec.StringSpec("ThisIsAString", 4, 15, False, "String A"))
|
|
confspec.add_spec("stringlist_a",
|
|
configspec.StringListSpec("ThisIsAString", 4, 15, False, "String A"))
|
|
|
|
confdictspec = confspec.add_spec("dict_a",
|
|
configspec.DictSpec(None, False, "Dict A"))
|
|
confdictspec.add_spec("bool_b",
|
|
configspec.BoolSpec(False, False, "Bool B"))
|
|
confdictspec.add_spec("int_b",
|
|
configspec.IntSpec(0, -4, 4, False, "Int B"))
|
|
confdictspec.add_spec("string_b",
|
|
configspec.StringSpec("ThisIsAString", 4, 15, False, "String B"))
|
|
|
|
confdictlist = confspec.add_spec("dictlist_a",
|
|
configspec.DictListSpec(None, False, "List of Dicts B"))
|
|
confdictlist.add_spec("bool_c",
|
|
configspec.BoolSpec(False, False, "Bool C"))
|
|
confdictlist.add_spec("int_c",
|
|
configspec.IntSpec(0, -4, 4, False, "Int C"))
|
|
confdictlist.add_spec("string_c",
|
|
configspec.StringSpec("ThisIsAString", 4, 15, False, "String C"))
|
|
|
|
return confspec
|
|
|
|
|
|
@pytest.fixture
|
|
def example_values():
|
|
vals = {'bool_a': True,
|
|
'boollist_a': [False, True],
|
|
'int_a': 1,
|
|
'intlist_a': [1, 2, 3, 4],
|
|
'string_a': 'sometext',
|
|
'stringlist_a': ['somemoretext', 'yetmoretext'],
|
|
'dict_a': {
|
|
'bool_b': False,
|
|
'int_b': 0,
|
|
'string_b': 'texttesttext'},
|
|
'dictlist_a': [{'bool_c': False,
|
|
'int_c': 0,
|
|
'string_c': 'string1'},
|
|
{'bool_c': False,
|
|
'int_c': 0,
|
|
'string_c': 'string2'}]}
|
|
|
|
return vals
|
|
|
|
|
|
def test_addspec(example_spec):
|
|
confspec = configspec.ConfigSpecification()
|
|
confspec.add_specs([
|
|
("bool_a", configspec.BoolSpec(False, False, "Bool A")),
|
|
("boollist_a", configspec.BoolListSpec(False, False, "Bool A")),
|
|
("int_a", configspec.IntSpec(0, -4, 4, False, "Int A")),
|
|
("intlist_a", configspec.IntListSpec(0, -4, 4, False, "Int A")),
|
|
("string_a", configspec.StringSpec("ThisIsAString", 4, 15, False, "String A")),
|
|
("stringlist_a", configspec.StringListSpec("ThisIsAString", 4, 15, False, "String A"))
|
|
])
|
|
|
|
confdictspec = confspec.add_spec("dict_a", configspec.DictSpec(None, False, "Dict A"))
|
|
|
|
confdictspec.add_specs([
|
|
("bool_b", configspec.BoolSpec(False, False, "Bool B")),
|
|
("int_b", configspec.IntSpec(0, -4, 4, False, "Int B")),
|
|
("string_b", configspec.StringSpec("ThisIsAString", 4, 15, False, "String B"))
|
|
])
|
|
|
|
confdictlist = confspec.add_spec("dictlist_a",
|
|
configspec.DictListSpec(None, False, "List of Dicts B"))
|
|
|
|
confdictlist.add_specs([
|
|
("bool_c", configspec.BoolSpec(False, False, "Bool C")),
|
|
("int_c", configspec.IntSpec(0, -4, 4, False, "Int C")),
|
|
("string_c", configspec.StringSpec("ThisIsAString", 4, 15, False, "String C"))
|
|
])
|
|
|
|
# Preserve to be able to directly compare resulting confspec structure
|
|
assert preserve.preserve(example_spec) == preserve.preserve(confspec)
|
|
|
|
|
|
def test_config_validate(example_spec, example_values):
|
|
spec = example_spec
|
|
spec.validate(example_values)
|
|
|
|
|
|
def test_invalid_bool():
|
|
spec = configspec.BoolSpec()
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be a boolean"):
|
|
spec.validate("false")
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be a boolean"):
|
|
spec.validate(None)
|
|
|
|
|
|
def test_invalid_int():
|
|
spec = configspec.IntSpec(minval=-4, maxval=4)
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be >="):
|
|
spec.validate(-5)
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be <="):
|
|
spec.validate(5)
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be an integer"):
|
|
spec.validate("5")
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be an integer"):
|
|
spec.validate(None)
|
|
|
|
|
|
def test_invalid_string():
|
|
spec = configspec.StringSpec(minlength=4, maxlength=15)
|
|
with pytest.raises(configspec.InvalidConfigError, match="string length must be >="):
|
|
spec.validate("123")
|
|
with pytest.raises(configspec.InvalidConfigError, match="string length must be <="):
|
|
spec.validate("1234567890abcdef")
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be a string"):
|
|
spec.validate(1)
|
|
with pytest.raises(configspec.InvalidConfigError, match="value must be a string"):
|
|
spec.validate(None)
|
|
|
|
|
|
def test_man(example_spec, example_values):
|
|
confman = configspec.ConfigManager()
|
|
confman.add_confspec("test_bundle", example_spec)
|
|
confman.load({"test_bundle": example_values})
|
|
assert confman.get_config_bundle("test_bundle") == example_values
|
|
|
|
confman.freeze_value("test_bundle", "int_a")
|
|
newvals = deepcopy(example_values)
|
|
newvals["int_a"] = 4
|
|
|
|
confman.load({"test_bundle": newvals})
|
|
assert confman.get_config_bundle("test_bundle") == example_values
|
|
confman.load_overlay({"test_bundle": {"string_a": "new text"}})
|
|
assert confman.get_config_bundle("test_bundle")["string_a"] == "new text"
|