(t *testing.T)
| 455 | } |
| 456 | |
| 457 | func TestWriteUpstreamError(t *testing.T) { |
| 458 | t.Parallel() |
| 459 | |
| 460 | tests := []struct { |
| 461 | name string |
| 462 | respErr *intercept.ResponseError |
| 463 | expectStatus int |
| 464 | // Empty string means the header should be absent. |
| 465 | expectRetryAfter string |
| 466 | // Substring expected in the marshaled body. Empty means no body check. |
| 467 | expectBodyContains string |
| 468 | }{ |
| 469 | { |
| 470 | // Standard error: status, code, and JSON body written. |
| 471 | name: "writes_status_and_body", |
| 472 | respErr: intercept.NewResponseError("upstream failed", "api_error", "server_error", http.StatusBadGateway, 0), |
| 473 | expectStatus: http.StatusBadGateway, |
| 474 | expectBodyContains: `"upstream failed"`, |
| 475 | }, |
| 476 | { |
| 477 | // OpenAI envelope: the code field round-trips into the body. |
| 478 | name: "writes_code_field", |
| 479 | respErr: intercept.NewResponseError("rate limited", "rate_limit_error", "rate_limit_exceeded", http.StatusTooManyRequests, 0), |
| 480 | expectStatus: http.StatusTooManyRequests, |
| 481 | expectBodyContains: `"rate_limit_exceeded"`, |
| 482 | }, |
| 483 | { |
| 484 | // Whole-second retryAfter: emitted as integer seconds. |
| 485 | name: "retry_after_in_seconds", |
| 486 | respErr: intercept.NewResponseError("rate limited", "rate_limit_error", "rate_limit_exceeded", http.StatusTooManyRequests, 60*time.Second), |
| 487 | expectStatus: http.StatusTooManyRequests, |
| 488 | expectRetryAfter: "60", |
| 489 | }, |
| 490 | { |
| 491 | // 500ms rounds up to Retry-After: 1. |
| 492 | name: "retry_after_500ms_rounds_up_to_one", |
| 493 | respErr: intercept.NewResponseError("rate limited", "rate_limit_error", "rate_limit_exceeded", http.StatusTooManyRequests, 500*time.Millisecond), |
| 494 | expectStatus: http.StatusTooManyRequests, |
| 495 | expectRetryAfter: "1", |
| 496 | }, |
| 497 | { |
| 498 | // 200ms rounds up to Retry-After: 1. |
| 499 | name: "retry_after_200ms_rounds_up_to_one", |
| 500 | respErr: intercept.NewResponseError("rate limited", "rate_limit_error", "rate_limit_exceeded", http.StatusTooManyRequests, 200*time.Millisecond), |
| 501 | expectStatus: http.StatusTooManyRequests, |
| 502 | expectRetryAfter: "1", |
| 503 | }, |
| 504 | { |
| 505 | // Negative retryAfter: header omitted. |
| 506 | name: "negative_retry_after_omits_header", |
| 507 | respErr: intercept.NewResponseError("rate limited", "rate_limit_error", "rate_limit_exceeded", http.StatusTooManyRequests, -1*time.Second), |
| 508 | expectStatus: http.StatusTooManyRequests, |
| 509 | expectRetryAfter: "", |
| 510 | }, |
| 511 | } |
| 512 | |
| 513 | for _, tc := range tests { |
| 514 | t.Run(tc.name, func(t *testing.T) { |
nothing calls this directly
no test coverage detected