47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
from functools import wraps
|
|
from pathlib import Path
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
from byteb4rb1e.testing.pytest import get_current_test
|
|
|
|
|
|
def run_in_subprocess_once():
|
|
"""
|
|
A decorator that reruns th test in a subprocess if not already inside one.
|
|
Requires pytest to be installed and test to be run by pytest.
|
|
|
|
For what? Anything that can't be done in a thread-safe manner, e.g. modifying PYTHON_PATH
|
|
"""
|
|
def decorator(test_func):
|
|
@wraps(test_func)
|
|
def wrapper(*args, **kwargs):
|
|
if os.environ.get("XPYTEST_INSIDE_SUBPROCESS") == "1":
|
|
return test_func(*args, **kwargs)
|
|
|
|
suite_path, case_name = get_current_test()
|
|
|
|
cmd = [
|
|
sys.executable,
|
|
"-m", "pytest",
|
|
f"{suite_path}::{case_name}",
|
|
]
|
|
|
|
result = subprocess.run(
|
|
cmd,
|
|
env={**os.environ, "XPYTEST_INSIDE_SUBPROCESS": "1"},
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
|
|
if result.returncode != 0:
|
|
print(' '.join(cmd))
|
|
print("==== Subprocess stdout ====")
|
|
print(result.stdout)
|
|
print("==== Subprocess stderr ====")
|
|
print(result.stderr)
|
|
raise AssertionError(f"Subprocess test failed with exit code {result.returncode}")
|
|
return wrapper
|
|
return decorator
|
|
|