MCPcopy Create free account
hub / github.com/coder/coder / TestIntegrationCircuitBreaker

Function TestIntegrationCircuitBreaker

enterprise/aibridged_integration_test.go:431–557  ·  view source on GitHub ↗

TestIntegrationCircuitBreaker validates that the circuit breaker opens after consecutive failures and that the corresponding metrics are exposed.

(t *testing.T)

Source from the content-addressed store, hash-verified

429// TestIntegrationCircuitBreaker validates that the circuit breaker opens after
430// consecutive failures and that the corresponding metrics are exposed.
431func TestIntegrationCircuitBreaker(t *testing.T) {
432 t.Parallel()
433
434 ctx := testutil.Context(t, testutil.WaitLong)
435
436 // Create prometheus registry and metrics.
437 registry := prometheus.NewRegistry()
438 metrics := aibridge.NewMetrics(registry)
439
440 // Set up mock OpenAI server that always returns 503 Service Unavailable.
441 mockOpenAI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
442 w.Header().Set("Content-Type", "application/json")
443 // Disable SDK retries.
444 w.Header().Set("x-should-retry", "false")
445 w.WriteHeader(http.StatusServiceUnavailable)
446 _, _ = w.Write([]byte(`{"error":{"message":"Service Unavailable.","type":"cf_service_unavailable","code":503}}`))
447 }))
448 t.Cleanup(mockOpenAI.Close)
449
450 // Set up mock Anthropic server that always returns 529 Overloaded.
451 mockAnthropic := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
452 w.Header().Set("Content-Type", "application/json")
453 // Anthropic uses 529 for overloaded errors.
454 w.WriteHeader(529)
455 _, _ = w.Write([]byte(`{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}`))
456 }))
457 t.Cleanup(mockAnthropic.Close)
458
459 // Database and coderd setup.
460 db, ps := dbtestutil.NewDB(t)
461 client, _, api, firstUser := coderdenttest.NewWithAPI(t, &coderdenttest.Options{
462 Options: &coderdtest.Options{
463 Database: db,
464 Pubsub: ps,
465 },
466 })
467
468 userClient, _ := coderdtest.CreateAnotherUser(t, client, firstUser.OrganizationID)
469
470 // Create an API token for the user.
471 apiKey, err := userClient.CreateToken(ctx, "me", codersdk.CreateTokenRequest{
472 TokenName: fmt.Sprintf("test-key-%d", time.Now().UnixNano()),
473 Lifetime: time.Hour,
474 Scope: codersdk.APIKeyScopeCoderAll,
475 })
476 require.NoError(t, err)
477
478 // Create aibridge client.
479 aiBridgeClient, err := api.AGPL.CreateInMemoryAIBridgeServer(ctx)
480 require.NoError(t, err)
481
482 logger := testutil.Logger(t)
483
484 // Create providers with circuit breaker configured to open after 2 failures.
485 cbConfig := &config.CircuitBreaker{
486 FailureThreshold: 2,
487 Interval: time.Minute,
488 Timeout: time.Minute,

Callers

nothing calls this directly

Calls 15

ContextFunction · 0.92
NewMetricsFunction · 0.92
NewDBFunction · 0.92
NewWithAPIFunction · 0.92
CreateAnotherUserFunction · 0.92
LoggerFunction · 0.92
NewOpenAIProviderFunction · 0.92
NewAnthropicProviderFunction · 0.92
NewCachedBridgePoolFunction · 0.92
NewFunction · 0.92
CreateTokenMethod · 0.80

Tested by

no test coverage detected