feat(台架工具): 原子性复验能力并进既有 verify_log 并接进 @test——旧口径判 PASS 的缺陷新口径判 FAIL
关键决定是**不造第二只校验器**:卡片原建议把校验器放进 scripts/,但「标记校验」这个 能力已归 .dsh/skills/serial-boot-test/scripts/verify_log.py,再造一只就是本仓反对的 实现漂移(reset.bat 折进技能是同一类判断)。改为扩展它 + 把开关接进 run_boot_test.py ——**不接就等于吸收了没人用得到**;默认路径逐字节不变(不传开关时 exact_check 根本不进)。 新增:--exact 整行锚定(并把「含最长字面串却未整行命中」的邻居原样打出来,那就是 行级交错的特征)、--pair 跨复位配对、--allow-residual 与 --head-char 服务崩溃注入腿、 --include-comments 复现旧行为、--selftest 判别自检。钉长度改成显式 @@LEN=<n> 逃生口, **不再是默认**。 最硬的一条实证(进文档表格,也钉成一条 selftest 用例):同一份缺陷捕获——行首被吃、 尾巴完好的那行 NAND_FTL——旧 --required 子串口径判 **PASS(假绿)**,--exact 判 **FAIL 并打出缺行首的邻居**。口径据此改写:凡是这一行可能丢行首或被插字节的标记,一律 --exact,不许只用子串。 实测不是声称:--selftest 16/16;真日志三向(修复后 PASS / 修复前 FAIL+邻居 / 带 ASCII 溯源头不再被头里的 [ERR] 误报);被动烟测(--flash-cmd 置空 = 不烧录、不动板上镜像、 只采 60 行空闲流量,bench 锁取了即还)证明四个开关在 @test 闭环里**真的执行了**; 空闲流量里 PROF 行长 124/78/123 交替,顺手再证一次「钉长度当默认」会天天假红。 作者自报四个自己的问题(都被自测抓到并修掉,卡里也写了):残留行被重复计成交错邻居 (会假红)、一条断言写反、**CLI 参数忘了接进 verify()——最危险那种:功能静默空跑而 外面看着全绿**、以及误报 run_boot_test.py 变 CRLF(实为自己的检查把换行符写成了字面 量,两个文件复核均为纯 LF,别按那句去查)。 boot_log_data/README.md 里同时有两个道的内容:bench23 的台账行,与 task-25 那条道写的 「证据可达性」规则与 force-add 定案——autostash 往返后两侧都逐一确认仍在。三份 bench23 证据 txt 首次入库(可再生的采集文本;两张非再生 .bin 已随前一笔入库)。
This commit is contained in:
@@ -392,6 +392,23 @@ def main(argv=None):
|
||||
ap.add_argument("--require-order", default=None,
|
||||
help="'>'-separated markers that must appear in that line order "
|
||||
"(catches out-of-order boot steps); empty = off")
|
||||
ap.add_argument("--exact", action="append", default=[],
|
||||
help="repeatable regex that must match a WHOLE firmware line "
|
||||
"(forwarded to verify_log.py --exact). Use it instead of --required "
|
||||
"for any marker whose line could lose its head or gain spliced "
|
||||
"bytes -- substring matching cannot see that class of damage. "
|
||||
"Suffix '@@LEN=<n>' pins byte length: opt-in only, lengths belong "
|
||||
"to one image")
|
||||
ap.add_argument("--pair", action="append", nargs=2, metavar=("FIRST", "THEN"), default=[],
|
||||
help="repeatable cross-reset pairing (exactly one FIRST, then exactly "
|
||||
"one THEN after it), e.g. --pair MEMFAULT 'reset cause:'")
|
||||
ap.add_argument("--allow-residual", type=int, default=0,
|
||||
help="accept up to N stray bytes before the line head on a --exact hit "
|
||||
"(crash-dump legs: 1 leftover from a reset mid-byte is known; "
|
||||
"recorded, not a failure)")
|
||||
ap.add_argument("--head-char", default="",
|
||||
help="every --exact hit must start with this char after the optional "
|
||||
"residual prefix (crash-dump legs: '[')")
|
||||
ap.add_argument("--done-marker", default=None,
|
||||
help="marker whose line marks boot completion (for --max-boot-ms); "
|
||||
"empty = don't measure")
|
||||
@@ -743,7 +760,9 @@ def main(argv=None):
|
||||
expect_reset_cause=args.expect_reset_cause,
|
||||
require_order=args.require_order,
|
||||
done_marker=args.done_marker,
|
||||
max_boot_ms=args.max_boot_ms)
|
||||
max_boot_ms=args.max_boot_ms,
|
||||
exact=args.exact, pairs=args.pair,
|
||||
allow_residual=args.allow_residual, head_char=args.head_char)
|
||||
if selftest_forced_fail and rc == 0:
|
||||
# 标记校验全过,但自检台账判定根本没能执行(无数据源 / 抓取失败 / 无法证明无新增)
|
||||
# —— 这类"判不了"必须以 FAIL 收口,否则就又回到假绿。
|
||||
|
||||
Reference in New Issue
Block a user