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_collection_modifyitems(session, config, items): 103 """If cleanup is requested, replace collected tests with their cleanups (if any)""" 104 if PLUGIN_ENABLED and config.option.atf_cleanup: 105 new_items = [] 106 handler = get_handler() 107 for obj in items: 108 if handler.has_object_cleanup(obj): 109 handler.override_runtest(obj) 110 new_items.append(obj) 111 items.clear() 112 items.extend(new_items) 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