Skip to content
This repository was archived by the owner on Aug 13, 2025. It is now read-only.

Commit b5c7ccf

Browse files
committed
Ensure tempdir is kept for failed system tests
The temporary directory contains artifacts for the pytest module. That module may contain multiple individual tests which were executed sequentially. The artifacts should be kept if even one of these tests failed. Since pytest doesn't have any facility to expose test results to fixtures, customize the pytest_runtest_makereport() hook to enable that. It stores the test results into a session scope variable which is available in all fixtures. When deciding whether to remove the temporary directory, find the relevant test results for this module and don't remove the tmpdir if any one the tests failed.
1 parent ec1809e commit b5c7ccf

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

bin/tests/system/conftest.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,27 @@ def pytest_configure():
142142
raise exc
143143
logging.debug(proc.stdout)
144144

145+
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
146+
def pytest_runtest_makereport(item):
147+
"""Hook that is used to expose test results to session (for use in fixtures)."""
148+
# execute all other hooks to obtain the report object
149+
outcome = yield
150+
report = outcome.get_result()
151+
152+
# Set the test outcome in session, so we can access it from module-level
153+
# fixture using nodeid. Note that this hook is called three times: for
154+
# setup, call and teardown. We only care about the overall result so we
155+
# merge the results together and preserve the information whether a test
156+
# passed.
157+
test_results = {}
158+
try:
159+
test_results = getattr(item.session, "test_results")
160+
except AttributeError:
161+
setattr(item.session, "test_results", test_results)
162+
node_result = test_results.get(item.nodeid)
163+
if node_result is None or report.outcome != "passed":
164+
test_results[item.nodeid] = report.outcome
165+
145166
# --------------------------- Fixtures -----------------------------------
146167

147168
@pytest.fixture(scope="session")
@@ -240,6 +261,25 @@ def system_test_dir(request, env, system_test_name, logger):
240261
FUTURE: This removes the need to have clean.sh scripts.
241262
"""
242263

264+
def get_test_result():
265+
"""Aggregate test results from all individual tests from this module
266+
into a single result: failed > skipped > passed."""
267+
test_results = {
268+
node.nodeid: request.session.test_results[node.nodeid]
269+
for node in request.node.collect()
270+
if node.nodeid in request.session.test_results
271+
}
272+
logger.debug(test_results)
273+
assert len(test_results)
274+
failed = any(res == "failed" for res in test_results.values())
275+
skipped = any(res == "skipped" for res in test_results.values())
276+
if failed:
277+
return "failed"
278+
if skipped:
279+
return "skipped"
280+
assert all(res == "passed" for res in test_results.values())
281+
return "passed"
282+
243283
# Create a temporary directory with a copy of the original system test dir contents
244284
system_test_root = Path(f"{env['TOP_BUILDDIR']}/bin/tests/system")
245285
testdir = Path(
@@ -266,9 +306,13 @@ def system_test_dir(request, env, system_test_name, logger):
266306
os.chdir(old_cwd)
267307
logger.debug("changed workdir to: %s", old_cwd)
268308

309+
result = get_test_result()
310+
269311
# Clean temporary dir unless it should be kept
270312
if request.config.getoption("--noclean"):
271313
logger.debug("--noclean requested, keeping temporary directory")
314+
elif result == "failed":
315+
logger.debug("test failure detected, keeping temporary directory")
272316
else:
273317
logger.debug("deleting temporary directory")
274318
shutil.rmtree(testdir)

0 commit comments

Comments
 (0)