Canceling the request context must surface as a body-read error, matching real-network behavior, and the handler must observe the cancellation through its own request context.
(t *testing.T)
| 189 | // real-network behavior, and the handler must observe the cancellation |
| 190 | // through its own request context. |
| 191 | func TestInMemoryRoundTripper_CancelCloses(t *testing.T) { |
| 192 | t.Parallel() |
| 193 | |
| 194 | handlerCtxObserved := make(chan struct{}) |
| 195 | handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 196 | w.WriteHeader(http.StatusOK) |
| 197 | if f, ok := w.(http.Flusher); ok { |
| 198 | f.Flush() |
| 199 | } |
| 200 | <-r.Context().Done() |
| 201 | close(handlerCtxObserved) |
| 202 | }) |
| 203 | |
| 204 | rt, err := aibridged.NewTransportFactory(handler).TransportFor("openai", aibridge.SourceAgents) |
| 205 | require.NoError(t, err) |
| 206 | |
| 207 | parentCtx := testutil.Context(t, testutil.WaitShort) |
| 208 | ctx, cancel := context.WithCancel(parentCtx) |
| 209 | ctx = aibridge.WithDelegatedAPIKeyID(ctx, "test-key-id") |
| 210 | req, err := http.NewRequestWithContext(ctx, http.MethodPost, "http://aibridge/stream", nil) |
| 211 | require.NoError(t, err) |
| 212 | |
| 213 | resp, err := rt.RoundTrip(req) |
| 214 | require.NoError(t, err) |
| 215 | defer resp.Body.Close() |
| 216 | |
| 217 | cancel() |
| 218 | _, err = io.ReadAll(resp.Body) |
| 219 | require.Error(t, err) |
| 220 | |
| 221 | select { |
| 222 | case <-handlerCtxObserved: |
| 223 | case <-parentCtx.Done(): |
| 224 | t.Fatal("handler did not observe context cancellation") |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | // Many independent in-flight requests on a shared handler must not interfere. |
| 229 | func TestInMemoryRoundTripper_ConcurrentRequests(t *testing.T) { |
nothing calls this directly
no test coverage detected