|
| 1 | +import logging |
| 2 | + |
| 3 | +import pytest |
| 4 | +from pytest import CollectReport, StashKey |
| 5 | + |
| 6 | +_phase_report_key = StashKey[dict[str, CollectReport]]() |
| 7 | +_pm_logger = logging.getLogger("post-mortem") |
| 8 | + |
| 9 | + |
| 10 | +@pytest.hookimpl(wrapper=True, tryfirst=True) |
| 11 | +def pytest_runtest_makereport(item: pytest.Item, call: pytest.CallInfo[None]): |
| 12 | + """ |
| 13 | + Make the report for a step available in the item's stash, so that |
| 14 | + fixtures can read the result in their teardown phase. |
| 15 | + Heavily inspired by: https://docs.pytest.org/en/latest/example/simple.html#making-test-result-information-available-in-fixtures |
| 16 | + Implements the runtest_makereport-hook: https://docs.pytest.org/en/latest/reference/reference.html#std-hook-pytest_runtest_makereport |
| 17 | +
|
| 18 | + :param item: The item the report is generated for. |
| 19 | + :param call: CallInfo for this phase |
| 20 | + :return: The report re received from the previous hook. |
| 21 | + """ |
| 22 | + rep = yield |
| 23 | + |
| 24 | + # store test results for each phase of a call, which can |
| 25 | + # be "setup", "call", "teardown" |
| 26 | + item.stash.setdefault(_phase_report_key, {})[rep.when] = rep |
| 27 | + return rep |
| 28 | + |
| 29 | + |
| 30 | +@pytest.fixture(autouse=True) |
| 31 | +def pm_system(request: pytest.FixtureRequest, strategy, record_property): |
| 32 | + """ |
| 33 | + Retrieves post-mortem diagnosis information from the strategy and emits the information to the log with level |
| 34 | + WARNING and also adds the information to the `junit.xml`. |
| 35 | +
|
| 36 | + The strategy must implement a strategy.postmotem_info(). |
| 37 | + It is up to the strategy to decide which information to collect depending on the DUTs status and the connections |
| 38 | + available (e.g. serial or ssh). |
| 39 | + """ |
| 40 | + yield |
| 41 | + |
| 42 | + report = request.node.stash[_phase_report_key] |
| 43 | + if "call" in report and report["call"].failed: |
| 44 | + post_mortem_info: dict[str, list[str]] = strategy.postmortem_info() |
| 45 | + record_property("postmortem", post_mortem_info) |
| 46 | + for key, value in post_mortem_info.items(): |
| 47 | + _pm_logger.warning(f"POST-MORTEM INFO: {key}") |
| 48 | + for line in value: |
| 49 | + _pm_logger.warning(f"| {line}") |
0 commit comments