"""Tests for the file-based audit/heartbeat logging (core/audit.py).""" import json from core import audit def test_log_heartbeat_writes_a_queryable_record(tmp_path, monkeypatch): # The observability stack (Alloy → Loki) tails these JSONL files and lifts # `level`/`tag` into labels, so a heartbeat must carry exactly those fields for # the dashboard to query notifier liveness as {job="app-json", tag="heartbeat"}. monkeypatch.setattr(audit, "HEARTBEAT_DIR", str(tmp_path)) audit.log_heartbeat("subscription-notifier", 900) files = list(tmp_path.glob("heartbeat-*.jsonl")) assert len(files) == 1 rec = json.loads(files[0].read_text().strip()) assert rec["tag"] == "heartbeat" assert rec["level"] == "info" assert rec["daemon"] == "subscription-notifier" assert rec["interval_s"] == 900 assert "ts" in rec def test_log_heartbeat_never_raises(monkeypatch): # Best-effort, like the rest of audit: an unwritable dir must not bubble up into # the notifier loop (which is why the loop can rely on calling it unguarded). monkeypatch.setattr(audit, "HEARTBEAT_DIR", "/proc/nonexistent/cannot-write") audit.log_heartbeat("subscription-notifier", 900) # no exception