from artemis.runtime.task_progress import progress_snapshot def test_queued_time_is_not_execution_time_even_with_legacy_started_at(): value = progress_snapshot(job={"status": "queued", "created_at": 10, "started_at": 10}, now=50) assert value["phase"] == "queued" assert value["durations"]["queued"] == 40 assert value["durations"]["execution"] is None def test_progress_splits_wait_pause_review_and_export_without_double_counting(): value = progress_snapshot( job={ "status": "completed", "created_at": 10, "worker_started_at": 20, "ended_at": 120, "finalized_at": 125, }, control={ "status": "running", "timing": { "started_at": 20, "state_started_at": 80, "seconds": {"queued": 10, "task_paused": 20, "resuming": 10, "running": 20}, }, }, reviews=[{"started_at": 90, "ended_at": 110}, {"started_at": 100, "ended_at": 115}], now=500, ) assert value["phase"] == "finished" assert value["durations"] == { "total": 115, "queued": 10, "resource_wait": 20, "paused": 20, "final_review": 25, "execution": 35, "report_export": 5, } def test_active_review_has_its_own_phase_and_terminal_review_is_not_still_active(): review = {"started_at": 30, "status": "running", "updated_at": 35} live = progress_snapshot(job={"status": "running"}, reviews=[review], now=40) assert live["phase"] == "final_review" assert live["durations"]["final_review"] == 10 stopped = progress_snapshot( job={"status": "cancelled", "ended_at": 45}, reviews=[review], now=500 ) assert stopped["phase"] == "finished" assert stopped["durations"]["final_review"] == 5 assert not stopped["review_timing_complete"] def test_legacy_missing_intervals_are_unknown_rather_than_zero_or_model_speed(): value = progress_snapshot( session={"status": "completed", "start_time": 20, "end_time": 100}, now=500 ) assert value["durations"]["queued"] is None assert value["durations"]["execution"] is None assert value["durations"]["paused"] is None assert value["durations"]["total"] is None assert value["observed_seconds"] == 80 def test_waiting_for_resource_and_pause_are_not_running(): for status, phase in ( ("queued", "waiting_resources"), ("resuming", "waiting_resources"), ("task_paused", "paused"), ): value = progress_snapshot( job={"status": "running", "worker_started_at": 10}, control={"status": status}, now=50 ) assert value["phase"] == phase def test_terminal_without_end_timestamp_does_not_keep_increasing_or_guess_duration(): job = {"status": "completed", "created_at": 10, "worker_started_at": 20} first = progress_snapshot(job=job, now=100) assert first == progress_snapshot(job=job, now=500) assert first["observed_at"] is None assert all(first["durations"][key] is None for key in ("total", "execution", "report_export")) def test_export_in_progress_keeps_total_current_without_extending_execution(): value = progress_snapshot( job={"status": "finalizing", "created_at": 10, "worker_started_at": 100, "ended_at": 200}, now=230, ) assert value["phase"] == "report_export" assert value["observed_at"] == 230 assert value["durations"]["total"] == 220 assert value["durations"]["report_export"] == 30 assert value["worker_ended_at"] == 200