Go Wiki:Watchflakes
Watchflakes 是一個程式,用於分類 build.golang.org 儀表板上的明顯測試瑕疵。
明顯的測試瑕疵是一種失敗,其
- 不在完全失敗的建構器上。
- 不在 排除的建構器 上。
- 未執行在 4 個或更多建構器上失敗的提交。
- 未包含在其建構器上 4 個或更多失敗提交的執行中。
Watchflakes 會將每個明顯的測試瑕疵張貼到 測試瑕疵專案 中的問題。
測試瑕疵專案中的每個問題說明都以與該問題相關的失敗模式開頭:例如,#55260 說明的標記開頭為
```
#!watchflakes
post <- pkg == "cmd/go" && test == "" && `unexpected files left in tmpdir`
```
Watchflakes 會將每個明顯的測試瑕疵與問題中的模式進行比對
- 如果瑕疵與問題中的模式相符,則會張貼到該問題。
- 如果瑕疵與多個問題中的模式相符,則會張貼到編號最小的問題。
- 如果瑕疵與任何問題中的模式都不相符,Watchflakes 會建立一個新的問題,其中包含與失敗的套件和測試案例相符的模式。
新建立的問題模式通常過於廣泛,應予以編輯,使其更具體地說明實際失敗。將失敗傳送至編號最小的相符問題可確保為新的失敗建立廣泛的預設模式不會「竊取」先前問題的失敗,也不會讓新的問題充斥著同一個測試中已個別追蹤的不相關失敗。
Watchflakes 會將新建立的問題置於測試瑕疵專案中,並新增 NeedsInvestigation 標籤。這些問題一開始沒有狀態(不是 Active,也不是 Done)。沒有狀態的問題需要由人員檢查,通常應精簡模式以擷取關於失敗的顯著資訊。已檢查的問題接著可以移至 Active。當問題關閉時,GitHub 會自動將問題從 Active 移至 Done。
Watchflakes 在比對新故障時會考慮任何狀態的問題。如果它為已關閉的問題找到新故障,它會張貼故障並重新開啟問題。因此,在修正程式發布時可以關閉問題,而不必等上數週來確認故障是否真的已消失:如果出現新故障,問題將會自動重新開啟。
Watchflakes 沒有維護自己的狀態:所有狀態都位於 GitHub 問題中。每次執行時,它會考慮過去 60 天的建置儀表板故障,並確保 Test Flakes 專案中已記錄所有明顯的瑕疵。當然,如果已將比對問題的故障張貼到該問題,watchflakes 就不會再次張貼。如果編輯問題以更新其模式以排除特定故障,watchflakes 也不會移除其舊張貼,但它會為這些故障尋找不同的比對問題,包括可能建立新問題。
語法
每個問題中的 watchflakes 節必須出現在問題說明的最上方。它必須是程式碼區塊(使用 ```
圍起來或縮排),第一行必須是 #!watchflakes
,以防止 watchflakes 誤解不相關的程式碼區塊。
區塊的其餘部分是一個小型 watchflakes 腳本。行尾註解以 #
開頭。腳本是一系列規則,每個規則的格式為 動作 <- 模式
(將與模式比對的結果傳送至動作)。
動作
動作為
張貼
將故障張貼至腳本出現的問題中。略過
忽略故障,將其丟棄。此動作應僅在罕見情況下使用(例如,設定如 #55166 中的政策)。default
是優先順序較低的 post 版本。如果問題有與失敗相符的post
或skip
,watchflakes 會執行該操作。但如果沒有其他相符項,watchflakes 會將default
模式視為相符項。(然後,如果沒有任何default
相符項,watchflakes 會建立新的問題。)
記錄
模式的輸入是具有命名欄位的記錄,每個欄位都有字串值
-
pkg
是無法建置或測試失敗的套件的完整匯入路徑。 -
test
是套件中測試函數的名稱,該函數測試失敗。 -
mode
是build
或test
,視此為建置失敗或測試失敗而定。 -
output
是來自失敗測試的輸出。此輸出會在測試二進位檔結束時列印最後的FAIL
行之前停止。它不包含在同一執行階段中也失敗的其他測試案例的輸出,也不包含 all.bash 或建置模組在測試開始前列印的任何內容。 -
log
是整個失敗的建置記錄。 -
snippet
是output
的簡短形式,將會發佈到問題本身。相符項幾乎總是會使用output
。 -
builder
是執行測試的建置模組的名稱(例如dragonfly-amd64-622
)。 -
repo
是正在測試的儲存庫名稱(go
、net
、tools
等)。 -
goos
是 GOOS 值(linux
、windows
等)。 -
goarch
是 GOARCH 值(amd64
、mips64le
等)。 -
date
是正在測試的提交日期,格式為2006-01-02T15:04:05
。沒有日期比較邏輯;請改用字串比較。很少會使用比較日期。 -
section
是發生失敗的建置記錄區段。在 all.bash 輸出中,區段由#####
介紹,而引導期間的每一個Building
行也會視為其自己的區段。在子儲存庫中,:: Running
行會各自介紹一個區段,該區段的名稱是正在執行的 go 指令(例如go test golang.org/x/tools/...
)。大多數模式不需要使用
section
。它最有助於主儲存庫中的測試,這些測試會在備用執行環境中重新執行測試。
模式
模式是 Go 類似語法的布林表達式,允許使用 ||、&&、!、( 和 ) 來建構複雜表達式;==、!=、<、<=、> 和 >= 來比較欄位和字串文字;以及 ~ 和 !~ 來比對正規表示式。
所有字串比較在左側必須有欄位名稱,在右側必須有雙引號括起來的字串文字,例如 builder == "linux-amd64-alpine"
或 `goos == "
所有正規表示式比對在左側必須有欄位名稱,在右側必須有反引號括起來的字串文字,例如 builder ~ `corellium`
。
單獨的反引號字串文字會被視為與 output
欄位進行比較,這適用於模式中絕大多數的正規表示式。
範例
將所有這些組合在一起,以下是幾個範例腳本。
#!watchflakes
post <- pkg == "net/http" && test == "TestHandlerAbortRacesBodyRead"
在 #55277 中的這個腳本是由 watchflakes 自動建立,以回應在 http.TestHandlerAbortRacesBodyRead 中失敗的建置執行。導致問題建立的特定失敗是逾時。如果在該測試中發現更多具有不同根本原因的失敗,則新增 && `panic: test timed out`
或進一步精簡模式可能就適當了。
#!watchflakes
post <- goos == "openbsd" && `unlinkat .*: operation not permitted`
在 #49751 中的這個腳本收集由 os.Remove 呼叫 unlinkat 產生的意外 EPERM 錯誤所導致的 openbsd 上的失敗。這些失敗會在各種測試中造成問題,因此對 pkg
或 test
沒有條件。
#!watchflakes
post <- pkg ~ `^cmd/go` && `appspot.com.*: 503`
在 #54608 中的這個腳本追蹤在 cmd/go/… 套件階層中任何測試中來自 appspot.com 的 503 回應的網路問題,不只限於 cmd/go 本身。
#!watchflakes
post <- goos == "windows" &&
(`dnsquery: DNS server failure` || `getaddrinfow: This is usually a temporary error`)
在 #55165 中的這個腳本比對在執行 Windows 的建置器上任何測試中的特定 DNS 失敗。
#!watchflakes
post <- builder == "darwin-arm64-12" && pkg == "" && test == ""
在 #55312 中的這個腳本是由 watchflakes 自動建立,用來追蹤在 darwin-arm64-12 建置器上在特定套件測試執行之前發生的失敗。
#!watchflakes
# note: sometimes the URL is printed with one /
default <- `(Get|read) "https://?(goproxy.io|proxy.golang.com.cn|goproxy.cn)`
在 #55163 中的這個腳本比對使用某些非標準 Go 代理程式產生的錯誤。它使用 default
讓其他問題可以擁有由這些代理程式造成的更特定失敗。未比對到其他問題的失敗會轉到 #55163,而不是建立新的問題。
#!watchflakes
default <- `: internal compiler error:`
在 #55257 中的這個腳本比對任何建置中的編譯器失敗,不論正在測試哪個套件或儲存庫。它使用 default
的原因與前一個範例相同:讓比對到特定編譯器錯誤的問題仍然可以提交,但未比對到其他問題的失敗會分組到 #55257,而不是建立指派給觸發問題的特定測試的新問題。
此內容是 Go Wiki 的一部分。