fix: fix race in setupInjectedToolTest (#25455)

Fixes race condition in `setupInjectedToolTest`.

To reproduce add short sleep to AsyncRecorder.RecordToolUsage method
(inside newly spawned go-routine):
https://github.com/coder/coder/blob/46821525f7d2f7466735463898fb6e054c169f85/aibridge/recorder/recorder.go#L254-L258

Upstream request counter can reach 2 while no recording has been done
since asyncRecorder does it asynchronously:
https://github.com/coder/coder/blob/46821525f7d2f7466735463898fb6e054c169f85/aibridge/internal/integrationtest/setupbridge.go#L242-L244

Added consuming request to `setupInjectedToolTest` so
`newInterceptionProcessor` handler finishes before returning from
`setupInjectedToolTest` which guarantees that all recordings are done:
https://github.com/coder/coder/blob/46821525f7d2f7466735463898fb6e054c169f85/aibridge/bridge.go#L282

Fixes: https://github.com/coder/internal/issues/1526
This commit is contained in:
Paweł Banaszewski
2026-05-19 09:36:38 +02:00
committed by GitHub
parent 9444eddf4e
commit c0b4180206
@@ -3,6 +3,7 @@ package integrationtest
import (
"bytes"
"context"
"io"
"net"
"net/http"
"net/http/httptest"
@@ -238,10 +239,12 @@ func setupInjectedToolTest(
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
// Wait both requests (initial + tool call result)
require.Eventually(t, func() bool {
return upstream.Calls.Load() == 2
}, testutil.WaitMedium, testutil.IntervalFast)
// Drain the body so the bridge handler returns and asyncRecorder.Wait()
// flushes pending recordings (see aibridge/bridge.go:newInterceptionProcessor).
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
_ = resp.Body.Close()
resp.Body = io.NopCloser(bytes.NewReader(body))
return bridgeServer, mockMCP, resp
}