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