dsh-lit-filecheck:把 lit + FileCheck 測試閉環帶進 DSH 會話

前言

在 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

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜