"""native_enc_diff.py — CAN 输出编码回归(不碰网卡,无 Python 后端依赖)。 阶段 4 切换后 Python 基准已删除;本脚本改为对照 native_enc_golden.json (阶段 2 与 Python _fill_can_out 逐字节对拍通过后固化的 4 组用例)。 byte0 是 seq(守护进程状态相关,每次 enctest 都 +1),不参与比对; 其余 383 字节必须逐字节一致,另校验 seq 两两 +1(跳 0) 的递增语义。 用法:native 在 8090 跑着即可(不需要 open/OP):python native_enc_diff.py 重新生成金标准(需 legacy 备份里的 ecat_server.py,一般不需要):见 git 历史/zip。 """ import json import sys import urllib.request GOLDEN = "native_enc_golden.json" URL = "http://127.0.0.1:8090/api/native/enctest" def main(): g = json.load(open(GOLDEN, encoding="utf-8")) cases = g["cases"] body = {"cases": CASES} req = urllib.request.Request(URL, data=json.dumps(body).encode(), headers={"Content-Type": "application/json"}) with urllib.request.urlopen(req) as r: d = json.loads(r.read()) got = d["hexes"] ok = True if len(got) != len(cases): print(f"用例数不符: golden={len(cases)} native={len(got)}") return 1 for i, (a, b) in enumerate(zip(cases, got)): if a[2:] != b[2:]: ok = False diff = [j for j in range(2, len(a), 2) if a[j:j+2] != b[j:j+2]] print(f"用例 {i}: 不一致!差异字节偏移 {diff[:12]}") j = diff[0] print(f" golden[{j}:{j+24}] = {a[j:j+24]}") print(f" native[{j}:{j+24}] = {b[j:j+24]}") else: print(f"用例 {i}: ✅ 383B 逐字节一致(byte0=seq 除外)") seqs = [int(h[:2], 16) for h in got] def nxt(s): s = (s + 1) & 0xFF return 1 if s == 0 else s inc = all(seqs[i + 1] == nxt(seqs[i]) for i in range(len(seqs) - 1)) print(f"seq 递增: {seqs} {'✅' if inc else '❌'}") return 0 if ok and inc else 1 # 与阶段 2 对拍时同一组用例(纯数据)。改动这里 = 改动金标准语义, # 必须连同 native_enc_golden.json 一起重新生成。 CASES = [ # 基础单帧:DLC32 电机 CMD {"win": 0, "ch": 1, "id": 0x30200, "dlc": 32, "data": bytes(range(32)).hex(), "batch": []}, # 批量边界:20×DLC8(332B 区,每项 16B → 20 项 320B,第 21 项 336>332 越界) {"win": 5, "ch": 0, "id": 0x123, "dlc": 8, "data": "AABBCCDDEEFF0011", "batch": [{"ch": 1, "id": 0x300 + i, "dlc": 8, "data": "0102030405060708"} for i in range(21)]}, # dlc=0 只发批量;6×DLC64(每项 72B → 4 项 288B,第 5 项 360 越界) {"win": 20, "ch": 2, "id": 0, "dlc": 0, "data": "", "batch": [{"ch": 2, "id": 0xFFFFF, "dlc": 64, "data": "EE" * 64} for _ in range(6)]}, # 混合 DLC + win 保持 {"win": 255, "ch": 1, "id": 7, "dlc": 32, "data": "11" * 32, "batch": [{"ch": 0, "id": 9, "dlc": 32, "data": "22" * 32}, {"ch": 1, "id": 10, "dlc": 4, "data": "33445566"}, {"ch": 2, "id": 11, "dlc": 12, "data": "55" * 12}]}, ] if __name__ == "__main__": sys.exit(main())