}
}
+// mustHaveContent succeeds if filePath is a path to a file,
+// and that file is readable and not empty.
+func (tg *testgoData) mustHaveContent(filePath string) {
+ tg.mustExist(filePath)
+ f, err := os.Stat(filePath)
+ if err != nil {
+ tg.t.Fatal(err)
+ }
+ if f.Size() == 0 {
+ tg.t.Fatalf("expected %s to have data, but is empty", filePath)
+ }
+}
+
// wantExecutable fails with msg if path is not executable.
func (tg *testgoData) wantExecutable(path, msg string) {
tg.t.Helper()
tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go")
}
+// Issue 19394
+func TestWriteProfilesOnTimeout(t *testing.T) {
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.tempDir("profiling")
+ tg.tempFile("profiling/timeouttest_test.go", `package timeouttest_test
+import "testing"
+import "time"
+func TestSleep(t *testing.T) { time.Sleep(time.Second) }`)
+ tg.cd(tg.path("profiling"))
+ tg.runFail(
+ "test",
+ "-cpuprofile", tg.path("profiling/cpu.pprof"), "-memprofile", tg.path("profiling/mem.pprof"),
+ "-timeout", "1ms")
+ tg.mustHaveContent(tg.path("profiling/cpu.pprof"))
+ tg.mustHaveContent(tg.path("profiling/mem.pprof"))
+}
+
func TestLinkXImportPathEscape(t *testing.T) {
// golang.org/issue/16710
tg := testgo(t)
tests []InternalTest
benchmarks []InternalBenchmark
examples []InternalExample
+
+ timer *time.Timer
+ afterOnce sync.Once
}
// testDeps is an internal interface of functionality that is
parseCpuList()
m.before()
- startAlarm()
+ defer m.after()
+ m.startAlarm()
haveExamples = len(m.examples) > 0
testRan, testOk := runTests(m.deps.MatchString, m.tests)
exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
- stopAlarm()
+ m.stopAlarm()
if !testRan && !exampleRan && *matchBenchmarks == "" {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
if !testOk || !exampleOk || !runBenchmarks(m.deps.ImportPath(), m.deps.MatchString, m.benchmarks) || race.Errors() > 0 {
fmt.Println("FAIL")
- m.after()
return 1
}
fmt.Println("PASS")
- m.after()
return 0
}
// after runs after all testing.
func (m *M) after() {
+ m.afterOnce.Do(func() {
+ m.writeProfiles()
+ })
+}
+
+func (m *M) writeProfiles() {
if *cpuProfile != "" {
m.deps.StopCPUProfile() // flushes profile to disk
}
return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
}
-var timer *time.Timer
-
// startAlarm starts an alarm if requested.
-func startAlarm() {
+func (m *M) startAlarm() {
if *timeout > 0 {
- timer = time.AfterFunc(*timeout, func() {
+ m.timer = time.AfterFunc(*timeout, func() {
+ m.after()
debug.SetTraceback("all")
panic(fmt.Sprintf("test timed out after %v", *timeout))
})
}
// stopAlarm turns off the alarm.
-func stopAlarm() {
+func (m *M) stopAlarm() {
if *timeout > 0 {
- timer.Stop()
+ m.timer.Stop()
}
}