mirror of https://github.com/tikv/client-go.git
isolation_test, delete_range_test: replace pingcap/check with testify (#161)
Signed-off-by: disksing <i@disksing.com>
This commit is contained in:
parent
65a2c46d22
commit
691f687223
|
|
@ -37,62 +37,56 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
. "github.com/pingcap/check"
|
|
||||||
"github.com/pingcap/tidb/store/mockstore/mockcopr"
|
"github.com/pingcap/tidb/store/mockstore/mockcopr"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/tikv/client-go/v2/mockstore/cluster"
|
"github.com/tikv/client-go/v2/mockstore/cluster"
|
||||||
"github.com/tikv/client-go/v2/mockstore/mocktikv"
|
"github.com/tikv/client-go/v2/mockstore/mocktikv"
|
||||||
"github.com/tikv/client-go/v2/tikv"
|
"github.com/tikv/client-go/v2/tikv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestDeleteRange(t *testing.T) {
|
||||||
|
suite.Run(t, new(testDeleteRangeSuite))
|
||||||
|
}
|
||||||
|
|
||||||
type testDeleteRangeSuite struct {
|
type testDeleteRangeSuite struct {
|
||||||
|
suite.Suite
|
||||||
cluster cluster.Cluster
|
cluster cluster.Cluster
|
||||||
store *tikv.KVStore
|
store *tikv.KVStore
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = SerialSuites(&testDeleteRangeSuite{})
|
func (s *testDeleteRangeSuite) SetupTest() {
|
||||||
|
|
||||||
func (s *testDeleteRangeSuite) SetUpTest(c *C) {
|
|
||||||
client, cluster, pdClient, err := mocktikv.NewTiKVAndPDClient("", mockcopr.NewCoprRPCHandler())
|
client, cluster, pdClient, err := mocktikv.NewTiKVAndPDClient("", mockcopr.NewCoprRPCHandler())
|
||||||
c.Assert(err, IsNil)
|
s.Require().Nil(err)
|
||||||
mocktikv.BootstrapWithMultiRegions(cluster, []byte("b"), []byte("c"), []byte("d"))
|
mocktikv.BootstrapWithMultiRegions(cluster, []byte("b"), []byte("c"), []byte("d"))
|
||||||
s.cluster = cluster
|
s.cluster = cluster
|
||||||
store, err := tikv.NewTestTiKVStore(client, pdClient, nil, nil, 0)
|
store, err := tikv.NewTestTiKVStore(client, pdClient, nil, nil, 0)
|
||||||
c.Check(err, IsNil)
|
s.Require().Nil(err)
|
||||||
|
|
||||||
// TODO: make this possible
|
|
||||||
// store, err := mockstore.NewMockStore(
|
|
||||||
// mockstore.WithStoreType(mockstore.MockTiKV),
|
|
||||||
// mockstore.WithClusterInspector(func(c cluster.Cluster) {
|
|
||||||
// mockstore.BootstrapWithMultiRegions(c, []byte("b"), []byte("c"), []byte("d"))
|
|
||||||
// s.cluster = c
|
|
||||||
// }),
|
|
||||||
// )
|
|
||||||
// c.Assert(err, IsNil)
|
|
||||||
|
|
||||||
s.store = store
|
s.store = store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testDeleteRangeSuite) TearDownTest(c *C) {
|
func (s *testDeleteRangeSuite) TearDownTest() {
|
||||||
err := s.store.Close()
|
err := s.store.Close()
|
||||||
c.Assert(err, IsNil)
|
s.Require().Nil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testDeleteRangeSuite) checkData(c *C, expectedData map[string]string) {
|
func (s *testDeleteRangeSuite) checkData(expectedData map[string]string) {
|
||||||
txn, err := s.store.Begin()
|
txn, err := s.store.Begin()
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
it, err := txn.Iter([]byte("a"), nil)
|
it, err := txn.Iter([]byte("a"), nil)
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
// Scan all data and save into a map
|
// Scan all data and save into a map
|
||||||
data := map[string]string{}
|
data := map[string]string{}
|
||||||
for it.Valid() {
|
for it.Valid() {
|
||||||
data[string(it.Key())] = string(it.Value())
|
data[string(it.Key())] = string(it.Value())
|
||||||
err = it.Next()
|
err = it.Next()
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
}
|
}
|
||||||
err = txn.Commit(context.Background())
|
err = txn.Commit(context.Background())
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
// Print log
|
// Print log
|
||||||
actualKeys := make([]string, 0, len(data))
|
actualKeys := make([]string, 0, len(data))
|
||||||
|
|
@ -105,18 +99,18 @@ func (s *testDeleteRangeSuite) checkData(c *C, expectedData map[string]string) {
|
||||||
}
|
}
|
||||||
sort.Strings(actualKeys)
|
sort.Strings(actualKeys)
|
||||||
sort.Strings(expectedKeys)
|
sort.Strings(expectedKeys)
|
||||||
c.Log("Actual: ", actualKeys)
|
s.T().Log("Actual: ", actualKeys)
|
||||||
c.Log("Expected: ", expectedKeys)
|
s.T().Log("Expected: ", expectedKeys)
|
||||||
|
|
||||||
// Assert data in the store is the same as expected
|
// Assert data in the store is the same as expected
|
||||||
c.Assert(data, DeepEquals, expectedData)
|
s.Equal(data, expectedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testDeleteRangeSuite) deleteRange(c *C, startKey []byte, endKey []byte) int {
|
func (s *testDeleteRangeSuite) deleteRange(startKey []byte, endKey []byte) int {
|
||||||
task := tikv.NewDeleteRangeTask(s.store, startKey, endKey, 1)
|
task := tikv.NewDeleteRangeTask(s.store, startKey, endKey, 1)
|
||||||
|
|
||||||
err := task.Execute(context.Background())
|
err := task.Execute(context.Background())
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
return task.CompletedRegions()
|
return task.CompletedRegions()
|
||||||
}
|
}
|
||||||
|
|
@ -132,17 +126,17 @@ func deleteRangeFromMap(m map[string]string, startKey []byte, endKey []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mustDeleteRange does delete range on both the map and the storage, and assert they are equal after deleting
|
// mustDeleteRange does delete range on both the map and the storage, and assert they are equal after deleting
|
||||||
func (s *testDeleteRangeSuite) mustDeleteRange(c *C, startKey []byte, endKey []byte, expected map[string]string, regions int) {
|
func (s *testDeleteRangeSuite) mustDeleteRange(startKey []byte, endKey []byte, expected map[string]string, regions int) {
|
||||||
completedRegions := s.deleteRange(c, startKey, endKey)
|
completedRegions := s.deleteRange(startKey, endKey)
|
||||||
deleteRangeFromMap(expected, startKey, endKey)
|
deleteRangeFromMap(expected, startKey, endKey)
|
||||||
s.checkData(c, expected)
|
s.checkData(expected)
|
||||||
c.Assert(completedRegions, Equals, regions)
|
s.Equal(completedRegions, regions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testDeleteRangeSuite) TestDeleteRange(c *C) {
|
func (s *testDeleteRangeSuite) TestDeleteRange() {
|
||||||
// Write some key-value pairs
|
// Write some key-value pairs
|
||||||
txn, err := s.store.Begin()
|
txn, err := s.store.Begin()
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
testData := map[string]string{}
|
testData := map[string]string{}
|
||||||
|
|
||||||
|
|
@ -153,19 +147,19 @@ func (s *testDeleteRangeSuite) TestDeleteRange(c *C) {
|
||||||
value := []byte{byte(rand.Intn(256)), byte(rand.Intn(256))}
|
value := []byte{byte(rand.Intn(256)), byte(rand.Intn(256))}
|
||||||
testData[string(key)] = string(value)
|
testData[string(key)] = string(value)
|
||||||
err := txn.Set(key, value)
|
err := txn.Set(key, value)
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = txn.Commit(context.Background())
|
err = txn.Commit(context.Background())
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
s.checkData(c, testData)
|
s.checkData(testData)
|
||||||
|
|
||||||
s.mustDeleteRange(c, []byte("b"), []byte("c0"), testData, 2)
|
s.mustDeleteRange([]byte("b"), []byte("c0"), testData, 2)
|
||||||
s.mustDeleteRange(c, []byte("c11"), []byte("c12"), testData, 1)
|
s.mustDeleteRange([]byte("c11"), []byte("c12"), testData, 1)
|
||||||
s.mustDeleteRange(c, []byte("d0"), []byte("d0"), testData, 0)
|
s.mustDeleteRange([]byte("d0"), []byte("d0"), testData, 0)
|
||||||
s.mustDeleteRange(c, []byte("d0\x00"), []byte("d1\x00"), testData, 1)
|
s.mustDeleteRange([]byte("d0\x00"), []byte("d1\x00"), testData, 1)
|
||||||
s.mustDeleteRange(c, []byte("c5"), []byte("d5"), testData, 2)
|
s.mustDeleteRange([]byte("c5"), []byte("d5"), testData, 2)
|
||||||
s.mustDeleteRange(c, []byte("a"), []byte("z"), testData, 4)
|
s.mustDeleteRange([]byte("a"), []byte("z"), testData, 4)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,26 +39,30 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/pingcap/check"
|
|
||||||
"github.com/pingcap/tidb/kv"
|
"github.com/pingcap/tidb/kv"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/tikv/client-go/v2/tikv"
|
"github.com/tikv/client-go/v2/tikv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestIsolation(t *testing.T) {
|
||||||
|
suite.Run(t, new(testIsolationSuite))
|
||||||
|
}
|
||||||
|
|
||||||
// testIsolationSuite represents test isolation suite.
|
// testIsolationSuite represents test isolation suite.
|
||||||
// The test suite takes too long under the race detector.
|
// The test suite takes too long under the race detector.
|
||||||
type testIsolationSuite struct {
|
type testIsolationSuite struct {
|
||||||
|
suite.Suite
|
||||||
store *tikv.KVStore
|
store *tikv.KVStore
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = SerialSuites(&testIsolationSuite{})
|
func (s *testIsolationSuite) SetupSuite() {
|
||||||
|
s.store = NewTestStoreT(s.T())
|
||||||
func (s *testIsolationSuite) SetUpSuite(c *C) {
|
|
||||||
s.store = NewTestStore(c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testIsolationSuite) TearDownSuite(c *C) {
|
func (s *testIsolationSuite) TearDownSuite() {
|
||||||
s.store.Close()
|
s.store.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,15 +77,15 @@ func (r writeRecords) Len() int { return len(r) }
|
||||||
func (r writeRecords) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
func (r writeRecords) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||||
func (r writeRecords) Less(i, j int) bool { return r[i].startTS <= r[j].startTS }
|
func (r writeRecords) Less(i, j int) bool { return r[i].startTS <= r[j].startTS }
|
||||||
|
|
||||||
func (s *testIsolationSuite) SetWithRetry(c *C, k, v []byte) writeRecord {
|
func (s *testIsolationSuite) SetWithRetry(k, v []byte) writeRecord {
|
||||||
for {
|
for {
|
||||||
txnRaw, err := s.store.Begin()
|
txnRaw, err := s.store.Begin()
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
txn := tikv.TxnProbe{KVTxn: txnRaw}
|
txn := tikv.TxnProbe{KVTxn: txnRaw}
|
||||||
|
|
||||||
err = txn.Set(k, v)
|
err = txn.Set(k, v)
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
err = txn.Commit(context.Background())
|
err = txn.Commit(context.Background())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -104,10 +108,10 @@ func (r readRecords) Len() int { return len(r) }
|
||||||
func (r readRecords) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
func (r readRecords) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||||
func (r readRecords) Less(i, j int) bool { return r[i].startTS <= r[j].startTS }
|
func (r readRecords) Less(i, j int) bool { return r[i].startTS <= r[j].startTS }
|
||||||
|
|
||||||
func (s *testIsolationSuite) GetWithRetry(c *C, k []byte) readRecord {
|
func (s *testIsolationSuite) GetWithRetry(k []byte) readRecord {
|
||||||
for {
|
for {
|
||||||
txn, err := s.store.Begin()
|
txn, err := s.store.Begin()
|
||||||
c.Assert(err, IsNil)
|
s.Nil(err)
|
||||||
|
|
||||||
val, err := txn.Get(context.TODO(), k)
|
val, err := txn.Get(context.TODO(), k)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -116,11 +120,11 @@ func (s *testIsolationSuite) GetWithRetry(c *C, k []byte) readRecord {
|
||||||
value: val,
|
value: val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Assert(kv.IsTxnRetryableError(err), IsTrue)
|
s.True(kv.IsTxnRetryableError(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testIsolationSuite) TestWriteWriteConflict(c *C) {
|
func (s *testIsolationSuite) TestWriteWriteConflict() {
|
||||||
const (
|
const (
|
||||||
threadCount = 10
|
threadCount = 10
|
||||||
setPerThread = 50
|
setPerThread = 50
|
||||||
|
|
@ -135,7 +139,7 @@ func (s *testIsolationSuite) TestWriteWriteConflict(c *C) {
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for j := 0; j < setPerThread; j++ {
|
for j := 0; j < setPerThread; j++ {
|
||||||
w := s.SetWithRetry(c, []byte("k"), []byte("v"))
|
w := s.SetWithRetry([]byte("k"), []byte("v"))
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
writes = append(writes, w)
|
writes = append(writes, w)
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
@ -147,11 +151,11 @@ func (s *testIsolationSuite) TestWriteWriteConflict(c *C) {
|
||||||
// Check all transactions' [startTS, commitTS] are not overlapped.
|
// Check all transactions' [startTS, commitTS] are not overlapped.
|
||||||
sort.Sort(writeRecords(writes))
|
sort.Sort(writeRecords(writes))
|
||||||
for i := 0; i < len(writes)-1; i++ {
|
for i := 0; i < len(writes)-1; i++ {
|
||||||
c.Assert(writes[i].commitTS, Less, writes[i+1].startTS)
|
s.Less(writes[i].commitTS, writes[i+1].startTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *testIsolationSuite) TestReadWriteConflict(c *C) {
|
func (s *testIsolationSuite) TestReadWriteConflict() {
|
||||||
const (
|
const (
|
||||||
readThreadCount = 10
|
readThreadCount = 10
|
||||||
writeCount = 10
|
writeCount = 10
|
||||||
|
|
@ -164,12 +168,12 @@ func (s *testIsolationSuite) TestReadWriteConflict(c *C) {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
)
|
)
|
||||||
|
|
||||||
s.SetWithRetry(c, []byte("k"), []byte("0"))
|
s.SetWithRetry([]byte("k"), []byte("0"))
|
||||||
|
|
||||||
writeDone := make(chan struct{})
|
writeDone := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
for i := 1; i <= writeCount; i++ {
|
for i := 1; i <= writeCount; i++ {
|
||||||
w := s.SetWithRetry(c, []byte("k"), []byte(fmt.Sprintf("%d", i)))
|
w := s.SetWithRetry([]byte("k"), []byte(fmt.Sprintf("%d", i)))
|
||||||
writes = append(writes, w)
|
writes = append(writes, w)
|
||||||
time.Sleep(time.Microsecond * 10)
|
time.Sleep(time.Microsecond * 10)
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +190,7 @@ func (s *testIsolationSuite) TestReadWriteConflict(c *C) {
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
r := s.GetWithRetry(c, []byte("k"))
|
r := s.GetWithRetry([]byte("k"))
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
reads = append(reads, r)
|
reads = append(reads, r)
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
@ -205,10 +209,10 @@ func (s *testIsolationSuite) TestReadWriteConflict(c *C) {
|
||||||
if r.startTS >= w.commitTS {
|
if r.startTS >= w.commitTS {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c.Assert(string(r.value), Equals, fmt.Sprintf("%d", i))
|
s.Equal(string(r.value), fmt.Sprintf("%d", i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ; j < len(reads); j++ {
|
for ; j < len(reads); j++ {
|
||||||
c.Assert(string(reads[j].value), Equals, fmt.Sprintf("%d", len(writes)))
|
s.Equal(string(reads[j].value), fmt.Sprintf("%d", len(writes)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue