freebsd-dev/tests/conftest.py
Alexander V. Chernikov 8eb2bee6c0 testing: Add basic atf support to pytest.
Implementation consists of the pytest plugin implementing ATF format and
a simple C++ wrapper, which reorders the provided arguments from ATF format
to the format understandable by pytest. Each test has this wrapper specified
after the shebang. When kyua executes the test, wrapper calls pytest, which
loads atf plugin, does the work and returns the result. Additionally, a
separate python "package", `/usr/tests/atf_python` has been added to collect
code that may be useful across different tests.

Current limitations:
* Opaque metadata passing via X-Name properties. Require some fixtures to write
* `-s srcdir` parameter passed by the runner is ignored.
* No `atf-c-api(3)` or similar - relying on pytest framework & existing python libraries
* No support for `atf_tc_<get|has>_config_var()` & `atf_tc_set_md_var()`.
 Can be probably implemented with env variables & autoload fixtures

Differential Revision: https://reviews.freebsd.org/D31084
Reviewed by:	kp, ngie
2022-06-25 19:25:15 +00:00

122 lines
3.6 KiB
Python

import pytest
from atf_python.atf_pytest import ATFHandler
PLUGIN_ENABLED = False
DEFAULT_HANDLER = None
def get_handler():
global DEFAULT_HANDLER
if DEFAULT_HANDLER is None:
DEFAULT_HANDLER = ATFHandler()
return DEFAULT_HANDLER
def pytest_addoption(parser):
"""Add file output"""
# Add meta-values
group = parser.getgroup("general", "Running and selection options")
group.addoption("--atf-var", dest="atf_vars", action="append", default=[])
group.addoption(
"--atf-source-dir",
type=str,
dest="atf_source_dir",
help="Path to the test source directory",
)
group.addoption(
"--atf-cleanup",
default=False,
action="store_true",
dest="atf_cleanup",
help="Call cleanup procedure for a given test",
)
group = parser.getgroup("terminal reporting", "reporting", after="general")
group.addoption(
"--atf",
default=False,
action="store_true",
help="Enable test listing/results output in atf format",
)
group.addoption(
"--atf-file",
type=str,
dest="atf_file",
help="Path to the status file provided by atf runtime",
)
@pytest.mark.trylast
def pytest_configure(config):
if config.option.help:
return
# Register markings anyway to avoid warnings
config.addinivalue_line("markers", "require_user(name): user to run the test with")
config.addinivalue_line(
"markers", "require_arch(names): List[str] of support archs"
)
# config.addinivalue_line("markers", "require_config(config): List[Tuple[str,Any]] of k=v pairs")
config.addinivalue_line(
"markers", "require_diskspace(amount): str with required diskspace"
)
config.addinivalue_line(
"markers", "require_files(space): List[str] with file paths"
)
config.addinivalue_line(
"markers", "require_machine(names): List[str] of support machine types"
)
config.addinivalue_line(
"markers", "require_memory(amount): str with required memory"
)
config.addinivalue_line(
"markers", "require_progs(space): List[str] with file paths"
)
config.addinivalue_line(
"markers", "timeout(dur): int/float with max duration in sec"
)
global PLUGIN_ENABLED
PLUGIN_ENABLED = config.option.atf
if not PLUGIN_ENABLED:
return
get_handler()
if config.option.collectonly:
# Need to output list of tests to stdout, hence override
# standard reporter plugin
reporter = config.pluginmanager.getplugin("terminalreporter")
if reporter:
config.pluginmanager.unregister(reporter)
def pytest_collection_modifyitems(session, config, items):
"""If cleanup is requested, replace collected tests with their cleanups (if any)"""
if PLUGIN_ENABLED and config.option.atf_cleanup:
new_items = []
handler = get_handler()
for obj in items:
if handler.has_object_cleanup(obj):
handler.override_runtest(obj)
new_items.append(obj)
items.clear()
items.extend(new_items)
def pytest_collection_finish(session):
if PLUGIN_ENABLED and session.config.option.collectonly:
handler = get_handler()
handler.list_tests(session.items)
def pytest_runtest_logreport(report):
if PLUGIN_ENABLED:
handler = get_handler()
handler.add_report(report)
def pytest_unconfigure(config):
if PLUGIN_ENABLED and config.option.atf_file:
handler = get_handler()
handler.write_report(config.option.atf_file)