diff options
Diffstat (limited to 'src/testing')
| -rw-r--r-- | src/testing/panic_test.go | 83 | ||||
| -rw-r--r-- | src/testing/testing.go | 13 |
2 files changed, 94 insertions, 2 deletions
diff --git a/src/testing/panic_test.go b/src/testing/panic_test.go new file mode 100644 index 0000000000..3491510b81 --- /dev/null +++ b/src/testing/panic_test.go @@ -0,0 +1,83 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testing_test + +import ( + "flag" + "fmt" + "internal/testenv" + "os" + "os/exec" + "regexp" + "strings" + "testing" +) + +var testPanicTest = flag.String("test_panic_test", "", "TestPanic: indicates which test should panic") + +func TestPanic(t *testing.T) { + testenv.MustHaveExec(t) + + testCases := []struct { + desc string + flags []string + want string + }{{ + desc: "root test panics", + flags: []string{"-test_panic_test=TestPanicHelper"}, + want: ` +--- FAIL: TestPanicHelper (N.NNs) + panic_test.go:NNN: TestPanicHelper +`, + }, { + desc: "subtest panics", + flags: []string{"-test_panic_test=TestPanicHelper/1"}, + want: ` +--- FAIL: TestPanicHelper (N.NNs) + panic_test.go:NNN: TestPanicHelper + --- FAIL: TestPanicHelper/1 (N.NNs) + panic_test.go:NNN: TestPanicHelper/1 +`, + }} + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + cmd := exec.Command(os.Args[0], "-test.run=TestPanicHelper") + cmd.Args = append(cmd.Args, tc.flags...) + cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1") + b, _ := cmd.CombinedOutput() + got := string(b) + want := strings.TrimSpace(tc.want) + re := makeRegexp(want) + if ok, err := regexp.MatchString(re, got); !ok || err != nil { + t.Errorf("output:\ngot:\n%s\nwant:\n%s", got, want) + } + }) + } +} + +func makeRegexp(s string) string { + s = regexp.QuoteMeta(s) + s = strings.ReplaceAll(s, ":NNN:", `:\d+:`) + s = strings.ReplaceAll(s, "N\\.NNs", `\d*\.\d*s`) + return s +} + +func TestPanicHelper(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + t.Log(t.Name()) + if t.Name() == *testPanicTest { + panic("panic") + } + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + t.Log(t.Name()) + if t.Name() == *testPanicTest { + panic("panic") + } + }) + } +} diff --git a/src/testing/testing.go b/src/testing/testing.go index bbb10263c3..b9d4f2b5a5 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -860,7 +860,6 @@ func tRunner(t *T, fn func(t *T)) { t.Errorf("race detected during execution of test") } - t.duration += time.Since(t.start) // If the test panicked, print any test output before dying. err := recover() signal := true @@ -877,10 +876,20 @@ func tRunner(t *T, fn func(t *T)) { } if err != nil { t.Fail() - t.report() + // Flush the output log up to the root before dying. + t.mu.Lock() + root := &t.common + for ; root.parent != nil; root = root.parent { + root.duration += time.Since(root.start) + fmt.Fprintf(root.parent.w, "--- FAIL: %s (%s)\n", root.name, fmtDuration(root.duration)) + root.parent.mu.Lock() + io.Copy(root.parent.w, bytes.NewReader(root.output)) + } panic(err) } + t.duration += time.Since(t.start) + if len(t.sub) > 0 { // Run parallel subtests. // Decrease the running count for this test. |
