NODEDC_MISSION_CORE/tests/test_e9_multirate_perceptio...

98 lines
2.7 KiB
Python

from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
from types import ModuleType
import pytest
def _worker_module() -> ModuleType:
worker_root = Path(__file__).parents[1] / "experiments" / "perception" / "worker"
path = worker_root / "run_e9_multirate_perception.py"
sys.path.insert(0, str(worker_root))
try:
spec = importlib.util.spec_from_file_location("e9_multirate_worker", 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
finally:
sys.path.pop(0)
def _profile_path() -> Path:
return (
Path(__file__).parents[1]
/ "experiments"
/ "perception"
/ "worker"
/ "e9_multirate_perception_profile.json"
)
def _semantic(worker: ModuleType, *, index: int, session_seconds: float) -> object:
return worker.SemanticResult(
frame_index=index,
source_frame_index=1000 + index,
session_seconds=session_seconds,
completed_monotonic=10.0,
completion_age_ms=180.0,
mask_sha256="a" * 64,
class_pixels={"road": 100},
class_fractions={"road": 0.5},
)
def test_e9_profile_pins_independent_bounded_rates() -> None:
worker = _worker_module()
profile, digest = worker._read_profile(_profile_path())
assert len(digest) == 64
assert profile["replay"]["detector_queue_capacity"] == 2
assert profile["replay"]["semantic_queue_capacity"] == 1
assert profile["replay"]["semantic_sample_every_frames"] == 5
assert profile["replay"]["semantic_ttl_ms"] == 750.0
def test_e9_semantic_binding_exposes_fresh_stale_and_unavailable() -> None:
worker = _worker_module()
semantic = _semantic(worker, index=5, session_seconds=20.0)
assert (
worker._semantic_binding(
None,
frame_session_seconds=20.1,
ttl_ms=750.0,
)["status"]
== "unavailable"
)
assert (
worker._semantic_binding(
semantic,
frame_session_seconds=20.7,
ttl_ms=750.0,
)["status"]
== "fresh"
)
assert (
worker._semantic_binding(
semantic,
frame_session_seconds=20.8,
ttl_ms=750.0,
)["status"]
== "stale"
)
def test_e9_latest_semantic_rejects_time_reversal() -> None:
worker = _worker_module()
latest = worker.LatestSemantic()
latest.publish(_semantic(worker, index=5, session_seconds=20.0))
with pytest.raises(RuntimeError, match="not monotonic"):
latest.publish(_semantic(worker, index=4, session_seconds=19.9))