210 lines
6 KiB
Go
210 lines
6 KiB
Go
// 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")
|
|
var testPanicParallel = flag.Bool("test_panic_parallel", false, "TestPanic: run subtests in parallel")
|
|
var testPanicCleanup = flag.Bool("test_panic_cleanup", false, "TestPanic: indicates whether test should call Cleanup")
|
|
var testPanicCleanupPanic = flag.String("test_panic_cleanup_panic", "", "TestPanic: indicate whether test should call Cleanup function that panics")
|
|
|
|
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
|
|
`,
|
|
}, {
|
|
desc: "subtest panics with cleanup",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
--- FAIL: TestPanicHelper/1 (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper/1
|
|
`,
|
|
}, {
|
|
desc: "subtest panics with outer cleanup panic",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_cleanup_panic=outer"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
`,
|
|
}, {
|
|
desc: "subtest panics with middle cleanup panic",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_cleanup_panic=middle"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
--- FAIL: TestPanicHelper/1 (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper/1
|
|
`,
|
|
}, {
|
|
desc: "subtest panics with inner cleanup panic",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_cleanup_panic=inner"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
--- FAIL: TestPanicHelper/1 (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper/1
|
|
`,
|
|
}, {
|
|
desc: "parallel subtest panics with cleanup",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_parallel"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
--- FAIL: TestPanicHelper/1 (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper/1
|
|
`,
|
|
}, {
|
|
desc: "parallel subtest panics with outer cleanup panic",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_cleanup_panic=outer", "-test_panic_parallel"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
`,
|
|
}, {
|
|
desc: "parallel subtest panics with middle cleanup panic",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_cleanup_panic=middle", "-test_panic_parallel"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- FAIL: TestPanicHelper (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper
|
|
--- FAIL: TestPanicHelper/1 (N.NNs)
|
|
panic_test.go:NNN: TestPanicHelper/1
|
|
`,
|
|
}, {
|
|
desc: "parallel subtest panics with inner cleanup panic",
|
|
flags: []string{"-test_panic_test=TestPanicHelper/1", "-test_panic_cleanup", "-test_panic_cleanup_panic=inner", "-test_panic_parallel"},
|
|
want: `
|
|
ran inner cleanup 1
|
|
ran middle cleanup 1
|
|
ran outer cleanup
|
|
--- 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")
|
|
}
|
|
switch *testPanicCleanupPanic {
|
|
case "", "outer", "middle", "inner":
|
|
default:
|
|
t.Fatalf("bad -test_panic_cleanup_panic: %s", *testPanicCleanupPanic)
|
|
}
|
|
t.Cleanup(func() {
|
|
fmt.Println("ran outer cleanup")
|
|
if *testPanicCleanupPanic == "outer" {
|
|
panic("outer cleanup")
|
|
}
|
|
})
|
|
for i := 0; i < 3; i++ {
|
|
i := i
|
|
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
|
|
chosen := t.Name() == *testPanicTest
|
|
if chosen && *testPanicCleanup {
|
|
t.Cleanup(func() {
|
|
fmt.Printf("ran middle cleanup %d\n", i)
|
|
if *testPanicCleanupPanic == "middle" {
|
|
panic("middle cleanup")
|
|
}
|
|
})
|
|
}
|
|
if chosen && *testPanicParallel {
|
|
t.Parallel()
|
|
}
|
|
t.Log(t.Name())
|
|
if chosen {
|
|
if *testPanicCleanup {
|
|
t.Cleanup(func() {
|
|
fmt.Printf("ran inner cleanup %d\n", i)
|
|
if *testPanicCleanupPanic == "inner" {
|
|
panic("inner cleanup")
|
|
}
|
|
})
|
|
}
|
|
panic("panic")
|
|
}
|
|
})
|
|
}
|
|
}
|