fiber/addon/retry/exponential_backoff_test.go
Gökhan Özeloğlu 4adda508b0
v3 (feature): add retry mechanism (#1972)
* v3-retry-mechanism: Add retry mechanism

* General logic is implemented.

* Unit tests are added.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Refactor test assertion

* Replaced testify/assert with fiber's assert.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Add test for next method

* currentInterval bug is fixed in Retry.

* If condition is fixed in next.

* struct definition refactored and if condtion is removed in TestExponentialBackoff_Retry.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Add config for retry.

* Constant variables are removed.

* Helper function is added for default.

* Helper function is used in New function.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Replace math/rand with crypto/rand

* Random number generation package has been replaced with more secure one,
crypto/rand.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Add a README for retry middleware

* Explanation and examples are added.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Add comment line for documentation

* Comment lines are added for ExponentialBackoff variables.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* Run go mod tidy

* Unused package(s) removed.

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>

* move middleware -> addon

Signed-off-by: Gökhan Özeloğlu <gokhan.ozeloglu@deliveryhero.com>
Co-authored-by: Muhammed Efe Çetin <efectn@protonmail.com>
2022-08-19 08:20:14 +02:00

125 lines
2.8 KiB
Go

package retry
import (
"fmt"
"github.com/gofiber/fiber/v3/utils"
"testing"
"time"
)
func TestExponentialBackoff_Retry(t *testing.T) {
tests := []struct {
name string
expBackoff *ExponentialBackoff
f func() error
expErr error
}{
{
name: "With default values - successful",
expBackoff: NewExponentialBackoff(),
f: func() error {
return nil
},
},
{
name: "With default values - unsuccessful",
expBackoff: NewExponentialBackoff(),
f: func() error {
return fmt.Errorf("failed function")
},
expErr: fmt.Errorf("failed function"),
},
{
name: "Successful function",
expBackoff: &ExponentialBackoff{
InitialInterval: 1 * time.Millisecond,
MaxBackoffTime: 100 * time.Millisecond,
Multiplier: 2.0,
MaxRetryCount: 5,
},
f: func() error {
return nil
},
},
{
name: "Unsuccessful function",
expBackoff: &ExponentialBackoff{
InitialInterval: 2 * time.Millisecond,
MaxBackoffTime: 100 * time.Millisecond,
Multiplier: 2.0,
MaxRetryCount: 5,
},
f: func() error {
return fmt.Errorf("failed function")
},
expErr: fmt.Errorf("failed function"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.expBackoff.Retry(tt.f)
utils.AssertEqual(t, tt.expErr, err)
})
}
}
func TestExponentialBackoff_Next(t *testing.T) {
tests := []struct {
name string
expBackoff *ExponentialBackoff
expNextTimeIntervals []time.Duration
}{
{
name: "With default values",
expBackoff: NewExponentialBackoff(),
expNextTimeIntervals: []time.Duration{
1 * time.Second,
2 * time.Second,
4 * time.Second,
8 * time.Second,
16 * time.Second,
32 * time.Second,
32 * time.Second,
32 * time.Second,
32 * time.Second,
32 * time.Second,
},
},
{
name: "Custom values",
expBackoff: &ExponentialBackoff{
InitialInterval: 2.0 * time.Second,
MaxBackoffTime: 64 * time.Second,
Multiplier: 3.0,
MaxRetryCount: 8,
currentInterval: 2.0 * time.Second,
},
expNextTimeIntervals: []time.Duration{
2 * time.Second,
6 * time.Second,
18 * time.Second,
54 * time.Second,
64 * time.Second,
64 * time.Second,
64 * time.Second,
64 * time.Second,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for i := 0; i < tt.expBackoff.MaxRetryCount; i++ {
next := tt.expBackoff.next()
if next < tt.expNextTimeIntervals[i] || next > tt.expNextTimeIntervals[i]+1*time.Second {
t.Errorf("wrong next time:\n"+
"actual:%v\n"+
"expected range:%v-%v\n",
next, tt.expNextTimeIntervals[i], tt.expNextTimeIntervals[i]+1*time.Second)
}
}
})
}
}