github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/restore/backoff_test.go (about) 1 // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0. 2 3 package restore_test 4 5 import ( 6 "context" 7 "time" 8 9 . "github.com/pingcap/check" 10 "github.com/pingcap/tidb/util/testleak" 11 "go.uber.org/multierr" 12 "google.golang.org/grpc/codes" 13 "google.golang.org/grpc/status" 14 15 berrors "github.com/pingcap/br/pkg/errors" 16 "github.com/pingcap/br/pkg/mock" 17 "github.com/pingcap/br/pkg/restore" 18 "github.com/pingcap/br/pkg/utils" 19 ) 20 21 var _ = Suite(&testBackofferSuite{}) 22 23 type testBackofferSuite struct { 24 mock *mock.Cluster 25 } 26 27 func (s *testBackofferSuite) SetUpSuite(c *C) { 28 var err error 29 s.mock, err = mock.NewCluster() 30 c.Assert(err, IsNil) 31 } 32 33 func (s *testBackofferSuite) TearDownSuite(c *C) { 34 testleak.AfterTest(c)() 35 } 36 37 func (s *testBackofferSuite) TestBackoffWithSuccess(c *C) { 38 var counter int 39 backoffer := restore.NewBackoffer(10, time.Nanosecond, time.Nanosecond) 40 err := utils.WithRetry(context.Background(), func() error { 41 defer func() { counter++ }() 42 switch counter { 43 case 0: 44 return status.Error(codes.Unavailable, "transport is closing") 45 case 1: 46 return berrors.ErrKVEpochNotMatch 47 case 2: 48 return nil 49 } 50 return nil 51 }, backoffer) 52 c.Assert(counter, Equals, 3) 53 c.Assert(err, IsNil) 54 } 55 56 func (s *testBackofferSuite) TestBackoffWithFatalError(c *C) { 57 var counter int 58 backoffer := restore.NewBackoffer(10, time.Nanosecond, time.Nanosecond) 59 gRPCError := status.Error(codes.Unavailable, "transport is closing") 60 err := utils.WithRetry(context.Background(), func() error { 61 defer func() { counter++ }() 62 switch counter { 63 case 0: 64 return gRPCError // nolint:wrapcheck 65 case 1: 66 return berrors.ErrKVEpochNotMatch 67 case 2: 68 return berrors.ErrKVDownloadFailed 69 case 3: 70 return berrors.ErrKVRangeIsEmpty 71 } 72 return nil 73 }, backoffer) 74 c.Assert(counter, Equals, 4) 75 c.Assert(multierr.Errors(err), DeepEquals, []error{ 76 gRPCError, 77 berrors.ErrKVEpochNotMatch, 78 berrors.ErrKVDownloadFailed, 79 berrors.ErrKVRangeIsEmpty, 80 }) 81 } 82 83 func (s *testBackofferSuite) TestBackoffWithFatalRawGRPCError(c *C) { 84 var counter int 85 canceledError := status.Error(codes.Canceled, "context canceled") 86 backoffer := restore.NewBackoffer(10, time.Nanosecond, time.Nanosecond) 87 err := utils.WithRetry(context.Background(), func() error { 88 defer func() { counter++ }() 89 return canceledError // nolint:wrapcheck 90 }, backoffer) 91 c.Assert(counter, Equals, 1) 92 c.Assert(multierr.Errors(err), DeepEquals, []error{ 93 canceledError, 94 }) 95 } 96 97 func (s *testBackofferSuite) TestBackoffWithRetryableError(c *C) { 98 var counter int 99 backoffer := restore.NewBackoffer(10, time.Nanosecond, time.Nanosecond) 100 err := utils.WithRetry(context.Background(), func() error { 101 defer func() { counter++ }() 102 return berrors.ErrKVEpochNotMatch 103 }, backoffer) 104 c.Assert(counter, Equals, 10) 105 c.Assert(multierr.Errors(err), DeepEquals, []error{ 106 berrors.ErrKVEpochNotMatch, 107 berrors.ErrKVEpochNotMatch, 108 berrors.ErrKVEpochNotMatch, 109 berrors.ErrKVEpochNotMatch, 110 berrors.ErrKVEpochNotMatch, 111 berrors.ErrKVEpochNotMatch, 112 berrors.ErrKVEpochNotMatch, 113 berrors.ErrKVEpochNotMatch, 114 berrors.ErrKVEpochNotMatch, 115 berrors.ErrKVEpochNotMatch, 116 }) 117 }