package httpapi import ( "context" "errors" "sync" "sync/atomic" "testing" "time" "github.com/easyai/easyai-ai-gateway/apps/api/internal/config" ) func TestAdmittedTaskRunModeReservesAcceptanceAndProductionSimulation(t *testing.T) { server := &Server{cfg: config.Config{AppEnv: "production"}} for _, runMode := range []string{"simulation", "SIMULATION", "acceptance", "acceptance_canary"} { _, err := server.admittedTaskRunMode(taskTrafficAdmission{}, map[string]any{"runMode": runMode}) var trafficErr *taskTrafficError if !errors.As(err, &trafficErr) || trafficErr.Status != 403 { t.Fatalf("run mode %q error=%v", runMode, err) } } for _, runMode := range []string{"acceptance", "acceptance_canary"} { got, err := server.admittedTaskRunMode(taskTrafficAdmission{RunMode: runMode}, map[string]any{ "runMode": "production", }) if err != nil || got != runMode { t.Fatalf("admitted mode=%q got=%q err=%v", runMode, got, err) } } } func TestCachedTaskTrafficAuthorizationCollapsesConcurrentLoads(t *testing.T) { server := &Server{} key := taskTrafficAuthorizationCacheKey{runID: "run", apiKeyID: "key", userID: "user"} var loads atomic.Int32 start := make(chan struct{}) const callers = 64 var wg sync.WaitGroup errCh := make(chan error, callers) for range callers { wg.Add(1) go func() { defer wg.Done() <-start runID, err := server.cachedTaskTrafficAuthorization( context.Background(), key, time.Minute, func() (string, error) { loads.Add(1) time.Sleep(10 * time.Millisecond) return "run", nil }, ) if err != nil || runID != "run" { errCh <- errors.New("unexpected cached authorization result") } }() } close(start) wg.Wait() close(errCh) for err := range errCh { t.Fatal(err) } if got := loads.Load(); got != 1 { t.Fatalf("authorization loads=%d, want 1", got) } if _, err := server.cachedTaskTrafficAuthorization( context.Background(), key, time.Minute, func() (string, error) { loads.Add(1) return "run", nil }, ); err != nil { t.Fatal(err) } if got := loads.Load(); got != 1 { t.Fatalf("cached authorization loads=%d, want 1", got) } } func TestCachedTaskTrafficAuthorizationDoesNotCacheFailures(t *testing.T) { server := &Server{} key := taskTrafficAuthorizationCacheKey{runID: "run", apiKeyID: "key", userID: "user"} wantErr := errors.New("database unavailable") loads := 0 for range 2 { _, err := server.cachedTaskTrafficAuthorization( context.Background(), key, time.Minute, func() (string, error) { loads++ return "", wantErr }, ) if !errors.Is(err, wantErr) { t.Fatalf("authorization error=%v, want %v", err, wantErr) } } if loads != 2 { t.Fatalf("failed authorization loads=%d, want 2", loads) } }