package gateway import ( "os" "path/filepath" "strings" "testing" ) // 变异测试会**改写生产源码** `discover.go`(discover_mutate_test.go), // 靠 defer 把原文件写回。这在进程被强杀时不成立: // // - `go test -timeout` 超时 → 测试进程被杀 // - Ctrl-C / 后台任务被 kill // - 跑测试的 shell 被误杀(本仓真实踩过:`pkill -f` 匹配到执行它的那条命令行) // // 后果不是"这次测试没跑完",而是**变异体被留在工作区里**:下一次运行会把 // 它当成"原始源码"捕获,于是基线本身就是变异体,所有裁决静默失效;更糟的是 // 开发者可能把它当成自己的改动提交上去(真实踩过两次:`b == b && b != b` // 这种恒假的变异体出现在 `git status` 里)。 // // 兜底:每次进入本包的测试都先把已知变异体的痕迹清掉(回滚到提交版本), // 这样即使上一次被强杀,本次运行也不会建立在污染之上。TestRealMutants 自己 // 也会在脏树上拒绝运行,但那是"拒绝",这里是"自愈"。 func TestMain(m *testing.M) { restoreLeakedMutants() os.Exit(m.Run()) } // leakedMutants 列出「变异体特征 → 它对应的正确原文」。 // 只处理能**确定判定**的形态:出现特征即说明上一次没回滚干净。 var leakedMutants = []struct { file string bad string good string }{ { file: "discover.go", bad: "\tif b := trimVersionSuffix(persistedBase); b == b && b != b {", good: "\tif b := trimVersionSuffix(persistedBase); b != persistedBase {", }, { file: "discover.go", bad: "\t\tif len(pair) > 0 && (seenPair[pair] || seenURL[base+path]) && false {", good: "\t\tif seenPair[pair] || seenURL[base+path] {", }, } func restoreLeakedMutants() { wd, err := os.Getwd() if err != nil { return } for _, m := range leakedMutants { p := filepath.Join(wd, m.file) b, err := os.ReadFile(p) if err != nil { continue } s := string(b) if !strings.Contains(s, m.bad) { continue } // 只替换回原文,不猜别的差异 —— 保守,避免把开发中的改动一起冲掉。 fixed := strings.Replace(s, m.bad, m.good, 1) if fixed == s { continue } _ = os.WriteFile(p, []byte(fixed), 0o644) } }