"""Asserts the AZ-406 directory layout is present. Every blackbox / fixture / Jetson task added later relies on these paths. Catching a missing directory here is much faster than failing inside the e2e-runner image build. """ from __future__ import annotations from pathlib import Path import pytest E2E_ROOT = Path(__file__).resolve().parents[1] @pytest.mark.parametrize( "relative_path", [ "README.md", ".gitignore", "docker/docker-compose.test.yml", "docker/docker-compose.tier2-bridge.yml", "docker/secrets/mavlink_passkey", "docker/run-tier1.sh", "jetson/run-tier2.sh", "jetson/tier2-on-jetson.sh", "jetson/tier2.service", "jetson/tegrastats_parser.py", "jetson/jtop_parser.py", "runner/Dockerfile", "runner/requirements.txt", "runner/pytest.ini", "runner/conftest.py", "runner/reporting/csv_reporter.py", "runner/reporting/evidence_bundler.py", "runner/reporting/nfr_recorder.py", "runner/helpers/frame_source_replay.py", "runner/helpers/imu_replay.py", "runner/helpers/sitl_observer.py", "runner/helpers/mavproxy_tlog_reader.py", "runner/helpers/fdr_reader.py", "runner/helpers/geo.py", "runner/helpers/anchor_pair_detector.py", "runner/helpers/estimate_schema.py", "runner/helpers/accuracy_evaluator.py", "runner/helpers/registration_classifier.py", "runner/helpers/mre_evaluator.py", "fixtures/mock-suite-sat/Dockerfile", "fixtures/mock-suite-sat/app.py", "fixtures/mock-suite-sat/requirements.txt", "fixtures/tile-cache-builder/README.md", "fixtures/tile-cache-builder/builder.py", "fixtures/tile-cache-builder/Dockerfile", "fixtures/tile-cache-builder/build.sh", "fixtures/age-injector/README.md", "fixtures/age-injector/age_injector.py", "fixtures/age-injector/inject.sh", "fixtures/injectors/outlier.py", "fixtures/injectors/blackout_spoof.py", "fixtures/injectors/multi_segment.py", "fixtures/injectors/cold_boot.py", "fixtures/injectors/_common.py", "fixtures/injectors/fc_proxy.py", "runner/helpers/injector_fixtures.py", "fixtures/cold-boot/README.md", "fixtures/cold-boot/cold_boot_fixture.json", "fixtures/secrets/mavlink-test-passkey.txt", "fixtures/security/generate_cve_jpeg.py", "fixtures/security/cve-2025-53644.jpg", "fixtures/security/README.md", "tests/__init__.py", "tests/conftest.py", "tests/positive/__init__.py", "tests/negative/__init__.py", "tests/performance/__init__.py", "tests/resilience/__init__.py", "tests/security/__init__.py", "tests/resource_limit/__init__.py", "tests/positive/test_smoke.py", "tests/positive/test_ft_p_01_still_image_accuracy.py", "tests/positive/test_ft_p_02_derkachi_drift.py", "tests/positive/test_ft_p_03_14_schema_wgs84.py", "tests/positive/test_ft_p_04_derkachi_f2f_registration.py", "tests/positive/test_ft_p_05_sat_anchor.py", "tests/positive/test_ft_p_06_mre_budgets.py", ], ) def test_required_path_exists(relative_path: str) -> None: """Each path AZ-406 + AZ-407 + AZ-444 + AZ-445 commit to must exist on disk.""" assert (E2E_ROOT / relative_path).exists(), ( f"layout invariant broken: e2e/{relative_path} is missing" ) def test_passkey_files_match() -> None: """Docker secret and runner-side passkey fixture must encode the same secret. The docker-secret file is consumed by mavproxy as a raw 64-hex passkey (no comments allowed in its body). The runner-side fixture file is the AZ-407 AC-5 deliverable and ships with a ``# TEST ONLY...`` header line so it self-documents during code review. We therefore compare the FIRST 64-hex line of each file rather than the raw bytes. The two files MUST encode the same 32-byte secret; drift between them would mean a mavproxy run uses a different key than the runner fixture states. """ # Arrange docker_pk = (E2E_ROOT / "docker/secrets/mavlink_passkey").read_text().strip().splitlines() runner_pk_lines = (E2E_ROOT / "fixtures/secrets/mavlink-test-passkey.txt").read_text().strip().splitlines() runner_pk = [line for line in runner_pk_lines if not line.lstrip().startswith("#")] # Assert assert docker_pk and runner_pk, "passkey files must contain at least one non-comment line" assert docker_pk[0] == runner_pk[0], ( "MAVLink test passkey secrets differ between docker secret and runner " "fixture. They MUST encode the same 32-byte secret — see " "e2e/fixtures/secrets/README.md." )