from __future__ import annotations import hashlib import importlib.util import json import sys from pathlib import Path import pytest def _module(name: str, relative: str): path = Path(__file__).resolve().parents[1] / relative spec = importlib.util.spec_from_file_location(name, path) assert spec is not None and spec.loader is not None module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module def test_camera_replay_loads_segments_lazily_and_checks_each_digest(tmp_path: Path) -> None: module = _module( "e21_source_replay_test", "experiments/perception/run_e12_shadow_transport_replay.py", ) epoch = tmp_path / "epoch-1" segments = epoch / "segments" segments.mkdir(parents=True) (epoch / "init.mp4").write_bytes(b"init") rows = [] for sequence, payload in ((1, b"one"), (2, b"two")): path = segments / f"{sequence}.m4s" path.write_bytes(payload) rows.append( { "host_epoch_ns": sequence * 100_000_000, "host_monotonic_ns": sequence * 100_000_000, "length": len(payload), "path": f"segments/{sequence}.m4s", "sequence": sequence, "sha256": hashlib.sha256(payload).hexdigest(), } ) (epoch / "index.jsonl").write_text( "".join(json.dumps(row) + "\n" for row in rows), encoding="utf-8", ) events = module._camera_events(epoch, 1.0) assert next(events).modality == "camera-init" assert next(events).payload == b"one" (segments / "2.m4s").write_bytes(b"changed-after-generator-start") with pytest.raises(RuntimeError, match="length differs"): next(events) def test_e21_trend_reports_accumulating_age_and_stable_memory() -> None: module = _module( "e21_analyzer_test", "experiments/perception/analyze_e21_realtime_envelope.py", ) growing = module._trend([(float(index), float(index) * 2) for index in range(20)]) stable = module._trend([(float(index), 100.0) for index in range(20)]) assert growing["slope_per_second"] == pytest.approx(2.0) assert growing["late_vs_early_p95"] > 0 assert stable["slope_per_second"] == pytest.approx(0.0) assert stable["late_vs_early_p95"] == pytest.approx(0.0) def test_e21_profile_keeps_diagnostic_authority_and_long_1x_gate() -> None: root = Path(__file__).resolve().parents[1] profile = json.loads( ( root / "experiments" / "perception" / "e21_realtime_envelope_profile.json" ).read_text() ) assert profile["source"]["speed"] == 1.0 assert profile["source"]["minimum_span_seconds"] >= 55.0 assert profile["worker"]["minimum_detector_fps"] >= 9.5 assert profile["worker"]["maximum_detector_drop_fraction"] <= 0.02 assert profile["worker"]["maximum_p95_world_state_age_ms"] == 200.0 assert profile["authority"] == { "commands_enabled": False, "navigation_or_safety_accepted": False, }