import (
"bytes"
- "context"
"errors"
"flag"
"fmt"
var toRemove []string
func TestMain(m *testing.M) {
+ _, coreErrBefore := os.Stat("core")
+
status := m.Run()
for _, file := range toRemove {
os.RemoveAll(file)
}
+
+ _, coreErrAfter := os.Stat("core")
+ if coreErrBefore != nil && coreErrAfter == nil {
+ fmt.Fprintln(os.Stderr, "runtime.test: some test left a core file behind")
+ if status == 0 {
+ status = 1
+ }
+ }
+
os.Exit(status)
}
}
testenv.MustHaveGoBuild(t)
+ t.Helper()
exe, err := buildTestProg(t, binary)
if err != nil {
t.Skip("-quick")
}
- ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
- defer cancel()
- cmd := testenv.CleanCmdEnv(testenv.CommandContext(t, ctx, exe, name))
+ start := time.Now()
+
+ cmd := testenv.CleanCmdEnv(testenv.Command(t, exe, name))
cmd.Env = append(cmd.Env, env...)
if testing.Short() {
cmd.Env = append(cmd.Env, "RUNTIME_TEST_SHORT=1")
}
out, err := cmd.CombinedOutput()
- if err != nil {
+ if err == nil {
+ t.Logf("%v (%v): ok", cmd, time.Since(start))
+ } else {
if _, ok := err.(*exec.ExitError); ok {
t.Logf("%v: %v", cmd, err)
} else if errors.Is(err, exec.ErrWaitDelay) {
exe := filepath.Join(dir, name+".exe")
- t.Logf("running go build -o %s %s", exe, strings.Join(flags, " "))
+ start := time.Now()
cmd := exec.Command(testenv.GoToolPath(t), append([]string{"build", "-o", exe}, flags...)...)
+ t.Logf("running %v", cmd)
cmd.Dir = "testdata/" + binary
out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
if err != nil {
target.err = fmt.Errorf("building %s %v: %v\n%s", binary, flags, err, out)
} else {
+ t.Logf("built %v in %v", name, time.Since(start))
target.exe = exe
target.err = nil
}
func testDeadlock(t *testing.T, name string) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", name)
want := "fatal error: all goroutines are asleep - deadlock!\n"
func TestGoexitDeadlock(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", "GoexitDeadlock")
want := "no goroutines (main called runtime.Goexit) - deadlock!"
func TestGoexitCrash(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", "GoexitExit")
want := "no goroutines (main called runtime.Goexit) - deadlock!"
func TestGoexitInPanic(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
// see issue 8774: this code used to trigger an infinite recursion
output := runTestProg(t, "testprog", "GoexitInPanic")
func TestRecoveredPanicAfterGoexit(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit")
func TestRecoverBeforePanicAfterGoexit2(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2")
got, err := testenv.CleanCmdEnv(exec.Command(exe, "MemProf")).CombinedOutput()
if err != nil {
- t.Fatal(err)
+ t.Fatalf("testprog failed: %s, output:\n%s", err, got)
}
fn := strings.TrimSpace(string(got))
defer os.Remove(fn)
func TestRuntimePanic(t *testing.T) {
testenv.MustHaveExec(t)
- cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestRuntimePanic"))
+ cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=^TestRuntimePanic$"))
cmd.Env = append(cmd.Env, "GO_TEST_RUNTIME_PANIC=1")
out, err := cmd.CombinedOutput()
t.Logf("%s", out)
func TestG0StackOverflow(t *testing.T) {
testenv.MustHaveExec(t)
- switch runtime.GOOS {
- case "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "android":
- t.Skipf("g0 stack is wrong on pthread platforms (see golang.org/issue/26061)")
+ if runtime.GOOS == "ios" {
+ testenv.SkipFlaky(t, 62671)
+ }
+ if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
+ testenv.SkipFlaky(t, 63938) // TODO(cherry): fix and unskip
}
if os.Getenv("TEST_G0_STACK_OVERFLOW") != "1" {
- cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestG0StackOverflow", "-test.v"))
+ cmd := testenv.CleanCmdEnv(testenv.Command(t, os.Args[0], "-test.run=^TestG0StackOverflow$", "-test.v"))
cmd.Env = append(cmd.Env, "TEST_G0_STACK_OVERFLOW=1")
out, err := cmd.CombinedOutput()
// Don't check err since it's expected to crash.
if n := strings.Count(string(out), "morestack on g0\n"); n != 1 {
t.Fatalf("%s\n(exit status %v)", out, err)
}
+ if runtime.CrashStackImplemented {
+ // check for a stack trace
+ want := "runtime.stackOverflow"
+ if n := strings.Count(string(out), want); n < 5 {
+ t.Errorf("output does not contain %q at least 5 times:\n%s", want, out)
+ }
+ return // it's not a signal-style traceback
+ }
// Check that it's a signal-style traceback.
if runtime.GOOS != "windows" {
if want := "PC="; !strings.Contains(string(out), want) {
t.Errorf("output does not contain %q:\n%s", want, output)
}
}
+
+func TestNetpollWaiters(t *testing.T) {
+ t.Parallel()
+ output := runTestProg(t, "testprognet", "NetpollWaiters")
+ want := "OK\n"
+ if output != want {
+ t.Fatalf("output is not %q\n%s", want, output)
+ }
+}