github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/utils/safe_point_test.go (about)

     1  // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
     2  
     3  package utils_test
     4  
     5  import (
     6  	"context"
     7  	"sync"
     8  
     9  	. "github.com/pingcap/check"
    10  	"github.com/pingcap/tidb/util/testleak"
    11  	pd "github.com/tikv/pd/client"
    12  
    13  	"github.com/pingcap/br/pkg/utils"
    14  )
    15  
    16  var _ = Suite(&testSafePointSuite{})
    17  
    18  type testSafePointSuite struct{}
    19  
    20  func (s *testSafePointSuite) SetUpSuite(c *C) {}
    21  
    22  func (s *testSafePointSuite) TearDownSuite(c *C) {
    23  	testleak.AfterTest(c)()
    24  }
    25  
    26  func (s *testSafePointSuite) TestCheckGCSafepoint(c *C) {
    27  	ctx := context.Background()
    28  	pdClient := &mockSafePoint{safepoint: 2333}
    29  	{
    30  		err := utils.CheckGCSafePoint(ctx, pdClient, 2333+1)
    31  		c.Assert(err, IsNil)
    32  	}
    33  	{
    34  		err := utils.CheckGCSafePoint(ctx, pdClient, 2333)
    35  		c.Assert(err, NotNil)
    36  	}
    37  	{
    38  		err := utils.CheckGCSafePoint(ctx, pdClient, 2333-1)
    39  		c.Assert(err, NotNil)
    40  	}
    41  	{
    42  		err := utils.CheckGCSafePoint(ctx, pdClient, 0)
    43  		c.Assert(err, ErrorMatches, ".*GC safepoint 2333 exceed TS 0.*")
    44  	}
    45  }
    46  
    47  type mockSafePoint struct {
    48  	sync.Mutex
    49  	pd.Client
    50  	safepoint           uint64
    51  	minServiceSafepoint uint64
    52  }
    53  
    54  func (m *mockSafePoint) UpdateServiceGCSafePoint(ctx context.Context, serviceID string, ttl int64, safePoint uint64) (uint64, error) {
    55  	m.Lock()
    56  	defer m.Unlock()
    57  
    58  	if m.safepoint > safePoint {
    59  		return m.safepoint, nil
    60  	}
    61  	if m.minServiceSafepoint == 0 || m.minServiceSafepoint > safePoint {
    62  		m.minServiceSafepoint = safePoint
    63  	}
    64  	return m.minServiceSafepoint, nil
    65  }
    66  
    67  func (m *mockSafePoint) UpdateGCSafePoint(ctx context.Context, safePoint uint64) (uint64, error) {
    68  	m.Lock()
    69  	defer m.Unlock()
    70  
    71  	if m.safepoint < safePoint && safePoint < m.minServiceSafepoint {
    72  		m.safepoint = safePoint
    73  	}
    74  	return m.safepoint, nil
    75  }
    76  
    77  func (s *testSafePointSuite) TestStartServiceSafePointKeeper(c *C) {
    78  	pdClient := &mockSafePoint{safepoint: 2333}
    79  
    80  	cases := []struct {
    81  		sp utils.BRServiceSafePoint
    82  		ok bool
    83  	}{
    84  		{
    85  			utils.BRServiceSafePoint{
    86  				ID:       "br",
    87  				TTL:      10,
    88  				BackupTS: 2333 + 1,
    89  			},
    90  			true,
    91  		},
    92  
    93  		// Invalid TTL.
    94  		{
    95  			utils.BRServiceSafePoint{
    96  				ID:       "br",
    97  				TTL:      0,
    98  				BackupTS: 2333 + 1,
    99  			}, false,
   100  		},
   101  
   102  		// Invalid ID.
   103  		{
   104  			utils.BRServiceSafePoint{
   105  				ID:       "",
   106  				TTL:      0,
   107  				BackupTS: 2333 + 1,
   108  			},
   109  			false,
   110  		},
   111  
   112  		// BackupTS is too small.
   113  		{
   114  			utils.BRServiceSafePoint{
   115  				ID:       "br",
   116  				TTL:      10,
   117  				BackupTS: 2333,
   118  			}, false,
   119  		},
   120  		{
   121  			utils.BRServiceSafePoint{
   122  				ID:       "br",
   123  				TTL:      10,
   124  				BackupTS: 2333 - 1,
   125  			},
   126  			false,
   127  		},
   128  	}
   129  	for i, cs := range cases {
   130  		ctx, cancel := context.WithCancel(context.Background())
   131  		err := utils.StartServiceSafePointKeeper(ctx, pdClient, cs.sp)
   132  		checker := IsNil
   133  		if !cs.ok {
   134  			checker = NotNil
   135  		}
   136  		c.Assert(err, checker, Commentf("case #%d, %v", i, cs))
   137  		cancel()
   138  	}
   139  }