[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
@@ -140,7 +140,7 @@ def test_ft_p_01_still_image_accuracy(
def _resolve_frame_sink(): # type: ignore[no-untyped-def]
"""Stub helper resolved when the underlying replayer lands."""
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()
@@ -146,14 +146,14 @@ def test_ft_p_02_derkachi_drift(
def _resolve_frame_sink(): # type: ignore[no-untyped-def]
"""Stub helper resolved when the underlying replayer lands."""
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_fc_inbound_emitter(fc_adapter: str, host: str): # type: ignore[no-untyped-def]
"""Stub helper resolved when the FC inbound emitter lands."""
raise NotImplementedError(
"FC inbound emitter resolution is owned by AZ-416/AZ-417 / runner.helpers.imu_replay"
)
"""Return a replay-mode `FcInboundEmitter` (counter-only; AZ-597)."""
from runner.helpers.replay_mode import NullFcInboundEmitter
return NullFcInboundEmitter()
@@ -106,13 +106,19 @@ def test_wgs84_coordinate_range(
def _push_single_image_and_observe(fc_adapter: str, vio_strategy: str): # type: ignore[no-untyped-def]
"""Push AD000001.jpg through the SUT and return (outbound_record, source_label).
"""Read the single-image observation fixture in replay mode (AZ-597).
Stub until runner.helpers.{frame_source_replay,sitl_observer,mavproxy_tlog_reader}
land; the scenario test's `sitl_replay_ready` skip gate (AZ-595)
keeps this from executing prematurely.
The fixture builder records the SUT's outbound estimate for the
single-image-push variant into
`${E2E_SITL_REPLAY_DIR}/single_image_observation.json` as
`{"record": {...estimate payload...}, "source_label": "..."}`.
"""
raise NotImplementedError(
"single-image push helper is owned by AZ-407 / AZ-416 / AZ-417 "
"(runner.helpers.frame_source_replay + sitl_observer + mavproxy_tlog_reader)"
)
from runner.helpers.replay_mode import load_replay_json
payload = load_replay_json("single_image_observation.json")
if not isinstance(payload, dict):
raise ValueError(
"single_image_observation.json must be a JSON object with "
"'record' and 'source_label' keys"
)
return payload["record"], payload["source_label"]
@@ -142,14 +142,14 @@ def test_ft_p_04_derkachi_f2f_registration(
def _resolve_frame_sink(): # type: ignore[no-untyped-def]
"""Stub helper resolved when the underlying replayer lands."""
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_fc_inbound_emitter(fc_adapter: str): # type: ignore[no-untyped-def]
"""Stub helper resolved when the FC inbound emitter lands."""
raise NotImplementedError(
"FC inbound emitter resolution is owned by AZ-416/AZ-417 / runner.helpers.imu_replay"
)
"""Return a replay-mode `FcInboundEmitter` (counter-only; AZ-597)."""
from runner.helpers.replay_mode import NullFcInboundEmitter
return NullFcInboundEmitter()
@@ -160,6 +160,7 @@ def test_ft_p_05_sat_anchor(
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()
@@ -148,12 +148,14 @@ def test_ft_p_07_sharp_turn_recovery(
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 _drive_imu_replay(csv_path: Path) -> None:
raise NotImplementedError(
"IMU replay driver is owned by AZ-416/AZ-417 / runner.helpers.imu_replay"
)
"""Replay-mode no-op: IMU samples pre-baked into FDR archive (AZ-597)."""
from runner.helpers.replay_mode import imu_replay_noop
imu_replay_noop(csv_path)
@@ -132,6 +132,7 @@ def test_ft_p_08_multi_segment_reloc(
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()
@@ -148,6 +148,7 @@ def test_ft_p_09_ap_signing(
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()
+4 -3
View File
@@ -139,6 +139,7 @@ def test_ft_p_09_inav(
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()
@@ -164,12 +164,14 @@ def test_ft_p_10_smoothing_lookback(
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_fc_inbound_emitter(fc_adapter: str): # type: ignore[no-untyped-def]
raise NotImplementedError(
"FC inbound emitter resolution is owned by AZ-416/AZ-417 / runner.helpers.imu_replay"
)
"""Return a replay-mode `FcInboundEmitter` (counter-only; AZ-597)."""
from runner.helpers.replay_mode import NullFcInboundEmitter
return NullFcInboundEmitter()
@@ -262,6 +262,7 @@ def test_ft_p_11_cold_start_no_origin_aborts(
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()