diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 20:37:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 20:37:50 +0000 |
commit | c1f743ab2e4a7046d5500875a47d1f62c8624603 (patch) | |
tree | 709946d52f5f3bbaeb38be9e3f1d56d11f058237 /tests/integration/deckard/conftest.py | |
parent | Initial commit. (diff) | |
download | knot-resolver-c1f743ab2e4a7046d5500875a47d1f62c8624603.tar.xz knot-resolver-c1f743ab2e4a7046d5500875a47d1f62c8624603.zip |
Adding upstream version 5.7.1.upstream/5.7.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/integration/deckard/conftest.py')
-rw-r--r-- | tests/integration/deckard/conftest.py | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/tests/integration/deckard/conftest.py b/tests/integration/deckard/conftest.py new file mode 100644 index 0000000..8cf9004 --- /dev/null +++ b/tests/integration/deckard/conftest.py @@ -0,0 +1,126 @@ +import glob +import os +import re +from collections import namedtuple + +import pytest +import yaml + +from contrib.namespaces import LinuxNamespace + +Scenario = namedtuple("Scenario", ["path", "qmin", "config"]) + + +def config_sanity_check(config_dict, config_name): + """Checks if parsed configuration is valid""" + mandatory_keys = {'name', 'binary', 'templates', 'configs', 'additional'} + for cfg in config_dict['programs']: + missing_keys = mandatory_keys - set(cfg.keys()) + assert not missing_keys, 'Mandatory fields in configuration are missing: %s' % missing_keys + + # sanity check templates vs. configs + assert len(cfg['templates']) == len(cfg['configs']),\ + ('Number of jinja2 template files is not equal ' + 'to number of config files to be generated for ' + 'program "%s" (%s), i.e. len(templates) != len(configs)' + % (cfg['name'], config_name)) + + for additional in cfg["additional"]: + assert isinstance(additional, str),\ + "All additional arguments in yaml should be strings. (%s, %s)"\ + % (cfg['name'], config_name) + + +def get_qmin_config(path): + """Reads configuration from the *.rpl file and determines query-minimization setting.""" + with open(path) as f: + for line in f: + if re.search(r"^CONFIG_END", line) or re.search(r"^SCENARIO_BEGIN", line): + return None + if re.search(r"^\s*query-minimization:\s*(on|yes)", line): + return True + if re.search(r"^\s*query-minimization:\s*(off|no)", line): + return False + return None + + +def scenarios(paths, configs): + """Returns list of *.rpl files from given path and packs them with their minimization setting""" + + assert len(paths) == len(configs),\ + "Number of --config has to be equal to number of --scenarios arguments." + + scenario_list = [] + + for path, config in zip(paths, configs): + with open(config) as f: + config_dict = yaml.load(f, yaml.SafeLoader) + config_sanity_check(config_dict, config) + + if os.path.isfile(path): + filelist = [path] # path to single file, accept it + else: + filelist = sorted(glob.glob(os.path.join(path, "*.rpl"))) + + if not filelist: + raise ValueError('no *.rpl files found in path "{}"'.format(path)) + + for file in filelist: + scenario_list.append(Scenario(file, get_qmin_config(file), config_dict)) + + return scenario_list + + +def rpls(paths): + for path in paths: + if os.path.isfile(path): + filelist = [path] # path to single file, accept it + else: + filelist = sorted(glob.glob(os.path.join(path, "*.rpl"))) + + return filelist + + +def pytest_addoption(parser): + parser.addoption("--config", action="append", help="path to Deckard configuration .yaml file") + parser.addoption("--scenarios", action="append", help="directory with .rpl files") + parser.addoption("--retries", action="store", help=("number of retries per" + "test when Deckard is under load")) + + +def pytest_generate_tests(metafunc): + """This is pytest weirdness to parametrize the test over all the *.rpl files. + See https://docs.pytest.org/en/latest/parametrize.html#basic-pytest-generate-tests-example + for more info.""" + + if 'scenario' in metafunc.fixturenames: + if metafunc.config.option.config is None: + configs = [] + else: + configs = metafunc.config.option.config + + if metafunc.config.option.scenarios is None: + paths = ["sets/resolver"] * len(configs) + else: + paths = metafunc.config.option.scenarios + + metafunc.parametrize("scenario", scenarios(paths, configs), ids=str) + if 'rpl_path' in metafunc.fixturenames: + paths = metafunc.config.option.scenarios + metafunc.parametrize("rpl_path", rpls(paths), ids=str) + if 'max_retries' in metafunc.fixturenames: + max_retries = metafunc.config.option.retries + if max_retries is None: + max_retries = 3 + metafunc.parametrize("max_retries", [max_retries], ids=lambda id: "max-retries-"+str(id)) + + +def pytest_collection_modifyitems(items): + """We automatically mark test that need faking monotonic time and run them separately.""" + for item in items: + if "monotonic" in item.nodeid: + item.add_marker(pytest.mark.monotonic) + + +def pytest_runtest_setup(item): # pylint: disable=unused-argument + LinuxNamespace("user").__enter__() |