[AZ-595] Batch 75: sitl_observer FDR-replay + scenario probe cleanup

Implement all 11 `sitl_observer` public surfaces as an offline
FDR-replay strategy (reads JSON fixtures under `${E2E_SITL_REPLAY_DIR}`
instead of live pymavlink/yamspy). Replace 12 per-scenario
`_harness_helpers_implemented` probes with one shared session-scoped
`sitl_replay_ready` fixture in `e2e/tests/conftest.py`.

Net: -636 LoC of duplicated scenario gating, +17 LoC shared fixture,
+38 new unit tests (596 total, up from 558). Includes K=3 cumulative
review for batches 73-75 (PASS).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-17 09:00:55 +03:00
parent 1d260f7e41
commit 43fdef1aac
23 changed files with 1485 additions and 639 deletions
@@ -0,0 +1,81 @@
# sitl_observer FDR-replay surfaces + scenario probe cleanup
**Task**: AZ-595_sitl_observer_fdr_replay
**Name**: Implement all 11 sitl_observer surfaces with an FDR-replay strategy + refactor scenario probes
**Description**: Replace `NotImplementedError` and stub patterns across `sitl_observer.py` with file-backed JSON readers. Refactor the brittle `_harness_helpers_implemented` probes in 8 scenarios to use an explicit `E2E_SITL_REPLAY_DIR` env-var check.
**Complexity**: 5 points
**Dependencies**: AZ-406, AZ-594
**Component**: Blackbox Tests / Test Infrastructure (epic AZ-262)
**Tracker**: AZ-595
**Epic**: AZ-262 (E-BBT)
## Problem
The `sitl_observer` module reserved 11 surfaces in AZ-406 and never
came back to fill them. Scenarios in batches 71-73 work around it
with a `_harness_helpers_implemented` probe that passes a fake path
to each helper and inspects the exception type — fragile and
misleading post-fix once underlying helpers stop raising
`NotImplementedError` (as they now do after batch 74).
## Outcome
- `sitl_observer.py` implements all 11 surfaces using an FDR-replay
strategy: each surface reads its fixture from
`${E2E_SITL_REPLAY_DIR}/<surface_name>.json` and returns a typed
result. Missing env var or missing file → empty result for `read_*`
surfaces; explicit `RuntimeError` for surfaces that require live
data.
- Scenario probes refactored to use a single `_e2e_sitl_replay_dir_available`
fixture that returns True iff env var is set + directory exists.
No more fake-path exception-introspection.
## Scope
### Included
- `sitl_observer.get_observer` + 10 free-function surfaces.
- Typed dataclasses for the read_* / capture_* / observe_* / query_*
return types.
- Comprehensive unit tests.
- Probe refactor across the 8 affected scenarios.
### Excluded
- `fc_proxy_runtime` driver (separate ticket).
- Live pymavlink / yamspy / TCP plumbing.
- Per-scenario fixture builders (the JSON files that go in
`E2E_SITL_REPLAY_DIR` for each scenario).
## Acceptance Criteria
**AC-1**: Each surface returns its typed result by parsing JSON at
`${E2E_SITL_REPLAY_DIR}/<surface_name>.json`. Missing env var →
returns empty list / vacuous result (for `read_*`) OR raises
`RuntimeError` (for surfaces requiring non-empty fixtures).
**AC-2**: Probe pattern in the 8 affected scenarios replaced with
`_e2e_sitl_replay_dir_available` fixture (True only when env var set
AND directory exists).
**AC-3**: ≥5 unit tests per surface category.
**AC-4**: Full e2e unit-test suite passes (regression gate).
## System Under Test Boundary
None — runner-side helper that parses runner-produced fixture files.
No `src/gps_denied_onboard` imports.
## Constraints
- Same `time.sleep` injection / `realtime` pattern as
`frame_source_replay` and `imu_replay` where pacing applies (e.g.
`capture_ap_tlog(duration_s)` should not block real wall-clock in
tests).
- File-not-found surfaces with clear `RuntimeError` messages that
point at the env var.
- All public dataclasses immutable (`frozen=True`).
## Document Dependencies
- `_docs/02_document/tests/blackbox-tests.md` § Test infrastructure
- `_docs/02_tasks/done/AZ-594_harness_stubs_core_three.md`