Skip to content

Commit 31a8063

Browse files
authored
Merge pull request #1304 from Workiva/gorepoTestTimeout
[go1.20] Updated gorepo test flag handling
2 parents bce1d3f + ac5011a commit 31a8063

File tree

1 file changed

+73
-10
lines changed

1 file changed

+73
-10
lines changed

tests/gorepo/run.go

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,8 @@ func (ctxt *context) match(name string) bool {
560560

561561
func init() { checkShouldTest() }
562562

563+
var errTimeout = errors.New("command exceeded time limit")
564+
563565
// run runs a test.
564566
func (t *test) run() {
565567
start := time.Now()
@@ -611,6 +613,7 @@ func (t *test) run() {
611613
}
612614

613615
var args, flags []string
616+
var tim int
614617
wantError := false
615618
f, err := splitQuoted(action)
616619
if err != nil {
@@ -644,14 +647,6 @@ func (t *test) run() {
644647
case "errorcheck", "errorcheckdir", "errorcheckoutput":
645648
t.action = action
646649
wantError = true
647-
for len(args) > 0 && strings.HasPrefix(args[0], "-") {
648-
if args[0] == "-0" {
649-
wantError = false
650-
} else {
651-
flags = append(flags, args[0])
652-
}
653-
args = args[1:]
654-
}
655650
case "skip":
656651
t.action = "skip"
657652
return
@@ -661,6 +656,38 @@ func (t *test) run() {
661656
return
662657
}
663658

659+
// collect flags
660+
for len(args) > 0 && strings.HasPrefix(args[0], "-") {
661+
switch args[0] {
662+
case "-1":
663+
wantError = true
664+
case "-0":
665+
wantError = false
666+
case "-s":
667+
// GOPHERJS: Doesn't use singlefilepkgs in test yet.
668+
case "-t": // timeout in seconds
669+
args = args[1:]
670+
var err error
671+
tim, err = strconv.Atoi(args[0])
672+
if err != nil {
673+
t.err = fmt.Errorf("need number of seconds for -t timeout, got %s instead", args[0])
674+
}
675+
if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
676+
timeoutScale, err := strconv.Atoi(s)
677+
if err != nil {
678+
log.Fatalf("failed to parse $GO_TEST_TIMEOUT_SCALE = %q as integer: %v", s, err)
679+
}
680+
tim *= timeoutScale
681+
}
682+
case "-goexperiment": // set GOEXPERIMENT environment
683+
args = args[1:]
684+
// GOPHERJS: Ignore GOEXPERIMENT for now
685+
default:
686+
flags = append(flags, args[0])
687+
}
688+
args = args[1:]
689+
}
690+
664691
t.makeTempDir()
665692
defer os.RemoveAll(t.tempDir)
666693

@@ -698,8 +725,40 @@ func (t *test) run() {
698725
cmd.Dir = t.tempDir
699726
cmd.Env = envForDir(cmd.Dir)
700727
}
701-
err := cmd.Run()
702-
if err != nil {
728+
729+
var err error
730+
if tim != 0 {
731+
err = cmd.Start()
732+
// This command-timeout code adapted from cmd/go/test.go
733+
// Note: the Go command uses a more sophisticated timeout
734+
// strategy, first sending SIGQUIT (if appropriate for the
735+
// OS in question) to try to trigger a stack trace, then
736+
// finally much later SIGKILL. If timeouts prove to be a
737+
// common problem here, it would be worth porting over
738+
// that code as well. See https://do.dev/issue/50973
739+
// for more discussion.
740+
if err == nil {
741+
tick := time.NewTimer(time.Duration(tim) * time.Second)
742+
done := make(chan error)
743+
go func() {
744+
done <- cmd.Wait()
745+
}()
746+
select {
747+
case err = <-done:
748+
// ok
749+
case <-tick.C:
750+
cmd.Process.Signal(os.Interrupt)
751+
time.Sleep(1 * time.Second)
752+
cmd.Process.Kill()
753+
<-done
754+
err = errTimeout
755+
}
756+
tick.Stop()
757+
}
758+
} else {
759+
err = cmd.Run()
760+
}
761+
if err != nil && err != errTimeout {
703762
err = fmt.Errorf("%s\n%s", err, buf.Bytes())
704763
}
705764
return buf.Bytes(), err
@@ -720,6 +779,10 @@ func (t *test) run() {
720779
t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
721780
return
722781
}
782+
if err == errTimeout {
783+
t.err = fmt.Errorf("compilation timed out")
784+
return
785+
}
723786
} else {
724787
if err != nil {
725788
t.err = err

0 commit comments

Comments
 (0)