conftest.py
1 import re 2 import os 3 from typing import Optional 4 import pytest 5 6 7 def pytest_addoption(parser: pytest.Parser): 8 group = parser.getgroup("coreblocks") 9 group.addoption("--coreblocks-regression", action="store_true", help="Run also regression tests.") 10 group.addoption( 11 "--coreblocks-backend", 12 default="cocotb", 13 choices=["cocotb", "pysim"], 14 help="Simulation backend for regression tests", 15 ) 16 group.addoption("--coreblocks-traces", action="store_true", help="Generate traces from regression tests") 17 group.addoption("--coreblocks-profile", action="store_true", help="Write execution profiles") 18 group.addoption("--coreblocks-list", action="store_true", help="List all tests in flatten format.") 19 group.addoption( 20 "--coreblocks-test-name", 21 action="store", 22 type=str, 23 help="Name or regexp in flatten format matching the tests to run.", 24 ) 25 group.addoption( 26 "--coreblocks-test-count", 27 action="store", 28 type=int, 29 help="Number of tests to start. If less than number of all selected tests, then starts only subset of them.", 30 ) 31 group.addoption("--coreblocks-log-filter", default=".*", action="store", help="Regexp used to filter out logs.") 32 33 34 def generate_unittestname(item: pytest.Item) -> str: 35 full_name = ".".join(map(lambda s: s[:-3] if s[-3:] == ".py" else s, map(lambda x: x.name, item.listchain()))) 36 return full_name 37 38 39 def generate_test_cases_list(session: pytest.Session) -> list[str]: 40 tests_list = [] 41 for item in session.items: 42 full_name = generate_unittestname(item) 43 tests_list.append(full_name) 44 return tests_list 45 46 47 def pytest_collection_finish(session: pytest.Session): 48 if session.config.getoption("coreblocks_list"): 49 full_names = generate_test_cases_list(session) 50 for i in full_names: 51 print(i) 52 53 54 @pytest.hookimpl(tryfirst=True) 55 def pytest_runtestloop(session: pytest.Session) -> Optional[bool]: 56 if session.config.getoption("coreblocks_list"): 57 return True 58 return None 59 60 61 def deselect_based_on_flatten_name(items: list[pytest.Item], config: pytest.Config) -> None: 62 coreblocks_test_name = config.getoption("coreblocks_test_name") 63 if not isinstance(coreblocks_test_name, str): 64 return 65 66 deselected = [] 67 remaining = [] 68 regexp = re.compile(coreblocks_test_name) 69 for item in items: 70 full_name = generate_unittestname(item) 71 match = regexp.search(full_name) 72 if match is None: 73 deselected.append(item) 74 else: 75 remaining.append(item) 76 if deselected: 77 config.hook.pytest_deselected(items=deselected) 78 items[:] = remaining 79 80 81 def deselect_based_on_count(items: list[pytest.Item], config: pytest.Config) -> None: 82 coreblocks_test_count = config.getoption("coreblocks_test_count") 83 if not isinstance(coreblocks_test_count, int): 84 return 85 86 deselected = items[coreblocks_test_count:] 87 remaining = items[:coreblocks_test_count] 88 if deselected: 89 config.hook.pytest_deselected(items=deselected) 90 items[:] = remaining 91 92 93 def pytest_collection_modifyitems(items: list[pytest.Item], config: pytest.Config) -> None: 94 deselect_based_on_flatten_name(items, config) 95 deselect_based_on_count(items, config) 96 97 98 def pytest_runtest_setup(item: pytest.Item): 99 """ 100 This function is called to perform the setup phase for every test, so 101 it is a perfect moment to set environment variables. 102 """ 103 if item.config.getoption("--coreblocks-traces", False): # type: ignore 104 os.environ["__TRANSACTRON_DUMP_TRACES"] = "1" 105 106 if item.config.getoption("--coreblocks-profile", False): # type: ignore 107 os.environ["__TRANSACTRON_PROFILE"] = "1" 108 109 log_filter = item.config.getoption("--coreblocks-log-filter") 110 os.environ["__TRANSACTRON_LOG_FILTER"] = ".*" if not isinstance(log_filter, str) else log_filter 111 112 log_level = item.config.getoption("--log-level") 113 os.environ["__TRANSACTRON_LOG_LEVEL"] = "WARNING" if not isinstance(log_level, str) else log_level