[AZ-597] Batch 77: replay_mode helpers + 13 scenario stub rewires

Add `runner/helpers/replay_mode.py` (NullFrameSink, NullFcInboundEmitter,
default_frame_period_ms, load_replay_json, resolve_replay_subdir,
imu_replay_noop) and rewire all 13 scenarios off their local
`_resolve_*` / `_drive_*` / `_push_*` NotImplementedError stubs.

Closes the offline FDR-replay execution path. `grep raise
NotImplementedError` under `e2e/tests/` now returns zero matches. +17
unit tests (626 total, up from 608). Unit-test behaviour unchanged
(scenarios still skip via b75 sitl_replay_ready gate when
E2E_SITL_REPLAY_DIR is unset).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-17 09:52:05 +03:00
parent 6554d568f1
commit f49d803252
22 changed files with 798 additions and 85 deletions
@@ -124,12 +124,33 @@ def test_ft_n_01_outlier_tolerance(
def _resolve_frame_sink(): # type: ignore[no-untyped-def]
raise NotImplementedError(
"frame sink resolution is owned by AZ-441 / runner.helpers.frame_source_replay"
)
"""Return a replay-mode `FrameSink` (counter-only; AZ-597)."""
from runner.helpers.replay_mode import NullFrameSink
return NullFrameSink()
def _resolve_gt_per_frame(report: OutlierInjectionReport) -> list[ote.GtPose]:
raise NotImplementedError(
"Per-frame GT resolution is owned by AZ-407 / runner.helpers.tile_cache_gt"
)
"""Load per-frame GT from `${E2E_SITL_REPLAY_DIR}/gt_per_frame.json` (AZ-597).
The fixture builder writes a list of `{frame_idx, lat_deg, lon_deg}`
records keyed off `report.out_root.name` (one file per injection
variant). In FDR-replay mode this is the GT the SUT was scored
against when the FDR archive was originally produced.
"""
from runner.helpers.replay_mode import load_replay_json
raw = load_replay_json("gt_per_frame.json")
if not isinstance(raw, list):
raise ValueError(
"gt_per_frame.json must be a JSON list of "
"{frame_idx, lat_deg, lon_deg} records"
)
return [
ote.GtPose(
frame_idx=int(entry["frame_idx"]),
lat_deg=float(entry["lat_deg"]),
lon_deg=float(entry["lon_deg"]),
)
for entry in raw
]