Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
#!/usr/bin/env python3
"""Tests for Phase-3 self-healing: heal(), humanize(), and the pure recovery checks.
Run: python3 tools/test_heal.py"""
import tempfile
import heal as H
import recovery
from pcbflow_log import PhaseLogger
def _logger(root):
return PhaseLogger("p", "ph", root=root)
def test_humanize():
d = {"title": "X frozen", "why": "because Z", "class": "EDA-7",
"retryable": True, "human_message": "do Y"}
failed = H.humanize(d, "tried a reset", False)
assert "What happened: X frozen" in failed and "Why: because Z" in failed
assert "What you need to do: do Y" in failed
ok = H.humanize(d, "tried a reset", True)
assert "Recovered automatically" in ok and "What you need to do" not in ok
def test_heal_success():
with tempfile.TemporaryDirectory() as t:
r = H.heal(_logger(t), "step", lambda: 5)
assert r["ok"] and r["v"] == 5
def test_heal_recovers_after_fix():
# first call fails (session expired), the recovery fixes it, the retry succeeds
with tempfile.TemporaryDirectory() as t:
state = {"n": 0}
def action():
state["n"] += 1
if state["n"] == 1:
raise Exception("HTTP 401 Unauthorized")
return "wired"
r = H.heal(_logger(t), "step", action, recoveries={"session": lambda: True})
assert r["ok"] and r.get("recovered") and r["v"] == "wired" and state["n"] == 2
assert "Recovered automatically" in r["human"]
def test_heal_escalates_when_no_recovery():
# KI-5 (kicad missing) has no automatic recovery → escalate with a human message
with tempfile.TemporaryDirectory() as t:
def action():
raise Exception("kicad-cli: command not found")
r = H.heal(_logger(t), "step", action, recoveries={})
assert r["ok"] is False
assert r["diagnosis"]["class"] == "KI-5"
assert "install kicad" in r["human"].lower()
def test_heal_non_idempotent_does_not_rerun():
# a non-idempotent live write is fixed but NOT auto-re-run (asks the engineer)
with tempfile.TemporaryDirectory() as t:
state = {"n": 0}
def action():
state["n"] += 1
raise Exception("HTTP 429 Too Many Requests")
r = H.heal(_logger(t), "step", action,
recoveries={"backoff": lambda: True}, idempotent=False)
assert r["ok"] is False and r.get("env_fixed") and state["n"] == 1
assert "say 'retry'" in r["human"]
def test_kicad_import_checks():
assert recovery.verify_kicad_import(113, 113)["ok"]
res = recovery.verify_kicad_import(113, 109)
assert res["ok"] is False and res["dropped"] == 4
assert recovery.missing_mounting_holes(["H1", "H2", "H3"], ["H1", "H3"]) == ["H2"]
if __name__ == "__main__":
test_humanize()
test_heal_success()
test_heal_recovers_after_fix()
test_heal_escalates_when_no_recovery()
test_heal_non_idempotent_does_not_rerun()
test_kicad_import_checks()
print("PASS — heal: engine, humanize, escalation, non-idempotent guard, KiCad checks (6/6).")
7315b96d0This file is pinned to the selected release. Download the original to open it in your design tool.