import asyncio from contextlib import suppress from app.scheduler import scheduled_probe_loop class EmptyStore: def __init__(self) -> None: self.prune_calls = 0 def list_services(self) -> list[object]: return [] def prune_probes(self, retention_days: int) -> int: assert retention_days == 30 self.prune_calls += 1 return 0 class SyntheticStore(EmptyStore): def demo_active(self) -> bool: return True def list_services(self) -> list[object]: raise AssertionError("synthetic demo must not start live probes") def test_scheduler_runs_first_cycle_before_initial_sleep() -> None: async def scenario() -> None: store = EmptyStore() task = asyncio.create_task( scheduled_probe_loop( store, # type: ignore[arg-type] interval_seconds=3600, timeout_seconds=1.0, retries=0, concurrency=1, retention_days=30, ) ) await asyncio.sleep(0) assert store.prune_calls == 1 task.cancel() with suppress(asyncio.CancelledError): await task asyncio.run(scenario()) def test_scheduler_pauses_live_probes_for_synthetic_demo() -> None: async def scenario() -> None: store = SyntheticStore() task = asyncio.create_task( scheduled_probe_loop( store, # type: ignore[arg-type] interval_seconds=3600, timeout_seconds=1.0, retries=0, concurrency=1, retention_days=30, ) ) await asyncio.sleep(0) assert store.prune_calls == 1 task.cancel() with suppress(asyncio.CancelledError): await task asyncio.run(scenario())