net-kingdom/tools/coordination-frame/tests/test_render.py
tegwick 2d0681f361
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Adopt shared hourly coordination frame and prepare guarded runtime patches
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a13eab-1e6a-7b33-9c37-372e90ada3a2
2026-10-15 20:45:06 +02:00

127 lines
5.8 KiB
Python

import hashlib
import importlib.util
import json
import shutil
from pathlib import Path
import pytest
import yaml
SCRIPT = Path(__file__).resolve().parents[1] / "render.py"
SPEC = importlib.util.spec_from_file_location("frame_renderer", SCRIPT)
renderer = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(renderer)
WORKSPACE = SCRIPT.parents[3]
@pytest.fixture
def workspace(tmp_path):
required = (
"coordination-engine/config/coordination-frame.json",
"coordination-engine/src/coordination_engine/timing.py",
"approval-engine/cadence.yaml",
"approval-engine/deploy/approval-engine.yaml",
"qonto-assistant/specs/audit-emission-cadence.yaml",
"rapp-qonto/runtime/knative/service.yaml",
"kings-guard/src/kings_guard/fixtures/qonto_assistant_source_cadence.json",
)
if any(not (WORKSPACE / name).is_file() for name in required):
pytest.skip("sibling owner sources required; no fallback frame or contract")
for name in (
"coordination-engine/config/coordination-frame.json",
"coordination-engine/src/coordination_engine/timing.py",
"approval-engine/cadence.yaml",
"approval-engine/deploy/approval-engine.yaml",
"qonto-assistant/specs/audit-emission-cadence.yaml",
"rapp-qonto/runtime/knative/service.yaml",
"kings-guard/src/kings_guard/fixtures/qonto_assistant_source_cadence.json",
):
path = tmp_path / name
path.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(WORKSPACE / name, path)
return tmp_path
@pytest.mark.parametrize("frame_seconds", [600, 3600, 86400])
def test_one_frame_edit_rescales_sources_runtime_and_receiver(workspace, frame_seconds):
config = workspace / renderer.FRAME_REF
config.write_text(
json.dumps({"schema_version": "coordination-frame/v1", "frame_seconds": frame_seconds})
)
_, outputs = renderer.compile_bindings(workspace)
approval = json.loads(outputs[workspace / "approval-engine/cadence.yaml"])
qonto = yaml.safe_load(outputs[workspace / "qonto-assistant/specs/audit-emission-cadence.yaml"])
for entry in approval["sources"]:
if "heartbeat" in entry:
assert entry["heartbeat"]["interval_seconds"] == frame_seconds
extension = entry["heartbeat"]["extensions"]["approval-engine"]
assert extension["requested_observer_max_gap_seconds"] == 2 * frame_seconds
assert extension["effective_deadline_seconds"] == 3 * frame_seconds
for entry in qonto["sources"]:
assert entry["heartbeat"]["interval"] == f"PT{frame_seconds}S"
observer = json.loads(
outputs[
workspace / "kings-guard/src/kings_guard/fixtures/qonto_assistant_source_cadence.json"
]
)
assert observer["sources"][0]["heartbeat"]["interval_seconds"] == frame_seconds
receiver = json.loads(
outputs[
workspace / "net-kingdom/generated/coordination-frame/approval-engine-receiver.json"
]
)
assert set(receiver["heartbeat_classes"].values()) == {2 * frame_seconds}
assert receiver["effective_deadline_seconds"] == 3 * frame_seconds
assert receiver["may_read"] is False
assert receiver["status"] == "proposed-not-applied"
for name in (
"approval-engine/approval_engine/coordination.py",
"qonto-assistant/src/qonto_assistant/coordination.py",
):
assert f"FRAME_SECONDS = {frame_seconds}\n" in outputs[workspace / name]
deploy = yaml.safe_load_all(outputs[workspace / "approval-engine/deploy/approval-engine.yaml"])
workload = next(item for item in deploy if item["kind"] == "StatefulSet")
expected_digest = hashlib.sha256(config.read_bytes()).hexdigest()
assert (
workload["spec"]["template"]["metadata"]["annotations"][
"coordination.coulomb.social/frame-sha256"
]
== expected_digest
)
args = workload["spec"]["template"]["spec"]["containers"][0]["args"]
assert args[args.index("--heartbeat-seconds") + 1] == str(frame_seconds)
service = yaml.safe_load(outputs[workspace / "rapp-qonto/runtime/knative/service.yaml"])
assert (
service["spec"]["template"]["metadata"]["annotations"][
"coordination.coulomb.social/frame-sha256"
]
== expected_digest
)
env = service["spec"]["template"]["spec"]["containers"][0]["env"]
assert next(
item["value"] for item in env if item["name"] == "QONTO_AUDIT_HEARTBEAT_INTERVAL_SECONDS"
) == str(frame_seconds)
def test_render_is_read_only_and_write_is_idempotent_with_drift_detection(workspace, capsys):
before = {path: path.read_bytes() for path in workspace.rglob("*") if path.is_file()}
assert renderer.main(["--workspace", str(workspace)]) == 0
assert all(path.read_bytes() == data for path, data in before.items())
assert renderer.main(["--workspace", str(workspace), "--check"]) == 1
assert renderer.main(["--workspace", str(workspace), "--write"]) == 0
assert renderer.main(["--workspace", str(workspace), "--check"]) == 0
receiver = workspace / "net-kingdom/generated/coordination-frame/approval-engine-receiver.json"
data = json.loads(receiver.read_text())
data["heartbeat_classes"]["revocation"] = 999999
receiver.write_text(json.dumps(data))
assert renderer.main(["--workspace", str(workspace), "--check"]) == 1
def test_invalid_frame_does_not_partially_rewrite_sources(workspace):
config = workspace / renderer.FRAME_REF
config.write_text('{"schema_version":"coordination-frame/v1","frame_seconds":0}')
before = {path: path.read_bytes() for path in workspace.rglob("*") if path.is_file()}
with pytest.raises(SystemExit):
renderer.main(["--workspace", str(workspace), "--write"])
assert all(path.read_bytes() == data for path, data in before.items())