tooling(micromate): exercise the event chain, and test the 0x06 count candidate
mm_client_check now drives the step-4 client methods rather than the protocol layer directly -- list_events(), iter_events(), get_event() and decode_error() -- so a bench run exercises the code that will actually be used. Prints each ref with the filename it would be stored under, and reports the PVS self-check result per event. The download uses iter_events(), which reproduces THOR's interleaved order. Adds the 0x06 test: reads storage range BEFORE the chain walk, prints content[0:4] as the candidate event count and content[4:8] as the unexplained companion value, then reports AGREES or DISAGREES against the chain length. Two samples on one unit said the count is right; a third value from a different unit either confirms it or kills it, and the tool now answers that in one run. The 0x06 read is wrapped in the same step() helper as everything else, so a unit that does not answer it degrades to a FAILED line rather than aborting the run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
+48
-18
@@ -314,25 +314,55 @@ def main() -> int:
|
|||||||
if setups:
|
if setups:
|
||||||
print(f" first={setups[0]!r} last={setups[-1]!r}")
|
print(f" first={setups[0]!r} last={setups[-1]!r}")
|
||||||
|
|
||||||
|
# ── SUB 0x06: is content[0:4] really the event count? ─────────────
|
||||||
|
# Two samples on one unit said yes, and THOR reads it BEFORE the chain
|
||||||
|
# walk then stops without ever reading the sentinel. A third value
|
||||||
|
# either confirms it or kills it.
|
||||||
|
claimed = None
|
||||||
|
raw06 = step("0x06 storage range", mm.protocol.read_storage_range)
|
||||||
|
if raw06:
|
||||||
|
c = _content(raw06)
|
||||||
|
claimed = int.from_bytes(c[0:4], "big")
|
||||||
|
print(f" content[0:4] = {claimed} <- CANDIDATE: event count")
|
||||||
|
print(f" content[4:8] = {int.from_bytes(c[4:8],'big')} "
|
||||||
|
f"<- unexplained (read 9 alongside a 6 on UM12947)")
|
||||||
|
|
||||||
if a.download:
|
if a.download:
|
||||||
print("\n event chain (read-only):")
|
print("\n event chain (read-only), via MicromateClient:")
|
||||||
proto = mm.protocol
|
t1 = time.monotonic()
|
||||||
proto.arm_event()
|
refs = mm.list_events() # walks to the sentinel
|
||||||
hdr = _content(proto.read_event_first())
|
walk = time.monotonic() - t1
|
||||||
key, size = hdr[0:4], int.from_bytes(hdr[4:8], "big")
|
print(f" {len(refs)} events in {walk:.1f} s "
|
||||||
if not size:
|
f"({walk/max(len(refs),1):.2f} s each, 3 round trips per event)")
|
||||||
print(" no events stored")
|
|
||||||
else:
|
if claimed is not None:
|
||||||
rec = _content(proto.read_event_record(key))
|
verdict = ("✓ AGREES" if claimed == len(refs)
|
||||||
print(f" first event key={key.hex()} size={size} B "
|
else f"✗ DISAGREES (0x06 said {claimed})")
|
||||||
f"type={_event_type(rec)}")
|
print(f" 0x06 count vs chain length: {verdict}")
|
||||||
t1 = time.monotonic()
|
|
||||||
blob = proto.read_event_file(key, size)
|
for ref in refs:
|
||||||
dt = time.monotonic() - t1
|
print(f" {ref}")
|
||||||
print(f" downloaded {len(blob)} B in {dt:.1f} s "
|
print(f" would be filed as {ref.filename}")
|
||||||
f"({len(blob)/dt/1024:.1f} KiB/s)")
|
|
||||||
assert len(blob) == size
|
if refs:
|
||||||
_decode(blob, key, rec)
|
# Download via iter_events, which reproduces THOR's interleaved
|
||||||
|
# order -- the one with captures behind it.
|
||||||
|
print("\n download (first event, THOR's interleaved order):")
|
||||||
|
for ref in mm.iter_events():
|
||||||
|
t1 = time.monotonic()
|
||||||
|
try:
|
||||||
|
result = mm.get_event(ref) # verify=True
|
||||||
|
except Exception as e:
|
||||||
|
print(f" {ref.key_hex}: {type(e).__name__}: {e}")
|
||||||
|
break
|
||||||
|
dt = max(time.monotonic() - t1, 1e-6)
|
||||||
|
n = sum(len(v) for v in getattr(result, "samples", {}).values())
|
||||||
|
err = mm.decode_error(ref, result)
|
||||||
|
check = ("PVS agrees to %+.4f%%" % (100 * err)
|
||||||
|
if err is not None else "PVS check n/a (histogram)")
|
||||||
|
print(f" {ref.key_hex} {ref.record_type:9} {ref.size:6} B "
|
||||||
|
f"in {dt:.1f} s -> {n} samples, {check}")
|
||||||
|
break
|
||||||
|
|
||||||
except ProtocolError as e:
|
except ProtocolError as e:
|
||||||
print(f"\n ABORTED {type(e).__name__}: {e}")
|
print(f"\n ABORTED {type(e).__name__}: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user