"""Tests for Failure Recovery Coordinator (F11).""" import numpy as np import pytest from gps_denied.core.chunk_manager import RouteChunkManager from gps_denied.core.gpr import GlobalPlaceRecognition from gps_denied.core.graph import FactorGraphOptimizer from gps_denied.core.metric import MetricRefinement from gps_denied.core.models import ModelManager from gps_denied.core.recovery import FailureRecoveryCoordinator from gps_denied.schemas.graph import FactorGraphConfig @pytest.fixture def recovery(): opt = FactorGraphOptimizer(FactorGraphConfig()) cm = RouteChunkManager(opt) mm = ModelManager() gpr = GlobalPlaceRecognition(mm) gpr.load_index("test", "test") metric = MetricRefinement(mm) return FailureRecoveryCoordinator(cm, gpr, metric) def test_handle_tracking_lost(recovery): flight = "recovery_fl" res = recovery.handle_tracking_lost(flight, 404) assert res is True # active chunk should be 404 active = recovery.chunk_manager.get_active_chunk(flight) assert active.start_frame_id == 404 def test_process_chunk_recovery_success(recovery, monkeypatch): # Mock LitSAM to guarantee match def mock_align(*args, **kwargs): from gps_denied.schemas import GPSPoint from gps_denied.schemas.metric import ChunkAlignmentResult, Sim3Transform return ChunkAlignmentResult( matched=True, chunk_id="x", chunk_center_gps=GPSPoint(lat=49, lon=30), rotation_angle=0, confidence=0.9, inlier_count=50, transform=Sim3Transform(translation=np.zeros(3), rotation=np.eye(3), scale=1), reprojection_error=1.0 ) monkeypatch.setattr(recovery.metric_refinement, "align_chunk_to_satellite", mock_align) flight = "rec2" recovery.handle_tracking_lost(flight, 10) chunk_id = recovery.chunk_manager.get_active_chunk(flight).chunk_id images = [np.zeros((256, 256, 3)) for _ in range(3)] res = recovery.process_chunk_recovery(flight, chunk_id, images) assert res is True from gps_denied.schemas.chunk import ChunkStatus active = recovery.chunk_manager.get_active_chunk(flight) assert active.has_anchor is True assert active.matching_status == ChunkStatus.ANCHORED