Skip to content

Commit

Permalink
catch innermost spec context timeout
Browse files Browse the repository at this point in the history
In order to prevent the panic() that occurs if a context timeout
cancel() function fires in the Go testing tool, we execute each test
spec in its own goroutine and catch the individual cancel() function
firing in order to properly output a failed assertion instead of a
panic.

Issue #37

Signed-off-by: Jay Pipes <[email protected]>
  • Loading branch information
jaypipes committed Jun 26, 2024
1 parent f051721 commit 3b618f6
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions scenario/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,19 @@ func (s *Scenario) Run(ctx context.Context, t *testing.T) error {
defer cancel()
}

res, rterr := s.runSpec(specCtx, rt, to, idx, spec)
var res *api.Result
ch := make(chan runSpecRes, 1)

go s.runSpec(specCtx, ch, rt, to, idx, spec)

select {
case <-specCtx.Done():
t.Fatalf("assertion failed: timeout exceeded (%s)", to.After)
break
case runres := <-ch:
res = runres.r
rterr = runres.err
}
if rterr != nil {
break
}
Expand All @@ -115,14 +127,20 @@ func (s *Scenario) Run(ctx context.Context, t *testing.T) error {
return rterr
}

type runSpecRes struct {
r *api.Result
err error
}

// runSpec executes an individual test spec
func (s *Scenario) runSpec(
ctx context.Context,
ch chan runSpecRes,
retry *api.Retry,
timeout *api.Timeout,
idx int,
spec api.Evaluable,
) (*api.Result, error) {
) {
sb := spec.Base()
specTraceMsg := strconv.Itoa(idx)
if sb.Name != "" {
Expand All @@ -136,13 +154,15 @@ func (s *Scenario) runSpec(
// Just evaluate the test spec once
res, err := spec.Eval(ctx)
if err != nil {
return nil, err
ch <- runSpecRes{nil, err}
return
}
debug.Println(
ctx, "run: single-shot (no retries) ok: %v",
!res.Failed(),
)
return res, nil
ch <- runSpecRes{res, nil}
return
}

// retry the action and test the assertions until they succeed,
Expand Down Expand Up @@ -187,7 +207,8 @@ func (s *Scenario) runSpec(

res, err = spec.Eval(ctx)
if err != nil {
return nil, err
ch <- runSpecRes{nil, err}
return
}
success = !res.Failed()
debug.Println(
Expand All @@ -206,7 +227,7 @@ func (s *Scenario) runSpec(
}
attempts++
}
return res, nil
ch <- runSpecRes{res, nil}
}

// getTimeout returns the timeout configuration for the test spec. We check for
Expand Down

0 comments on commit 3b618f6

Please sign in to comment.