Files
gps-denied-onboard/_docs/02_tasks/todo/AZ-407_fixture_builders_static.md
T
Oleksandr Bezdieniezhnykh 880eabcb3f Decompose Step 6 snapshot: 140 task specs + contract docs
Closes out greenfield Step 6 (Decompose) for all 14 components
(C1-C13 + cross-cutting helpers/replay). Covers tasks AZ-266..AZ-446
plus the _dependencies_table.md and component contract documents.

State file updated to greenfield Step 7 (Implement), not_started.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:39:48 +03:00

6.2 KiB

Fixture Builders — Static (tile-cache, age-injector, cold-boot, mavlink-passkey, cve-jpeg)

Task: AZ-407_fixture_builders_static Name: Static fixture builders for tile cache, aged tiles, cold-boot pose, MAVLink passkey, CVE JPEG Description: Implement reproducible fixture builders for the five static (build-once-per-CI) fixtures named in test-data.md: tile-cache-fixture, synth-age-tile-set, cold-boot-fixture, mavlink-passkey, cve-jpeg-fixture. Complexity: 3 points Dependencies: AZ-406 Component: Blackbox Tests / Fixture builders (epic AZ-262 / E-BBT) Tracker: AZ-407 Epic: AZ-262 (E-BBT)

Problem

Several blackbox scenarios assume the existence of static fixtures that do not vary across runs (FAISS HNSW index, aged tile manifests, frozen FC pose, signing passkey, crafted JPEG). Without a single owner producing them deterministically, every scenario task would re-implement its own variant and assertions would drift.

Outcome

  • tests/fixtures/tile-cache-builder/build.sh produces the same tile-cache-fixture content (FAISS index hashes, tile manifest rows, on-disk file sizes) bit-for-bit on two consecutive runs from the same _docs/00_problem/input_data/ source. Builds at minimum: 60 still-image footprints + Derkachi route bbox at 0.3-0.5 m/px. When D-PROJ-3 is unresolved, footprints without paired _gmaps.png use stub-tile content with explicit "STUB" provenance in the manifest.
  • tests/fixtures/age-injector/ clones tile-cache-fixture and produces synth-age-7mo (>6 mo, exceeds AC-8.2 active-conflict threshold) and synth-age-13mo (>12 mo, exceeds rear threshold). Tile pixels unchanged; only the manifest capture_date field mutated.
  • tests/fixtures/cold-boot/ ships a JSON snapshot of a GLOBAL_POSITION_INT pose at flight-resume time, loadable by ardupilot-plane-sitl / inav-sitl SITL via the standard parameter-load path.
  • tests/fixtures/secrets/mavlink-test-passkey.txt ships a 32-byte hex passkey, prefixed # TEST ONLY — not for production use.
  • tests/fixtures/security/cve-2025-53644.jpg ships a license-checked PoC OR a generation script that produces an equivalent crafted JPEG following the published PoC structure.

Scope

Included

  • build.sh + Dockerfile for tile-cache-builder; FAISS index emission; tile filesystem layout; manifest CSV/SQLite per restrictions.md § Satellite Imagery schema.
  • age-injector script that copies the tile-cache volume and mutates manifest dates only.
  • Static cold-boot JSON, mavlink-passkey, CVE JPEG fixtures + their license/provenance README.
  • A top-level make fixtures (or equivalent CI step) that builds all five fixtures into named Docker volumes / files.

Excluded

  • Synthetic-injection fixtures (outlier, blackout-spoof, multi-segment) — owned by AZ-408.
  • Real Derkachi video / 60 still images — bind-mounted from _docs/00_problem/input_data/, not built.
  • The Suite Sat Service mock — owned by AZ-406.
  • Production-grade tile-cache content (real public-data subset for D-PROJ-3); stub-tile fallback is acceptable until D-PROJ-3 lands.

Acceptance Criteria

AC-1: tile-cache-fixture is deterministic Given a clean Docker volume state When tests/fixtures/tile-cache-builder/build.sh runs twice from the same source Then both runs produce a tile-cache-fixture with identical FAISS index hash, identical manifest rows, and identical tile-filesystem byte sizes.

AC-2: tile-cache-fixture covers required footprints Given the build completes Then the manifest contains entries for all 60 still-image footprints AND the Derkachi route bbox AND the 2 paired _gmaps.png references; m/px ≥ 0.5 for every entry.

AC-3: synth-age-7mo and synth-age-13mo correctly aged Given tile-cache-fixture exists When age-injector runs with target=7mo / target=13mo Then the resulting volume has all capture_date fields set to (now - 7 mo) / (now - 13 mo) ± 1 day; tile pixel content is bit-identical to the source.

AC-4: cold-boot-fixture loads into SITL Given the JSON pose snapshot When loaded into ardupilot-plane-sitl (and separately inav-sitl) per the SITL parameter-load convention Then the SITL EKF reflects the snapshot pose within ±1 m of the JSON's lat/lon/alt fields.

AC-5: mavlink-passkey is a valid 32-byte hex secret Given mavlink-test-passkey.txt Then the file contains exactly 64 hex characters (32 bytes); the first line is # TEST ONLY — not for production use.

AC-6: cve-jpeg-fixture is decodable / triggers the CVE behavior Given cve-2025-53644.jpg When fed to OpenCV ≥4.12.0 imdecode under AddressSanitizer Then no buffer-overflow / use-after-free is reported AND OpenCV either decodes the image or returns an error gracefully (no crash). When fed to a vulnerable OpenCV (≤4.11) the PoC behavior is observable.

AC-7: License + provenance documented Given each fixture Then a README.md next to it states: source URL (or "synthetic"), license, and re-distribution terms. Fixtures lacking a clear license are generated programmatically rather than checked in.

System Under Test Boundary

This task ONLY produces fixtures consumed by other test tasks. It does NOT exercise SUT behavior. The fixtures themselves are the deliverable.

  • No internal SUT modules are imported by the builders.
  • The tile-cache-builder uses only the public on-disk schema documented in _docs/00_problem/restrictions.md § Satellite Imagery; it does NOT depend on the runtime tile-cache implementation (C6).
  • If C6's on-disk schema later evolves, this builder's output must be updated to match — the builder is a contract test on the schema.

Constraints

  • Re-runnability: each builder MUST be idempotent; running twice produces the same output.
  • Volume-driven: tile-cache + age-injector emit named Docker volumes (tile-cache-fixture, synth-age-7mo, synth-age-13mo) so compose can mount them RO into the SUT.
  • License hygiene: any third-party data must be license-checked at build time; failures abort the build with a human-readable error.

Document Dependencies

  • _docs/02_document/tests/test-data.md § Seed Data Sets, § Input Data Mapping
  • _docs/00_problem/restrictions.md § Satellite Imagery (manifest schema)
  • _docs/02_document/tests/blackbox-tests.md (which scenarios consume which fixture)