RX-tx understanding
This commit is contained in:
93
tests/test_rx_branch_trace.py
Normal file
93
tests/test_rx_branch_trace.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import io
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from h8536.rx_branch_trace import analyze_rx_branch_trace, format_text_report, main
|
||||
|
||||
|
||||
def ins(address: int, text: str | None = None) -> dict[str, object]:
|
||||
return {
|
||||
"address": address,
|
||||
"text": text or f"INS_{address:04X}",
|
||||
"mnemonic": (text or "NOP").split()[0],
|
||||
"operands": "",
|
||||
"kind": "normal",
|
||||
"targets": [],
|
||||
"references": [],
|
||||
}
|
||||
|
||||
|
||||
def fixture_payload() -> dict[str, object]:
|
||||
addresses = {
|
||||
0x3FEF, 0x3FF3, 0x3FF5, 0x3FF9, 0x3FFD, 0x4001, 0x4003, 0x4007,
|
||||
0xBB57, 0xBB5B, 0xBB5F, 0xBB63, 0xBB67, 0xBB6D, 0xBB71, 0xBB75,
|
||||
0xBB77, 0xBB7D, 0xBB82, 0xBB84, 0xBB88, 0xBB8A, 0xBB90, 0xBB96,
|
||||
0xBB9A, 0xBB9C, 0xBB9E, 0xBBA3, 0xBBAB, 0xBBB0, 0xBBB3, 0xBBCB,
|
||||
0xBBCF, 0xBBD3, 0xBBD6, 0xBBD8, 0xBBDC, 0xBBE0, 0xBBE4, 0xBBE8,
|
||||
0xBBEC, 0xBBF0, 0xBBF3, 0xBBF7, 0xBBFD, 0xBC01, 0xBC08, 0xBC0C,
|
||||
0xBC0F, 0xBC13, 0xBC15, 0xBC19, 0xBC1D, 0xBC20, 0xBC24, 0xBC29,
|
||||
0xBC2E, 0xBC33, 0xBC37, 0xBC3A, 0xBC3C, 0xBC3E, 0xBC42, 0xBC45,
|
||||
0xBC4A, 0xBC4F, 0xBC54, 0xBC5C, 0xBC60, 0xBC63, 0xBC67, 0xBC69,
|
||||
0xBC75, 0xBC79, 0xBC82, 0xBC86, 0xBCB0, 0xBCCD, 0xBCD0, 0xBCD7,
|
||||
0xBCE0, 0xBCE8, 0xBCEC, 0xBCF0, 0xBCF6, 0xBCFA, 0xBCFD, 0xBD04,
|
||||
0xBD08, 0xBD0B, 0xBD0E, 0xBD1A, 0xBD1E, 0xBD22, 0xBD26, 0xBD35,
|
||||
0xBD64, 0xBD67, 0xBD6D, 0xBD75, 0xBD79, 0xBD80, 0xBD85, 0xBD94,
|
||||
0xBD9A, 0xBDB5, 0xBDBF, 0xBDC2, 0xBDC8, 0xBDD0, 0xBDD4, 0xBDDB,
|
||||
0xBDE5, 0xBDE9, 0xBDED, 0xBDF3, 0xBDFB, 0xBDFF, 0xBE05, 0xBE09,
|
||||
0xBE0D, 0xBE11, 0xBE15, 0xBE19, 0xBE1D, 0xBE22, 0xBE27, 0xBE29,
|
||||
0xBE2D, 0xBE31, 0xBE33, 0xBE37, 0xBE3C, 0xBE3E, 0xBE43, 0xBE47,
|
||||
0xBE4D, 0xBE52, 0xBE5A, 0xBE62, 0xBE6A, 0xBE70, 0xBE78, 0xBE80,
|
||||
0xBE82, 0xBE84, 0xBE88, 0xBE91, 0xBE95, 0xBE99, 0xBE9D, 0xBE9E,
|
||||
0xBEA5, 0xBEA9, 0xBEAD, 0xBEAF, 0xBEB5, 0xBEBB, 0xBEBF, 0xBEC1,
|
||||
0xBEC5, 0xBECB, 0xBED1, 0xBED5, 0xBEE4,
|
||||
}
|
||||
return {"instructions": [ins(address) for address in sorted(addresses)]}
|
||||
|
||||
|
||||
class RxBranchTraceTest(unittest.TestCase):
|
||||
def test_analyzes_dispatch_split_and_commands(self):
|
||||
analysis = analyze_rx_branch_trace(fixture_payload())
|
||||
|
||||
self.assertEqual(analysis["summary"]["confidence"], "high")
|
||||
self.assertEqual(analysis["frame_model"]["checksum_seed"], 0x5A)
|
||||
self.assertTrue(analysis["stages"][2]["present"])
|
||||
self.assertIn("FAA2 != 0", analysis["stages"][2]["summary"])
|
||||
|
||||
commands = {command["command"]: command for command in analysis["commands"]}
|
||||
self.assertIn("continuation path only", commands[0x04]["availability"])
|
||||
self.assertIn("selector zero is special", "\n".join(commands[0x04]["side_effects"]))
|
||||
self.assertIn("selectors 0x006C", "\n".join(commands[0x05]["side_effects"]))
|
||||
self.assertIn("previous finalized TX frame", commands[0x07]["summary"])
|
||||
|
||||
def test_text_report_mentions_bench_implications(self):
|
||||
text = format_text_report(analyze_rx_branch_trace(fixture_payload()))
|
||||
|
||||
self.assertIn("H8/536 SCI1 RX Branch Trace", text)
|
||||
self.assertIn("cmd 0x04 continuation_set_value_candidate", text)
|
||||
self.assertIn("standalone command 4 frame from idle should not hit BD0E", text)
|
||||
self.assertIn("Command 5 is not a generic always-live ACK", text)
|
||||
self.assertIn("Selector Decode", text)
|
||||
self.assertIn("TXI/RXI race and continuation collapse", text)
|
||||
self.assertIn("RX-to-TX Feedback Loops", text)
|
||||
|
||||
def test_cli_writes_json_output(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
input_path = Path(tmp) / "rom.json"
|
||||
output_path = Path(tmp) / "rx.json"
|
||||
input_path.write_text(json.dumps(fixture_payload()), encoding="utf-8")
|
||||
stdout = io.StringIO()
|
||||
|
||||
rc = main(["--json", "--out", str(output_path), str(input_path)], stdout=stdout)
|
||||
|
||||
self.assertEqual(rc, 0)
|
||||
self.assertIn("wrote", stdout.getvalue())
|
||||
payload = json.loads(output_path.read_text(encoding="utf-8"))
|
||||
self.assertEqual(payload["kind"], "rx_branch_trace")
|
||||
self.assertIn("downstream_traces", payload)
|
||||
self.assertIn("feedback_loops", payload)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user