"""MAS backup failure notices: queued privately, delivered with a verified echo, replayed.""" import importlib.util import json from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[1] spec = importlib.util.spec_from_file_location("notify", ROOT / "scripts/mas_evidence_notify.py") nt = importlib.util.module_from_spec(spec) spec.loader.exec_module(nt) class Hub: def __init__(self, down=False): self.down, self.sent = down, [] def __call__(self, base, message): if self.down: raise OSError("hub unreachable") self.sent.append(message) return f"00000000-0000-0000-0000-{len(self.sent):012d}" def test_backup_failure_is_delivered_to_platform_root(tmp_path): hub = Hub() result = nt.notify(tmp_path / "n", unit="mas-evidence-backup.service", sender=hub) assert result["status"] == "inbox_delivery_verified" and len(result["message_ids"]) == 1 message = hub.sent[0] assert message["to_agent"] == "platform-root" and message["subject"] == "MAS evidence backup failure" body = json.loads(message["body"]) assert body["unit"] == "mas-evidence-backup.service" and body["test"] is False assert "never delete retained objects" in body["action"] def test_stale_notice_has_its_own_subject(tmp_path): hub = Hub() nt.notify(tmp_path / "n", unit="mas-evidence-freshness.service", sender=hub) assert hub.sent[0]["subject"] == "MAS evidence backup stale" def test_hub_outage_keeps_the_notice_and_replay_delivers_it_once(tmp_path): state = tmp_path / "n" down = nt.notify(state, unit="mas-evidence-backup.service", sender=Hub(down=True)) assert down["status"] == "pending_notification_requires_replay" and len(down["pending_event_ids"]) == 1 hub = Hub() replay = nt.notify(state, sender=hub) assert replay["status"] == "inbox_delivery_verified" and len(hub.sent) == 1 again = Hub() nt.notify(state, sender=again) assert again.sent == [] def test_test_unit_marks_the_notice_as_a_test(tmp_path): hub = Hub() nt.notify(tmp_path / "n", unit="mas-evidence-alert-test.service", sender=hub) assert hub.sent[0]["subject"] == "MAS evidence notification test" assert json.loads(hub.sent[0]["body"])["test"] is True def test_unknown_unit_is_refused(tmp_path): with pytest.raises(nt.Refused): nt.notify(tmp_path / "n", unit="sshd.service", sender=Hub()) def test_echo_mismatch_is_not_counted_as_delivered(tmp_path): def tampering(base, message): raise nt.Refused("inbox_receipt_not_verified") result = nt.notify(tmp_path / "n", unit="mas-evidence-backup.service", sender=tampering) assert result["status"] == "pending_notification_requires_replay" record = json.loads(next((tmp_path / "n").glob("*.json")).read_text()) assert record["status"] == "pending"