feat: add HIL diagnostics and meter health handling

This commit is contained in:
2026-08-17 22:33:04 +02:00
parent bc2ac6e8f6
commit aa25aa2c12
30 changed files with 2108 additions and 236 deletions
+48
View File
@@ -0,0 +1,48 @@
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "tools" / "hil"))
from hil_common import parse_hil_line
from meter_simulator import fixture, frame
from report import evaluate
def test_parse_structured_trace():
parsed = parse_hil_line(b'noise HIL:{"event":"boot","ms":12}\r\n')
assert parsed == {"event": "boot", "ms": 12}
assert parse_hil_line(b'HIL:not-json\n') is None
def test_meter_fixtures_are_bounded_and_recoverable():
valid = frame()
assert valid.startswith(b"/") and b"0-0:96.8.0*255" in valid and b"1-0:1.8.0*255" in valid
assert valid.rstrip().endswith(b"!")
malformed_then_valid = fixture("malformed_then_valid")
assert len(malformed_then_valid) == 2
assert malformed_then_valid[-1][0] == valid
assert len(fixture("oversized")[0][0]) > 512
def test_report_requires_end_to_end_batch_correlation():
events = [
{"event": "role", "source": "sender", "role": "sender"},
{"event": "role", "source": "receiver", "role": "receiver"},
{"event": "boot", "source": "sender"},
{"event": "boot", "source": "receiver"},
{"event": "time_bootstrap", "source": "sender", "stage": "complete", "ok": True},
{"event": "meter_frame", "source": "sender", "ok": True},
{"event": "health", "source": "sender"},
{"event": "health", "source": "receiver"},
{"event": "batch_created", "source": "sender", "batch_id": 7},
{"event": "reassembly_complete", "source": "receiver", "batch_id": 7},
{"event": "payload_decode", "source": "receiver", "batch_id": 7, "ok": True},
{"event": "ack_tx", "source": "receiver", "batch_id": 7, "ok": True},
{"event": "ack_rx", "source": "sender", "batch_id": 7, "ok": True},
]
results = {check.name: check.status for check in evaluate(events)}
assert results["batch and ACK correlation"] == "pass"
assert all(status == "pass" for status in results.values())