from __future__ import annotations from datetime import datetime, timezone from unittest.mock import MagicMock from app.models import AoiOperation, AoiOperationPartition, AnalysisRun, Job from app.services.runtime_reconciliation_service import RuntimeReconciliationService def test_reconciliation_terminalizes_only_running_work() -> None: db = MagicMock() jobs = MagicMock() runs = MagicMock() resumable_partitions = MagicMock() exhausted_partitions = MagicMock() operations = MagicMock() jobs.filter.return_value.update.return_value = 5 runs.filter.return_value.update.return_value = 2 resumable_partitions.filter.return_value.update.return_value = 3 exhausted_partitions.filter.return_value.update.return_value = 1 operations.filter.return_value.update.return_value = 2 db.query.side_effect = [jobs, runs, resumable_partitions, exhausted_partitions, operations] finished_at = datetime(2026, 7, 17, 20, 0, tzinfo=timezone.utc) result = RuntimeReconciliationService.reconcile( db, finished_at=finished_at, ) assert result.interrupted_jobs == 5 assert result.interrupted_analysis_runs == 2 assert result.resumed_aoi_partitions == 3 assert result.exhausted_aoi_partitions == 1 jobs.filter.assert_called_once() runs.filter.assert_called_once() resumable_partitions.filter.assert_called_once() exhausted_partitions.filter.assert_called_once() operations.filter.assert_called_once() job_values = jobs.filter.return_value.update.call_args.args[0] run_values = runs.filter.return_value.update.call_args.args[0] assert job_values[Job.status] == "failed" assert job_values[Job.finished_at] == finished_at assert "PROCESS_INTERRUPTED" in job_values[Job.error_message] assert run_values[AnalysisRun.status] == "failed" assert run_values[AnalysisRun.finished_at] == finished_at assert "PROCESS_INTERRUPTED" in run_values[AnalysisRun.error_message] resumed_values = resumable_partitions.filter.return_value.update.call_args.args[0] exhausted_values = exhausted_partitions.filter.return_value.update.call_args.args[0] operation_values = operations.filter.return_value.update.call_args.args[0] assert resumed_values[AoiOperationPartition.status] == "queued" assert exhausted_values[AoiOperationPartition.status] == "failed" assert operation_values[AoiOperation.status] == "queued" db.commit.assert_called_once_with() def test_startup_reconciliation_is_enabled_only_in_all_in_one_runtime() -> None: start_script = ( __import__("pathlib").Path(__file__).resolve().parents[2] / "deploy" / "unraid" / "all-in-one-start.sh" ).read_text(encoding="utf-8") assert ( 'GEOINTEL_RECONCILE_INTERRUPTED_RUNS_ON_STARTUP:-true' in start_script )