github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/inspectkv/inspectkv_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 inspectkv 15 16 import ( 17 "fmt" 18 "testing" 19 20 . "github.com/insionng/yougam/libraries/pingcap/check" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/column" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/kv" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/meta" 24 "github.com/insionng/yougam/libraries/pingcap/tidb/meta/autoid" 25 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 26 "github.com/insionng/yougam/libraries/pingcap/tidb/mysql" 27 "github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/variable" 28 "github.com/insionng/yougam/libraries/pingcap/tidb/store/localstore" 29 "github.com/insionng/yougam/libraries/pingcap/tidb/store/localstore/goleveldb" 30 "github.com/insionng/yougam/libraries/pingcap/tidb/table" 31 "github.com/insionng/yougam/libraries/pingcap/tidb/table/tables" 32 "github.com/insionng/yougam/libraries/pingcap/tidb/util/mock" 33 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak" 34 "github.com/insionng/yougam/libraries/pingcap/tidb/util/types" 35 ) 36 37 func TestT(t *testing.T) { 38 TestingT(t) 39 } 40 41 var _ = Suite(&testSuite{}) 42 43 type testSuite struct { 44 store kv.Storage 45 ctx *mock.Context 46 dbInfo *model.DBInfo 47 tbInfo *model.TableInfo 48 } 49 50 func (s *testSuite) SetUpSuite(c *C) { 51 driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} 52 var err error 53 s.store, err = driver.Open("memory:test_inspect") 54 c.Assert(err, IsNil) 55 56 s.ctx = mock.NewContext() 57 s.ctx.Store = s.store 58 variable.BindSessionVars(s.ctx) 59 60 txn, err := s.store.Begin() 61 c.Assert(err, IsNil) 62 t := meta.NewMeta(txn) 63 64 s.dbInfo = &model.DBInfo{ 65 ID: 1, 66 Name: model.NewCIStr("a"), 67 } 68 err = t.CreateDatabase(s.dbInfo) 69 c.Assert(err, IsNil) 70 71 col := &model.ColumnInfo{ 72 Name: model.NewCIStr("c"), 73 ID: 0, 74 Offset: 0, 75 DefaultValue: 1, 76 State: model.StatePublic, 77 FieldType: *types.NewFieldType(mysql.TypeLong), 78 } 79 col1 := &model.ColumnInfo{ 80 Name: model.NewCIStr("c1"), 81 ID: 1, 82 Offset: 1, 83 DefaultValue: 1, 84 State: model.StatePublic, 85 FieldType: *types.NewFieldType(mysql.TypeLong), 86 } 87 idx := &model.IndexInfo{ 88 Name: model.NewCIStr("c"), 89 ID: 1, 90 Unique: true, 91 Columns: []*model.IndexColumn{{ 92 Name: model.NewCIStr("c"), 93 Offset: 0, 94 Length: 255, 95 }}, 96 State: model.StatePublic, 97 } 98 s.tbInfo = &model.TableInfo{ 99 ID: 1, 100 Name: model.NewCIStr("t"), 101 State: model.StatePublic, 102 Columns: []*model.ColumnInfo{col, col1}, 103 Indices: []*model.IndexInfo{idx}, 104 } 105 err = t.CreateTable(s.dbInfo.ID, s.tbInfo) 106 c.Assert(err, IsNil) 107 108 err = txn.Commit() 109 c.Assert(err, IsNil) 110 } 111 112 func (s *testSuite) TearDownSuite(c *C) { 113 txn, err := s.store.Begin() 114 c.Assert(err, IsNil) 115 t := meta.NewMeta(txn) 116 117 err = t.DropTable(s.dbInfo.ID, s.tbInfo.ID) 118 c.Assert(err, IsNil) 119 err = t.DropDatabase(s.dbInfo.ID) 120 c.Assert(err, IsNil) 121 err = txn.Commit() 122 c.Assert(err, IsNil) 123 124 err = s.store.Close() 125 c.Assert(err, IsNil) 126 } 127 128 func (s *testSuite) TestGetDDLInfo(c *C) { 129 defer testleak.AfterTest(c)() 130 txn, err := s.store.Begin() 131 c.Assert(err, IsNil) 132 t := meta.NewMeta(txn) 133 134 owner := &model.Owner{OwnerID: "owner"} 135 err = t.SetDDLJobOwner(owner) 136 c.Assert(err, IsNil) 137 dbInfo2 := &model.DBInfo{ 138 ID: 2, 139 Name: model.NewCIStr("b"), 140 State: model.StateNone, 141 } 142 job := &model.Job{ 143 SchemaID: dbInfo2.ID, 144 Type: model.ActionCreateSchema, 145 } 146 err = t.EnQueueDDLJob(job) 147 c.Assert(err, IsNil) 148 info, err := GetDDLInfo(txn) 149 c.Assert(err, IsNil) 150 c.Assert(info.Owner, DeepEquals, owner) 151 c.Assert(info.Job, DeepEquals, job) 152 c.Assert(info.ReorgHandle, Equals, int64(0)) 153 err = txn.Commit() 154 c.Assert(err, IsNil) 155 } 156 157 func (s *testSuite) TestGetBgDDLInfo(c *C) { 158 defer testleak.AfterTest(c)() 159 txn, err := s.store.Begin() 160 c.Assert(err, IsNil) 161 t := meta.NewMeta(txn) 162 163 owner := &model.Owner{OwnerID: "owner"} 164 err = t.SetBgJobOwner(owner) 165 c.Assert(err, IsNil) 166 job := &model.Job{ 167 SchemaID: 1, 168 Type: model.ActionDropTable, 169 } 170 err = t.EnQueueBgJob(job) 171 c.Assert(err, IsNil) 172 info, err := GetBgDDLInfo(txn) 173 c.Assert(err, IsNil) 174 c.Assert(info.Owner, DeepEquals, owner) 175 c.Assert(info.Job, DeepEquals, job) 176 c.Assert(info.ReorgHandle, Equals, int64(0)) 177 err = txn.Commit() 178 c.Assert(err, IsNil) 179 } 180 181 func (s *testSuite) TestScan(c *C) { 182 defer testleak.AfterTest(c)() 183 alloc := autoid.NewAllocator(s.store, s.dbInfo.ID) 184 tb, err := tables.TableFromMeta(alloc, s.tbInfo) 185 c.Assert(err, IsNil) 186 indices := tb.Indices() 187 _, err = tb.AddRecord(s.ctx, types.MakeDatums(10, 11)) 188 c.Assert(err, IsNil) 189 s.ctx.FinishTxn(false) 190 191 record1 := &RecordData{Handle: int64(1), Values: types.MakeDatums(int64(10), int64(11))} 192 record2 := &RecordData{Handle: int64(2), Values: types.MakeDatums(int64(20), int64(21))} 193 ver, err := s.store.CurrentVersion() 194 c.Assert(err, IsNil) 195 records, _, err := ScanSnapshotTableRecord(s.store, ver, tb, int64(1), 1) 196 c.Assert(err, IsNil) 197 c.Assert(records, DeepEquals, []*RecordData{record1}) 198 199 _, err = tb.AddRecord(s.ctx, record2.Values) 200 c.Assert(err, IsNil) 201 s.ctx.FinishTxn(false) 202 txn, err := s.store.Begin() 203 c.Assert(err, IsNil) 204 205 records, nextHandle, err := ScanTableRecord(txn, tb, int64(1), 1) 206 c.Assert(err, IsNil) 207 c.Assert(records, DeepEquals, []*RecordData{record1}) 208 records, nextHandle, err = ScanTableRecord(txn, tb, nextHandle, 1) 209 c.Assert(err, IsNil) 210 c.Assert(records, DeepEquals, []*RecordData{record2}) 211 startHandle := nextHandle 212 records, nextHandle, err = ScanTableRecord(txn, tb, startHandle, 1) 213 c.Assert(err, IsNil) 214 c.Assert(records, IsNil) 215 c.Assert(nextHandle, Equals, startHandle) 216 217 idxRow1 := &RecordData{Handle: int64(1), Values: types.MakeDatums(int64(10))} 218 idxRow2 := &RecordData{Handle: int64(2), Values: types.MakeDatums(int64(20))} 219 kvIndex := kv.NewKVIndex(tb.IndexPrefix(), indices[0].Name.L, indices[0].ID, indices[0].Unique) 220 idxRows, nextVals, err := ScanIndexData(txn, kvIndex, idxRow1.Values, 2) 221 c.Assert(err, IsNil) 222 c.Assert(idxRows, DeepEquals, []*RecordData{idxRow1, idxRow2}) 223 idxRows, nextVals, err = ScanIndexData(txn, kvIndex, idxRow1.Values, 1) 224 c.Assert(err, IsNil) 225 c.Assert(idxRows, DeepEquals, []*RecordData{idxRow1}) 226 idxRows, nextVals, err = ScanIndexData(txn, kvIndex, nextVals, 1) 227 c.Assert(err, IsNil) 228 c.Assert(idxRows, DeepEquals, []*RecordData{idxRow2}) 229 idxRows, nextVals, err = ScanIndexData(txn, kvIndex, nextVals, 1) 230 c.Assert(idxRows, IsNil) 231 c.Assert(nextVals, DeepEquals, types.MakeDatums(nil)) 232 c.Assert(err, IsNil) 233 234 s.testTableData(c, tb, []*RecordData{record1, record2}) 235 236 s.testIndex(c, tb, tb.Indices()[0]) 237 238 err = tb.RemoveRecord(s.ctx, 1, record1.Values) 239 c.Assert(err, IsNil) 240 err = tb.RemoveRecord(s.ctx, 2, record2.Values) 241 c.Assert(err, IsNil) 242 } 243 244 func newDiffRetError(prefix string, ra, rb *RecordData) string { 245 return fmt.Sprintf("[inspectkv:1]%s:%v != record:%v", prefix, ra, rb) 246 } 247 248 func (s *testSuite) testTableData(c *C, tb table.Table, rs []*RecordData) { 249 txn, err := s.store.Begin() 250 c.Assert(err, IsNil) 251 252 err = CompareTableRecord(txn, tb, rs, true) 253 c.Assert(err, IsNil) 254 255 cnt, err := GetTableRecordsCount(txn, tb, 0) 256 c.Assert(err, IsNil) 257 c.Assert(cnt, Equals, int64(len(rs))) 258 259 records := []*RecordData{ 260 {Handle: rs[0].Handle}, 261 {Handle: rs[1].Handle}, 262 } 263 err = CompareTableRecord(txn, tb, records, false) 264 c.Assert(err, IsNil) 265 266 record := &RecordData{Handle: rs[1].Handle, Values: types.MakeDatums(int64(30))} 267 err = CompareTableRecord(txn, tb, []*RecordData{rs[0], record}, true) 268 c.Assert(err, NotNil) 269 diffMsg := newDiffRetError("data", record, rs[1]) 270 c.Assert(err.Error(), DeepEquals, diffMsg) 271 272 record.Handle = 3 273 err = CompareTableRecord(txn, tb, []*RecordData{rs[0], record, rs[1]}, true) 274 c.Assert(err, NotNil) 275 diffMsg = newDiffRetError("data", record, nil) 276 c.Assert(err.Error(), DeepEquals, diffMsg) 277 278 err = CompareTableRecord(txn, tb, []*RecordData{rs[0], rs[1], record}, true) 279 c.Assert(err, NotNil) 280 diffMsg = newDiffRetError("data", record, nil) 281 c.Assert(err.Error(), DeepEquals, diffMsg) 282 283 err = CompareTableRecord(txn, tb, []*RecordData{rs[0]}, true) 284 c.Assert(err, NotNil) 285 diffMsg = newDiffRetError("data", nil, rs[1]) 286 c.Assert(err.Error(), DeepEquals, diffMsg) 287 288 err = CompareTableRecord(txn, tb, nil, true) 289 c.Assert(err, NotNil) 290 diffMsg = newDiffRetError("data", nil, rs[0]) 291 c.Assert(err.Error(), DeepEquals, diffMsg) 292 293 errRs := append(rs, &RecordData{Handle: int64(1), Values: types.MakeDatums(int64(3))}) 294 err = CompareTableRecord(txn, tb, errRs, false) 295 c.Assert(err.Error(), DeepEquals, "[inspectkv:2]handle:1 is repeated in data") 296 } 297 298 func (s *testSuite) testIndex(c *C, tb table.Table, idx *column.IndexedCol) { 299 txn, err := s.store.Begin() 300 c.Assert(err, IsNil) 301 302 err = CompareIndexData(txn, tb, idx) 303 c.Assert(err, IsNil) 304 305 cnt, err := GetIndexRecordsCount(txn, idx.X, nil) 306 c.Assert(err, IsNil) 307 c.Assert(cnt, Equals, int64(2)) 308 309 // current index data: 310 // index data (handle, data): (1, 10), (2, 20), (3, 30) 311 // index col data (handle, data): (1, 10), (2, 20), (4, 40) 312 err = idx.X.Create(txn, types.MakeDatums(int64(30)), 3) 313 c.Assert(err, IsNil) 314 col := tb.Cols()[idx.Columns[0].Offset] 315 key := tb.RecordKey(4, col) 316 err = tables.SetColValue(txn, key, types.NewDatum(int64(40))) 317 c.Assert(err, IsNil) 318 err = txn.Commit() 319 c.Assert(err, IsNil) 320 321 txn, err = s.store.Begin() 322 c.Assert(err, IsNil) 323 err = CompareIndexData(txn, tb, idx) 324 c.Assert(err, NotNil) 325 record1 := &RecordData{Handle: int64(3), Values: types.MakeDatums(int64(30))} 326 diffMsg := newDiffRetError("index", record1, &RecordData{Handle: int64(3), Values: types.MakeDatums(nil)}) 327 c.Assert(err.Error(), DeepEquals, diffMsg) 328 329 // current index data: 330 // index data (handle, data): (1, 10), (2, 20), (3, 30), (4, 40) 331 // index col data (handle, data): (1, 10), (2, 20), (4, 40), (3, 31) 332 err = idx.X.Create(txn, types.MakeDatums(int64(40)), 4) 333 c.Assert(err, IsNil) 334 key = tb.RecordKey(3, col) 335 err = tables.SetColValue(txn, key, types.NewDatum(int64(31))) 336 c.Assert(err, IsNil) 337 err = txn.Commit() 338 c.Assert(err, IsNil) 339 340 txn, err = s.store.Begin() 341 c.Assert(err, IsNil) 342 err = CompareIndexData(txn, tb, idx) 343 c.Assert(err, NotNil) 344 record2 := &RecordData{Handle: int64(3), Values: types.MakeDatums(int64(31))} 345 diffMsg = newDiffRetError("index", record1, record2) 346 c.Assert(err.Error(), DeepEquals, diffMsg) 347 348 // current index data: 349 // index data (handle, data): (1, 10), (2, 20), (3, 30), (4, 40) 350 // index col data (handle, data): (1, 10), (2, 20), (4, 40), (5, 30) 351 key = tb.RecordKey(3, col) 352 txn.Delete(key) 353 key = tb.RecordKey(5, col) 354 err = tables.SetColValue(txn, key, types.NewDatum(int64(30))) 355 c.Assert(err, IsNil) 356 err = txn.Commit() 357 c.Assert(err, IsNil) 358 359 txn, err = s.store.Begin() 360 c.Assert(err, IsNil) 361 err = checkRecordAndIndex(txn, tb, idx) 362 c.Assert(err, NotNil) 363 record2 = &RecordData{Handle: int64(5), Values: types.MakeDatums(int64(30))} 364 diffMsg = newDiffRetError("index", record1, record2) 365 c.Assert(err.Error(), DeepEquals, diffMsg) 366 367 // current index data: 368 // index data (handle, data): (1, 10), (2, 20), (3, 30), (4, 40) 369 // index col data (handle, data): (1, 10), (2, 20), (3, 30) 370 key = tb.RecordKey(4, col) 371 txn.Delete(key) 372 key = tb.RecordKey(3, col) 373 err = tables.SetColValue(txn, key, types.NewDatum(int64(30))) 374 c.Assert(err, IsNil) 375 err = txn.Commit() 376 c.Assert(err, IsNil) 377 378 txn, err = s.store.Begin() 379 c.Assert(err, IsNil) 380 err = CompareIndexData(txn, tb, idx) 381 c.Assert(err, NotNil) 382 record1 = &RecordData{Handle: int64(4), Values: types.MakeDatums(int64(40))} 383 diffMsg = newDiffRetError("index", record1, &RecordData{Handle: int64(4), Values: types.MakeDatums(nil)}) 384 c.Assert(err.Error(), DeepEquals, diffMsg) 385 386 // current index data: 387 // index data (handle, data): (1, 10), (2, 20), (3, 30) 388 // index col data (handle, data): (1, 10), (2, 20), (3, 30), (4, 40) 389 err = idx.X.Delete(txn, types.MakeDatums(int64(40)), 4) 390 c.Assert(err, IsNil) 391 key = tb.RecordKey(4, col) 392 err = tables.SetColValue(txn, key, types.NewDatum(int64(40))) 393 c.Assert(err, IsNil) 394 err = txn.Commit() 395 c.Assert(err, IsNil) 396 397 txn, err = s.store.Begin() 398 c.Assert(err, IsNil) 399 err = CompareIndexData(txn, tb, idx) 400 c.Assert(err, NotNil) 401 diffMsg = newDiffRetError("index", nil, record1) 402 c.Assert(err.Error(), DeepEquals, diffMsg) 403 }