sots-engine/tests/shim_trace/oracle_emit.py

96 lines
5.1 KiB
Python

#!/usr/bin/env python3
"""oracle_emit.py HARNESS_DIR CPP_FIXTURE.jsonl
Rebuilds the records test_emitter.cpp::write_oracle_fixture() writes, using the
reference emitter in HARNESS_DIR/mkfixture.py (emit_meta / emit_record), and compares
the two files byte for byte. Exit 0 = identical, 1 = differ, 2 = usage.
Stdlib only.
"""
import sys
def build(mk) -> str:
inf, nan = float("inf"), float("nan")
meta = {"format": 1, "build": "shim-trace test", "exe_sha256": "0" * 64,
"started": "2026-09-07T00:00:00Z", "inline_max": 256,
"hooks": {"Hook::A": {"ftol": 0.0, "ftol_kind": "abs", "ptr": "ignore"},
"Mars::ParseBlock": {"ftol": 1e-6, "ftol_kind": "rel", "ptr": "exact",
"unordered": ["ret.v.items"]}}}
fwd = bytes(range(16))
recs = [
{"ts": 1000, "hook": "CfgVar_RegisterKey", "mode": "trace", "call_id": 0, "thread": 4120, "depth": 0,
"args": [mk.s("Résumé", "key"), mk.i32(-3, "value"), mk.ptr(0x00A36FD0, "table")],
"ret": mk.boolean(True),
"side": {"cfg_table": {"before": mk.by(fwd), "after": mk.by(fwd[::-1])}}},
{"ts": 1037, "hook": "Manifest_Load", "mode": "trace", "call_id": 1, "thread": 4120,
"args": [mk.s("Weapons/_weapons.txt", "path")],
"ret": mk.i32(2, "count"),
"side": {"registry": {"after": mk.struct_({
"entries": mk.lst(mk.struct_({"id": mk.u32(i), "name": mk.s("w%d.weapon" % i)}) for i in (7, 9)),
"deleted": mk.sset(mk.u32(i) for i in (501, 550, 599)),
"flags": mk.enum(2, "MF_0"),
"big": mk.u64(2**60 + 1),
"small": mk.u64(5),
"edge": mk.u64(2**53),
"neg": mk._tv("i64", str(-(2**60)), None), # |v| >= 2^53 -> decimal string (section 3)
"nothing": mk.null(),
"w": mk._tv("wstr", "A€\x00", None)})}}},
{"ts": 1074, "hook": "Mars::ParseBlock", "mode": "trace", "call_id": 2, "thread": 4124, "depth": 1,
"args": [mk.s('Tab\tKey Quote"d Back\\slash nl\nx cr\rx \x01\x7f\xff €', "text"), mk.u32(2, "len")],
"ret": mk.jsonv({"weapon": {"count": 3, "damage": 1.5, "name": "Laser\xe9", "ok": True, "range": 2.25,
"tags": ["a", "b"]}}),
"side": {"scratch": {"after": mk.lst(mk.f32(v) for v in (1.5, 0.1, -2.5e-7, 1e30))},
"nanbox": {"after": mk.f32(nan)},
"infs": {"after": mk.lst([mk._tv("f64", "inf", None), mk._tv("f64", "-inf", None),
mk._tv("f64", 0.1, None), mk._tv("f64", 1e300, None),
mk._tv("f64", 0.0, None)])},
"blob": {"before": None, "after": mk.by(bytes(range(256)) * 2)}}},
{"ts": 1111, "hook": "CfgVar_RegisterKey", "mode": "compare", "call_id": 3, "thread": 4120,
"args": [mk._tv("i8", -128, None), mk._tv("i16", 32767, None), mk._tv("u8", 255, None),
mk._tv("u16", 65535, None), mk.u64(2**53 - 1)],
"ret": mk.null(), "side": {},
"ours": {"ret": mk.null(), "side": {}}, "diverged": False, "diff": []},
{"ts": 1148, "hook": "Manifest_Load", "mode": "compare", "call_id": 4, "thread": 1,
"args": [], "ret": mk.i32(1), "side": {"r": {"after": mk.by(b"\x01\x02")}},
"ours": {"ret": mk.i32(2), "side": {"r": {"after": mk.by(b"\x01\x03")}}},
"diverged": True,
"diff": [{"path": "ret", "why": "exact", "orig": mk.i32(1), "ours": mk.i32(2)},
{"path": "side.r.after", "why": "hash", "orig": mk.by(b"\x01\x02"), "ours": mk.by(b"\x01\x03"),
"first_diff_offset": 1}],
"note": "hello"},
{"ts": 1185, "hook": "X", "mode": "compare", "call_id": 5, "thread": 1,
"args": [], "ret": None, "side": {},
"diverged": True, "diff": [{"path": "call", "why": "err", "orig": None, "ours": "ours threw"}],
"err": "ours threw"},
{"ts": 1222, "hook": "Y", "mode": "replace", "call_id": 6, "thread": 2,
"args": [mk.boolean(False, "flag")], "ret": mk.ptr(0), "side": {}},
]
return mk.emit_meta(meta) + "".join(mk.emit_record(r) for r in recs)
def main(argv):
if len(argv) != 3:
print(__doc__)
return 2
sys.path.insert(0, argv[1])
import mkfixture as mk # noqa: E402
want = build(mk)
with open(argv[2], "r", encoding="utf-8", newline="") as f:
got = f.read()
if got == want:
print("oracle_emit: identical (%d bytes, %d lines)" % (len(want), want.count("\n")))
return 0
gl, wl = got.split("\n"), want.split("\n")
for i, (g, w) in enumerate(zip(gl, wl), 1):
if g != w:
j = next((k for k in range(min(len(g), len(w))) if g[k] != w[k]), min(len(g), len(w)))
print("oracle_emit: line %d differs at column %d" % (i, j + 1))
print(" cpp: ...%s" % g[max(0, j - 40):j + 60])
print(" py: ...%s" % w[max(0, j - 40):j + 60])
return 1
print("oracle_emit: line count differs (cpp %d, py %d)" % (len(gl), len(wl)))
return 1
if __name__ == "__main__":
sys.exit(main(sys.argv))