Files
orisys-sdk/tests/test_harness_guards.py
T
2026-09-12 15:49:28 +08:00

117 lines
4.0 KiB
Python

"""Guards for the pytest harness itself.
``tests/conftest.py`` was accidentally deleted in commit edc6e42 while four test
modules still depended on its fixtures, which made the suite unrunnable without
anything failing loudly in CI. These tests turn that class of regression into an
explicit failure, and also catch a stale ``orisys`` install silently shadowing
``src/orisys`` (a real hazard: base/py312 environments have older orisys copies
in site-packages).
"""
from __future__ import annotations
import functools
import importlib.util
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parents[1]
CONFTEST_PATH = Path(__file__).resolve().parent / "conftest.py"
# Names that must exist in tests/conftest.py.
REQUIRED_CONFTEST_NAMES = (
"DEFAULT_VIDEO_CANDIDATES",
"make_sensor",
"test_video_path",
"test_config_name",
"available_backends",
"sensor_factory",
)
# Fixtures that must be resolvable through pytest.
REQUIRED_FIXTURES = (
"test_video_path",
"test_config_name",
"available_backends",
"sensor_factory",
)
@functools.lru_cache(maxsize=1)
def _load_conftest_module():
"""Load tests/conftest.py by path so a deletion is observable here."""
spec = importlib.util.spec_from_file_location("_orisys_conftest_probe", CONFTEST_PATH)
if spec is None or spec.loader is None:
raise AssertionError(f"Cannot load {CONFTEST_PATH}")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_conftest_defines_shared_fixtures():
assert CONFTEST_PATH.is_file(), (
f"{CONFTEST_PATH} is missing. test_backends.py, test_smoke_api.py, "
"test_errors_and_cleanup.py and test_longrun_stability.py depend on its "
"fixtures; it was accidentally deleted in commit edc6e42. Restore it "
"instead of deleting it."
)
module = _load_conftest_module()
missing = [
name for name in REQUIRED_CONFTEST_NAMES if getattr(module, name, None) is None
]
assert not missing, (
f"tests/conftest.py no longer defines: {', '.join(missing)}. "
"The shared sensor-test fixtures are required by the suite."
)
def test_default_test_video_is_reachable():
"""At least one default candidate must exist, or every sensor test skips."""
module = _load_conftest_module()
candidates = [REPO_ROOT / Path(rel) for rel in module.DEFAULT_VIDEO_CANDIDATES]
existing = [path for path in candidates if path.is_file()]
assert existing, (
"None of the default test videos exist:\n "
+ "\n ".join(str(path) for path in candidates)
+ "\nCommit a sample clip under data/sample/ or set ORISYS_TEST_VIDEO."
)
def test_fixtures_are_registered_with_pytest(request):
missing: list[str] = []
for name in REQUIRED_FIXTURES:
try:
request.getfixturevalue(name)
except pytest.FixtureLookupError:
missing.append(name)
assert not missing, (
f"pytest did not register these fixtures: {', '.join(missing)}. "
"Check that tests/conftest.py is present and the @pytest.fixture "
"decorators are intact."
)
def test_tests_run_against_checkout_not_stale_install():
"""Fail loudly when an old orisys in site-packages shadows src/orisys."""
src_pkg = (REPO_ROOT / "src" / "orisys").resolve()
if not src_pkg.is_dir():
pytest.skip("src/orisys is not present in this checkout layout")
import orisys
module_file = getattr(orisys, "__file__", None)
assert module_file, (
"import orisys resolved to a namespace package (__file__ is None) "
f"instead of {src_pkg}. A stale orisys in site-packages is shadowing "
"the checkout; run `pip uninstall -y orisys` in this environment."
)
resolved_parent = Path(module_file).resolve().parent
assert resolved_parent == src_pkg, (
f"import orisys resolved to {resolved_parent} instead of {src_pkg}. "
"A stale orisys in site-packages is shadowing the checkout; run "
"`pip uninstall -y orisys` in this environment."
)