Problem
Tests/BestASRKitTests/CLITests.swift 的三個 spawn helper 都在 waitUntilExit() 之前依序抽乾兩條 pipe:
let outData = outPipe.fileHandleForReading.readDataToEndOfFile()
let errData = errPipe.fileHandleForReading.readDataToEndOfFile()
process.waitUntilExit()
(:752-754、:849-850、:950-951)
child 若在 fd 2 寫超過 pipe buffer,parent 還卡在讀 fd 1 → deadlock。而 Swift Testing 沒有 per-test timeout,所以越界的 fixture 是讓 CI 掛住而不是讓它失敗——同 #91 的類別(那次是 1 小時 CI hang)。
Type
bug(測試基礎設施)
Evidence
Round-4 verify 用 Python 複製同樣的讀取順序對 payload 做二分,量到邊界:
stderr payload 60010 bytes -> ok
stderr payload 65546 bytes -> DEADLOCK
boundary: last OK ~65482 bytes on fd 2, first DEADLOCK ~65546 bytes
Darwin pipe capacity = 65 536 bytes,且只有 fd 2 會 deadlock(child 先寫 stderr、parent 先讀 stdout,fd 1 一直在被抽乾)。
目前的 fixture 遠低於邊界(最大的 warning 61 bytes、explanation 33 bytes),安全邊際約 1000×。
為什麼現在開
Round 4 把這條標為 LOW 並判給「separate issue」,然後沒開。1afa2ee(seam)之後它的面積變大:subprocess 測試從 2 個變 6 個、helper 從 1 個變 3 個,而其中 runTranscribe 餵的是真實 router 產出的 warning 文字(不再是測試自己寫死的短字串),所以「payload 由測試完全控制」這個讓它安全的前提弱化了。
約束只活在註解裡
:749-751:
// Read before waiting. Sequential reads are safe only because the
// payload is a few hundred bytes, far under the pipe buffer; a larger
// fixture would need concurrent draining to avoid deadlock.
沒有任何機制阻止下一個人加一則大 warning。
可能的方向(未定案)
- 並行抽乾兩條 pipe(
readabilityHandler,或各開一個 Task)——正解,但三個 helper 都要改。
- 或在 helper 裡對 payload 大小加一個顯式上限斷言,讓越界時失敗而不是掛住。
前者消除問題;後者只是把「掛住」換成「失敗」,但便宜且立刻可見。
發現於 PR #141 round-4 verify(logic + security lens);面積於 round-5 seam 後擴大。相關:#91、#136。
Problem
Tests/BestASRKitTests/CLITests.swift的三個 spawn helper 都在waitUntilExit()之前依序抽乾兩條 pipe:(
:752-754、:849-850、:950-951)child 若在 fd 2 寫超過 pipe buffer,parent 還卡在讀 fd 1 → deadlock。而 Swift Testing 沒有 per-test timeout,所以越界的 fixture 是讓 CI 掛住而不是讓它失敗——同 #91 的類別(那次是 1 小時 CI hang)。
Type
bug(測試基礎設施)
Evidence
Round-4 verify 用 Python 複製同樣的讀取順序對 payload 做二分,量到邊界:
Darwin pipe capacity = 65 536 bytes,且只有 fd 2 會 deadlock(child 先寫 stderr、parent 先讀 stdout,fd 1 一直在被抽乾)。
目前的 fixture 遠低於邊界(最大的 warning 61 bytes、explanation 33 bytes),安全邊際約 1000×。
為什麼現在開
Round 4 把這條標為 LOW 並判給「separate issue」,然後沒開。
1afa2ee(seam)之後它的面積變大:subprocess 測試從 2 個變 6 個、helper 從 1 個變 3 個,而其中runTranscribe餵的是真實 router 產出的 warning 文字(不再是測試自己寫死的短字串),所以「payload 由測試完全控制」這個讓它安全的前提弱化了。約束只活在註解裡
:749-751:沒有任何機制阻止下一個人加一則大 warning。
可能的方向(未定案)
readabilityHandler,或各開一個Task)——正解,但三個 helper 都要改。前者消除問題;後者只是把「掛住」換成「失敗」,但便宜且立刻可見。
發現於 PR #141 round-4 verify(logic + security lens);面積於 round-5 seam 後擴大。相關:#91、#136。