Skip to content

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
Signed-off-by: JmPotato <ghzpotato@gmail.com>
  • Loading branch information
JmPotato committed Jan 8, 2024
1 parent f9aa0a0 commit f539e0f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
28 changes: 28 additions & 0 deletions client/http/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import (
"net/http"
"strings"
"testing"
"time"

"github.com/pingcap/errors"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
"github.com/stretchr/testify/require"
"github.com/tikv/pd/client/retry"
"go.uber.org/atomic"
)

Expand Down Expand Up @@ -169,3 +171,29 @@ func TestRedirectWithMetrics(t *testing.T) {
re.Equal(float64(4), out.Counter.GetValue())
c.Close()
}

func TestWithBackoffer(t *testing.T) {
re := require.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := NewClient("test-with-backoffer", []string{"http://127.0.0.1"})

base := 100 * time.Millisecond
max := 500 * time.Millisecond
total := time.Second
bo := retry.InitialBackoffer(base, max, total)
// Test the time cost of the backoff.
start := time.Now()
_, err := c.WithBackoffer(bo).GetPDVersion(ctx)
re.InDelta(total, time.Since(start), float64(250*time.Millisecond))
re.Error(err)
// Test if the infinite retry works.
bo = retry.InitialBackoffer(base, max, 0)
timeoutCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
start = time.Now()
_, err = c.WithBackoffer(bo).GetPDVersion(timeoutCtx)
re.InDelta(3*time.Second, time.Since(start), float64(250*time.Millisecond))
re.ErrorIs(err, context.DeadlineExceeded)
c.Close()
}
7 changes: 5 additions & 2 deletions client/retry/backoff.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"time"

"github.com/pingcap/errors"
"github.com/pingcap/failpoint"
)

Expand Down Expand Up @@ -48,6 +49,8 @@ func (bo *Backoffer) Exec(
after := time.NewTimer(currentInterval)
select {
case <-ctx.Done():
after.Stop()
return errors.Trace(ctx.Err())
case <-after.C:
failpoint.Inject("backOffExecute", func() {
testBackOffExecuteFlag = true
Expand All @@ -71,7 +74,7 @@ func (bo *Backoffer) Exec(
// - `base` defines the initial time interval to wait before each retry.
// - `max` defines the max time interval to wait before each retry.
// - `total` defines the max total time duration cost in retrying. If it's 0, it means infinite retry until success.
func InitialBackoffer(base, max, total time.Duration) Backoffer {
func InitialBackoffer(base, max, total time.Duration) *Backoffer {
// Make sure the base is less than or equal to the max.
if base > max {
base = max
Expand All @@ -80,7 +83,7 @@ func InitialBackoffer(base, max, total time.Duration) Backoffer {
if total > 0 && total < base {
total = base
}
return Backoffer{
return &Backoffer{
base: base,
max: max,
total: total,
Expand Down
35 changes: 22 additions & 13 deletions client/retry/backoff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,45 @@ import (
func TestBackoffer(t *testing.T) {
re := require.New(t)

baseBackoff := 100 * time.Millisecond
maxBackoff := time.Second
totalBackoff := time.Second

backoff := InitialBackoffer(baseBackoff, maxBackoff, totalBackoff)
re.Equal(backoff.nextInterval(), baseBackoff)
re.Equal(backoff.nextInterval(), 2*baseBackoff)
base := time.Second
max := 100 * time.Millisecond
total := time.Millisecond
// Test initial backoffer.
bo := InitialBackoffer(time.Second, 100*time.Millisecond, time.Millisecond)
// `bo.base` will be set to `bo.max` if `bo.base` is greater than `bo.max`.
re.Equal(max, bo.base)
re.Equal(max, bo.max)
// `bo.total` will be set to `bo.base` if `bo.total` is greater than `bo.base`.
re.Equal(bo.base, bo.total)

base = 100 * time.Millisecond
max = time.Second
total = time.Second
// Test the nextInterval function.
bo = InitialBackoffer(base, max, total)
re.Equal(bo.nextInterval(), base)
re.Equal(bo.nextInterval(), 2*base)
for i := 0; i < 10; i++ {
re.LessOrEqual(backoff.nextInterval(), maxBackoff)
re.LessOrEqual(bo.nextInterval(), max)
}
re.Equal(backoff.nextInterval(), maxBackoff)
re.Equal(bo.nextInterval(), max)

// Reset backoff
backoff.resetBackoff()
bo.resetBackoff()
var (
start time.Time
execCount int
err error
expectedErr = errors.New("test")
)
err = backoff.Exec(context.Background(), func() error {
err = bo.Exec(context.Background(), func() error {
execCount++
if start.IsZero() {
start = time.Now()
}
return expectedErr
})
total := time.Since(start)
re.InDelta(total, time.Since(start), float64(250*time.Millisecond))
re.ErrorIs(err, expectedErr)
re.Equal(4, execCount)
re.InDelta(totalBackoff, total, float64(maxBackoff/2))
}

0 comments on commit f539e0f

Please sign in to comment.