Files
fm_be/internal/resilience/breaker_test.go
2026-07-16 22:16:45 +07:00

93 lines
2.5 KiB
Go

package resilience
import (
"context"
"errors"
"io"
"log/slog"
"testing"
"time"
"github.com/aws/smithy-go"
"wucher/internal/config"
)
func TestExecutor_ExcludedErrorsDoNotTrip(t *testing.T) {
executor := NewExecutor("ses", config.CircuitBreakerPolicy{
Enabled: true,
Timeout: time.Second,
MinRequests: 2,
FailureRatio: 0.5,
ConsecutiveFailures: 2,
}, slog.New(slog.NewJSONHandler(io.Discard, nil)), func(error) Classification {
return ClassificationExcluded
})
for range 2 {
err := executor.Execute(context.Background(), func(context.Context) error {
return errors.New("validation error")
})
if err == nil {
t.Fatalf("expected original error")
}
}
counts := executor.Counts()
if counts.TotalExclusions != 2 {
t.Fatalf("expected 2 exclusions, got %+v", counts)
}
if counts.TotalFailures != 0 {
t.Fatalf("expected 0 failures, got %+v", counts)
}
}
func TestExecutor_FailuresTripBreaker(t *testing.T) {
executor := NewExecutor("sqs", config.CircuitBreakerPolicy{
Enabled: true,
Timeout: time.Second,
MinRequests: 1,
FailureRatio: 0.5,
ConsecutiveFailures: 2,
}, slog.New(slog.NewJSONHandler(io.Discard, nil)), nil)
for range 2 {
err := executor.Execute(context.Background(), func(context.Context) error {
return errors.New("dependency down")
})
if err == nil {
t.Fatalf("expected dependency error")
}
}
err := executor.Execute(context.Background(), func(context.Context) error {
return nil
})
var openErr *OpenError
if !errors.As(err, &openErr) {
t.Fatalf("expected breaker open error, got %v", err)
}
}
func TestClassifySQSError(t *testing.T) {
if got := ClassifySQSError(apiError{code: "AccessDenied", fault: smithy.FaultClient}); got != ClassificationExcluded {
t.Fatalf("expected client fault excluded, got %v", got)
}
if got := ClassifySQSError(apiError{code: "InternalError", fault: smithy.FaultServer}); got != ClassificationFailure {
t.Fatalf("expected server fault failure, got %v", got)
}
if got := ClassifySQSError(apiError{code: "ThrottlingException", fault: smithy.FaultClient}); got != ClassificationFailure {
t.Fatalf("expected throttling failure, got %v", got)
}
}
type apiError struct {
code string
fault smithy.ErrorFault
}
func (e apiError) Error() string { return e.code }
func (e apiError) ErrorCode() string { return e.code }
func (e apiError) ErrorMessage() string { return e.code }
func (e apiError) ErrorFault() smithy.ErrorFault { return e.fault }