TestPassthrough_KeyFailover exercises the KeyFailoverTransport end-to-end through the passthrough proxy, parameterised over providers (anthropic, openai). Each scenario asserts the upstream request count, the response status and Retry-After, and the final pool state.
(t *testing.T)
| 296 | // request count, the response status and Retry-After, and the final |
| 297 | // pool state. |
| 298 | func TestPassthrough_KeyFailover(t *testing.T) { |
| 299 | t.Parallel() |
| 300 | |
| 301 | type upstreamResponse struct { |
| 302 | statusCode int |
| 303 | body string |
| 304 | headers map[string]string |
| 305 | } |
| 306 | |
| 307 | const ( |
| 308 | rateLimitBody = `{"error":"rate"}` |
| 309 | authErrorBody = `{"error":"unauthorized"}` |
| 310 | serverErrorBody = `{"error":"server"}` |
| 311 | successBody = `{"data":[]}` |
| 312 | ) |
| 313 | |
| 314 | // providers parameterises the table over the providers exposed |
| 315 | // to the failover transport. Each entry encapsulates the |
| 316 | // provider-specific bits the test needs: how the mock upstream |
| 317 | // extracts the key from the request, how a BYOK request sets |
| 318 | // it, and how the provider is constructed for a given pool. |
| 319 | providers := []struct { |
| 320 | name string |
| 321 | byokOnly bool |
| 322 | extractKey func(*http.Request) string |
| 323 | setBYOK func(*http.Request, string) |
| 324 | newProvider func(baseURL string, pool *keypool.Pool) provider.Provider |
| 325 | }{ |
| 326 | { |
| 327 | name: "anthropic", |
| 328 | extractKey: func(r *http.Request) string { |
| 329 | return r.Header.Get("X-Api-Key") |
| 330 | }, |
| 331 | setBYOK: func(r *http.Request, key string) { |
| 332 | r.Header.Set("X-Api-Key", key) |
| 333 | }, |
| 334 | newProvider: func(baseURL string, pool *keypool.Pool) provider.Provider { |
| 335 | return provider.NewAnthropic(config.Anthropic{ |
| 336 | BaseURL: baseURL, |
| 337 | KeyPool: pool, |
| 338 | }, nil) |
| 339 | }, |
| 340 | }, |
| 341 | { |
| 342 | name: "openai", |
| 343 | extractKey: func(r *http.Request) string { |
| 344 | return strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ") |
| 345 | }, |
| 346 | setBYOK: func(r *http.Request, key string) { |
| 347 | r.Header.Set("Authorization", "Bearer "+key) |
| 348 | }, |
| 349 | newProvider: func(baseURL string, pool *keypool.Pool) provider.Provider { |
| 350 | cfg := config.OpenAI{BaseURL: baseURL} |
| 351 | if pool != nil { |
| 352 | cfg.KeyPool = pool |
| 353 | } |
| 354 | return provider.NewOpenAI(cfg) |
| 355 | }, |
nothing calls this directly
no test coverage detected