100 lines
2.6 KiB
Go
100 lines
2.6 KiB
Go
package circuitbreaker
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const success = "Success"
|
|
|
|
func TestCircuitBreaker_ExecuteSuccessSingle(t *testing.T) {
|
|
cb := NewCircuitBreaker(Config{
|
|
CommandName: "SuccessSingle", // unique name to avoid conflicts with go tests `-count` option
|
|
Timeout: 1000,
|
|
MaxConcurrentRequests: 100,
|
|
RequestVolumeThreshold: 10,
|
|
SleepWindow: 10,
|
|
ErrorPercentThreshold: 10,
|
|
})
|
|
|
|
expectedResult := success
|
|
cmd := Command{
|
|
functors: []*Functor{
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
return []any{expectedResult}, nil
|
|
}),
|
|
},
|
|
}
|
|
|
|
result := cb.Execute(cmd)
|
|
require.NoError(t, result.Error())
|
|
require.Equal(t, expectedResult, result.Result()[0].(string))
|
|
}
|
|
|
|
func TestCircuitBreaker_ExecuteMultipleFallbacksFail(t *testing.T) {
|
|
cb := NewCircuitBreaker(Config{
|
|
CommandName: "MultipleFail", // unique name to avoid conflicts with go tests `-count` option
|
|
Timeout: 10,
|
|
MaxConcurrentRequests: 100,
|
|
RequestVolumeThreshold: 10,
|
|
SleepWindow: 10,
|
|
ErrorPercentThreshold: 10,
|
|
})
|
|
|
|
cmd := Command{
|
|
functors: []*Functor{
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
time.Sleep(100 * time.Millisecond) // will cause hystrix: timeout
|
|
return []any{success}, nil
|
|
}),
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
return nil, errors.New("provider 2 failed")
|
|
}),
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
return nil, errors.New("provider 3 failed")
|
|
}),
|
|
},
|
|
}
|
|
|
|
result := cb.Execute(cmd)
|
|
require.Error(t, result.Error())
|
|
}
|
|
|
|
func TestCircuitBreaker_ExecuteMultipleFallbacksFailButLastSuccessStress(t *testing.T) {
|
|
cb := NewCircuitBreaker(Config{
|
|
CommandName: "LastSuccessStress", // unique name to avoid conflicts with go tests `-count` option
|
|
Timeout: 10,
|
|
MaxConcurrentRequests: 100,
|
|
RequestVolumeThreshold: 10,
|
|
SleepWindow: 10,
|
|
ErrorPercentThreshold: 10,
|
|
})
|
|
|
|
expectedResult := success
|
|
|
|
// These are executed sequentially, but I had an issue with the test failing
|
|
// because of the open circuit
|
|
for i := 0; i < 1000; i++ {
|
|
cmd := Command{
|
|
functors: []*Functor{
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
return nil, errors.New("provider 1 failed")
|
|
}),
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
return nil, errors.New("provider 2 failed")
|
|
}),
|
|
NewFunctor(func() ([]interface{}, error) {
|
|
return []any{expectedResult}, nil
|
|
}),
|
|
},
|
|
}
|
|
|
|
result := cb.Execute(cmd)
|
|
require.NoError(t, result.Error())
|
|
require.Equal(t, expectedResult, result.Result()[0].(string))
|
|
}
|
|
}
|