@@ -6,6 +6,7 @@ package main
66import (
77 "bufio"
88 "bytes"
9+ "context"
910 "errors"
1011 "flag"
1112 "fmt"
@@ -366,13 +367,20 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
366367 return
367368 }
368369
370+ // Reserve CPU time for the test to run.
371+ // This attempts to ensure that the test is not CPU-starved.
372+ options .Semaphore <- struct {}{}
373+ defer func () { <- options .Semaphore }()
374+
369375 // Create the test command, taking care of emulators etc.
376+ ctx , cancel := context .WithTimeout (context .Background (), time .Minute )
377+ defer cancel ()
370378 var cmd * exec.Cmd
371379 if len (spec .Emulator ) == 0 {
372- cmd = exec .Command ( binary )
380+ cmd = exec .CommandContext ( ctx , binary )
373381 } else {
374382 args := append (spec .Emulator [1 :], binary )
375- cmd = exec .Command ( spec .Emulator [0 ], args ... )
383+ cmd = exec .CommandContext ( ctx , spec .Emulator [0 ], args ... )
376384 }
377385 if len (spec .Emulator ) != 0 && spec .Emulator [0 ] == "wasmtime" {
378386 // Allow reading from the current directory.
@@ -389,8 +397,6 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
389397 }
390398
391399 // Run the test.
392- runComplete := make (chan struct {})
393- ranTooLong := false
394400 stdout := & bytes.Buffer {}
395401 if len (spec .Emulator ) != 0 && spec .Emulator [0 ] == "simavr" {
396402 cmd .Stdout = os .Stderr
@@ -403,32 +409,11 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
403409 if err != nil {
404410 t .Fatal ("failed to start:" , err )
405411 }
406- go func () {
407- // Terminate the process if it runs too long.
408- maxDuration := 10 * time .Second
409- if runtime .GOOS == "windows" {
410- // For some reason, tests on Windows can take around
411- // 30s to complete. TODO: investigate why and fix this.
412- maxDuration = 40 * time .Second
413- }
414- timer := time .NewTimer (maxDuration )
415- select {
416- case <- runComplete :
417- timer .Stop ()
418- case <- timer .C :
419- ranTooLong = true
420- if runtime .GOOS == "windows" {
421- cmd .Process .Signal (os .Kill ) // Windows doesn't support SIGINT.
422- } else {
423- cmd .Process .Signal (os .Interrupt )
424- }
425- }
426- }()
427412 err = cmd .Wait ()
428- close (runComplete )
429413
430- if ranTooLong {
414+ if cerr := ctx . Err (); cerr == context . DeadlineExceeded {
431415 stdout .WriteString ("--- test ran too long, terminating...\n " )
416+ err = cerr
432417 }
433418
434419 // putchar() prints CRLF, convert it to LF.
0 commit comments