diff options
author | Andrei Zeliankou <zelenkov@nginx.com> | 2023-06-12 14:16:59 +0100 |
---|---|---|
committer | Andrei Zeliankou <zelenkov@nginx.com> | 2023-06-12 14:16:59 +0100 |
commit | ce2405ec3dd97e8bdf8f63312e3c6ce59ef562d4 (patch) | |
tree | 818e60eb10d7f2be90f25003b3a2b347314e966f /test/conftest.py | |
parent | a3b9b49cfb091410ca8f3c8d9df24d1fe184f8e0 (diff) | |
download | unit-ce2405ec3dd97e8bdf8f63312e3c6ce59ef562d4.tar.gz unit-ce2405ec3dd97e8bdf8f63312e3c6ce59ef562d4.tar.bz2 |
Tests: prerequisites checking reworked.
Prerequisites check moved to the module level to simplify class structure.
Discovery and prerequisites checks functions moved to the separate files.
Introduced "require" fixture to provide per-test requirements check.
Diffstat (limited to 'test/conftest.py')
-rw-r--r-- | test/conftest.py | 154 |
1 files changed, 47 insertions, 107 deletions
diff --git a/test/conftest.py b/test/conftest.py index 84902dc2..4487f059 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -13,14 +13,8 @@ import time from multiprocessing import Process import pytest -from unit.check.chroot import check_chroot -from unit.check.go import check_go -from unit.check.isolation import check_isolation -from unit.check.njs import check_njs -from unit.check.node import check_node -from unit.check.regex import check_regex -from unit.check.tls import check_openssl -from unit.check.unix_abstract import check_unix_abstract +from unit.check.discover_available import discover_available +from unit.check.check_prerequisites import check_prerequisites from unit.http import TestHTTP from unit.log import Log from unit.log import print_log_on_assert @@ -130,6 +124,9 @@ def pytest_generate_tests(metafunc): type = cls.application_type def generate_tests(versions): + if not versions: + pytest.skip('no available module versions') + metafunc.fixturenames.append('tmp_ct') metafunc.parametrize('tmp_ct', versions) @@ -140,75 +137,43 @@ def pytest_generate_tests(metafunc): # take available module from option and generate tests for each version - for module, prereq_version in cls.prerequisites['modules'].items(): - if module in option.available['modules']: - available_versions = option.available['modules'][module] + available_modules = option.available['modules'] + + for module, version in metafunc.module.prerequisites['modules'].items(): + if module in available_modules and available_modules[module]: + available_versions = available_modules[module] - if prereq_version == 'all': + if version == 'all': generate_tests(available_versions) - elif prereq_version == 'any': + elif version == 'any': option.generated_tests[ metafunc.function.__name__ ] = f'{type} {available_versions[0]}' - elif callable(prereq_version): - generate_tests(list(filter(prereq_version, available_versions))) + elif callable(version): + generate_tests(list(filter(version, available_versions))) else: raise ValueError( f''' -Unexpected prerequisite version "{prereq_version}" for module "{module}" in -{cls}. 'all', 'any' or callable expected.''' +Unexpected prerequisite version "{version}" for module "{module}". +'all', 'any' or callable expected.''' ) def pytest_sessionstart(): - option.available = {'modules': {}, 'features': {}} - unit = unit_run() - output_version = subprocess.check_output( - [unit['unitd'], '--version'], stderr=subprocess.STDOUT - ).decode() - - if not _wait_for_record(r'controller started'): - Log.print_log() - exit("Unit is writing log too long") - - # discover available modules from unit.log - - for module in re.findall( - r'module: ([a-zA-Z]+) (.*) ".*"$', Log.read(), re.M - ): - versions = option.available['modules'].setdefault(module[0], []) - if module[1] not in versions: - versions.append(module[1]) - - # discover modules from check - option.available['modules']['go'] = check_go() - option.available['modules']['njs'] = check_njs(output_version) - option.available['modules']['node'] = check_node(option.current_dir) - option.available['modules']['openssl'] = check_openssl(output_version) - option.available['modules']['regex'] = check_regex(output_version) + discover_available(unit) - # remove None values - - option.available['modules'] = { - k: v for k, v in option.available['modules'].items() if v is not None - } - - check_chroot() - check_isolation() - check_unix_abstract() - - _clear_conf(f'{unit["temp_dir"]}/control.unit.sock') + _clear_conf() unit_stop() Log.check_alerts() if option.restart: - shutil.rmtree(unit_instance['temp_dir']) + shutil.rmtree(unit['temp_dir']) else: _clear_temp_dir() @@ -225,38 +190,10 @@ def pytest_runtest_makereport(item): setattr(item, f'rep_{rep.when}', rep) -@pytest.fixture(scope='class', autouse=True) -def check_prerequisites(request): - cls = request.cls - missed = [] - - # check modules - - if 'modules' in cls.prerequisites: - available_modules = list(option.available['modules'].keys()) - - for module in cls.prerequisites['modules']: - if module in available_modules: - continue - - missed.append(module) - - if missed: - pytest.skip(f'Unit has no {", ".join(missed)} module(s)') - - # check features - - if 'features' in cls.prerequisites: - available_features = list(option.available['features'].keys()) - - for feature in cls.prerequisites['features']: - if feature in available_features: - continue - - missed.append(feature) - - if missed: - pytest.skip(f'{", ".join(missed)} feature(s) not supported') +@pytest.fixture(scope='module', autouse=True) +def check_prerequisites_module(request): + if hasattr(request.module, 'prerequisites'): + check_prerequisites(request.module.prerequisites) @pytest.fixture(autouse=True) @@ -283,7 +220,7 @@ def run(request): # prepare log - with Log.open(encoding='utf-8') as f: + with Log.open() as f: log = f.read() Log.set_pos(f.tell()) @@ -294,7 +231,7 @@ def run(request): # clean temp_dir before the next test if not option.restart: - _clear_conf(f'{unit["temp_dir"]}/control.unit.sock', log=log) + _clear_conf(log=log) _clear_temp_dir() # check descriptors @@ -384,7 +321,7 @@ def unit_run(state_dir=None): unit_instance['pid'] = f.read().rstrip() if state_dir is None: - _clear_conf(control_sock) + _clear_conf() _fds_info['main']['fds'] = _count_fds(unit_instance['pid']) @@ -440,7 +377,9 @@ def unit_stop(): @print_log_on_assert -def _clear_conf(sock, *, log=None): +def _clear_conf(*, log=None): + sock = unit_instance['control_sock'] + resp = http.put( url='/config', sock_type='unix', @@ -456,7 +395,10 @@ def _clear_conf(sock, *, log=None): def delete(url): return http.delete(url=url, sock_type='unix', addr=sock)['body'] - if 'openssl' in option.available['modules']: + if ( + 'openssl' in option.available['modules'] + and option.available['modules']['openssl'] + ): try: certs = json.loads(get('/certificates')).keys() @@ -466,7 +408,10 @@ def _clear_conf(sock, *, log=None): for cert in certs: assert 'success' in delete(f'/certificates/{cert}'), 'delete cert' - if 'njs' in option.available['modules']: + if ( + 'njs' in option.available['modules'] + and option.available['modules']['njs'] + ): try: scripts = json.loads(get('/js_modules')).keys() @@ -621,19 +566,6 @@ def _count_fds(pid): return 0 -def _wait_for_record(pattern, name='unit.log', wait=150, flags=re.M): - with Log.open(name) as file: - for _ in range(wait): - found = re.search(pattern, file.read(), flags) - - if found is not None: - break - - time.sleep(0.1) - - return found - - def run_process(target, *args): global _processes @@ -696,8 +628,8 @@ def date_to_sec_epoch(): @pytest.fixture def findall(): - def _findall(pattern, name='unit.log', flags=re.M): - return re.findall(pattern, Log.read(name), flags) + def _findall(*args, **kwargs): + return Log.findall(*args, **kwargs) return _findall @@ -713,6 +645,11 @@ def is_unsafe(request): @pytest.fixture +def require(): + return check_prerequisites + + +@pytest.fixture def search_in_file(): def _search_in_file(pattern, name='unit.log', flags=re.M): return re.search(pattern, Log.read(name), flags) @@ -760,4 +697,7 @@ def unit_pid(): @pytest.fixture def wait_for_record(): + def _wait_for_record(*args, **kwargs): + return Log.wait_for_record(*args, **kwargs) + return _wait_for_record |