3434 flagSkipRegexp string
3535 flagShuffle string
3636 flagCount int
37+ flagTimeout time.Duration
3738)
3839
3940var initRan bool
@@ -52,6 +53,7 @@ func Init() {
5253 flag .StringVar (& flagShuffle , "test.shuffle" , "off" , "shuffle: off, on, <numeric-seed>" )
5354
5455 flag .IntVar (& flagCount , "test.count" , 1 , "run each test or benchmark `count` times" )
56+ flag .DurationVar (& flagTimeout , "test.timeout" , 0 , "panic test binary after duration d (default 0, timeout disabled)" )
5557
5658 initBenchmarkFlags ()
5759}
@@ -513,8 +515,6 @@ func (t *T) Run(name string, f func(t *T)) bool {
513515//
514516// The ok result is false if the -timeout flag indicates “no timeout” (0).
515517// For now tinygo always return 0, false.
516- //
517- // Not Implemented.
518518func (t * T ) Deadline () (deadline time.Time , ok bool ) {
519519 deadline = t .context .deadline
520520 return deadline , ! deadline .IsZero ()
@@ -527,7 +527,7 @@ type testContext struct {
527527 deadline time.Time
528528}
529529
530- func newTestContext (m * matcher ) * testContext {
530+ func newTestContext (deadline time. Time , m * matcher ) * testContext {
531531 return & testContext {
532532 match : m ,
533533 }
@@ -544,6 +544,8 @@ type M struct {
544544 // value to pass to os.Exit, the outer test func main
545545 // harness calls os.Exit with this code. See #34129.
546546 exitCode int
547+
548+ timer * time.Timer
547549}
548550
549551type testDeps interface {
@@ -588,7 +590,8 @@ func (m *M) Run() (code int) {
588590 }
589591 }
590592
591- testRan , testOk := runTests (m .deps .MatchString , m .Tests )
593+ deadline := m .startAlarm ()
594+ testRan , testOk := runTests (deadline , m .deps .MatchString , m .Tests )
592595 if ! testRan && * matchBenchmarks == "" {
593596 fmt .Fprintln (os .Stderr , "testing: warning: no tests to run" )
594597 }
@@ -599,13 +602,34 @@ func (m *M) Run() (code int) {
599602 fmt .Println ("PASS" )
600603 m .exitCode = 0
601604 }
605+ m .stopAlarm ()
602606 return
603607}
604608
605- func runTests (matchString func (pat , str string ) (bool , error ), tests []InternalTest ) (ran , ok bool ) {
609+ // startAlarm starts an alarm if requested.
610+ func (m * M ) startAlarm () time.Time {
611+ if flagTimeout <= 0 {
612+ return time.Time {}
613+ }
614+
615+ deadline := time .Now ().Add (flagTimeout )
616+ m .timer = time .AfterFunc (flagTimeout , func () {
617+ panic (fmt .Sprintf ("test timed out after %v" , flagTimeout ))
618+ })
619+ return deadline
620+ }
621+
622+ // stopAlarm turns off the alarm.
623+ func (m * M ) stopAlarm () {
624+ if flagTimeout > 0 {
625+ m .timer .Stop ()
626+ }
627+ }
628+
629+ func runTests (deadline time.Time , matchString func (pat , str string ) (bool , error ), tests []InternalTest ) (ran , ok bool ) {
606630 ok = true
607631
608- ctx := newTestContext (newMatcher (matchString , flagRunRegexp , "-test.run" , flagSkipRegexp ))
632+ ctx := newTestContext (deadline , newMatcher (matchString , flagRunRegexp , "-test.run" , flagSkipRegexp ))
609633 t := & T {
610634 common : common {
611635 output : & logger {logToStdout : flagVerbose },
0 commit comments