2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

Ensure pytest runner get proper outcome from flaky reruns

When a test is re-run by the flaky plugin, the TestReport outcomes
collected in the pytest_runtest_makereport() hook should be overriden.
Each of the setup/call/teardown phases is reported again and since we
care about the overall outcome, their respective results should be
overriden so that only the outcome from the final test (re)run gets
reported.

Prior to this change, it lead to a situation where an extra_artifact
generated during the test might be ignored. This was caused because the
check was skipped, since the test was incorrectly considered as "failed"
in the case where the test would fail on the first run, but pass on a
subsequent flaky rerun.
This commit is contained in:
Nicki Křížek
2024-11-12 10:07:02 +01:00
parent a10d78db55
commit b66fb31dcb

View File

@@ -134,16 +134,25 @@ def pytest_collection_modifyitems(items):
class NodeResult: class NodeResult:
def __init__(self, report=None): def __init__(self, report=None):
self.outcome = None self._outcomes = {}
self.messages = [] self.messages = {}
if report is not None: if report is not None:
self.update(report) self.update(report)
def update(self, report): def update(self, report):
if self.outcome is None or report.outcome != "passed": # Allow the same nodeid/when to be overriden. This only happens when
self.outcome = report.outcome # the test is re-run with flaky plugin. In that case, we want the
if report.longreprtext: # latest result to override any previous results.
self.messages.append(report.longreprtext) key = (report.nodeid, report.when)
self._outcomes[key] = report.outcome
self.messages[key] = report.longreprtext
@property
def outcome(self):
for outcome in self._outcomes.values():
if outcome != "passed":
return outcome
return "passed"
@pytest.hookimpl(tryfirst=True, hookwrapper=True) @pytest.hookimpl(tryfirst=True, hookwrapper=True)
@@ -347,7 +356,7 @@ def system_test_dir(request, system_test_name, expected_artifacts):
messages = [] messages = []
for node, result in test_results.items(): for node, result in test_results.items():
isctest.log.debug("%s %s", result.outcome.upper(), node) isctest.log.debug("%s %s", result.outcome.upper(), node)
messages.extend(result.messages) messages.extend(result.messages.values())
for message in messages: for message in messages:
isctest.log.debug("\n" + message) isctest.log.debug("\n" + message)
failed = any(res.outcome == "failed" for res in test_results.values()) failed = any(res.outcome == "failed" for res in test_results.values())