github.com/polarismesh/polaris@v1.17.8/store/mysql/admin_test.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package sqldb 19 20 import ( 21 "context" 22 "errors" 23 "os" 24 "testing" 25 26 "github.com/golang/mock/gomock" 27 28 "github.com/polarismesh/polaris/common/eventhub" 29 "github.com/polarismesh/polaris/common/utils" 30 "github.com/polarismesh/polaris/store/mock" 31 ) 32 33 const ( 34 TestElectKey = "test-key" 35 ) 36 37 func setup() { 38 eventhub.InitEventHub() 39 } 40 41 func teardown() { 42 } 43 44 func TestAdminStore_LeaderElection_Follower1(t *testing.T) { 45 ctrl := gomock.NewController(t) 46 defer ctrl.Finish() 47 48 mockStore := mock.NewMockLeaderElectionStore(ctrl) 49 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return("127.0.0.2", false, nil) 50 51 ctx, cancel := context.WithCancel(context.TODO()) 52 le := leaderElectionStateMachine{ 53 electKey: TestElectKey, 54 leStore: mockStore, 55 leaderFlag: 0, 56 version: 0, 57 ctx: ctx, 58 cancel: cancel, 59 } 60 61 le.tick() 62 if le.isLeaderAtomic() { 63 t.Error("expect stay follower state") 64 } 65 } 66 67 func TestAdminStore_LeaderElection_Follower2(t *testing.T) { 68 ctrl := gomock.NewController(t) 69 defer ctrl.Finish() 70 71 mockStore := mock.NewMockLeaderElectionStore(ctrl) 72 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return(utils.LocalHost, true, nil) 73 mockStore.EXPECT().GetVersion(TestElectKey).Return(int64(0), nil) 74 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(0), int64(1), "127.0.0.1").Return(false, nil) 75 76 ctx, cancel := context.WithCancel(context.TODO()) 77 le := leaderElectionStateMachine{ 78 electKey: TestElectKey, 79 leStore: mockStore, 80 leaderFlag: 0, 81 version: 0, 82 ctx: ctx, 83 cancel: cancel, 84 } 85 86 le.tick() 87 if le.isLeaderAtomic() { 88 t.Error("expect stay follower state") 89 } 90 } 91 92 func TestAdminStore_LeaderElection_Follower3(t *testing.T) { 93 ctrl := gomock.NewController(t) 94 defer ctrl.Finish() 95 96 mockStore := mock.NewMockLeaderElectionStore(ctrl) 97 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return(utils.LocalHost, false, errors.New("err")) 98 ctx, cancel := context.WithCancel(context.TODO()) 99 le := leaderElectionStateMachine{ 100 electKey: TestElectKey, 101 leStore: mockStore, 102 leaderFlag: 0, 103 version: 0, 104 ctx: ctx, 105 cancel: cancel, 106 } 107 108 le.tick() 109 if le.isLeaderAtomic() { 110 t.Error("expect stay follower state") 111 } 112 } 113 114 func TestAdminStore_LeaderElection_Follower4(t *testing.T) { 115 ctrl := gomock.NewController(t) 116 defer ctrl.Finish() 117 118 mockStore := mock.NewMockLeaderElectionStore(ctrl) 119 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return(utils.LocalHost, true, nil) 120 mockStore.EXPECT().GetVersion(TestElectKey).Return(int64(0), errors.New("err")) 121 122 ctx, cancel := context.WithCancel(context.TODO()) 123 le := leaderElectionStateMachine{ 124 electKey: TestElectKey, 125 leStore: mockStore, 126 leaderFlag: 0, 127 version: 0, 128 ctx: ctx, 129 cancel: cancel, 130 } 131 132 le.tick() 133 if le.isLeaderAtomic() { 134 t.Error("expect stay follower state") 135 } 136 } 137 138 func TestAdminStore_LeaderElection_Follower5(t *testing.T) { 139 ctrl := gomock.NewController(t) 140 defer ctrl.Finish() 141 142 mockStore := mock.NewMockLeaderElectionStore(ctrl) 143 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return(utils.LocalHost, true, nil) 144 mockStore.EXPECT().GetVersion(TestElectKey).Return(int64(0), nil) 145 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(0), int64(1), "127.0.0.1").Return(false, errors.New("err")) 146 147 ctx, cancel := context.WithCancel(context.TODO()) 148 le := leaderElectionStateMachine{ 149 electKey: TestElectKey, 150 leStore: mockStore, 151 leaderFlag: 0, 152 version: 0, 153 ctx: ctx, 154 cancel: cancel, 155 } 156 157 le.tick() 158 if le.isLeaderAtomic() { 159 t.Error("expect stay follower state") 160 } 161 } 162 163 func TestAdminStore_LeaderElection_FollowerToLeader(t *testing.T) { 164 ctrl := gomock.NewController(t) 165 defer ctrl.Finish() 166 167 mockStore := mock.NewMockLeaderElectionStore(ctrl) 168 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return(utils.LocalHost, true, nil) 169 mockStore.EXPECT().GetVersion(TestElectKey).Return(int64(42), nil) 170 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(42), int64(43), "127.0.0.1").Return(true, nil) 171 172 ctx, cancel := context.WithCancel(context.TODO()) 173 le := leaderElectionStateMachine{ 174 electKey: TestElectKey, 175 leStore: mockStore, 176 leaderFlag: 0, 177 version: 0, 178 ctx: ctx, 179 cancel: cancel, 180 } 181 182 le.tick() 183 if !le.isLeaderAtomic() { 184 t.Error("expect to leader state") 185 } 186 if le.version != 43 { 187 t.Errorf("epect version is %d, actual is %d", 43, le.version) 188 } 189 } 190 191 func TestAdminStore_LeaderElection_Leader1(t *testing.T) { 192 ctrl := gomock.NewController(t) 193 defer ctrl.Finish() 194 195 mockStore := mock.NewMockLeaderElectionStore(ctrl) 196 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(42), int64(43), "127.0.0.1").Return(true, nil) 197 198 ctx, cancel := context.WithCancel(context.TODO()) 199 le := leaderElectionStateMachine{ 200 electKey: TestElectKey, 201 leStore: mockStore, 202 leaderFlag: 1, 203 version: 42, 204 ctx: ctx, 205 cancel: cancel, 206 } 207 208 le.tick() 209 if !le.isLeaderAtomic() { 210 t.Error("expect stay leader state") 211 } 212 if le.version != 43 { 213 t.Errorf("epect version is %d, actual is %d", 43, le.version) 214 } 215 } 216 217 func TestAdminStore_LeaderElection_LeaderToFollower1(t *testing.T) { 218 ctrl := gomock.NewController(t) 219 defer ctrl.Finish() 220 221 mockStore := mock.NewMockLeaderElectionStore(ctrl) 222 mockStore.EXPECT().CheckMtimeExpired(gomock.Any(), gomock.Any()).Return("127.0.0.2", false, nil) 223 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(42), int64(43), "127.0.0.1").Return(false, errors.New("err")) 224 225 ctx, cancel := context.WithCancel(context.TODO()) 226 le := leaderElectionStateMachine{ 227 electKey: TestElectKey, 228 leStore: mockStore, 229 leaderFlag: 1, 230 version: 42, 231 ctx: ctx, 232 cancel: cancel, 233 } 234 235 le.tick() 236 if le.isLeaderAtomic() { 237 t.Error("expect to follower state") 238 } 239 } 240 241 func TestAdminStore_LeaderElection_LeaderToFollower2(t *testing.T) { 242 ctrl := gomock.NewController(t) 243 defer ctrl.Finish() 244 245 mockStore := mock.NewMockLeaderElectionStore(ctrl) 246 mockStore.EXPECT().CheckMtimeExpired(gomock.Any(), gomock.Any()).Return("127.0.0.2", false, nil) 247 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(42), int64(43), "127.0.0.1").Return(false, nil) 248 249 ctx, cancel := context.WithCancel(context.TODO()) 250 le := leaderElectionStateMachine{ 251 electKey: TestElectKey, 252 leStore: mockStore, 253 leaderFlag: 1, 254 version: 42, 255 ctx: ctx, 256 cancel: cancel, 257 } 258 259 le.tick() 260 if le.isLeaderAtomic() { 261 t.Error("expect to follower state") 262 } 263 } 264 265 func TestAdminStore_StartLeaderElection1(t *testing.T) { 266 ctrl := gomock.NewController(t) 267 defer ctrl.Finish() 268 269 mockStore := mock.NewMockLeaderElectionStore(ctrl) 270 mockStore.EXPECT().CreateLeaderElection(TestElectKey).Return(errors.New("err")) 271 272 m := &adminStore{ 273 leStore: mockStore, 274 leMap: make(map[string]*leaderElectionStateMachine), 275 } 276 277 err := m.StartLeaderElection(TestElectKey) 278 if err == nil { 279 t.Errorf("should start failed") 280 } 281 _, ok := m.leMap[TestElectKey] 282 if ok { 283 t.Errorf("should not in map") 284 } 285 } 286 287 func TestAdminStore_StartLeaderElection2(t *testing.T) { 288 ctrl := gomock.NewController(t) 289 defer ctrl.Finish() 290 291 mockStore := mock.NewMockLeaderElectionStore(ctrl) 292 mockStore.EXPECT().CreateLeaderElection(TestElectKey).Return(nil) 293 294 m := &adminStore{ 295 leStore: mockStore, 296 leMap: make(map[string]*leaderElectionStateMachine), 297 } 298 299 err := m.StartLeaderElection(TestElectKey) 300 if err != nil { 301 t.Errorf("should start success") 302 } 303 _, ok := m.leMap[TestElectKey] 304 if !ok { 305 t.Errorf("should in map") 306 } 307 308 m.StopLeaderElections() 309 } 310 311 func TestAdminStore_StartLeaderElection3(t *testing.T) { 312 ctrl := gomock.NewController(t) 313 defer ctrl.Finish() 314 315 mockStore := mock.NewMockLeaderElectionStore(ctrl) 316 mockStore.EXPECT().CreateLeaderElection(TestElectKey).Return(nil) 317 318 m := &adminStore{ 319 leStore: mockStore, 320 leMap: make(map[string]*leaderElectionStateMachine), 321 } 322 323 err := m.StartLeaderElection(TestElectKey) 324 if err != nil { 325 t.Errorf("should start success") 326 } 327 _, ok := m.leMap[TestElectKey] 328 if !ok { 329 t.Errorf("should in map") 330 } 331 332 err = m.StartLeaderElection(TestElectKey) 333 if err != nil { 334 t.Errorf("expect no err if already started") 335 } 336 337 m.StopLeaderElections() 338 } 339 340 func TestAdminStore_ReleaseLeaderElection1(t *testing.T) { 341 ctrl := gomock.NewController(t) 342 defer ctrl.Finish() 343 344 mockStore := mock.NewMockLeaderElectionStore(ctrl) 345 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(42), int64(43), "127.0.0.1").Return(true, nil) 346 347 ctx, cancel := context.WithCancel(context.TODO()) 348 le := leaderElectionStateMachine{ 349 electKey: TestElectKey, 350 leStore: mockStore, 351 leaderFlag: 1, 352 version: 42, 353 ctx: ctx, 354 cancel: cancel, 355 releaseSignal: 0, 356 releaseTickLimit: 0, 357 } 358 359 le.tick() 360 if !le.isLeaderAtomic() { 361 t.Error("expect stay leader state") 362 } 363 364 le.setReleaseSignal() 365 le.tick() 366 if le.isLeaderAtomic() { 367 t.Error("expect to follower state") 368 } 369 370 limit := le.releaseTickLimit 371 for i := 0; i < int(limit); i++ { 372 le.tick() 373 if le.isLeaderAtomic() { 374 t.Error("expect stay follower state") 375 } 376 } 377 378 mockStore.EXPECT().CheckMtimeExpired(TestElectKey, int32(LeaseTime)).Return(utils.LocalHost, true, nil) 379 mockStore.EXPECT().GetVersion(TestElectKey).Return(int64(101), nil) 380 mockStore.EXPECT().CompareAndSwapVersion(TestElectKey, int64(101), int64(102), "127.0.0.1").Return(true, nil) 381 382 le.tick() 383 if !le.isLeaderAtomic() { 384 t.Error("expect to leader state") 385 } 386 } 387 388 func TestAdminStore_ReleaseLeaderElection2(t *testing.T) { 389 ctrl := gomock.NewController(t) 390 defer ctrl.Finish() 391 392 mockStore := mock.NewMockLeaderElectionStore(ctrl) 393 mockStore.EXPECT().CreateLeaderElection(TestElectKey).Return(nil) 394 395 m := &adminStore{ 396 leStore: mockStore, 397 leMap: make(map[string]*leaderElectionStateMachine), 398 } 399 400 err := m.ReleaseLeaderElection(TestElectKey) 401 if err == nil { 402 t.Error("expect err when release not existed key") 403 } 404 405 _ = m.StartLeaderElection(TestElectKey) 406 err = m.ReleaseLeaderElection(TestElectKey) 407 if err != nil { 408 t.Errorf("unexpect err: %v", err) 409 } 410 411 m.StopLeaderElections() 412 } 413 414 func TestMain(m *testing.M) { 415 setup() 416 code := m.Run() 417 teardown() 418 os.Exit(code) 419 }