Establish a golden master of the current routing core's emitted packets so the forward_group extraction (and the later OBP/HBP unification) can be proven to change nothing on the wire. - tests/harness.cfg: self-contained topology (2 HBP masters, 1 HBP peer, 2 OBPs) so scenarios can cover every source/target combination including OBP<->OBP. - tests/baseline_scenarios.py: deterministic full-call scenarios -- HBP<->HBP (same slot, cross slot with TS-bit flip, TGID rewrite), HBP<->OBP, OBP->HBP, OBP->OBP, multi-target fan-out, and a contention case where the second stream is correctly blocked. - tests/baseline_emissions.json: frozen emissions captured from current code. - tests/test_baseline.py: replays the scenarios and asserts byte-identical match. Verified the baseline distinguishes real semantics (cross-slot flips the TS bit, TGID rewrite applies, HBP targets get 55-byte frames with BER/RSSI while OBP targets get 53-byte frames without) and that a single changed byte fails the test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
51 lines
1.8 KiB
Python
51 lines
1.8 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Golden-master test: replays the fixed scenarios in baseline_scenarios.py
|
|
# through the current routing core and asserts the emitted packets match the
|
|
# frozen baseline in baseline_emissions.json byte-for-byte.
|
|
#
|
|
# This is the safety net for the routing refactor: regenerate the baseline ONLY
|
|
# from known-good code (python tests/baseline_scenarios.py shows current output;
|
|
# the file was frozen from the pre-refactor code). After the forward_group
|
|
# extraction and the later unification, this test must still pass unchanged.
|
|
#
|
|
# Run from the repo root: venv/bin/python -m unittest discover -s tests
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
sys.path.insert(0, os.path.dirname(_HERE))
|
|
sys.path.insert(0, _HERE)
|
|
|
|
import baseline_scenarios
|
|
|
|
BASELINE = os.path.join(_HERE, 'baseline_emissions.json')
|
|
|
|
|
|
class TestRoutingBaseline(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
with open(BASELINE) as f:
|
|
cls.expected = json.load(f)
|
|
|
|
def test_scenarios_match_frozen_baseline(self):
|
|
# Same set of scenarios as when the baseline was frozen.
|
|
self.assertEqual(set(baseline_scenarios.SCENARIOS),
|
|
set(self.expected),
|
|
'scenario set drifted from the frozen baseline')
|
|
|
|
for name in sorted(baseline_scenarios.SCENARIOS):
|
|
with self.subTest(scenario=name):
|
|
got = baseline_scenarios.SCENARIOS[name]()
|
|
# JSON round-trips tuples to lists; normalize for comparison.
|
|
got = [[s, h] for (s, h) in got]
|
|
self.assertEqual(got, self.expected[name],
|
|
'emissions changed for scenario %r' % name)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|