mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-21 19:51:12 +00:00
2db50bc124
Keep generated tiles auditable and untrusted onboard while preserving covariance, quality, and sidecar metadata for post-flight sync. Co-authored-by: Cursor <cursoragent@cursor.com>
138 lines
4.5 KiB
Python
138 lines
4.5 KiB
Python
from datetime import datetime, timezone
|
|
|
|
from tile_manager import LocalTileManager, TileGenerationRequest, TileManifestEntry
|
|
|
|
NOW = datetime(2026, 5, 3, tzinfo=timezone.utc)
|
|
|
|
|
|
def _entry(**overrides: object) -> TileManifestEntry:
|
|
payload: dict[str, object] = {
|
|
"tile_id": "tile-1",
|
|
"chunk_id": "chunk-1",
|
|
"crs": "EPSG:3857",
|
|
"meters_per_pixel": 0.3,
|
|
"capture_date": "2026-05-01",
|
|
"expires_at": "2026-06-01T00:00:00+00:00",
|
|
"content_hash": "sha256:tile",
|
|
"expected_content_hash": "sha256:tile",
|
|
"sidecar_hash": "sha256:sidecar",
|
|
"expected_sidecar_hash": "sha256:sidecar",
|
|
"signature_hash": "sig:trusted",
|
|
"provenance": "suite-satellite-service",
|
|
"footprint": {"min_lat": 49.0, "max_lat": 50.0},
|
|
"descriptor_ref": "descriptors/chunk-1.vlad",
|
|
}
|
|
payload.update(overrides)
|
|
return TileManifestEntry.model_validate(payload)
|
|
|
|
|
|
def test_valid_cache_manifest_activates_trusted_records() -> None:
|
|
# Arrange
|
|
manager = LocalTileManager(trusted_signature_hashes={"sig:trusted"}, now=NOW)
|
|
|
|
# Act
|
|
report = manager.validate_cache([_entry()])
|
|
|
|
# Assert
|
|
assert report.activated is True
|
|
assert report.decisions[0].accepted is True
|
|
assert report.trusted_records[0].trust_level == "trusted"
|
|
|
|
|
|
def test_tampered_or_stale_tile_is_rejected_with_auditable_reason() -> None:
|
|
# Arrange
|
|
manager = LocalTileManager(trusted_signature_hashes={"sig:trusted"}, now=NOW)
|
|
tampered = _entry(tile_id="tile-tampered", content_hash="sha256:bad")
|
|
stale = _entry(
|
|
tile_id="tile-stale",
|
|
chunk_id="chunk-stale",
|
|
expires_at="2026-05-01T00:00:00+00:00",
|
|
)
|
|
|
|
# Act
|
|
report = manager.validate_cache([tampered, stale])
|
|
|
|
# Assert
|
|
assert report.activated is False
|
|
assert [decision.reason for decision in report.decisions] == [
|
|
"content_hash_mismatch",
|
|
"stale",
|
|
]
|
|
|
|
|
|
def test_tile_metadata_lookup_returns_record_or_explicit_rejection() -> None:
|
|
# Arrange
|
|
manager = LocalTileManager(trusted_signature_hashes={"sig:trusted"}, now=NOW)
|
|
manager.validate_cache([_entry()])
|
|
|
|
# Act
|
|
found = manager.get_tile_metadata("chunk-1")
|
|
missing = manager.get_tile_metadata("missing")
|
|
|
|
# Assert
|
|
assert found.found is True
|
|
assert found.record is not None
|
|
assert found.descriptor_ref == "descriptors/chunk-1.vlad"
|
|
assert missing.found is False
|
|
assert missing.error is not None
|
|
assert missing.error.category == "validation"
|
|
|
|
|
|
def _generation_request(**overrides: object) -> TileGenerationRequest:
|
|
payload: dict[str, object] = {
|
|
"mission_id": "mission-1",
|
|
"frame_id": "frame-1",
|
|
"image_ref": "replay/frame-1.jpg",
|
|
"timestamp_ns": 10_000,
|
|
"parent_covariance_m": 2.5,
|
|
"frame_usable": True,
|
|
"quality_score": 0.8,
|
|
"footprint": {"min_lat": 49.0, "max_lat": 49.1},
|
|
"source_provenance": "nav-camera-generated",
|
|
}
|
|
payload.update(overrides)
|
|
return TileGenerationRequest.model_validate(payload)
|
|
|
|
|
|
def test_eligible_frame_stages_generated_cog_and_sidecar() -> None:
|
|
# Arrange
|
|
manager = LocalTileManager(trusted_signature_hashes={"sig:trusted"}, now=NOW)
|
|
|
|
# Act
|
|
candidate = manager.orthorectify_frame(_generation_request())
|
|
|
|
# Assert
|
|
assert candidate.accepted is True
|
|
assert candidate.cog_ref == "generated/mission-1/generated-mission-1-frame-1.cog.tif"
|
|
assert candidate.sidecar is not None
|
|
assert candidate.sidecar.trust_level == "generated"
|
|
assert candidate.sidecar.parent_covariance_m == 2.5
|
|
|
|
|
|
def test_high_covariance_generated_tile_write_is_rejected() -> None:
|
|
# Arrange
|
|
manager = LocalTileManager(trusted_signature_hashes={"sig:trusted"}, now=NOW)
|
|
|
|
# Act
|
|
candidate = manager.orthorectify_frame(_generation_request(parent_covariance_m=7.5))
|
|
|
|
# Assert
|
|
assert candidate.accepted is False
|
|
assert candidate.rejection_reason == "covariance_too_high"
|
|
assert manager.package_sync("mission-1").sidecars == ()
|
|
|
|
|
|
def test_sync_package_includes_manifest_delta_sidecar_covariance_and_trust_level() -> None:
|
|
# Arrange
|
|
manager = LocalTileManager(trusted_signature_hashes={"sig:trusted"}, now=NOW)
|
|
manager.orthorectify_frame(_generation_request())
|
|
|
|
# Act
|
|
package = manager.package_sync("mission-1")
|
|
|
|
# Assert
|
|
assert package.package_ref == "generated/mission-1/sync-package.json"
|
|
assert package.sidecars[0].parent_covariance_m == 2.5
|
|
assert package.manifest_delta[0]["trust_level"] == "generated"
|
|
assert package.manifest_delta[0]["parent_covariance_m"] == 2.5
|