1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
import pytest
from .support import ExtensionCompiler, DefaultExtensionTemplate,\
PythonSubprocessRunner, HPyDebugCapture, make_hpy_abi_fixture
from pathlib import Path
IS_VALGRIND_RUN = False
# addoption only works in a top-level conftest file
def _pytest_addoption(parser):
parser.addoption(
"--compiler-v", action="store_true",
help="Print to stdout the commands used to invoke the compiler")
parser.addoption(
"--subprocess-v", action="store_true",
help="Print to stdout the stdout and stderr of Python subprocesses "
"executed via run_python_subprocess")
parser.addoption(
"--dump-dir",
help="Enables dump mode and specifies where to write generated test "
"sources. This will then only generate the sources and skip "
"evaluation of the tests.")
parser.addoption(
'--reuse-venv', action="store_true",
help="Development only: reuse the venv for test_distutils.py instead of "
"creating a new one for every test")
@pytest.hookimpl(trylast=True)
def pytest_configure(config):
global IS_VALGRIND_RUN
IS_VALGRIND_RUN = config.pluginmanager.hasplugin('valgrind_checker')
config.addinivalue_line(
"markers", "syncgc: Mark tests that rely on a synchronous GC."
)
# this is the default set of hpy_abi for all the tests. Individual files and
# classes can override it.
hpy_abi = make_hpy_abi_fixture('default')
@pytest.fixture(scope='session')
def hpy_devel(request):
from hpy.devel import HPyDevel
return HPyDevel()
@pytest.fixture
def leakdetector(hpy_abi):
"""
Automatically detect leaks when the hpy_abi == 'debug'
"""
from hpy.debug.leakdetector import LeakDetector
if 'debug' in hpy_abi:
with LeakDetector() as ld:
yield ld
else:
yield None
@pytest.fixture
def ExtensionTemplate():
return DefaultExtensionTemplate
@pytest.fixture
def compiler(request, tmpdir, hpy_devel, hpy_abi, ExtensionTemplate):
compiler_verbose = request.config.getoption('--compiler-v')
dump_dir = request.config.getoption('--dump-dir')
if dump_dir:
# Test-specific dump dir in format: dump_dir/[mod_][cls_]func
qname_parts = []
if request.module:
qname_parts.append(request.module.__name__)
if request.cls:
qname_parts.append(request.cls.__name__)
qname_parts.append(request.function.__name__)
test_dump_dir = "_".join(qname_parts).replace(".", "_")
dump_dir = Path(dump_dir).joinpath(test_dump_dir)
dump_dir.mkdir(parents=True, exist_ok=True)
return ExtensionCompiler(tmpdir, hpy_devel, hpy_abi,
compiler_verbose=compiler_verbose,
dump_dir=dump_dir,
ExtensionTemplate=ExtensionTemplate)
@pytest.fixture(scope="session")
def fatal_exit_code(request):
import sys
return {
"linux": -6, # SIGABRT
# See https://bugs.python.org/issue36116#msg336782 -- the
# return code from abort on Windows 8+ is a stack buffer overrun.
# :|
"win32": 0xC0000409, # STATUS_STACK_BUFFER_OVERRUN
}.get(sys.platform, -6)
@pytest.fixture
def python_subprocess(request, hpy_abi):
verbose = request.config.getoption('--subprocess-v')
yield PythonSubprocessRunner(verbose, hpy_abi)
@pytest.fixture()
def hpy_debug_capture(request, hpy_abi):
assert hpy_abi == 'debug'
with HPyDebugCapture() as reporter:
yield reporter
|