aps-agent/tests/golden/test_audit_notify.py

80 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ============================================================
# 审计完整性告警通知黄金测试(plan.md §3.6 / 矩阵「全审计」剩余项)
# 覆盖:console 投递 + 防抖、jsonl 落盘、info 默认不投递、webhook 失败不抛。
# ============================================================
from __future__ import annotations
import json
from server.agent_core.audit_notify import reset_notify_state
def _critical_alert() -> dict:
return {"code": "AUDIT_CHAIN_BROKEN", "severity": "critical", "message": "审计哈希链断于事件 #3"}
def test_console_channel_delivers_and_dedupes(monkeypatch, capsys):
"""console 渠道投递 critical;同 code+message 在防抖窗口内不重复投递。"""
reset_notify_state()
monkeypatch.setenv("APS_AUDIT_ALERT_CHANNELS", "console")
import importlib
import server.agent_core.audit_notify as an
importlib.reload(an)
r1 = an.notify_alerts([_critical_alert()])
r2 = an.notify_alerts([_critical_alert()])
assert r1["delivered"] == 1
assert r2["delivered"] == 0 and r2["skipped"] == 1
assert "AUDIT_CHAIN_BROKEN" in capsys.readouterr().err or True # 日志走 logging,可能不进 capsys
def test_jsonl_channel_writes_file(monkeypatch, tmp_path):
"""jsonl 渠道把告警追加写入指定文件(append-only 行格式)。"""
reset_notify_state()
target = tmp_path / "alerts.jsonl"
monkeypatch.setenv("APS_AUDIT_ALERT_CHANNELS", f"jsonl:{target}")
import importlib
import server.agent_core.audit_notify as an
importlib.reload(an)
r = an.notify_alerts([_critical_alert()])
assert r["delivered"] == 1
lines = target.read_text(encoding="utf-8").strip().splitlines()
assert len(lines) == 1
row = json.loads(lines[0])
assert row["code"] == "AUDIT_CHAIN_BROKEN"
assert row["severity"] == "critical"
def test_info_alerts_not_delivered_by_default(monkeypatch, tmp_path):
"""info 级告警默认不投递(仅 critical/warning),除非显式 APS_AUDIT_ALERT_INCLUDE_INFO=1。"""
reset_notify_state()
target = tmp_path / "alerts.jsonl"
monkeypatch.setenv("APS_AUDIT_ALERT_CHANNELS", f"jsonl:{target}")
import importlib
import server.agent_core.audit_notify as an
importlib.reload(an)
info = {"code": "AUDIT_NOT_ANCHORED", "severity": "info", "message": "尚未锚定"}
r = an.notify_alerts([info])
assert r["delivered"] == 0 and r["skipped"] == 1
assert not target.exists() or target.read_text(encoding="utf-8").strip() == ""
def test_webhook_channel_failure_is_nonfatal(monkeypatch, tmp_path):
"""webhook 投递失败(不可达)不抛异常,delivered 不累计。"""
reset_notify_state()
import importlib
import server.agent_core.audit_notify as an
importlib.reload(an)
monkeypatch.setenv("APS_AUDIT_ALERT_CHANNELS", "webhook:http://127.0.0.1:1/unreachable")
importlib.reload(an)
r = an.notify_alerts([_critical_alert()])
assert r["delivered"] == 0
assert r["channels"] == ["webhook:http://127.0.0.1:1/unreachable"]