An older build module's output for a race after the tests' PASS is now worded by the race's heading, access and frame, not by go test's PASS or the report's separator line (1901/AC5).
59 lines
3.8 KiB
Go
59 lines
3.8 KiB
Go
package check
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// What the build module before this fix sent for two packages that failed after their tests passed (issue 1901, its third
|
|
// meeting: a try of mesh-controller kept "PASS" as its failure's words). Each is that build module's Output for the real
|
|
// `go test -json` of a throwaway package (mesh-catalog modules/mesh-build-go testdata/captured/go-test-json-pkg-*.jsonl):
|
|
// TestMain panicking in a goroutine after m.Run, TestMain exiting 2 after m.Run, and TestMain racing after m.Run.
|
|
const (
|
|
oldPassThenPanic = "PASS\npanic: the bus closed after the tests: nats: connection closed\ngoroutine 20 [running]:\n" +
|
|
"example.com/passthenfail.TestMain.func1()\n\t/tmp/fix-1901b/passthenfail/p_test.go:13 +0x25\n" +
|
|
"created by example.com/passthenfail.TestMain in goroutine 1\n\t/tmp/fix-1901b/passthenfail/p_test.go:13 +0x25\n" +
|
|
"FAIL\texample.com/passthenfail\t0.005s"
|
|
oldPassThenExit = "PASS\nFAIL\texample.com/mainexit\t0.004s"
|
|
// TestMain racing after m.Run passed, under go test -race (go-test-json-pkg-racemain.jsonl).
|
|
oldPassThenRace = "PASS\n==================\nWARNING: DATA RACE\nWrite at 0x000000836428 by goroutine 9:\n example.com/racemain.TestMain.func1()\n /tmp/fix-1901b/racemain/p_test.go:15 +0x24\nPrevious write at 0x000000836428 by main goroutine:\n example.com/racemain.TestMain()\n /tmp/fix-1901b/racemain/p_test.go:16 +0x44\n main.main()\n _testmain.go:48 +0x171\nGoroutine 9 (running) created at:\n example.com/racemain.TestMain()\n /tmp/fix-1901b/racemain/p_test.go:15 +0x37\n main.main()\n _testmain.go:48 +0x171\n==================\nFound 1 data race(s)\nFAIL\texample.com/racemain\t1.031s"
|
|
)
|
|
|
|
// A failure with no cause told apart never has "PASS" or "ok" as its words: the checker takes the panic line from the
|
|
// output, or says that the tests passed and the program failed after them (1901/AC5).
|
|
func TestAPackageFailureIsNeverWordedPass(t *testing.T) { // 1901/AC5
|
|
cases := []struct {
|
|
name, output, want string
|
|
}{
|
|
{"panic after the tests", oldPassThenPanic, "panic: the bus closed after the tests: nats: connection closed"},
|
|
{"exit after the tests", oldPassThenExit, "the tests passed, then the test program exited with a failure"},
|
|
{"race after the tests", oldPassThenRace, "WARNING: DATA RACE: Write at 0x000000836428 by goroutine 9 in example.com/racemain.TestMain.func1()"},
|
|
{"a panic deep in a long output", "PASS\npanic: the seat row vanished\n" + strings.Repeat("goroutine 7 [chan receive]:\n\tsome/frame.go:1 +0x1\n", 300) + "FAIL\tp\t2.0s", "panic: the seat row vanished"},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
v := levelFailure(&target{}, "integration", Tested{Failed: []Failure{{Package: "github.com/novox/mesh-controller/cmd/mesh-controller", Output: c.output}}})
|
|
for _, l := range strings.Split(v.Failed.Words, "\n") {
|
|
if l = strings.TrimSpace(l); l == "PASS" || strings.HasPrefix(l, "ok ") || strings.HasPrefix(l, "ok\t") {
|
|
t.Errorf("1901/AC5: the words keep %q: %q", l, v.Failed.Words)
|
|
}
|
|
}
|
|
if !strings.HasPrefix(v.Failed.Words, c.want) {
|
|
t.Errorf("1901/AC5: words start %q, want %q", firstLine(v.Failed.Words), c.want)
|
|
}
|
|
if got := firstFailed(*v); !strings.Contains(got, c.want) || strings.HasSuffix(got, ": PASS") {
|
|
t.Errorf("1901/AC5: status = %q", got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// A cause the build module told apart is cut to a line's bound, so the words keep their bound (the 1901 review's note).
|
|
func TestALongCauseIsCutToALinesBound(t *testing.T) { // 1901/AC5
|
|
f := Failure{Package: "p", Test: "TestX", Cause: strings.Repeat("c", 5000), Output: "x_test.go:1: something"}
|
|
v := levelFailure(&target{}, "unit", Tested{Failed: []Failure{f}})
|
|
if len(v.Failed.Words) > MaxWords+200 {
|
|
t.Errorf("1901/AC5: words are %d bytes, bound %d", len(v.Failed.Words), MaxWords)
|
|
}
|
|
}
|