/ test / conftest.py
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