Go Wiki:Watchflakes

Watchflakes 是一个程序,用于对 build.golang.org 仪表板上的明显测试缺陷进行分类。

明显的测试缺陷是指

Watchflakes 将每个明显的测试缺陷发布到 测试缺陷项目 中的问题中。

测试缺陷项目中的每个问题描述都以与该问题相关的失败模式开头:例如,#55260 的描述的标记语言以

```
#!watchflakes
post <- pkg == "cmd/go" && test == "" && `unexpected files left in tmpdir`
```

Watchflakes 将每个明显的测试缺陷与问题中的模式进行匹配

新创建的 issue 的模式通常过于宽泛,应该对其进行编辑,使其更具体地针对实际故障。将故障发送到编号最低的匹配 issue 可以确保为新故障创建宽泛的默认模式不会“窃取”早期 issue 的故障,也不会向新 issue 发送同一测试中已单独跟踪的不相关故障。

Watchflakes 将新创建的 issue 放入 Test Flakes 项目,并添加 NeedsInvestigation 标签。这些 issue 最初没有状态(不是 Active,也不是 Done)。没有状态的 issue 需要由人来检查,通常应该优化模式以捕获有关故障的重要信息。已检查的 issue 随后可以移至 Active。当 issue 关闭时,GitHub 会自动将 issue 从 Active 移至 Done。

Watchflakes 在匹配新故障时会考虑任何状态的 issue。如果它为已关闭的 issue 找到新故障,它将发布该故障并重新打开该 issue。因此,当修复程序发布时,可以关闭 issue,而不必等待几周来查看故障是否真的消失了:如果出现新故障,该 issue 将自动重新打开。

Watchflakes 不维护自己的状态:所有状态都在 GitHub issue 中。每次运行时,它都会考虑过去 60 天的构建仪表板故障,并确保每个明显的 flake 都在 Test Flakes 项目中得到说明。如果与 issue 匹配的故障已发布到该 issue,watchflakes 当然不会再次发布它。如果编辑 issue 以更新其模式以排除某些故障,watchflakes 不会删除其旧帖子,但它会为这些故障寻找不同的匹配 issue,包括可能创建一个新的 issue。

语法

每个 issue 中的 watchflakes 节必须出现在 issue 描述的顶部。它必须是一个代码块(使用 ``` 围起来或缩进),第一行必须是 #!watchflakes,以防止 watchflakes 误解不相关的代码块。

该块的其余部分是一个小的 watchflakes 脚本。行尾注释以 # 引入。该脚本是一系列规则,每条规则都具有 action <- pattern 的形式(将模式匹配项发送到操作)。

操作

操作为

记录

模式的输入是一个具有命名字段的记录,每个字段都有一个字符串值

模式

模式是 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 中的这个脚本收集了 openbsd 上由 os.Remove 调用 unlinkat 导致的意外 EPERM 错误造成的故障。这些故障在各种测试中都会导致问题,因此对 pkgtest 没有条件。

#!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 的一部分。