Files
Jyotisha/tests/conftest.py
T
ClaudeandClaude Opus 5.5 c1a69445b5 refactor: retire event-scored rectification backend (BUG-1644)
Remove the V5 scoring pipeline, dynamic rectification, minute-rectification
evaluations and the research scripts built on them, plus their API routes.
Keep the upstream skill layer (gate, questionnaire, active events), the
varga-segments scan and the consult range reading (moved to
scripts/birth_window_range_reading.py).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
2026-11-06 02:40:28 +08:00

101 lines
3.3 KiB
Python

"""Pytest import guardrails for local project modules."""
from __future__ import annotations
import sys
import time
from pathlib import Path
import pytest
# Deliberately fictional birth data; not a real person or an oracle golden.
FIXTURE_BIRTH_DATE = "1990-06-15"
FIXTURE_BIRTH_TIME = "10:20"
FIXTURE_BIRTH_LAT = 31.2
FIXTURE_BIRTH_LON = 121.5
ROOT = Path(__file__).resolve().parents[1]
SCRIPTS = str(ROOT / "scripts")
WORKBUDDY_SKILL_SCRIPTS = ".workbuddy/skills/jyotish-vedic-astrology/scripts"
SLOW_API_SECURITY_PREFIXES = (
"test_vedastro_",
"test_high_rigor_",
"test_professional_reading",
"test_api_prompt_pack",
"test_consultation_workflow",
"test_thematic_report",
"test_capability_audit",
"test_technique_catalog",
)
def ensure_project_scripts_first() -> None:
if SCRIPTS in sys.path:
sys.path.remove(SCRIPTS)
sys.path.insert(0, SCRIPTS)
def remove_workbuddy_shadow_modules() -> None:
for name, module in list(sys.modules.items()):
module_file = getattr(module, "__file__", "") or ""
if WORKBUDDY_SKILL_SCRIPTS in module_file:
del sys.modules[name]
def pytest_runtest_setup() -> None:
remove_workbuddy_shadow_modules()
ensure_project_scripts_first()
@pytest.fixture(autouse=True)
def _isolate_vedastro_snapshot_cache(tmp_path_factory, monkeypatch) -> None:
cache_dir = tmp_path_factory.mktemp("vedastro_snapshot_cache")
monkeypatch.setenv("JYOTISH_VEDASTRO_SNAPSHOT_CACHE_DIR", str(cache_dir))
# Foreground failures are remembered for the day there too (issue #130).
negative_dir = tmp_path_factory.mktemp("vedastro_snapshot_negative_cache")
monkeypatch.setenv("JYOTISH_VEDASTRO_SNAPSHOT_NEGATIVE_CACHE_DIR", str(negative_dir))
_FOREGROUND_EXECUTOR_MODULES = (
"scripts.vedastro_foreground",
"vedastro_foreground",
"scripts.jyotish_api_server",
"jyotish_api_server",
)
@pytest.fixture(autouse=True)
def _isolate_foreground_vedastro_executor(monkeypatch):
"""A fresh foreground pool per test, drained at teardown (BUG-1498).
A task left running stores its outcome under whatever cache directory the
environment names when it finishes, which would be the next test's.
"""
from concurrent.futures import ThreadPoolExecutor
from scripts import vedastro_foreground
executor = ThreadPoolExecutor(
max_workers=vedastro_foreground._FOREGROUND_VEDASTRO_WORKERS,
thread_name_prefix="jyotish-vedastro-fg-test",
)
for name in _FOREGROUND_EXECUTOR_MODULES:
module = sys.modules.get(name)
if module is not None and hasattr(module, "_FOREGROUND_VEDASTRO_EXECUTOR"):
monkeypatch.setattr(module, "_FOREGROUND_VEDASTRO_EXECUTOR", executor)
yield
# Queued work is dropped; running work gets a bounded wait so a stuck stub cannot hang the run.
executor.shutdown(wait=False, cancel_futures=True)
deadline = time.monotonic() + 10
for thread in list(getattr(executor, "_threads", ())):
thread.join(max(deadline - time.monotonic(), 0))
def pytest_collection_modifyitems(items) -> None:
for item in items:
if item.fspath.basename == "test_api_server_security.py" and item.name.startswith(SLOW_API_SECURITY_PREFIXES):
item.add_marker("slow")
ensure_project_scripts_first()