| # Copyright 2023 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| import os |
| from pathlib import Path |
| import pytest |
| import shutil |
| |
| ARTIFACT_DIR_KEY = pytest.StashKey[Path]() |
| TEST_DIR_KEY = pytest.StashKey[Path]() |
| MAX_PATHLENGTH = os.pathconf("/", "PC_NAME_MAX") |
| |
| |
| def pytest_addoption(parser, pluginmanager) -> None: |
| parser.addoption( |
| "--openxla-pjrt-artifact-dir", |
| dest="OPENXLA_PJRT_ARTIFACT_DIR", |
| help="Saves OpenXLA PJRT compilation artifacts", |
| ) |
| |
| |
| def pytest_sessionstart(session: pytest.Session) -> None: |
| artifact_dir = session.config.getoption("OPENXLA_PJRT_ARTIFACT_DIR") |
| session.stash[ARTIFACT_DIR_KEY] = Path(artifact_dir) |
| |
| |
| def pytest_runtest_setup(item: pytest.Item) -> None: |
| artifact_dir = item.session.stash[ARTIFACT_DIR_KEY] |
| if artifact_dir is None: |
| return |
| sanitized_name = ( |
| item.nodeid.replace(".py::", "::").replace("/", "_").replace("::", "__") |
| ) |
| |
| test_dir = artifact_dir / sanitized_name |
| if len(sanitized_name) > MAX_PATHLENGTH: |
| test_dir = artifact_dir / str(hash(sanitized_name)) |
| else: |
| test_dir = artifact_dir / sanitized_name |
| |
| shutil.rmtree(test_dir, ignore_errors=True) |
| test_dir.mkdir(parents=True, exist_ok=True) |
| item.stash[TEST_DIR_KEY] = test_dir |
| os.putenv("IREE_PJRT_SAVE_ARTIFACTS", str(test_dir)) |
| with open(test_dir / "NAME", "wt") as f: |
| f.write(sanitized_name) |
| |
| with open(test_dir / "CRASH_MARKER", "wt") as f: |
| f.write("If this file exists, the test crashed or was killed") |
| |
| |
| @pytest.hookimpl(hookwrapper=True) |
| def pytest_runtest_makereport(item, call): |
| outcome = yield |
| test_dir = item.stash[TEST_DIR_KEY] |
| if test_dir is None: |
| return |
| |
| result = outcome.get_result() |
| |
| if call.when == "call" and result.failed: |
| with open(test_dir / "error.txt", "wt") as f: |
| f.write(result.longreprtext) |
| f.write("\n\nSTDERR:\n-------\n") |
| f.write(result.capstderr) |
| f.write("\n\nLOG:\n----\n") |
| f.write(result.caplog) |
| f.write("\n\nSTDOUT:\n-------\n") |
| f.write(result.capstdout) |
| |
| |
| def pytest_runtest_teardown(item: pytest.Item) -> None: |
| test_dir = item.stash[TEST_DIR_KEY] |
| if test_dir is None: |
| return |
| dir_entries = list(test_dir.iterdir()) |
| crash_marker = test_dir / "CRASH_MARKER" |
| if crash_marker.is_file(): |
| crash_marker.unlink() |
| if not dir_entries: |
| # Remove empty directories on success. |
| test_dir.rmdir() |