proxy-pool/internal/controller/health/unhealthy_reaper_test.go
youfak 84ed10bd7a
Some checks are pending
ci / proto (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
ci / race (push) Waiting to run
ci / integration (push) Waiting to run
feat: reap sustained unhealthy proxies
2026-08-02 10:15:25 +08:00

65 lines
2.5 KiB
Go

package health
import (
"context"
"testing"
"time"
"proxy-pool/internal/config"
"proxy-pool/internal/domain/activitypool"
)
type unhealthyRemoverStub struct {
command activitypool.UnhealthySweepCommand
calls int
result activitypool.UnhealthySweepResult
}
func (store *unhealthyRemoverStub) SweepUnhealthy(
_ context.Context,
command activitypool.UnhealthySweepCommand,
) (activitypool.UnhealthySweepResult, error) {
store.calls++
store.command = command
return store.result, nil
}
func TestConfiguredUnhealthyReaperUsesEffectiveEnabledPolicies(t *testing.T) {
now := time.Date(2026, 8, 2, 14, 0, 0, 0, time.UTC)
store := &unhealthyRemoverStub{result: activitypool.UnhealthySweepResult{Removed: 2}}
reaper, err := NewConfiguredUnhealthyReaper(&configurationSourceStub{configuration: &config.Config{
Defaults: config.Defaults{Check: config.Check{UnhealthyRemoveAfter: config.Duration(2 * time.Minute)}},
Upstreams: map[string]config.Upstream{
"provider-a": {Enabled: true, Check: config.Check{UnhealthyRemoveAfter: config.Duration(3 * time.Minute)}},
"provider-b": {Enabled: true},
"provider-c": {Enabled: false},
},
}}, store, UnhealthyReaperOptions{PollInterval: time.Second, BatchSize: 32, Now: func() time.Time { return now }})
if err != nil {
t.Fatalf("NewConfiguredUnhealthyReaper() = %v", err)
}
result, err := reaper.Tick(context.Background())
if err != nil || result != (activitypool.UnhealthySweepResult{Removed: 2}) {
t.Fatalf("Tick() = %+v, %v", result, err)
}
if store.calls != 1 || !store.command.Now.Equal(now) || store.command.Limit != 32 ||
store.command.RemoveAfterByUpstream["provider-a"] != 3*time.Minute ||
store.command.RemoveAfterByUpstream["provider-b"] != 2*time.Minute ||
len(store.command.RemoveAfterByUpstream) != 2 {
t.Fatalf("SweepUnhealthy() command = %+v", store.command)
}
}
func TestConfiguredUnhealthyReaperSkipsDisabledRemoval(t *testing.T) {
store := &unhealthyRemoverStub{}
reaper, err := NewConfiguredUnhealthyReaper(&configurationSourceStub{configuration: &config.Config{
Upstreams: map[string]config.Upstream{"provider-a": {Enabled: true}},
}}, store, UnhealthyReaperOptions{PollInterval: time.Second, BatchSize: 1, Now: time.Now})
if err != nil {
t.Fatalf("NewConfiguredUnhealthyReaper() = %v", err)
}
if result, err := reaper.Tick(context.Background()); err != nil || result != (activitypool.UnhealthySweepResult{}) || store.calls != 0 {
t.Fatalf("Tick(disabled) = (%+v, %v), calls=%d", result, err, store.calls)
}
}