github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/store/tikv/snapshot_test.go (about)

     1  // Copyright 2016 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 tikv
    15  
    16  import (
    17  	"fmt"
    18  	"time"
    19  
    20  	"github.com/insionng/yougam/libraries/ngaut/log"
    21  	. "github.com/insionng/yougam/libraries/pingcap/check"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/kv"
    23  )
    24  
    25  type testSnapshotSuite struct {
    26  	store   *tikvStore
    27  	prefix  string
    28  	rowNums []int
    29  }
    30  
    31  var _ = Suite(&testSnapshotSuite{})
    32  
    33  func (s *testSnapshotSuite) SetUpSuite(c *C) {
    34  	s.store = newTestStore(c)
    35  	s.prefix = fmt.Sprintf("snapshot_%d", time.Now().Unix())
    36  	s.rowNums = append(s.rowNums, 1, 100, 191)
    37  }
    38  
    39  func (s *testSnapshotSuite) TearDownSuite(c *C) {
    40  	txn := s.beginTxn(c)
    41  	scanner, err := txn.Seek(encodeKey(s.prefix, ""))
    42  	c.Assert(err, IsNil)
    43  	c.Assert(scanner, NotNil)
    44  	for scanner.Valid() {
    45  		k := scanner.Key()
    46  		err = txn.Delete(k)
    47  		c.Assert(err, IsNil)
    48  		scanner.Next()
    49  	}
    50  	err = txn.Commit()
    51  	c.Assert(err, IsNil)
    52  	err = s.store.Close()
    53  	c.Assert(err, IsNil)
    54  }
    55  
    56  func (s *testSnapshotSuite) beginTxn(c *C) *tikvTxn {
    57  	txn, err := s.store.Begin()
    58  	c.Assert(err, IsNil)
    59  	return txn.(*tikvTxn)
    60  }
    61  
    62  func (s *testSnapshotSuite) checkAll(keys []kv.Key, c *C) {
    63  	txn := s.beginTxn(c)
    64  	snapshot := newTiKVSnapshot(s.store, kv.Version{Ver: txn.StartTS()})
    65  	m, err := snapshot.BatchGet(keys)
    66  	c.Assert(err, IsNil)
    67  
    68  	scan, err := txn.Seek(encodeKey(s.prefix, ""))
    69  	c.Assert(err, IsNil)
    70  	cnt := 0
    71  	for scan.Valid() {
    72  		cnt++
    73  		k := scan.Key()
    74  		v := scan.Value()
    75  		v2, ok := m[string(k)]
    76  		c.Assert(ok, IsTrue, Commentf("key: %q", k))
    77  		c.Assert(v, BytesEquals, v2)
    78  		scan.Next()
    79  	}
    80  	err = txn.Commit()
    81  	c.Assert(err, IsNil)
    82  	c.Assert(m, HasLen, cnt)
    83  }
    84  
    85  func (s *testSnapshotSuite) deleteKeys(keys []kv.Key, c *C) {
    86  	txn := s.beginTxn(c)
    87  	for _, k := range keys {
    88  		err := txn.Delete(k)
    89  		c.Assert(err, IsNil)
    90  	}
    91  	err := txn.Commit()
    92  	c.Assert(err, IsNil)
    93  }
    94  
    95  func (s *testSnapshotSuite) TestBatchGet(c *C) {
    96  	for _, rowNum := range s.rowNums {
    97  		log.Debugf("Test BatchGet with length[%d]", rowNum)
    98  		txn := s.beginTxn(c)
    99  		for i := 0; i < rowNum; i++ {
   100  			k := encodeKey(s.prefix, s08d("key", i))
   101  			err := txn.Set(k, valueBytes(i))
   102  			c.Assert(err, IsNil)
   103  		}
   104  		err := txn.Commit()
   105  		c.Assert(err, IsNil)
   106  
   107  		keys := makeKeys(rowNum, s.prefix)
   108  		s.checkAll(keys, c)
   109  		s.deleteKeys(keys, c)
   110  	}
   111  }
   112  
   113  func (s *testSnapshotSuite) TestBatchGetLock(c *C) {
   114  	for _, rowNum := range s.rowNums {
   115  		log.Debugf("Test BatchGetLock with length[%d]", rowNum)
   116  		txn := s.beginTxn(c)
   117  		for i := 0; i < rowNum; i++ {
   118  			k := encodeKey(s.prefix, s08d("key", i))
   119  			err := txn.Set(k, valueBytes(i))
   120  			c.Assert(err, IsNil)
   121  		}
   122  		err := txn.Commit()
   123  		c.Assert(err, IsNil)
   124  
   125  		txn2 := s.beginTxn(c)
   126  		txn2.DONOTCOMMIT = true
   127  		lockKey := encodeKey(s.prefix, s08d("key", rowNum/2))
   128  		err = txn2.Set(lockKey, []byte("lock"))
   129  		c.Assert(err, IsNil)
   130  		err = txn2.Commit()
   131  		c.Assert(err, IsNil)
   132  
   133  		keys := makeKeys(rowNum, s.prefix)
   134  		txn3 := s.beginTxn(c)
   135  		snapshot := newTiKVSnapshot(s.store, kv.Version{Ver: txn3.StartTS()})
   136  		_, err = snapshot.BatchGet(keys)
   137  		c.Assert(err, IsNil)
   138  
   139  		s.checkAll(keys, c)
   140  		s.deleteKeys(keys, c)
   141  	}
   142  }
   143  
   144  func (s *testSnapshotSuite) TestBatchGetNotExist(c *C) {
   145  	for _, rowNum := range s.rowNums {
   146  		log.Debugf("Test BatchGetNotExist with length[%d]", rowNum)
   147  		txn := s.beginTxn(c)
   148  		for i := 0; i < rowNum; i++ {
   149  			k := encodeKey(s.prefix, s08d("key", i))
   150  			err := txn.Set(k, valueBytes(i))
   151  			c.Assert(err, IsNil)
   152  		}
   153  		err := txn.Commit()
   154  		c.Assert(err, IsNil)
   155  
   156  		keys := makeKeys(rowNum, s.prefix)
   157  		keys = append(keys, kv.Key("noSuchKey"))
   158  		s.checkAll(keys, c)
   159  		s.deleteKeys(keys, c)
   160  	}
   161  }
   162  
   163  func (s *testSnapshotSuite) TestMergeResult(c *C) {
   164  	d1 := makeDict([]string{"1", "2"})
   165  	d2 := makeDict([]string{"a", "foo"})
   166  	d1, err := mergeResult(d1, d2)
   167  	c.Assert(err, IsNil)
   168  	r1 := makeDict([]string{"a", "foo", "1", "2"})
   169  	equalByteDict(c, d1, r1)
   170  }
   171  
   172  func (s *testSnapshotSuite) TestMergeResultNil(c *C) {
   173  	var d1 map[string][]byte
   174  	d2 := makeDict([]string{"a", "foo"})
   175  	d1, err := mergeResult(d1, d2)
   176  	c.Assert(err, IsNil)
   177  	r1 := makeDict([]string{"a", "foo"})
   178  	equalByteDict(c, d1, r1)
   179  
   180  	var d3 map[string][]byte
   181  	var d4 map[string][]byte
   182  	d3, err = mergeResult(d3, d4)
   183  	c.Assert(err, IsNil)
   184  	var r2 map[string][]byte
   185  	equalByteDict(c, d3, r2)
   186  }
   187  
   188  func (s *testSnapshotSuite) TestMergeResultConflict(c *C) {
   189  	d1 := makeDict([]string{"1", "2"})
   190  	d2 := makeDict([]string{"a", "foo", "1"})
   191  	d1, err := mergeResult(d1, d2)
   192  	c.Assert(err, NotNil)
   193  }
   194  
   195  func makeDict(keys []string) map[string][]byte {
   196  	d := make(map[string][]byte)
   197  	for _, k := range keys {
   198  		d[k] = []byte(k)
   199  	}
   200  	return d
   201  }
   202  
   203  func equalByteDict(c *C, lhs, rhs map[string][]byte) {
   204  	c.Assert(lhs, HasLen, len(rhs))
   205  	for k, v1 := range lhs {
   206  		v2, ok := rhs[k]
   207  		c.Assert(ok, IsTrue)
   208  		c.Assert(v1, BytesEquals, v2)
   209  	}
   210  }
   211  
   212  func makeKeys(rowNum int, prefix string) []kv.Key {
   213  	keys := make([]kv.Key, 0, rowNum)
   214  	for i := 0; i < rowNum; i++ {
   215  		k := encodeKey(prefix, s08d("key", i))
   216  		keys = append(keys, k)
   217  	}
   218  	return keys
   219  }