mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-15 04:18:03 +00:00
- RESP -ERR no longer closes healthy conn / aborts batch; global cap replacement-aware - global health-check pass serialized (latent data race); MemoryMonitor via ResourceManager - token-exchange retry, open-circuit rejections counted as failures - TLS-posture matching transport reuse (no silent InsecureSkipVerify handoff)
52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package resilience
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestCircuitBreaker_HalfOpenGateNotExceeded guards the R152 fix to
|
|
// AllowRequest: the open→half-open transition returned true without
|
|
// incrementing halfOpenRequests, so the very probe that opens the
|
|
// half-open window was free — allowing exactly one more request than
|
|
// the configured gate (on a serial refusal loop: gate+1 pass). The
|
|
// probe must be counted so cumulative half-open admissions stay
|
|
// within HalfOpenMaxRequests.
|
|
func TestCircuitBreaker_HalfOpenGateNotExceeded(t *testing.T) {
|
|
config := &CircuitBreakerConfig{
|
|
MaxFailures: 2,
|
|
Timeout: 50 * time.Millisecond,
|
|
HalfOpenMaxRequests: 2,
|
|
}
|
|
cb := NewCircuitBreaker(config)
|
|
ctx := context.Background()
|
|
|
|
// Open the circuit.
|
|
for i := 0; i < 2; i++ {
|
|
cb.Execute(ctx, func() error { return errors.New("boom") })
|
|
}
|
|
if cb.GetState() != StateOpen {
|
|
t.Fatal("expected open after failures")
|
|
}
|
|
|
|
time.Sleep(100 * time.Millisecond) // past timeout → cooldown expired
|
|
|
|
// Serially offer gate+overflow admission slots. The transition probe
|
|
// must count toward the gate; un-fixed code allows one extra.
|
|
allowed := 0
|
|
for i := 0; i < config.HalfOpenMaxRequests+5; i++ {
|
|
if !cb.AllowRequest() {
|
|
break
|
|
}
|
|
allowed++
|
|
}
|
|
if allowed > config.HalfOpenMaxRequests {
|
|
t.Fatalf("half-open gate exceeded: %d admitted, max %d", allowed, config.HalfOpenMaxRequests)
|
|
}
|
|
if allowed == 0 {
|
|
t.Fatal("at least one probe must be allowed once the cooldown expires")
|
|
}
|
|
}
|