feat: add independent platform modules and multi-provider storage
This commit is contained in:
75
resilience/breaker_test.go
Normal file
75
resilience/breaker_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user