github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/store_test.go (about) 1 // Copyright 2020 WHTCORPS INC, 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 causetstore 15 16 import ( 17 "context" 18 "fmt" 19 "os" 20 "strconv" 21 "sync" 22 "sync/atomic" 23 "testing" 24 "time" 25 26 . "github.com/whtcorpsinc/check" 27 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 28 "github.com/whtcorpsinc/milevadb/ekv" 29 "github.com/whtcorpsinc/milevadb/soliton/logutil" 30 "github.com/whtcorpsinc/milevadb/soliton/testleak" 31 ) 32 33 const ( 34 startIndex = 0 35 testCount = 2 36 indexStep = 2 37 ) 38 39 type brokenStore struct{} 40 41 func (s *brokenStore) Open(schemaReplicant string) (ekv.CausetStorage, error) { 42 return nil, ekv.ErrTxnRetryable 43 } 44 45 func TestT(t *testing.T) { 46 CustomVerboseFlag = true 47 logLevel := os.Getenv("log_level") 48 logutil.InitLogger(logutil.NewLogConfig(logLevel, logutil.DefaultLogFormat, "", logutil.EmptyFileLogConfig, false)) 49 TestingT(t) 50 } 51 52 var _ = Suite(&testKVSuite{}) 53 54 type testKVSuite struct { 55 s ekv.CausetStorage 56 } 57 58 func (s *testKVSuite) SetUpSuite(c *C) { 59 testleak.BeforeTest() 60 causetstore, err := mockstore.NewMockStore() 61 c.Assert(err, IsNil) 62 s.s = causetstore 63 } 64 65 func (s *testKVSuite) TearDownSuite(c *C) { 66 err := s.s.Close() 67 c.Assert(err, IsNil) 68 testleak.AfterTest(c)() 69 } 70 71 func insertData(c *C, txn ekv.Transaction) { 72 for i := startIndex; i < testCount; i++ { 73 val := encodeInt(i * indexStep) 74 err := txn.Set(val, val) 75 c.Assert(err, IsNil) 76 } 77 } 78 79 func mustDel(c *C, txn ekv.Transaction) { 80 for i := startIndex; i < testCount; i++ { 81 val := encodeInt(i * indexStep) 82 err := txn.Delete(val) 83 c.Assert(err, IsNil) 84 } 85 } 86 87 func encodeInt(n int) []byte { 88 return []byte(fmt.Sprintf("%010d", n)) 89 } 90 91 func decodeInt(s []byte) int { 92 var n int 93 fmt.Sscanf(string(s), "%010d", &n) 94 return n 95 } 96 97 func valToStr(c *C, iter ekv.Iterator) string { 98 val := iter.Value() 99 return string(val) 100 } 101 102 func checkSeek(c *C, txn ekv.Transaction) { 103 for i := startIndex; i < testCount; i++ { 104 val := encodeInt(i * indexStep) 105 iter, err := txn.Iter(val, nil) 106 c.Assert(err, IsNil) 107 c.Assert([]byte(iter.Key()), BytesEquals, val) 108 c.Assert(decodeInt([]byte(valToStr(c, iter))), Equals, i*indexStep) 109 iter.Close() 110 } 111 112 // Test iterator Next() 113 for i := startIndex; i < testCount-1; i++ { 114 val := encodeInt(i * indexStep) 115 iter, err := txn.Iter(val, nil) 116 c.Assert(err, IsNil) 117 c.Assert([]byte(iter.Key()), BytesEquals, val) 118 c.Assert(valToStr(c, iter), Equals, string(val)) 119 120 err = iter.Next() 121 c.Assert(err, IsNil) 122 c.Assert(iter.Valid(), IsTrue) 123 124 val = encodeInt((i + 1) * indexStep) 125 c.Assert([]byte(iter.Key()), BytesEquals, val) 126 c.Assert(valToStr(c, iter), Equals, string(val)) 127 iter.Close() 128 } 129 130 // Non exist and beyond maximum seek test 131 iter, err := txn.Iter(encodeInt(testCount*indexStep), nil) 132 c.Assert(err, IsNil) 133 c.Assert(iter.Valid(), IsFalse) 134 135 // Non exist but between existing keys seek test, 136 // it returns the smallest key that larger than the one we are seeking 137 inBetween := encodeInt((testCount-1)*indexStep - 1) 138 last := encodeInt((testCount - 1) * indexStep) 139 iter, err = txn.Iter(inBetween, nil) 140 c.Assert(err, IsNil) 141 c.Assert(iter.Valid(), IsTrue) 142 c.Assert([]byte(iter.Key()), Not(BytesEquals), inBetween) 143 c.Assert([]byte(iter.Key()), BytesEquals, last) 144 iter.Close() 145 } 146 147 func mustNotGet(c *C, txn ekv.Transaction) { 148 for i := startIndex; i < testCount; i++ { 149 s := encodeInt(i * indexStep) 150 _, err := txn.Get(context.TODO(), s) 151 c.Assert(err, NotNil) 152 } 153 } 154 155 func mustGet(c *C, txn ekv.Transaction) { 156 for i := startIndex; i < testCount; i++ { 157 s := encodeInt(i * indexStep) 158 val, err := txn.Get(context.TODO(), s) 159 c.Assert(err, IsNil) 160 c.Assert(string(val), Equals, string(s)) 161 } 162 } 163 164 func (s *testKVSuite) TestNew(c *C) { 165 causetstore, err := New("goleveldb://relative/path") 166 c.Assert(err, NotNil) 167 c.Assert(causetstore, IsNil) 168 } 169 170 func (s *testKVSuite) TestGetSet(c *C) { 171 txn, err := s.s.Begin() 172 c.Assert(err, IsNil) 173 174 insertData(c, txn) 175 176 mustGet(c, txn) 177 178 // Check transaction results 179 err = txn.Commit(context.Background()) 180 c.Assert(err, IsNil) 181 182 txn, err = s.s.Begin() 183 c.Assert(err, IsNil) 184 defer txn.Commit(context.Background()) 185 186 mustGet(c, txn) 187 mustDel(c, txn) 188 } 189 190 func (s *testKVSuite) TestSeek(c *C) { 191 txn, err := s.s.Begin() 192 c.Assert(err, IsNil) 193 194 insertData(c, txn) 195 checkSeek(c, txn) 196 197 // Check transaction results 198 err = txn.Commit(context.Background()) 199 c.Assert(err, IsNil) 200 201 txn, err = s.s.Begin() 202 c.Assert(err, IsNil) 203 defer txn.Commit(context.Background()) 204 205 checkSeek(c, txn) 206 mustDel(c, txn) 207 } 208 209 func (s *testKVSuite) TestInc(c *C) { 210 txn, err := s.s.Begin() 211 c.Assert(err, IsNil) 212 213 key := []byte("incKey") 214 n, err := ekv.IncInt64(txn, key, 100) 215 c.Assert(err, IsNil) 216 c.Assert(n, Equals, int64(100)) 217 218 // Check transaction results 219 err = txn.Commit(context.Background()) 220 c.Assert(err, IsNil) 221 222 txn, err = s.s.Begin() 223 c.Assert(err, IsNil) 224 225 n, err = ekv.IncInt64(txn, key, -200) 226 c.Assert(err, IsNil) 227 c.Assert(n, Equals, int64(-100)) 228 229 err = txn.Delete(key) 230 c.Assert(err, IsNil) 231 232 n, err = ekv.IncInt64(txn, key, 100) 233 c.Assert(err, IsNil) 234 c.Assert(n, Equals, int64(100)) 235 236 err = txn.Delete(key) 237 c.Assert(err, IsNil) 238 239 err = txn.Commit(context.Background()) 240 c.Assert(err, IsNil) 241 } 242 243 func (s *testKVSuite) TestDelete(c *C) { 244 txn, err := s.s.Begin() 245 c.Assert(err, IsNil) 246 247 insertData(c, txn) 248 249 mustDel(c, txn) 250 251 mustNotGet(c, txn) 252 err = txn.Commit(context.Background()) 253 c.Assert(err, IsNil) 254 255 // Try get 256 txn, err = s.s.Begin() 257 c.Assert(err, IsNil) 258 259 mustNotGet(c, txn) 260 261 // Insert again 262 insertData(c, txn) 263 err = txn.Commit(context.Background()) 264 c.Assert(err, IsNil) 265 266 // Delete all 267 txn, err = s.s.Begin() 268 c.Assert(err, IsNil) 269 270 mustDel(c, txn) 271 err = txn.Commit(context.Background()) 272 c.Assert(err, IsNil) 273 274 txn, err = s.s.Begin() 275 c.Assert(err, IsNil) 276 277 mustNotGet(c, txn) 278 err = txn.Commit(context.Background()) 279 c.Assert(err, IsNil) 280 } 281 282 func (s *testKVSuite) TestDelete2(c *C) { 283 txn, err := s.s.Begin() 284 c.Assert(err, IsNil) 285 val := []byte("test") 286 txn.Set([]byte("DATA_test_tbl_department_record__0000000001_0003"), val) 287 txn.Set([]byte("DATA_test_tbl_department_record__0000000001_0004"), val) 288 txn.Set([]byte("DATA_test_tbl_department_record__0000000002_0003"), val) 289 txn.Set([]byte("DATA_test_tbl_department_record__0000000002_0004"), val) 290 err = txn.Commit(context.Background()) 291 c.Assert(err, IsNil) 292 293 // Delete all 294 txn, err = s.s.Begin() 295 c.Assert(err, IsNil) 296 297 it, err := txn.Iter([]byte("DATA_test_tbl_department_record__0000000001_0003"), nil) 298 c.Assert(err, IsNil) 299 for it.Valid() { 300 err = txn.Delete(it.Key()) 301 c.Assert(err, IsNil) 302 err = it.Next() 303 c.Assert(err, IsNil) 304 } 305 err = txn.Commit(context.Background()) 306 c.Assert(err, IsNil) 307 308 txn, err = s.s.Begin() 309 c.Assert(err, IsNil) 310 it, _ = txn.Iter([]byte("DATA_test_tbl_department_record__000000000"), nil) 311 c.Assert(it.Valid(), IsFalse) 312 err = txn.Commit(context.Background()) 313 c.Assert(err, IsNil) 314 } 315 316 func (s *testKVSuite) TestSetNil(c *C) { 317 txn, err := s.s.Begin() 318 defer txn.Commit(context.Background()) 319 c.Assert(err, IsNil) 320 err = txn.Set([]byte("1"), nil) 321 c.Assert(err, NotNil) 322 } 323 324 func (s *testKVSuite) TestBasicSeek(c *C) { 325 txn, err := s.s.Begin() 326 c.Assert(err, IsNil) 327 txn.Set([]byte("1"), []byte("1")) 328 err = txn.Commit(context.Background()) 329 c.Assert(err, IsNil) 330 txn, err = s.s.Begin() 331 c.Assert(err, IsNil) 332 defer txn.Commit(context.Background()) 333 334 it, err := txn.Iter([]byte("2"), nil) 335 c.Assert(err, IsNil) 336 c.Assert(it.Valid(), Equals, false) 337 txn.Delete([]byte("1")) 338 } 339 340 func (s *testKVSuite) TestBasicTable(c *C) { 341 txn, err := s.s.Begin() 342 c.Assert(err, IsNil) 343 for i := 1; i < 5; i++ { 344 b := []byte(strconv.Itoa(i)) 345 txn.Set(b, b) 346 } 347 err = txn.Commit(context.Background()) 348 c.Assert(err, IsNil) 349 txn, err = s.s.Begin() 350 c.Assert(err, IsNil) 351 defer txn.Commit(context.Background()) 352 353 err = txn.Set([]byte("1"), []byte("1")) 354 c.Assert(err, IsNil) 355 356 it, err := txn.Iter([]byte("0"), nil) 357 c.Assert(err, IsNil) 358 c.Assert(string(it.Key()), Equals, "1") 359 360 err = txn.Set([]byte("0"), []byte("0")) 361 c.Assert(err, IsNil) 362 it, err = txn.Iter([]byte("0"), nil) 363 c.Assert(err, IsNil) 364 c.Assert(string(it.Key()), Equals, "0") 365 err = txn.Delete([]byte("0")) 366 c.Assert(err, IsNil) 367 368 txn.Delete([]byte("1")) 369 it, err = txn.Iter([]byte("0"), nil) 370 c.Assert(err, IsNil) 371 c.Assert(string(it.Key()), Equals, "2") 372 373 err = txn.Delete([]byte("3")) 374 c.Assert(err, IsNil) 375 it, err = txn.Iter([]byte("2"), nil) 376 c.Assert(err, IsNil) 377 c.Assert(string(it.Key()), Equals, "2") 378 379 it, err = txn.Iter([]byte("3"), nil) 380 c.Assert(err, IsNil) 381 c.Assert(string(it.Key()), Equals, "4") 382 err = txn.Delete([]byte("2")) 383 c.Assert(err, IsNil) 384 err = txn.Delete([]byte("4")) 385 c.Assert(err, IsNil) 386 } 387 388 func (s *testKVSuite) TestRollback(c *C) { 389 txn, err := s.s.Begin() 390 c.Assert(err, IsNil) 391 392 err = txn.Rollback() 393 c.Assert(err, IsNil) 394 395 txn, err = s.s.Begin() 396 c.Assert(err, IsNil) 397 398 insertData(c, txn) 399 400 mustGet(c, txn) 401 402 err = txn.Rollback() 403 c.Assert(err, IsNil) 404 405 txn, err = s.s.Begin() 406 c.Assert(err, IsNil) 407 defer txn.Commit(context.Background()) 408 409 for i := startIndex; i < testCount; i++ { 410 _, err := txn.Get(context.TODO(), []byte(strconv.Itoa(i))) 411 c.Assert(err, NotNil) 412 } 413 } 414 415 func (s *testKVSuite) TestSeekMin(c *C) { 416 rows := []struct { 417 key string 418 value string 419 }{ 420 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001", "dagger-version"}, 421 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0002", "1"}, 422 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0003", "hello"}, 423 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002", "dagger-version"}, 424 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0002", "2"}, 425 {"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0003", "hello"}, 426 } 427 428 txn, err := s.s.Begin() 429 c.Assert(err, IsNil) 430 for _, event := range rows { 431 txn.Set([]byte(event.key), []byte(event.value)) 432 } 433 434 it, err := txn.Iter(nil, nil) 435 c.Assert(err, IsNil) 436 for it.Valid() { 437 it.Next() 438 } 439 440 it, err = txn.Iter([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000"), nil) 441 c.Assert(err, IsNil) 442 c.Assert(string(it.Key()), Equals, "DATA_test_main_db_tbl_tbl_test_record__00000000000000000001") 443 444 for _, event := range rows { 445 txn.Delete([]byte(event.key)) 446 } 447 } 448 449 func (s *testKVSuite) TestConditionIfNotExist(c *C) { 450 var success int64 451 cnt := 100 452 b := []byte("1") 453 var wg sync.WaitGroup 454 wg.Add(cnt) 455 for i := 0; i < cnt; i++ { 456 go func() { 457 defer wg.Done() 458 txn, err := s.s.Begin() 459 c.Assert(err, IsNil) 460 err = txn.Set(b, b) 461 if err != nil { 462 return 463 } 464 err = txn.Commit(context.Background()) 465 if err == nil { 466 atomic.AddInt64(&success, 1) 467 } 468 }() 469 } 470 wg.Wait() 471 // At least one txn can success. 472 c.Assert(success, Greater, int64(0)) 473 474 // Clean up 475 txn, err := s.s.Begin() 476 c.Assert(err, IsNil) 477 err = txn.Delete(b) 478 c.Assert(err, IsNil) 479 err = txn.Commit(context.Background()) 480 c.Assert(err, IsNil) 481 } 482 483 func (s *testKVSuite) TestConditionIfEqual(c *C) { 484 var success int64 485 cnt := 100 486 b := []byte("1") 487 var wg sync.WaitGroup 488 wg.Add(cnt) 489 490 txn, err := s.s.Begin() 491 c.Assert(err, IsNil) 492 txn.Set(b, b) 493 err = txn.Commit(context.Background()) 494 c.Assert(err, IsNil) 495 496 for i := 0; i < cnt; i++ { 497 go func() { 498 defer wg.Done() 499 // Use txn1/err1 instead of txn/err is 500 // to pass `go tool vet -shadow` check. 501 txn1, err1 := s.s.Begin() 502 c.Assert(err1, IsNil) 503 txn1.Set(b, []byte("newValue")) 504 err1 = txn1.Commit(context.Background()) 505 if err1 == nil { 506 atomic.AddInt64(&success, 1) 507 } 508 }() 509 } 510 wg.Wait() 511 c.Assert(success, Greater, int64(0)) 512 513 // Clean up 514 txn, err = s.s.Begin() 515 c.Assert(err, IsNil) 516 err = txn.Delete(b) 517 c.Assert(err, IsNil) 518 err = txn.Commit(context.Background()) 519 c.Assert(err, IsNil) 520 } 521 522 func (s *testKVSuite) TestConditionUFIDelate(c *C) { 523 txn, err := s.s.Begin() 524 c.Assert(err, IsNil) 525 txn.Delete([]byte("b")) 526 ekv.IncInt64(txn, []byte("a"), 1) 527 err = txn.Commit(context.Background()) 528 c.Assert(err, IsNil) 529 } 530 531 func (s *testKVSuite) TestDBClose(c *C) { 532 c.Skip("don't know why it fails.") 533 causetstore, err := mockstore.NewMockStore() 534 c.Assert(err, IsNil) 535 536 txn, err := causetstore.Begin() 537 c.Assert(err, IsNil) 538 539 err = txn.Set([]byte("a"), []byte("b")) 540 c.Assert(err, IsNil) 541 542 err = txn.Commit(context.Background()) 543 c.Assert(err, IsNil) 544 545 ver, err := causetstore.CurrentVersion() 546 c.Assert(err, IsNil) 547 c.Assert(ekv.MaxVersion.Cmp(ver), Equals, 1) 548 549 snap, err := causetstore.GetSnapshot(ekv.MaxVersion) 550 c.Assert(err, IsNil) 551 552 _, err = snap.Get(context.TODO(), []byte("a")) 553 c.Assert(err, IsNil) 554 555 txn, err = causetstore.Begin() 556 c.Assert(err, IsNil) 557 558 err = causetstore.Close() 559 c.Assert(err, IsNil) 560 561 _, err = causetstore.Begin() 562 c.Assert(err, NotNil) 563 564 _, err = causetstore.GetSnapshot(ekv.MaxVersion) 565 c.Assert(err, NotNil) 566 567 err = txn.Set([]byte("a"), []byte("b")) 568 c.Assert(err, IsNil) 569 570 err = txn.Commit(context.Background()) 571 c.Assert(err, NotNil) 572 } 573 574 func (s *testKVSuite) TestIsolationInc(c *C) { 575 threadCnt := 4 576 577 ids := make(map[int64]struct{}, threadCnt*100) 578 var m sync.Mutex 579 var wg sync.WaitGroup 580 581 wg.Add(threadCnt) 582 for i := 0; i < threadCnt; i++ { 583 go func() { 584 defer wg.Done() 585 for j := 0; j < 100; j++ { 586 var id int64 587 err := ekv.RunInNewTxn(s.s, true, func(txn ekv.Transaction) error { 588 var err1 error 589 id, err1 = ekv.IncInt64(txn, []byte("key"), 1) 590 return err1 591 }) 592 c.Assert(err, IsNil) 593 594 m.Lock() 595 _, ok := ids[id] 596 ids[id] = struct{}{} 597 m.Unlock() 598 c.Assert(ok, IsFalse) 599 } 600 }() 601 } 602 603 wg.Wait() 604 605 // delete 606 txn, err := s.s.Begin() 607 c.Assert(err, IsNil) 608 defer txn.Commit(context.Background()) 609 txn.Delete([]byte("key")) 610 } 611 612 func (s *testKVSuite) TestIsolationMultiInc(c *C) { 613 threadCnt := 4 614 incCnt := 100 615 keyCnt := 4 616 617 keys := make([][]byte, 0, keyCnt) 618 for i := 0; i < keyCnt; i++ { 619 keys = append(keys, []byte(fmt.Sprintf("test_key_%d", i))) 620 } 621 622 var wg sync.WaitGroup 623 624 wg.Add(threadCnt) 625 for i := 0; i < threadCnt; i++ { 626 go func() { 627 defer wg.Done() 628 for j := 0; j < incCnt; j++ { 629 err := ekv.RunInNewTxn(s.s, true, func(txn ekv.Transaction) error { 630 for _, key := range keys { 631 _, err1 := ekv.IncInt64(txn, key, 1) 632 if err1 != nil { 633 return err1 634 } 635 } 636 637 return nil 638 }) 639 c.Assert(err, IsNil) 640 } 641 }() 642 } 643 644 wg.Wait() 645 646 err := ekv.RunInNewTxn(s.s, false, func(txn ekv.Transaction) error { 647 for _, key := range keys { 648 id, err1 := ekv.GetInt64(context.TODO(), txn, key) 649 if err1 != nil { 650 return err1 651 } 652 c.Assert(id, Equals, int64(threadCnt*incCnt)) 653 txn.Delete(key) 654 } 655 return nil 656 }) 657 c.Assert(err, IsNil) 658 } 659 660 func (s *testKVSuite) TestRetryOpenStore(c *C) { 661 begin := time.Now() 662 Register("dummy", &brokenStore{}) 663 causetstore, err := newStoreWithRetry("dummy://dummy-causetstore", 3) 664 if causetstore != nil { 665 defer causetstore.Close() 666 } 667 c.Assert(err, NotNil) 668 elapse := time.Since(begin) 669 c.Assert(uint64(elapse), GreaterEqual, uint64(3*time.Second), Commentf("elapse: %s", elapse)) 670 } 671 672 func (s *testKVSuite) TestOpenStore(c *C) { 673 Register("open", &brokenStore{}) 674 causetstore, err := newStoreWithRetry(":", 3) 675 if causetstore != nil { 676 defer causetstore.Close() 677 } 678 c.Assert(err, NotNil) 679 } 680 681 func (s *testKVSuite) TestRegister(c *C) { 682 err := Register("retry", &brokenStore{}) 683 c.Assert(err, IsNil) 684 err = Register("retry", &brokenStore{}) 685 c.Assert(err, NotNil) 686 }