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  }