xref: /freebsd/tests/conftest.py (revision a0b956f5ac5e0941f9e74e24c1c53e05ad061a38)
1import pytest
2from atf_python.atf_pytest import ATFHandler
3from typing import Dict
4
5
6PLUGIN_ENABLED = False
7DEFAULT_HANDLER = None
8
9
10def get_handler():
11    global DEFAULT_HANDLER
12    if DEFAULT_HANDLER is None:
13        DEFAULT_HANDLER = ATFHandler()
14    return DEFAULT_HANDLER
15
16
17def pytest_addoption(parser):
18    """Add file output"""
19    # Add meta-values
20    group = parser.getgroup("general", "Running and selection options")
21    group.addoption(
22        "--atf-source-dir",
23        type=str,
24        dest="atf_source_dir",
25        help="Path to the test source directory",
26    )
27    group.addoption(
28        "--atf-cleanup",
29        default=False,
30        action="store_true",
31        dest="atf_cleanup",
32        help="Call cleanup procedure for a given test",
33    )
34    group = parser.getgroup("terminal reporting", "reporting", after="general")
35    group.addoption(
36        "--atf",
37        default=False,
38        action="store_true",
39        help="Enable test listing/results output in atf format",
40    )
41    group.addoption(
42        "--atf-file",
43        type=str,
44        dest="atf_file",
45        help="Path to the status file provided by atf runtime",
46    )
47
48
49@pytest.fixture(autouse=True, scope="session")
50def atf_vars() -> Dict[str, str]:
51    return ATFHandler.get_atf_vars()
52
53
54@pytest.mark.trylast
55def pytest_configure(config):
56    if config.option.help:
57        return
58
59    # Register markings anyway to avoid warnings
60    config.addinivalue_line("markers", "require_user(name): user to run the test with")
61    config.addinivalue_line(
62        "markers", "require_arch(names): List[str] of support archs"
63    )
64    # config.addinivalue_line("markers", "require_config(config): List[Tuple[str,Any]] of k=v pairs")
65    config.addinivalue_line(
66        "markers", "require_diskspace(amount): str with required diskspace"
67    )
68    config.addinivalue_line(
69        "markers", "require_files(space): List[str] with file paths"
70    )
71    config.addinivalue_line(
72        "markers", "require_machine(names): List[str] of support machine types"
73    )
74    config.addinivalue_line(
75        "markers", "require_memory(amount): str with required memory"
76    )
77    config.addinivalue_line(
78        "markers", "require_progs(space): List[str] with file paths"
79    )
80    config.addinivalue_line(
81        "markers", "timeout(dur): int/float with max duration in sec"
82    )
83
84    global PLUGIN_ENABLED
85    PLUGIN_ENABLED = config.option.atf
86    if not PLUGIN_ENABLED:
87        return
88    get_handler()
89
90    if config.option.collectonly:
91        # Need to output list of tests to stdout, hence override
92        # standard reporter plugin
93        reporter = config.pluginmanager.getplugin("terminalreporter")
94        if reporter:
95            config.pluginmanager.unregister(reporter)
96
97
98def pytest_collection_modifyitems(session, config, items):
99    """If cleanup is requested, replace collected tests with their cleanups (if any)"""
100    if PLUGIN_ENABLED and config.option.atf_cleanup:
101        new_items = []
102        handler = get_handler()
103        for obj in items:
104            if handler.has_object_cleanup(obj):
105                handler.override_runtest(obj)
106                new_items.append(obj)
107        items.clear()
108        items.extend(new_items)
109
110
111def pytest_collection_finish(session):
112    if PLUGIN_ENABLED and session.config.option.collectonly:
113        handler = get_handler()
114        handler.list_tests(session.items)
115
116
117def pytest_runtest_logreport(report):
118    if PLUGIN_ENABLED:
119        handler = get_handler()
120        handler.add_report(report)
121
122
123def pytest_unconfigure(config):
124    if PLUGIN_ENABLED and config.option.atf_file:
125        handler = get_handler()
126        handler.write_report(config.option.atf_file)
127