前言¶
在 LLVM / MLIR 相关的开发里,跑测试通常不只是一次 lit 命令。真正有价值的是失败以后的下一层信息:哪个 CHECK 行没过、是哪一行实际输出把它弄坏的、怎么只重跑刚才失败的那些测试。手动做这套闭环时,人要在 lit 输出、测试文件、实际 IR 之间反复切,碎片化的步骤很适合交给会话里的工具。
dsh-lit-filecheck 就是针对这个场景的 DSH 插件。它把 lit + FileCheck 的测试循环拆成三个工具,让会话内的智能体可以按顺序执行「跑一遍、只重跑失败集、单独校验一对文件」,并把失败信息结构化到 CHECK 行级别。下面介绍它提供的能力、安装方式和典型用法。
这是什么¶
dsh-lit-filecheck 是一个 DSH 插件,维护者是 Rcyc-1025,npm 包名 dsh-lit-filecheck@0.1.0,插件 id 为 lit-filecheck。它解决的问题是:让 DSH 会话里的智能体能够执行 lit 测试套件,并从失败输出中提取可定位的 CHECK 诊断,而不是只拿到一段完整的原始 lit 输出。
它属于「工作流」分类,采用 ESM 编写,不启动后台任务,也不持久化状态——重跑目标只存在于当前插件实例的内存里。简单说,会话结束、插件实例销毁,上一次跑了哪些失败就跟着消失。
三个工具分别做什么¶
插件提供三个工具,对应测试闭环中的三件事。
lit_run:在给定的套件根目录运行 llvm-lit,报告 total/passed/failed/skipped,并把每块失败输出拆成单条 CHECK 诊断——指出测试文件里哪一行是 CHECK、实际 IR 的哪一行把它弄坏了。
lit_rerun_failed:只重跑「本插件实例上一次 lit_run」中失败的那些测试,不做全量重新扫描。没有 --filter,命令行里只带上之前失败的测试路径。
filecheck:在一对明确的「含 CHECK 行的测试文件 + 实际 IR 文件」上单独运行一次 FileCheck,报告匹配与不匹配处及出错行。
安装与启用¶
该插件以 DSH bundle 形式提供安装。仓库里的 cordis.patch.yml 负责把插件条目插入会话配置,插件自身的 package.json 也声明了 bundle patch 位置:
"dsh": {
"bundle": {
"patch": "./cordis.patch.yml"
}
}
cordis.patch.yml 的条目结构如下,config 里是插件默认配置:
- insert:
- id: lit-filecheck
name: 'dsh-lit-filecheck'
config:
timeoutMs: 120000
maxOutputBytes: 1048576
maxChecks: 50
logDir: .lit-logs
requireFileCheck: true
engines 要求 Node 版本和 DSH 版本满足:
"engines": {
"node": "^22.19.0 || >=24.0.0",
"dsh": ">=0.2.1-rc.5 <0.3.0-0"
}
一个完整的 npm 安装方式是把该包作为依赖加入,并确保 bundle patch 被读取。具体取决于你当前使用的 DSH bundle 机制,README 中只给出了 cordis.patch.yml 条目本身,没有给出 dsh plugin add 形式的命令,这里就不自行拼接。
配置项¶
插件的配置项集中在一个 config 对象里。toolchainPath 指向 toolchain.json,查找顺序是:该键 > MLIR_TOOLCHAIN_JSON > <session cwd>/mlir-lang/toolchain.json。
litCommand 是完整的 lit argv 数组,优先级最高,例如 ["D:/Code/python/python.exe","D:/Code/llvm-build/bin/llvm-lit.py"];设置后插件不再探测。litPath 指向 llvm-lit.py 或一个可执行文件;.py 文件会自动在前面加上 pythonPath,.cmd / .bat 会被拒绝(cmd 转发在 Windows 上会弄坏参数)。pythonPath 是 .py lit 的解释器,不设时依次尝试 D:/Code/python/python.exe 和 PATH。filecheckPath 指向 FileCheck.exe;不设时在 llvmRoot/bin、D:/Code/llvm-build/bin、D:/Code/llvm/bin 和 PATH 中查找。
运行行为相关的几个键:timeoutMs 默认 120000,是单次 lit 运行的总预算;maxOutputBytes 默认 1048576,是 stdout / stderr 各自保留上限;maxChecks 默认 50,是每次运行解析的 CHECK 诊断上限;logDir 默认 .lit-logs,相对会话 cwd;requireFileCheck 默认 true,为 true 时缺少 FileCheck 直接报 tool-missing,为 false 时只告警并继续跑 lit。
超范围的数字不抛错,只发一条告警并回退到默认值。
典型用法:三件套顺序执行¶
典型的会话流程是先跑一遍套件,再针对失败做隔离。
第一步,lit_run。参数 suiteDir 必填,另有 filter、jobs(1–64)、timeoutMs。插件在 suiteDir 目录下执行:
<litCommand...> -v --no-progress-bar --show-unsupported [--filter=<filter>] [-j <jobs>] .
返回值里有 ok、total、passed、failed、skipped,以及 failures 数组。每块失败含 test、status、reason、runLine 和 checks 数组;每个 checks 条目给出 checkFile、line、column、prefix、pattern、expected、matched、actualLine、actualText、message。另有 logPath、truncated、timedOut、durationMs、preflight、warnings、error。
ok 为 true 的条件是 preflight 通过、退出码为 0、failed === 0 且没有超时。失败的一次运行仍然返回完整的 failures / checks / logPath——真正有信息量的正是这条红的结果。reason 取以下之一:filecheck-mismatch、command-failed、timeout、no-filecheck-diagnostic、unknown。
第二步,lit_rerun_failed。无参数。它执行的命令只带上之前失败的路径,且没有 --filter:
<litCommand...> -v --no-progress-bar <failed test paths...>
几种边界情况:上一次没有失败,则 ok:true, noop:true, total:0,不给 lit 起进程;从未跑过 lit_run,则返回 no-previous-run;某个失败的测试文件已被删除,会出现在 missingTests 并附带告警,全部消失则返回 path-not-found。返回结构与 lit_run 一致,另有 onlyFailed、noop、source{suiteDir,startedAt}、missingTests。
第三步,filecheck。参数 testFile、irFile 都必填,且必须是存在的常规文件,另有 extraArgs 和 timeoutMs(默认 30000)。它执行:
<FileCheck.exe> --color=false <extraArgs...> <testFile> --input-file=<irFile>
extraArgs 里包含 --input-file 或 - 会被拒绝,因为会覆盖 irFile。返回 ok、mismatches[]、stdout、stderr、truncated、logPath、durationMs、error、hint;只有退出码为 0 时 ok 才为 true。测试文件里完全没有 CHECK 指令时返回 no-check-lines,不会被猜成通过。
CHECK 诊断是怎么解析出来的¶
FileCheck 的标准错误行形如:
<check-file>:<line>:<column>: error: CHECK: expected string not found in input
插件把 <line> 这一行读作 pattern,CHECK: 之后的文字读作 expected。actualLine / actualText 来自第一个可用的 note:优先 note: possible intended match located ...,其次 note: scanning from here。两者都不存在时保持为 null,不做任何猜测。
崩溃信息(PLEASE submit a bug report / Stack dump)不会被当成诊断,只会进入日志和 warnings。
日志与错误处理¶
每次运行会把完整输出写入 <logDir>/lit-<yyyyMMdd-HHmmss>-<rand>.log,内容包括 argv、cwd、起止时间、退出码、计数、失败详情和完整的 stdout / stderr。工具返回值里的 stdout / stderr 会按 maxOutputBytes 截断(保留头尾)。如果日志写不进去,logPath 为 null 并附带 log-write-failed 告警,结果本身仍然返回。
失败不会抛异常,而是以 ok:false + error{code,message} + 一条可操作的中文 hint 返回。错误码覆盖:invalid-input、path-not-found、not-a-directory、tool-missing、spawn-failed、timeout、lit-internal-error、no-previous-run、invalid-extra-args、no-check-lines、log-write-failed、parse-failed。
测试与验证状态¶
仓库自带测试。npm test 跑 68 个用例,其中 66 个通过,2 个真实 lit 集成用例默认跳过;npm run smoke 会真的跑一遍 plain 套件并打印三个工具的结果。跑真实集成用例:
$env:LIT_FILECHECK_REAL='1'; node --test --test-isolation=none test/integration.test.mjs
README 记录的验证状态是 2026-11-05 在本机、LLVM 23.1.4 下的结果。lit 一侧已真实验证:test/fixtures/plain/ 有 5 个测试,3 个通过 2 个失败,lit_run 报 total=5/passed=3/failed=2,lit_rerun_failed 恰好重跑那 2 个;失败块解析按捕获的真实输出 test/golden/plain-lit-output.txt 做基准。FileCheck 一侧没有对真实二进制验证:该机 Windows LLVM 23.1.4 包不附带 FileCheck.exe,也没有 MSVC 工具链可编译;CHECK 级解析(line 对应 CHECK 行、actualLine 对应实际 IR 行)由手工编写的 test/golden/filecheck-stderr.txt 和 test/golden/lit-filecheck-output.txt 覆盖。需要在 FileCheck 可用后重跑一次真实 CHECK 级验收。
已知限制¶
三个限制值得在采用前确认。
lit.cfg.py 必须为纯 ASCII。Windows 上 lit 用平台 locale(GBK)读配置文件,出现非 ASCII 注释会因 UnicodeDecodeError 挂掉。
llvm-lit 的 .cmd / .bat 形式会被有意拒绝,请改用 llvm-lit.py 并指定 pythonPath。
在 DSH 受限沙箱下,带管道的 Node spawn 会被拒绝(spawn EPERM),lit 的多进程池会命中 PermissionError,工具返回 spawn-failed;宿主机运行时则正常。
适用场景与注意¶
适合的场景:在 DSH 会话里处理 MLIR / LLVM lit 测试套件,尤其需要把失败定位到 CHECK 行、需要只重跑失败集、或者需要对一对「测试文件 + 实际 IR」单独跑 FileCheck 时。分类属工作流,定位是把测试循环流程化,不是替代 lit 本身。
几点要注意。插件以当前 dsh 进程的权限运行,会执行外部 lit / FileCheck 进程,读取套件目录和日志目录,安装前应先检查源码与许可证(本插件为 MIT 许可,见仓库 LICENSE)。重跑目标只存在插件实例内存中,会话重启后 lit_rerun_failed 无记忆。Windows 上 .cmd / .bat 的 lit 不可用,lit.cfg.py 需要用 ASCII。README 明确 FileCheck 一侧尚未对真实二进制验证,首次接入时建议按上述命令跑一遍真实集成用例再决定。
小结¶
dsh-lit-filecheck 的价值在于把「跑 lit → 拆 CHECK 诊断 → 只重跑失败集 → 单独校验一对文件」这套动作变成会话里可调用的三个工具,并把失败信息结构化到行级。它适合 MLIR / LLVM 测试场景中的重复迭代,代价是需要确认 Windows 下的 lit 路径与 FileCheck 可用性,以及接受 FileCheck 侧目前只有手工 golden 覆盖。
插件目录页:https://www.skillhub.cn/plugins/Rcyc-1025/dsh-lit-filecheck
GitHub:https://github.com/Rcyc-1025/dsh-lit-filecheck