aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2019-10-23 10:54:09 -0400
committerBryan C. Mills <bcmills@google.com>2020-02-21 17:46:33 +0000
commit9ca57923e222335cc63924833d5bf562962e06c9 (patch)
tree3c8b3888401db2f9e23795e88896b56a8d1fe66a /src/testing
parent1b47fde55c3899ee50e7fab35e151645aba96e9c (diff)
downloadgo-9ca57923e222335cc63924833d5bf562962e06c9.tar.gz
go-9ca57923e222335cc63924833d5bf562962e06c9.zip
testing: testing: add (*T).Deadline method for test timeout
Fixes #28135 Change-Id: I62818595eaf4a59d8b5c26cd6848c08fec795ad1 Reviewed-on: https://go-review.googlesource.com/c/go/+/202758 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/testing.go43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 8a0c7b3021..4b424e6abb 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -1049,10 +1049,20 @@ func (t *T) Run(name string, f func(t *T)) bool {
return !t.failed
}
+// Deadline reports the time at which the test binary will have
+// exceeded the timeout specified by the -timeout flag.
+//
+// The ok result is false if the -timeout flag indicates “no timeout” (0).
+func (t *T) Deadline() (deadline time.Time, ok bool) {
+ deadline = t.context.deadline
+ return deadline, !deadline.IsZero()
+}
+
// testContext holds all fields that are common to all tests. This includes
// synchronization primitives to run at most *parallel tests.
type testContext struct {
- match *matcher
+ match *matcher
+ deadline time.Time
mu sync.Mutex
@@ -1195,9 +1205,9 @@ func (m *M) Run() int {
m.before()
defer m.after()
- m.startAlarm()
+ deadline := m.startAlarm()
haveExamples = len(m.examples) > 0
- testRan, testOk := runTests(m.deps.MatchString, m.tests)
+ testRan, testOk := runTests(m.deps.MatchString, m.tests, deadline)
exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
m.stopAlarm()
if !testRan && !exampleRan && *matchBenchmarks == "" {
@@ -1255,14 +1265,18 @@ func listTests(matchString func(pat, str string) (bool, error), tests []Internal
// RunTests is an internal function but exported because it is cross-package;
// it is part of the implementation of the "go test" command.
func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
- ran, ok := runTests(matchString, tests)
+ var deadline time.Time
+ if *timeout > 0 {
+ deadline = time.Now().Add(*timeout)
+ }
+ ran, ok := runTests(matchString, tests, deadline)
if !ran && !haveExamples {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
return ok
}
-func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ran, ok bool) {
+func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest, deadline time.Time) (ran, ok bool) {
ok = true
for _, procs := range cpuList {
runtime.GOMAXPROCS(procs)
@@ -1271,6 +1285,7 @@ func runTests(matchString func(pat, str string) (bool, error), tests []InternalT
break
}
ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run"))
+ ctx.deadline = deadline
t := &T{
common: common{
signal: make(chan bool),
@@ -1452,14 +1467,18 @@ func toOutputDir(path string) string {
}
// startAlarm starts an alarm if requested.
-func (m *M) startAlarm() {
- if *timeout > 0 {
- m.timer = time.AfterFunc(*timeout, func() {
- m.after()
- debug.SetTraceback("all")
- panic(fmt.Sprintf("test timed out after %v", *timeout))
- })
+func (m *M) startAlarm() time.Time {
+ if *timeout <= 0 {
+ return time.Time{}
}
+
+ deadline := time.Now().Add(*timeout)
+ m.timer = time.AfterFunc(*timeout, func() {
+ m.after()
+ debug.SetTraceback("all")
+ panic(fmt.Sprintf("test timed out after %v", *timeout))
+ })
+ return deadline
}
// stopAlarm turns off the alarm.