66 lines
2.6 KiB
Python
66 lines
2.6 KiB
Python
import unittest
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
from src.services.runtime.runtime_task_watchdog_service import RuntimeTaskWatchdogService
|
|
|
|
|
|
class RuntimeTaskWatchdogServiceTests(unittest.TestCase):
|
|
def test_build_watchdog_returns_empty_when_tasks_are_fresh(self) -> None:
|
|
now = datetime(2026, 5, 12, 0, 0, tzinfo=timezone.utc)
|
|
service = RuntimeTaskWatchdogService(stale_multiplier=3, min_stuck_seconds=120)
|
|
tasks = {
|
|
"watch": {
|
|
"interval_seconds": 20,
|
|
"last_status": "ok",
|
|
"run_count": 1,
|
|
"last_completed_ts": (now - timedelta(seconds=10)).isoformat(),
|
|
"last_success_ts": (now - timedelta(seconds=10)).isoformat(),
|
|
}
|
|
}
|
|
|
|
payload = service.build_watchdog(tasks, checked_ts=now)
|
|
|
|
self.assertEqual(payload["stalled_task_count"], 0)
|
|
self.assertEqual(payload["warning_codes"], [])
|
|
|
|
def test_build_watchdog_flags_running_task_that_exceeds_threshold(self) -> None:
|
|
now = datetime(2026, 5, 12, 0, 0, tzinfo=timezone.utc)
|
|
service = RuntimeTaskWatchdogService(stale_multiplier=3, min_stuck_seconds=120)
|
|
tasks = {
|
|
"watch": {
|
|
"interval_seconds": 20,
|
|
"last_status": "running",
|
|
"run_count": 1,
|
|
"last_started_ts": (now - timedelta(seconds=180)).isoformat(),
|
|
}
|
|
}
|
|
|
|
payload = service.build_watchdog(tasks, checked_ts=now)
|
|
|
|
self.assertEqual(payload["stalled_task_count"], 1)
|
|
self.assertEqual(payload["stalled_tasks"][0]["reason"], "running_too_long")
|
|
self.assertIn("runtime_task_stalled:watch:running_too_long", payload["warning_codes"])
|
|
|
|
def test_build_watchdog_flags_overdue_task(self) -> None:
|
|
now = datetime(2026, 5, 12, 0, 0, tzinfo=timezone.utc)
|
|
service = RuntimeTaskWatchdogService(stale_multiplier=3, min_stuck_seconds=120)
|
|
tasks = {
|
|
"alert_dispatch": {
|
|
"interval_seconds": 20,
|
|
"last_status": "ok",
|
|
"run_count": 2,
|
|
"last_completed_ts": (now - timedelta(seconds=180)).isoformat(),
|
|
"last_success_ts": (now - timedelta(seconds=180)).isoformat(),
|
|
}
|
|
}
|
|
|
|
payload = service.build_watchdog(tasks, checked_ts=now)
|
|
|
|
self.assertEqual(payload["stalled_task_count"], 1)
|
|
self.assertEqual(payload["stalled_tasks"][0]["reason"], "overdue")
|
|
self.assertIn("runtime_task_stalled:alert_dispatch:overdue", payload["warning_codes"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|