76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
package resilience
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type roundTripFunc func(*http.Request) (*http.Response, error)
|
|
|
|
func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { return f(r) }
|
|
func TestBreakerProbeAndLateResult(t *testing.T) {
|
|
b, _ := New(Config{FailureThreshold: 1, MaxConcurrent: 2, OpenTimeout: time.Second})
|
|
now := time.Now()
|
|
b.now = func() time.Time { return now }
|
|
ctx := context.Background()
|
|
first, _ := b.Acquire(ctx)
|
|
late, _ := b.Acquire(ctx)
|
|
first(false)
|
|
late(true)
|
|
if b.Snapshot().State != "open" {
|
|
t.Fatal(b.Snapshot())
|
|
}
|
|
if _, err := b.Acquire(ctx); !errors.Is(err, ErrOpen) {
|
|
t.Fatal(err)
|
|
}
|
|
now = now.Add(time.Second)
|
|
probe, err := b.Acquire(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err = b.Acquire(ctx); !errors.Is(err, ErrOpen) {
|
|
t.Fatal(err)
|
|
}
|
|
probe(true)
|
|
probe(false)
|
|
if s := b.Snapshot(); s.State != "closed" || s.Active != 0 {
|
|
t.Fatal(s)
|
|
}
|
|
}
|
|
func TestTransportHoldsSlotAndReleasesPanic(t *testing.T) {
|
|
b, _ := New(Config{MaxConcurrent: 1})
|
|
tr := Transport{Breaker: b, Base: roundTripFunc(func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader("hello"))}, nil
|
|
})}
|
|
req, _ := http.NewRequest("GET", "http://example.test", nil)
|
|
r, err := tr.RoundTrip(req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err = tr.RoundTrip(req); !errors.Is(err, ErrBusy) {
|
|
t.Fatal(err)
|
|
}
|
|
io.ReadAll(r.Body)
|
|
r.Body.Close()
|
|
if b.Snapshot().Active != 0 {
|
|
t.Fatal(b.Snapshot())
|
|
}
|
|
tr.Base = roundTripFunc(func(*http.Request) (*http.Response, error) { panic("fixture") })
|
|
func() {
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Error("panic lost")
|
|
}
|
|
}()
|
|
tr.RoundTrip(req)
|
|
}()
|
|
if b.Snapshot().Active != 0 {
|
|
t.Fatal(b.Snapshot())
|
|
}
|
|
}
|