package bootstrap import ( "strconv" "strings" "testing" "time" "proxy-pool/internal/config" "proxy-pool/internal/controller/provider" "proxy-pool/internal/platform/credentials" ) func TestProviderRuntimeConfigMapsValidatedUpstreamOnce(t *testing.T) { configuration, err := config.Load(strings.NewReader(bootstrapTestConfig)) if err != nil { t.Fatalf("config.Load(): %v", err) } upstream := configuration.Upstreams["provider-a"] mapped, err := providerRuntimeConfig("provider-a", upstream) if err != nil { t.Fatalf("providerRuntimeConfig(): %v", err) } if mapped.Provider.UpstreamID != "provider-a" || mapped.Provider.RequestInterval != time.Second || mapped.Provider.Timeout != 3*time.Second || mapped.Provider.MaxAttempts != 3 || mapped.Provider.MaxInFlight != 1 || mapped.Provider.MaxTotal != 1_000 || mapped.Provider.MaxSize != 100 || mapped.Provider.TTL != 2*time.Minute || mapped.Provider.AllocationSafetyMargin != 10*time.Second { t.Fatalf("Provider config = %+v", mapped.Provider) } if mapped.ReconcileInterval != time.Second || mapped.ReconcilePolicy.MinimumAvailableSlots != 100 || mapped.ReconcilePolicy.TargetAvailableSlots != 200 || mapped.ReconcilePolicy.ExpectedPerFetch != 10 || mapped.ReconcilePolicy.ExpectedSlotsPerFetch != 100 || mapped.ReconcilePolicy.SafetyMargin != 10*time.Second { t.Fatalf("Reconcile config = %+v interval=%s", mapped.ReconcilePolicy, mapped.ReconcileInterval) } } func TestNewProviderFleetBuildsEnabledUpstreamsInStableOrder(t *testing.T) { configuration, err := config.Load(strings.NewReader(bootstrapTestConfig)) if err != nil { t.Fatalf("config.Load(): %v", err) } configuration.Upstreams["disabled"] = config.Upstream{} credentialStore, err := credentials.NewMemoryStore(10) if err != nil { t.Fatalf("NewMemoryStore(): %v", err) } fleet, err := newProviderFleet(configuration, ports{ activity: &stubActivityStore{}, coordinator: coordinatorStub{}, credentials: credentialStore, }) if err != nil { t.Fatalf("newProviderFleet(): %v", err) } if got := fleet.IDs(); len(got) != 2 || got[0] != "provider-a" || got[1] != "provider-b" { t.Fatalf("Fleet IDs = %v, want [provider-a provider-b]", got) } configuration.Upstreams["provider-a"] = config.Upstream{} configuration.Upstreams["provider-b"] = config.Upstream{} fleet, err = newProviderFleet(configuration, ports{}) if err != nil || fleet != nil { t.Fatalf("newProviderFleet(no enabled) = (%v, %v), want nil fleet", fleet, err) } } func TestProviderRuntimeConfigRejectsDisabledAndOverflowingInputs(t *testing.T) { if _, err := providerRuntimeConfig("provider-a", config.Upstream{}); err == nil { t.Fatal("providerRuntimeConfig(disabled) error = nil") } overflowing := config.Upstream{ Enabled: true, Pool: config.Pool{MaxSize: int(^uint(0) >> 1)}, Capacity: config.Capacity{ MaxConcurrencyPerProxy: int(^uint(0) >> 1), }, Fetch: config.Fetch{EstimatedIPsPerCall: int(^uint(0) >> 1)}, } if _, err := providerRuntimeConfig("provider-a", overflowing); err == nil { t.Fatal("providerRuntimeConfig(overflow) error = nil") } configuration, err := config.Load(strings.NewReader(bootstrapTestConfig)) if err != nil { t.Fatalf("config.Load(): %v", err) } tooLarge := configuration.Upstreams["provider-a"] tooLarge.Pool.MaxSize = redisMaximumScan + 1 if _, err := providerRuntimeConfig("provider-a", tooLarge); err == nil { t.Fatal("providerRuntimeConfig(oversized inventory) error = nil") } tooLarge = configuration.Upstreams["provider-a"] tooLarge.Fetch.MaxTotal = int(provider.MaximumCoordinationInteger) if strconv.IntSize == 64 { tooLarge.Fetch.MaxTotal++ if _, err := providerRuntimeConfig("provider-a", tooLarge); err == nil { t.Fatal("providerRuntimeConfig(inexact Redis integer) error = nil") } } }