1
0
mirror of https://github.com/golang/go synced 2024-11-22 07:34:40 -07:00

testing: add -test.timeout option.

Since Go code can deadlock, this lets a testsuite driver set a
time limit for the test to run.  This is simple but imperfect,
in that it only catches deadlocks in Go code, not in the
runtime scheduler.

R=r, rsc, iant2
CC=golang-dev
https://golang.org/cl/4326048
This commit is contained in:
Ian Lance Taylor 2011-03-31 15:27:51 -07:00
parent 3907031358
commit 554082d6b1
4 changed files with 32 additions and 2 deletions

View File

@ -61,7 +61,7 @@ test:
gotest gotest
testshort: testshort:
gotest -test.short gotest -test.short -test.timeout=60
bench: bench:
gotest -test.bench=. -test.run="Do not run tests" gotest -test.bench=. -test.run="Do not run tests"

View File

@ -82,11 +82,15 @@ collection.
Use -test.run or -test.bench to limit profiling to a particular test Use -test.run or -test.bench to limit profiling to a particular test
or benchmark. or benchmark.
The -test.short package tells long-running tests to shorten their run The -test.short flag tells long-running tests to shorten their run
time. It is off by default but set by all.bash so installations of time. It is off by default but set by all.bash so installations of
the Go tree can do a sanity check but not spend time running the Go tree can do a sanity check but not spend time running
exhaustive tests. exhaustive tests.
The -test.timeout flag sets a timeout for the test in seconds. If the
test runs for longer than that, it will panic, dumping a stack trace
of all existing goroutines.
For convenience, each of these -test.X flags of the test binary is For convenience, each of these -test.X flags of the test binary is
also available as the flag -X in gotest itself. Flags not listed here also available as the flag -X in gotest itself. Flags not listed here
are unaffected. For instance, the command are unaffected. For instance, the command

View File

@ -28,6 +28,7 @@ var usageMessage = `Usage of %s:
-memprofilerate=0: passes -test.memprofilerate to test -memprofilerate=0: passes -test.memprofilerate to test
-run="": passes -test.run to test -run="": passes -test.run to test
-short=false: passes -test.short to test -short=false: passes -test.short to test
-timeout=0: passes -test.timeout to test
-v=false: passes -test.v to test -v=false: passes -test.v to test
` `
@ -60,6 +61,7 @@ var flagDefn = []*flagSpec{
&flagSpec{name: "memprofilerate", passToTest: true}, &flagSpec{name: "memprofilerate", passToTest: true},
&flagSpec{name: "run", passToTest: true}, &flagSpec{name: "run", passToTest: true},
&flagSpec{name: "short", isBool: true, passToTest: true}, &flagSpec{name: "short", isBool: true, passToTest: true},
&flagSpec{name: "timeout", passToTest: true},
&flagSpec{name: "v", isBool: true, passToTest: true}, &flagSpec{name: "v", isBool: true, passToTest: true},
} }

View File

@ -61,6 +61,7 @@ var (
memProfile = flag.String("test.memprofile", "", "write a memory profile to the named file after execution") memProfile = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate") memProfileRate = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution") cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
timeout = flag.Int64("test.timeout", 0, "if > 0, sets time limit for tests in seconds")
) )
// Short reports whether the -test.short flag is set. // Short reports whether the -test.short flag is set.
@ -158,7 +159,9 @@ func Main(matchString func(pat, str string) (bool, os.Error), tests []InternalTe
flag.Parse() flag.Parse()
before() before()
startAlarm()
RunTests(matchString, tests) RunTests(matchString, tests)
stopAlarm()
RunBenchmarks(matchString, benchmarks) RunBenchmarks(matchString, benchmarks)
after() after()
} }
@ -241,3 +244,24 @@ func after() {
f.Close() f.Close()
} }
} }
var timer *time.Timer
// startAlarm starts an alarm if requested.
func startAlarm() {
if *timeout > 0 {
timer = time.AfterFunc(*timeout*1e9, alarm)
}
}
// stopAlarm turns off the alarm.
func stopAlarm() {
if *timeout > 0 {
timer.Stop()
}
}
// alarm is called if the timeout expires.
func alarm() {
panic("test timed out")
}