net-kingdom/tools/rotation-lanes/tests/test_check.py
tegwick 666160a390
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
NK-WP-0055-T15: credential rotation-lane register with coverage check
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 308701@bnt-lap001
Assistant-Session: 5548e447-444c-4dcc-bed1-05c16eebfe56
2026-10-28 11:01:08 +01:00

118 lines
3.9 KiB
Python

"""Synthetic tests for the rotation-lane coverage check (NK-WP-0055-T15)."""
import importlib.util
from pathlib import Path
import yaml
SOURCE = Path(__file__).parents[1] / "check.py"
spec = importlib.util.spec_from_file_location("rotation_lanes_check", SOURCE)
rl = importlib.util.module_from_spec(spec)
spec.loader.exec_module(rl)
STANDARD = "# CM\n\n## 6. Secret Rotation\n\n| Secret | Blast |\n|---|---|\n| `APP_SECRET` | Low |\n\n## 7. Next\n| `NOT_IN_SIX` | x |\n"
CRISIS = "| # | Item |\n|---|---|\n| 1 | **key** | a |\n| 2 | ~~retired~~ | b |\n"
def make_root(tmp_path):
(tmp_path / "tools/service-identity/declarations").mkdir(parents=True)
(tmp_path / "canon/standards").mkdir(parents=True)
(tmp_path / "docs").mkdir()
(tmp_path / "workplans").mkdir()
decl = {
"service": "svc",
"identities": [
{"name": "bind", "custody": ["delivered-secret"]},
{"name": "sso", "custody": ["none"]},
],
}
(tmp_path / "tools/service-identity/declarations/svc.yaml").write_text(
yaml.safe_dump(decl)
)
(tmp_path / "canon/standards/credential-management_v0.2.md").write_text(STANDARD)
(tmp_path / "docs/crisis-custody-list.md").write_text(CRISIS)
(tmp_path / "workplans/NK-WP-0001-x.md").write_text("id: NK-WP-0001-T01\n")
return tmp_path
def lane(**over):
base = {
"id": "l1",
"class": "service",
"state": "designed",
"path": "swap it",
"verification": "old refused",
"owner_lane": ["NK-WP-0001-T01"],
"blast_radius": {"level": "low", "affects": ["svc"], "effect": "sessions end"},
"identities": ["svc/bind"],
"credentials": ["APP_SECRET"],
"crisis_items": ["1"],
}
base.update(over)
return base
def test_complete_register_passes(tmp_path):
_, errors = rl.check({"lanes": [lane()]}, make_root(tmp_path))
assert errors == []
def test_missing_coverage_is_reported(tmp_path):
_, errors = rl.check(
{"lanes": [lane(identities=[], credentials=[], crisis_items=[])]},
make_root(tmp_path),
)
assert "no lane for identity svc/bind" in errors
assert "no lane for credential APP_SECRET" in errors
assert "no lane for crisis_item 1" in errors
def test_federated_identity_may_be_named_but_is_not_required(tmp_path):
_, errors = rl.check(
{"lanes": [lane(identities=["svc/bind", "svc/sso"])]}, make_root(tmp_path)
)
assert errors == []
def test_retired_crisis_row_and_other_sections_are_ignored(tmp_path):
_, errors = rl.check(
{
"lanes": [
lane(crisis_items=["1", "2"], credentials=["APP_SECRET", "NOT_IN_SIX"])
]
},
make_root(tmp_path),
)
assert "lane l1 names unknown crisis_items entry 2" in errors
assert "lane l1 names unknown credentials entry NOT_IN_SIX" in errors
def test_lane_fields_and_owner_refs_are_enforced(tmp_path):
bad = lane(
state="maybe",
verification="",
owner_lane=["NK-WP-0099-T01", "bogus"],
blast_radius={"level": "huge"},
)
_, errors = rl.check({"lanes": [bad]}, make_root(tmp_path))
assert any("state must be" in e for e in errors)
assert "l1: verification is empty" in errors
assert any("blast_radius needs" in e for e in errors)
assert "l1: owner_lane NK-WP-0099-T01 not found in workplans/" in errors
assert any("'bogus' is not a workplan" in e for e in errors)
def test_duplicate_assignment_is_reported(tmp_path):
_, errors = rl.check(
{"lanes": [lane(), lane(id="l2", credentials=[], crisis_items=[])]},
make_root(tmp_path),
)
assert "l2: identities svc/bind already in lane l1" in errors
def test_checked_in_register_is_complete():
root = Path(__file__).parents[3]
_, errors = rl.check(
yaml.safe_load((root / "tools/rotation-lanes/lanes.yaml").read_text()), root
)
assert errors == []