Files
awoooi/scripts/ops/tests/test_backup_alert_label_contract.py

57 lines
1.7 KiB
Python

from __future__ import annotations
import subprocess
import sys
from pathlib import Path
import yaml
ROOT = Path(__file__).resolve().parents[3]
CHECKER = ROOT / "scripts" / "ops" / "backup-alert-label-contract-check.py"
RULES = ROOT / "ops" / "monitoring" / "alerts-unified.yml"
BASELINE = ROOT / "ops" / "reboot-recovery" / "full-stack-backup-baseline.yml"
def _run(rules: Path) -> subprocess.CompletedProcess[str]:
return subprocess.run(
[
sys.executable,
str(CHECKER),
"--rules",
str(rules),
"--baseline",
str(BASELINE),
],
cwd=ROOT,
capture_output=True,
text=True,
check=False,
)
def test_checker_accepts_firing_only_receipt_contract() -> None:
result = _run(RULES)
assert result.returncode == 0, result.stderr
assert "requires receipts only for actively firing backup/Gitea alerts" in result.stdout
assert "BACKUP_ALERT_LABEL_CONTRACT_OK" in result.stdout
def test_checker_rejects_non_firing_receipt_selector(tmp_path: Path) -> None:
payload = yaml.safe_load(RULES.read_text(encoding="utf-8"))
for group in payload["groups"]:
for rule in group.get("rules", []):
if rule.get("alert") == "BackupAlertReceiptStageMissing":
rule["expr"] = str(rule["expr"]).replace(
'alertstate="firing"',
'alertstate="pending"',
)
candidate = tmp_path / "alerts.yml"
candidate.write_text(yaml.safe_dump(payload, allow_unicode=True, sort_keys=False), encoding="utf-8")
result = _run(candidate)
assert result.returncode != 0
assert 'alertstate="firing"' in result.stderr