github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/checker/lightning_test.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package checker 15 16 import ( 17 "context" 18 "testing" 19 20 "github.com/pingcap/tidb/lightning/pkg/precheck" 21 "github.com/pingcap/tiflow/pkg/errors" 22 "github.com/stretchr/testify/require" 23 ) 24 25 type mockPrecheckItem struct { 26 err error 27 pass bool 28 msg string 29 } 30 31 func (m mockPrecheckItem) Check(ctx context.Context) (*precheck.CheckResult, error) { 32 if m.err != nil { 33 return nil, m.err 34 } 35 return &precheck.CheckResult{ 36 Passed: m.pass, 37 Message: m.msg, 38 }, nil 39 } 40 41 func (m mockPrecheckItem) GetCheckItemID() precheck.CheckItemID { 42 return "mock" 43 } 44 45 // nolint:dupl 46 func TestEmptyRegionChecker(t *testing.T) { 47 ctx := context.Background() 48 c := &LightningEmptyRegionChecker{inner: mockPrecheckItem{pass: true}} 49 result := c.Check(ctx) 50 require.Equal(t, StateSuccess, result.State) 51 require.Len(t, result.Errors, 0) 52 require.Equal(t, "", result.Extra) 53 54 c.inner = mockPrecheckItem{err: errors.New("mock error")} 55 result = c.Check(ctx) 56 require.Equal(t, StateFailure, result.State) 57 require.Equal(t, "", result.Extra) 58 require.Len(t, result.Errors, 1) 59 require.Equal(t, "mock error", result.Errors[0].ShortErr) 60 require.Equal(t, StateFailure, result.Errors[0].Severity) 61 62 // lightning prechecker returns fail 63 lightningMsg := "TiKV stores (1) contains more than 1000 empty regions respectively, which will greatly affect the import speed and success rate" 64 c.inner = mockPrecheckItem{msg: lightningMsg} 65 result = c.Check(ctx) 66 require.Equal(t, StateWarning, result.State) 67 require.Equal(t, "", result.Extra) 68 require.Len(t, result.Errors, 1) 69 require.Equal(t, lightningMsg, result.Errors[0].ShortErr) 70 require.Equal(t, StateWarning, result.Errors[0].Severity) 71 72 // lightning prechecker returns warning or success 73 lightningMsg = "Cluster doesn't have too many empty regions" 74 c.inner = mockPrecheckItem{msg: lightningMsg, pass: true} 75 result = c.Check(ctx) 76 require.Equal(t, StateSuccess, result.State) 77 require.Equal(t, "", result.Extra) 78 require.Len(t, result.Errors, 0) 79 } 80 81 // nolint:dupl 82 func TestRegionUnbalanced(t *testing.T) { 83 ctx := context.Background() 84 c := &LightningRegionDistributionChecker{inner: mockPrecheckItem{pass: true}} 85 result := c.Check(ctx) 86 require.Equal(t, StateSuccess, result.State) 87 require.Len(t, result.Errors, 0) 88 require.Equal(t, "", result.Extra) 89 90 c.inner = mockPrecheckItem{err: errors.New("mock error")} 91 result = c.Check(ctx) 92 require.Equal(t, StateFailure, result.State) 93 require.Equal(t, "", result.Extra) 94 require.Len(t, result.Errors, 1) 95 require.Equal(t, "mock error", result.Errors[0].ShortErr) 96 require.Equal(t, StateFailure, result.Errors[0].Severity) 97 98 // lightning prechecker returns fail 99 lightningMsg := "Region distribution is unbalanced, the ratio of the regions count of the store(2) with least regions(500) to the store(1) with most regions(5000) is 0.1, but we expect it must not be less than 0.5" 100 c.inner = mockPrecheckItem{msg: lightningMsg} 101 result = c.Check(ctx) 102 require.Equal(t, StateWarning, result.State) 103 require.Equal(t, "", result.Extra) 104 require.Len(t, result.Errors, 1) 105 require.Equal(t, lightningMsg, result.Errors[0].ShortErr) 106 require.Equal(t, StateWarning, result.Errors[0].Severity) 107 108 // lightning prechecker returns warning or success 109 lightningMsg = "Cluster region distribution is balanced" 110 c.inner = mockPrecheckItem{msg: lightningMsg, pass: true} 111 result = c.Check(ctx) 112 require.Equal(t, StateSuccess, result.State) 113 require.Equal(t, "", result.Extra) 114 require.Len(t, result.Errors, 0) 115 } 116 117 func TestClusterVersion(t *testing.T) { 118 ctx := context.Background() 119 c := &LightningClusterVersionChecker{inner: mockPrecheckItem{pass: true}} 120 result := c.Check(ctx) 121 require.Equal(t, StateSuccess, result.State) 122 require.Len(t, result.Errors, 0) 123 require.Equal(t, "", result.Extra) 124 125 c.inner = mockPrecheckItem{err: errors.New("mock error")} 126 result = c.Check(ctx) 127 require.Equal(t, StateFailure, result.State) 128 require.Equal(t, "", result.Extra) 129 require.Len(t, result.Errors, 1) 130 require.Equal(t, "mock error", result.Errors[0].ShortErr) 131 require.Equal(t, StateFailure, result.Errors[0].Severity) 132 133 lightningMsg := "Cluster version check failed: TiNB version too old, required to be in [2.3.5, 3.0.0), found '2.1.0': [BR:Common:ErrVersionMismatch]version mismatch" 134 c.inner = mockPrecheckItem{msg: lightningMsg} 135 result = c.Check(ctx) 136 require.Equal(t, StateFailure, result.State) 137 require.Equal(t, "", result.Extra) 138 require.Len(t, result.Errors, 1) 139 require.Equal(t, lightningMsg, result.Errors[0].ShortErr) 140 require.Equal(t, StateFailure, result.Errors[0].Severity) 141 } 142 143 func TestTableEmpty(t *testing.T) { 144 ctx := context.Background() 145 c := &LightningTableEmptyChecker{inner: mockPrecheckItem{pass: true}} 146 result := c.Check(ctx) 147 require.Equal(t, StateSuccess, result.State) 148 require.Len(t, result.Errors, 0) 149 require.Equal(t, "", result.Extra) 150 151 c.inner = mockPrecheckItem{err: errors.New("mock error")} 152 result = c.Check(ctx) 153 require.Equal(t, StateFailure, result.State) 154 require.Equal(t, "", result.Extra) 155 require.Len(t, result.Errors, 1) 156 require.Equal(t, "mock error", result.Errors[0].ShortErr) 157 require.Equal(t, StateFailure, result.Errors[0].Severity) 158 159 lightningMsg := "table(s) [test.t1] are not empty" 160 c.inner = mockPrecheckItem{msg: lightningMsg} 161 result = c.Check(ctx) 162 require.Equal(t, StateFailure, result.State) 163 require.Equal(t, "", result.Extra) 164 require.Len(t, result.Errors, 1) 165 require.Equal(t, lightningMsg, result.Errors[0].ShortErr) 166 require.Equal(t, StateFailure, result.Errors[0].Severity) 167 }