github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/lightning/tikv/tikv_test.go (about) 1 package tikv_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/http/httptest" 9 "net/url" 10 "sort" 11 "sync" 12 13 "github.com/coreos/go-semver/semver" 14 . "github.com/pingcap/check" 15 "github.com/pingcap/kvproto/pkg/import_sstpb" 16 17 "github.com/pingcap/br/pkg/lightning/common" 18 kv "github.com/pingcap/br/pkg/lightning/tikv" 19 ) 20 21 type tikvSuite struct{} 22 23 var _ = Suite(&tikvSuite{}) 24 25 var ( 26 // Samples from importer backend for testing the Check***Version functions. 27 // No need keep these versions in sync. 28 requiredMinPDVersion = *semver.New("2.1.0") 29 requiredMinTiKVVersion = *semver.New("2.1.0") 30 requiredMaxPDVersion = *semver.New("6.0.0") 31 requiredMaxTiKVVersion = *semver.New("6.0.0") 32 ) 33 34 func (s *tikvSuite) TestForAllStores(c *C) { 35 server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 36 _, err := w.Write([]byte(` 37 { 38 "count": 5, 39 "stores": [ 40 { 41 "store": { 42 "id": 1, 43 "address": "127.0.0.1:20160", 44 "version": "3.0.0-beta.1", 45 "state_name": "Up" 46 }, 47 "status": {} 48 }, 49 { 50 "store": { 51 "id": 2, 52 "address": "127.0.0.1:20161", 53 "version": "3.0.0-rc.1", 54 "state_name": "Down" 55 }, 56 "status": {} 57 }, 58 { 59 "store": { 60 "id": 3, 61 "address": "127.0.0.1:20162", 62 "version": "3.0.0-rc.2", 63 "state_name": "Disconnected" 64 }, 65 "status": {} 66 }, 67 { 68 "store": { 69 "id": 4, 70 "address": "127.0.0.1:20163", 71 "version": "3.0.0", 72 "state_name": "Tombstone" 73 }, 74 "status": {} 75 }, 76 { 77 "store": { 78 "id": 5, 79 "address": "127.0.0.1:20164", 80 "version": "3.0.1", 81 "state_name": "Offline" 82 }, 83 "status": {} 84 } 85 ] 86 } 87 `)) 88 c.Assert(err, IsNil) 89 })) 90 defer server.Close() 91 92 ctx := context.Background() 93 var ( 94 allStoresLock sync.Mutex 95 allStores []*kv.Store 96 ) 97 tls := common.NewTLSFromMockServer(server) 98 err := kv.ForAllStores(ctx, tls, kv.StoreStateDown, func(c2 context.Context, store *kv.Store) error { 99 allStoresLock.Lock() 100 allStores = append(allStores, store) 101 allStoresLock.Unlock() 102 return nil 103 }) 104 c.Assert(err, IsNil) 105 106 sort.Slice(allStores, func(i, j int) bool { return allStores[i].Address < allStores[j].Address }) 107 108 c.Assert(allStores, DeepEquals, []*kv.Store{ 109 { 110 Address: "127.0.0.1:20160", 111 Version: "3.0.0-beta.1", 112 State: kv.StoreStateUp, 113 }, 114 { 115 Address: "127.0.0.1:20161", 116 Version: "3.0.0-rc.1", 117 State: kv.StoreStateDown, 118 }, 119 { 120 Address: "127.0.0.1:20162", 121 Version: "3.0.0-rc.2", 122 State: kv.StoreStateDisconnected, 123 }, 124 { 125 Address: "127.0.0.1:20164", 126 Version: "3.0.1", 127 State: kv.StoreStateOffline, 128 }, 129 }) 130 } 131 132 func (s *tikvSuite) TestFetchModeFromMetrics(c *C) { 133 testCases := []struct { 134 metrics string 135 mode import_sstpb.SwitchMode 136 isErr bool 137 }{ 138 { 139 metrics: `tikv_config_rocksdb{cf="default",name="hard_pending_compaction_bytes_limit"} 274877906944`, 140 mode: import_sstpb.SwitchMode_Normal, 141 }, 142 { 143 metrics: `tikv_config_rocksdb{cf="default",name="hard_pending_compaction_bytes_limit"} 0`, 144 mode: import_sstpb.SwitchMode_Import, 145 }, 146 { 147 metrics: ``, 148 isErr: true, 149 }, 150 } 151 152 for _, tc := range testCases { 153 comment := Commentf("test case '%s'", tc.metrics) 154 mode, err := kv.FetchModeFromMetrics(tc.metrics) 155 if tc.isErr { 156 c.Assert(err, NotNil, comment) 157 } else { 158 c.Assert(err, IsNil, comment) 159 c.Assert(mode, Equals, tc.mode, comment) 160 } 161 } 162 } 163 164 func (s *tikvSuite) TestCheckPDVersion(c *C) { 165 var version string 166 ctx := context.Background() 167 168 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 169 c.Assert(req.URL.Path, Equals, "/pd/api/v1/version") 170 w.WriteHeader(http.StatusOK) 171 _, err := w.Write([]byte(version)) 172 c.Assert(err, IsNil) 173 })) 174 mockURL, err := url.Parse(mockServer.URL) 175 c.Assert(err, IsNil) 176 177 tls := common.NewTLSFromMockServer(mockServer) 178 179 version = `{ 180 "version": "v4.0.0-rc.2-451-g760fb650" 181 }` 182 c.Assert(kv.CheckPDVersion(ctx, tls, mockURL.Host, requiredMinPDVersion, requiredMaxPDVersion), IsNil) 183 184 version = `{ 185 "version": "v4.0.0" 186 }` 187 c.Assert(kv.CheckPDVersion(ctx, tls, mockURL.Host, requiredMinPDVersion, requiredMaxPDVersion), IsNil) 188 189 version = `{ 190 "version": "v9999.0.0" 191 }` 192 c.Assert(kv.CheckPDVersion(ctx, tls, mockURL.Host, requiredMinPDVersion, requiredMaxPDVersion), ErrorMatches, "PD version too new.*") 193 194 version = `{ 195 "version": "v6.0.0" 196 }` 197 c.Assert(kv.CheckPDVersion(ctx, tls, mockURL.Host, requiredMinPDVersion, requiredMaxPDVersion), ErrorMatches, "PD version too new.*") 198 199 version = `{ 200 "version": "v6.0.0-beta" 201 }` 202 c.Assert(kv.CheckPDVersion(ctx, tls, mockURL.Host, requiredMinPDVersion, requiredMaxPDVersion), ErrorMatches, "PD version too new.*") 203 204 version = `{ 205 "version": "v1.0.0" 206 }` 207 c.Assert(kv.CheckPDVersion(ctx, tls, mockURL.Host, requiredMinPDVersion, requiredMaxPDVersion), ErrorMatches, "PD version too old.*") 208 } 209 210 func (s *tikvSuite) TestCheckTiKVVersion(c *C) { 211 var versions []string 212 ctx := context.Background() 213 214 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 215 c.Assert(req.URL.Path, Equals, "/pd/api/v1/stores") 216 w.WriteHeader(http.StatusOK) 217 218 stores := make([]map[string]interface{}, 0, len(versions)) 219 for i, v := range versions { 220 stores = append(stores, map[string]interface{}{ 221 "store": map[string]interface{}{ 222 "address": fmt.Sprintf("tikv%d.test:20160", i), 223 "version": v, 224 }, 225 }) 226 } 227 err := json.NewEncoder(w).Encode(map[string]interface{}{ 228 "count": len(versions), 229 "stores": stores, 230 }) 231 c.Assert(err, IsNil) 232 })) 233 mockURL, err := url.Parse(mockServer.URL) 234 c.Assert(err, IsNil) 235 236 tls := common.NewTLSFromMockServer(mockServer) 237 238 versions = []string{"4.1.0", "v4.1.0-alpha-9-ga27a7dd"} 239 c.Assert(kv.CheckTiKVVersion(ctx, tls, mockURL.Host, requiredMinTiKVVersion, requiredMaxTiKVVersion), IsNil) 240 241 versions = []string{"9999.0.0", "4.0.0"} 242 c.Assert(kv.CheckTiKVVersion(ctx, tls, mockURL.Host, requiredMinTiKVVersion, requiredMaxTiKVVersion), ErrorMatches, `TiKV \(at tikv0\.test:20160\) version too new.*`) 243 244 versions = []string{"4.0.0", "1.0.0"} 245 c.Assert(kv.CheckTiKVVersion(ctx, tls, mockURL.Host, requiredMinTiKVVersion, requiredMaxTiKVVersion), ErrorMatches, `TiKV \(at tikv1\.test:20160\) version too old.*`) 246 247 versions = []string{"6.0.0"} 248 c.Assert(kv.CheckTiKVVersion(ctx, tls, mockURL.Host, requiredMinTiKVVersion, requiredMaxTiKVVersion), ErrorMatches, `TiKV \(at tikv0\.test:20160\) version too new.*`) 249 250 versions = []string{"6.0.0-beta"} 251 c.Assert(kv.CheckTiKVVersion(ctx, tls, mockURL.Host, requiredMinTiKVVersion, requiredMaxTiKVVersion), ErrorMatches, `TiKV \(at tikv0\.test:20160\) version too new.*`) 252 }