From 36492623161737e84c5ff78049c8d2fc5b3aaa84 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 21 Apr 2026 17:22:48 -0300 Subject: [PATCH] test(ariadne): close scheduler coverage gap --- tests/test_scheduler.py | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index a22d902..0e130e7 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -130,6 +130,76 @@ def test_scheduler_start_hydrates_persisted_schedule_metrics(monkeypatch) -> Non assert not any(item[0] == "unknown" for item in recorded) +def test_scheduler_hydration_ignores_storage_without_state_listing() -> None: + class MinimalStorage: + pass + + scheduler = CronScheduler(MinimalStorage(), tick_sec=0.01) + + scheduler._hydrate_schedule_metrics() + + +def test_scheduler_hydration_logs_storage_errors(monkeypatch) -> None: + class BrokenStorage(DummyStorage): + def list_schedule_states(self): + raise RuntimeError("storage offline") + + warnings = [] + scheduler = CronScheduler(BrokenStorage(), tick_sec=0.01) + monkeypatch.setattr(scheduler._logger, "warning", lambda *args, **kwargs: warnings.append((args, kwargs))) + + scheduler._hydrate_schedule_metrics() + + assert warnings + assert warnings[0][1]["extra"]["detail"] == "storage offline" + + +def test_scheduler_hydration_records_error_and_unknown_statuses(monkeypatch) -> None: + finished = datetime(2026, 1, 1, 12, 0, tzinfo=timezone.utc) + + class StatusStorage(DummyStorage): + def list_schedule_states(self): + return [ + ScheduleState( + task_name="failed-task", + cron_expr="*/5 * * * *", + last_started_at=finished, + last_finished_at=None, + last_status="error", + last_error="boom", + last_duration_ms=100, + next_run_at=None, + ), + ScheduleState( + task_name="pending-task", + cron_expr="*/10 * * * *", + last_started_at=finished, + last_finished_at=None, + last_status="running", + last_error=None, + last_duration_ms=100, + next_run_at=None, + ), + ] + + recorded = [] + monkeypatch.setattr("ariadne.scheduler.cron.record_schedule_state", lambda *args: recorded.append(args)) + + scheduler = CronScheduler(StatusStorage(), tick_sec=0.01) + scheduler.add_task("failed-task", "*/5 * * * *", lambda: None) + scheduler.add_task("pending-task", "*/10 * * * *", lambda: None) + scheduler._next_run.pop("pending-task") + + scheduler._hydrate_schedule_metrics() + + failed = next(item for item in recorded if item[0] == "failed-task") + pending = next(item for item in recorded if item[0] == "pending-task") + assert failed[2] is None + assert failed[4] is False + assert pending[3] is None + assert pending[4] is None + + def test_compute_next_handles_naive_timestamp() -> None: scheduler = CronScheduler(DummyStorage(), tick_sec=0.1) base = datetime(2024, 1, 1, 12, 0, 0)