test: fix concurrent start test assertions#1094
Conversation
There was a problem hiding this comment.
Pull request overview
Refactors TestServer_StartDev_ConcurrentStarts to avoid calling testing.T/require assertions from worker goroutines by having each concurrent start return an error, then asserting in the main test goroutine. This aligns with Go’s testing constraints and should reduce flakiness/misreporting in the concurrent dev-server start integration test.
Changes:
- Reworked the concurrent-start worker logic to return errors from each run and aggregate them in the main goroutine.
- Replaced the command harness usage inside worker goroutines with a small helper that executes
temporalcli.Executeusing captured stdout/stderr. - Updated the concurrency level to a fixed worker pool of 6 and improved error reporting to include command output.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| h := NewCommandHarness(t) | ||
| defer h.Close() | ||
| startOne := func() error { | ||
| ctx, cancel := context.WithCancel(context.Background()) |
There was a problem hiding this comment.
@nanookclaw I like the approach. let's use t.Context() instead of context.Background()
| } | ||
| } | ||
|
|
||
| func executeConcurrentStartCommand(ctx context.Context, args ...string) *CommandResult { |
There was a problem hiding this comment.
let's add func (h *CommandHarness) ExecuteWithContext(ctx context.Context, args ...string) *CommandResult {
so we can keep using the harness
| var cl client.Client | ||
| h.EventuallyWithT(func(t *assert.CollectT) { | ||
| var lastDialErr error | ||
| for start := time.Now(); time.Since(start) < 3*time.Second; { |
There was a problem hiding this comment.
how about something like this:
ticker := time.NewTicker(200 * time.Millisecond)
defer ticker.Stop()
timeout := time.NewTimer(3 * time.Second)
defer timeout.Stop()
outer:
for {
select {
case res := <-resCh:
return concurrentStartCommandResultError("got early server result", res)
case <-timeout.C:
break outer
case <-ticker.C:
var err error
cl, err = client.Dial(client.Options{HostPort: "127.0.0.1:" + port})
if err == nil {
break outer
}
lastDialErr = err
}
}
64ade53 to
ce9c1a5
Compare
|
Updated in ce9c1a5 to address the review comments:
Local verification:
|
Summary
Fixes #581 by removing
testing.Tassertions from the worker goroutines inTestServer_StartDev_ConcurrentStarts. Each concurrent start now returns anerror, and the main test goroutine collects those errors and reports them withrequire.NoError.The test still starts 40 dev server instances with a fixed worker pool of 6 concurrent executions. The replacement command helper runs
server start-devwith a cancellable context and captured stdout/stderr, so failures from early command exit or cleanup are preserved in the final assertion message without callingFailNow-style methods outside the test goroutine.Verification
gofmt -w internal/temporalcli/commands.server_test.gogit diff --checkgo test ./internal/temporalcli -run '^TestServer_StartDev_ConcurrentStarts$' -count=1