@@ -1049,10 +1049,20 @@ func (t *T) Run(name string, f func(t *T)) bool {
1049
1049
return ! t .failed
1050
1050
}
1051
1051
1052
+ // Deadline reports the time at which the test binary will have
1053
+ // exceeded the timeout specified by the -timeout flag.
1054
+ //
1055
+ // The ok result is false if the -timeout flag indicates “no timeout” (0).
1056
+ func (t * T ) Deadline () (deadline time.Time , ok bool ) {
1057
+ deadline = t .context .deadline
1058
+ return deadline , ! deadline .IsZero ()
1059
+ }
1060
+
1052
1061
// testContext holds all fields that are common to all tests. This includes
1053
1062
// synchronization primitives to run at most *parallel tests.
1054
1063
type testContext struct {
1055
- match * matcher
1064
+ match * matcher
1065
+ deadline time.Time
1056
1066
1057
1067
mu sync.Mutex
1058
1068
@@ -1195,9 +1205,9 @@ func (m *M) Run() int {
1195
1205
1196
1206
m .before ()
1197
1207
defer m .after ()
1198
- m .startAlarm ()
1208
+ deadline := m .startAlarm ()
1199
1209
haveExamples = len (m .examples ) > 0
1200
- testRan , testOk := runTests (m .deps .MatchString , m .tests )
1210
+ testRan , testOk := runTests (m .deps .MatchString , m .tests , deadline )
1201
1211
exampleRan , exampleOk := runExamples (m .deps .MatchString , m .examples )
1202
1212
m .stopAlarm ()
1203
1213
if ! testRan && ! exampleRan && * matchBenchmarks == "" {
@@ -1255,14 +1265,18 @@ func listTests(matchString func(pat, str string) (bool, error), tests []Internal
1255
1265
// RunTests is an internal function but exported because it is cross-package;
1256
1266
// it is part of the implementation of the "go test" command.
1257
1267
func RunTests (matchString func (pat , str string ) (bool , error ), tests []InternalTest ) (ok bool ) {
1258
- ran , ok := runTests (matchString , tests )
1268
+ var deadline time.Time
1269
+ if * timeout > 0 {
1270
+ deadline = time .Now ().Add (* timeout )
1271
+ }
1272
+ ran , ok := runTests (matchString , tests , deadline )
1259
1273
if ! ran && ! haveExamples {
1260
1274
fmt .Fprintln (os .Stderr , "testing: warning: no tests to run" )
1261
1275
}
1262
1276
return ok
1263
1277
}
1264
1278
1265
- func runTests (matchString func (pat , str string ) (bool , error ), tests []InternalTest ) (ran , ok bool ) {
1279
+ func runTests (matchString func (pat , str string ) (bool , error ), tests []InternalTest , deadline time. Time ) (ran , ok bool ) {
1266
1280
ok = true
1267
1281
for _ , procs := range cpuList {
1268
1282
runtime .GOMAXPROCS (procs )
@@ -1271,6 +1285,7 @@ func runTests(matchString func(pat, str string) (bool, error), tests []InternalT
1271
1285
break
1272
1286
}
1273
1287
ctx := newTestContext (* parallel , newMatcher (matchString , * match , "-test.run" ))
1288
+ ctx .deadline = deadline
1274
1289
t := & T {
1275
1290
common : common {
1276
1291
signal : make (chan bool ),
@@ -1452,14 +1467,18 @@ func toOutputDir(path string) string {
1452
1467
}
1453
1468
1454
1469
// startAlarm starts an alarm if requested.
1455
- func (m * M ) startAlarm () {
1456
- if * timeout > 0 {
1457
- m .timer = time .AfterFunc (* timeout , func () {
1458
- m .after ()
1459
- debug .SetTraceback ("all" )
1460
- panic (fmt .Sprintf ("test timed out after %v" , * timeout ))
1461
- })
1470
+ func (m * M ) startAlarm () time.Time {
1471
+ if * timeout <= 0 {
1472
+ return time.Time {}
1462
1473
}
1474
+
1475
+ deadline := time .Now ().Add (* timeout )
1476
+ m .timer = time .AfterFunc (* timeout , func () {
1477
+ m .after ()
1478
+ debug .SetTraceback ("all" )
1479
+ panic (fmt .Sprintf ("test timed out after %v" , * timeout ))
1480
+ })
1481
+ return deadline
1463
1482
}
1464
1483
1465
1484
// stopAlarm turns off the alarm.
0 commit comments