github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/milevadb-server/einsteindb/ticlient_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 einsteindb 15 16 import ( 17 "context" 18 "flag" 19 "fmt" 20 "sync" 21 "time" 22 23 . "github.com/whtcorpsinc/check" 24 "github.com/whtcorpsinc/errors" 25 "github.com/whtcorpsinc/milevadb/causetstore/mockstore/entangledstore" 26 "github.com/whtcorpsinc/milevadb/ekv" 27 "github.com/whtcorpsinc/milevadb/soliton/codec" 28 ) 29 30 var ( 31 withEinsteinDBGlobalLock sync.RWMutex 32 WithEinsteinDB = flag.Bool("with-einsteindb", false, "run tests with EinsteinDB cluster started. (not use the mock server)") 33 FIDelAddrs = flag.String("fidel-addrs", "127.0.0.1:2379", "fidel addrs") 34 ) 35 36 // NewTestStore creates a ekv.CausetStorage for testing purpose. 37 func NewTestStore(c *C) ekv.CausetStorage { 38 if !flag.Parsed() { 39 flag.Parse() 40 } 41 42 if *WithEinsteinDB { 43 var d Driver 44 causetstore, err := d.Open(fmt.Sprintf("einsteindb://%s", *FIDelAddrs)) 45 c.Assert(err, IsNil) 46 err = clearStorage(causetstore) 47 c.Assert(err, IsNil) 48 return causetstore 49 } 50 client, FIDelClient, cluster, err := entangledstore.New("") 51 c.Assert(err, IsNil) 52 entangledstore.BootstrapWithSingleStore(cluster) 53 causetstore, err := NewTestEinsteinDBStore(client, FIDelClient, nil, nil, 0) 54 c.Assert(err, IsNil) 55 return causetstore 56 } 57 58 func clearStorage(causetstore ekv.CausetStorage) error { 59 txn, err := causetstore.Begin() 60 if err != nil { 61 return errors.Trace(err) 62 } 63 iter, err := txn.Iter(nil, nil) 64 if err != nil { 65 return errors.Trace(err) 66 } 67 for iter.Valid() { 68 txn.Delete(iter.Key()) 69 if err := iter.Next(); err != nil { 70 return errors.Trace(err) 71 } 72 } 73 return txn.Commit(context.Background()) 74 } 75 76 type testTiclientSuite struct { 77 OneByOneSuite 78 causetstore *einsteindbStore 79 // prefix is prefix of each key in this test. It is used for causet isolation, 80 // or it may pollute other data. 81 prefix string 82 } 83 84 var _ = Suite(&testTiclientSuite{}) 85 86 func (s *testTiclientSuite) SetUpSuite(c *C) { 87 s.OneByOneSuite.SetUpSuite(c) 88 s.causetstore = NewTestStore(c).(*einsteindbStore) 89 s.prefix = fmt.Sprintf("ticlient_%d", time.Now().Unix()) 90 } 91 92 func (s *testTiclientSuite) TearDownSuite(c *C) { 93 // Clean all data, or it may pollute other data. 94 txn := s.beginTxn(c) 95 scanner, err := txn.Iter(encodeKey(s.prefix, ""), nil) 96 c.Assert(err, IsNil) 97 c.Assert(scanner, NotNil) 98 for scanner.Valid() { 99 k := scanner.Key() 100 err = txn.Delete(k) 101 c.Assert(err, IsNil) 102 scanner.Next() 103 } 104 err = txn.Commit(context.Background()) 105 c.Assert(err, IsNil) 106 err = s.causetstore.Close() 107 c.Assert(err, IsNil) 108 s.OneByOneSuite.TearDownSuite(c) 109 } 110 111 func (s *testTiclientSuite) beginTxn(c *C) *einsteindbTxn { 112 txn, err := s.causetstore.Begin() 113 c.Assert(err, IsNil) 114 return txn.(*einsteindbTxn) 115 } 116 117 func (s *testTiclientSuite) TestSingleKey(c *C) { 118 txn := s.beginTxn(c) 119 err := txn.Set(encodeKey(s.prefix, "key"), []byte("value")) 120 c.Assert(err, IsNil) 121 err = txn.LockKeys(context.Background(), new(ekv.LockCtx), encodeKey(s.prefix, "key")) 122 c.Assert(err, IsNil) 123 err = txn.Commit(context.Background()) 124 c.Assert(err, IsNil) 125 126 txn = s.beginTxn(c) 127 val, err := txn.Get(context.TODO(), encodeKey(s.prefix, "key")) 128 c.Assert(err, IsNil) 129 c.Assert(val, BytesEquals, []byte("value")) 130 131 txn = s.beginTxn(c) 132 err = txn.Delete(encodeKey(s.prefix, "key")) 133 c.Assert(err, IsNil) 134 err = txn.Commit(context.Background()) 135 c.Assert(err, IsNil) 136 } 137 138 func (s *testTiclientSuite) TestMultiKeys(c *C) { 139 const keyNum = 100 140 141 txn := s.beginTxn(c) 142 for i := 0; i < keyNum; i++ { 143 err := txn.Set(encodeKey(s.prefix, s08d("key", i)), valueBytes(i)) 144 c.Assert(err, IsNil) 145 } 146 err := txn.Commit(context.Background()) 147 c.Assert(err, IsNil) 148 149 txn = s.beginTxn(c) 150 for i := 0; i < keyNum; i++ { 151 val, err1 := txn.Get(context.TODO(), encodeKey(s.prefix, s08d("key", i))) 152 c.Assert(err1, IsNil) 153 c.Assert(val, BytesEquals, valueBytes(i)) 154 } 155 156 txn = s.beginTxn(c) 157 for i := 0; i < keyNum; i++ { 158 err = txn.Delete(encodeKey(s.prefix, s08d("key", i))) 159 c.Assert(err, IsNil) 160 } 161 err = txn.Commit(context.Background()) 162 c.Assert(err, IsNil) 163 } 164 165 func (s *testTiclientSuite) TestNotExist(c *C) { 166 txn := s.beginTxn(c) 167 _, err := txn.Get(context.TODO(), encodeKey(s.prefix, "noSuchKey")) 168 c.Assert(err, NotNil) 169 } 170 171 func (s *testTiclientSuite) TestLargeRequest(c *C) { 172 largeValue := make([]byte, 9*1024*1024) // 9M value. 173 txn := s.beginTxn(c) 174 err := txn.Set([]byte("key"), largeValue) 175 c.Assert(err, NotNil) 176 err = txn.Commit(context.Background()) 177 c.Assert(err, IsNil) 178 c.Assert(ekv.IsTxnRetryableError(err), IsFalse) 179 } 180 181 func encodeKey(prefix, s string) []byte { 182 return codec.EncodeBytes(nil, []byte(fmt.Sprintf("%s_%s", prefix, s))) 183 } 184 185 func valueBytes(n int) []byte { 186 return []byte(fmt.Sprintf("value%d", n)) 187 } 188 189 // s08d is for returning format string "%s%08d" to keep string sorted. 190 // e.g.: "0002" < "0011", otherwise "2" > "11" 191 func s08d(prefix string, n int) string { 192 return fmt.Sprintf("%s%08d", prefix, n) 193 }