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