K1Guitar/tools/k1_harness/suites/packs_bin123.py

109 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""packs 套件:资源包 1.bin/2.bin/3.bin 加载校验 + 拨片起奏 + 3.bin 尾奏回归.
- 加载: `tone bin1 N` / `tone bin2 N` / `tone bin3 N` → 期望 TONE_* 行 ret=0 且地址 OK
`tone bin2` 依赖新固件命令;缺失时 2.bin 用例记 SKIP
- 起奏: `tone start` 后 3s 内应有 [PITCH] on 事件
- 尾奏(音师需求 20260914: 万能 3.bin 起奏后 `adc key 1 on`(独立尾奏键,
与万能第4段落键同路径 AutoBand_StartOutro→ 之后 4s 内仍应出现 [PITCH] on
不再「一按立刻全静音」;结束 `adc key 1 off`
"""
from __future__ import annotations
from ..transports.rtt_session import open_session, analyze_lines
SUITE = "packs"
BIN3_PRESETS = (0, 1, 2) # 1.1645 / 2.1564 / 3.1364
def _load_and_check(report, sess, cmd: str, tag: str, name: str, *, missing: str = "FAIL") -> bool:
"""发加载命令,校验 <tag> 行。True=有响应False=无响应(按 missing 记结果)."""
sess.pump(0.2)
got = sess.cmd_ack(cmd, tag, timeout_s=4.0, retries=4)
if not got:
report.add(SUITE, name, missing, f"{tag} 响应")
return False
hit = [l for l in sess.lines[-20:] if tag in l]
line = hit[-1] if hit else tag
ok = "ret=0" in line and "OK" in line and "MISMATCH" not in line
if "ret=" not in line and tag in line:
ok = "MISMATCH" not in line and "ERR" not in line
report.add(SUITE, name, "PASS" if ok else "FAIL", line.strip())
return True
def run(report, ctx) -> None:
with open_session(ctx.device) as sess:
if not sess.cmd_ack("log status", "LOG_STATUS", timeout_s=3.0, retries=4):
report.add(SUITE, "RTT 下行探测", "FAIL", "log status 无响应J-Link/固件忙?)")
return
sess.cmd("log clear", 0.3)
_load_and_check(report, sess, "tone bin1 0", "TONE_BIN1", "1.bin 节奏加载 idx0")
if not _load_and_check(report, sess, "tone bin2 0", "TONE_BIN2",
"2.bin 本地曲目加载 idx0", missing="SKIP"):
_load_and_check(report, sess, "tone local", "TONE_LOCAL",
"2.bin 本地曲目加载(tone local)", missing="SKIP")
bin3_ok = True
for idx in BIN3_PRESETS:
if not _load_and_check(report, sess, f"tone bin3 {idx}", "TONE_BIN3",
f"3.bin 万能加载 idx{idx}"):
bin3_ok = False
if not bin3_ok:
report.add(SUITE, "拨片起奏/尾奏", "SKIP", "3.bin 加载失败,级联跳过")
return
# ---- 拨片起奏(万能 idx0----
sess.cmd("log clear", 0.2)
sess.cmd_ack("tone bin3 0", "TONE_BIN3", timeout_s=4.0, retries=3)
base = len(sess.lines)
sess.cmd_ack("tone start", "TONE_START_DONE", timeout_s=3.0, retries=3)
sess.pump(3.0)
pick_lines = sess.lines[base:]
pitch_on = [l for l in pick_lines if "[PITCH]" in l and " on " in l]
report.add(SUITE, "3.bin 拨片起奏有声", "PASS" if pitch_on else "FAIL",
f"{len(pitch_on)} 条 PITCH on" if pitch_on else "起奏后无 PITCH on")
# ---- 尾奏回归 ----
if not sess.cmd_ack("adc key 1 on", "ADC_KEY_OK", timeout_s=2.5, retries=4):
# 兜底:万能第 4 键(固件已映射到 AutoBand_StartOutro
if sess.cmd_ack("chord key 4", "CHORD_KEY_OK", timeout_s=2.0, retries=3):
report.add(SUITE, "3.bin 尾奏触发", "PASS", "chord key 4adc key 不可用)")
else:
report.add(SUITE, "3.bin 尾奏(adc key 1)", "SKIP",
"固件缺少 'adc key'chord key 4 也无 ACK")
sess.cmd_ack("chord key 23", "CHORD_KEY_OK", timeout_s=2.0, retries=3)
return
else:
report.add(SUITE, "3.bin 尾奏触发", "PASS", "ADC_KEY_OK")
out_base = len(sess.lines)
sess.pump(4.0)
outro_lines = sess.lines[out_base:]
outro_pitch = [l for l in outro_lines if "[PITCH]" in l and " on " in l]
stopped = any(("Stop_AutoBand" in l) or ("stop" in l.lower() and "AUTOBAND" in l)
for l in outro_lines)
if outro_pitch:
report.add(SUITE, "3.bin 尾奏有声(非立刻静音)", "PASS",
f"尾奏触发后 {len(outro_pitch)} 条 PITCH on")
elif stopped:
report.add(SUITE, "3.bin 尾奏有声(非立刻静音)", "FAIL",
"尾奏触发后立刻停止3.bin Postamble 数据为空?见音师需求 20260914")
else:
report.add(SUITE, "3.bin 尾奏有声(非立刻静音)", "FAIL",
"尾奏触发后无任何 PITCH on")
sess.cmd_ack("adc key 1 off", "ADC_KEY_OK", timeout_s=2.0, retries=2)
sess.cmd_ack("chord key 23", "CHORD_KEY_OK", timeout_s=2.0, retries=3)
res = analyze_lines(sess.lines)
if res.fail:
report.add(SUITE, "音区映射断言", "FAIL", f"{res.fail} 条 FAIL详见日志")
elif res.ok:
report.add(SUITE, "音区映射断言", "PASS", f"{res.ok} OK / {res.skip} SKIP")
else:
report.add(SUITE, "音区映射断言", "SKIP", "无可分析 PITCH 样本")