Skip to content

Commit

Permalink
test: make TestExtractStartTs stable (#24585)
Browse files Browse the repository at this point in the history
  • Loading branch information
longfangsong authored May 13, 2021
1 parent d5a0e6a commit 68d0a25
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 41 deletions.
74 changes: 33 additions & 41 deletions store/tikv/extract_start_ts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
package tikv

import (
"context"

. "github.com/pingcap/check"
"github.com/pingcap/failpoint"
"github.com/pingcap/kvproto/pkg/metapb"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/store/mockstore/unistore"
Expand All @@ -28,7 +27,7 @@ type extractStartTsSuite struct {
store *KVStore
}

var _ = Suite(&extractStartTsSuite{})
var _ = SerialSuites(&extractStartTsSuite{})

func (s *extractStartTsSuite) SetUpTest(c *C) {
client, pdClient, cluster, err := unistore.New("")
Expand Down Expand Up @@ -63,60 +62,53 @@ func (s *extractStartTsSuite) SetUpTest(c *C) {

func (s *extractStartTsSuite) TestExtractStartTs(c *C) {
i := uint64(100)
cases := []kv.TransactionOption{
// to prevent time change during test case execution
// we use failpoint to make it "fixed"
c.Assert(failpoint.Enable("github.com/pingcap/tidb/store/tikv/MockStalenessTimestamp", "return(200)"), IsNil)
c.Assert(failpoint.Enable("github.com/pingcap/tidb/store/tikv/MockCurrentTimestamp", `return(300)`), IsNil)

cases := []struct {
expectedTS uint64
option kv.TransactionOption
}{
// StartTS setted
{TxnScope: oracle.GlobalTxnScope, StartTS: &i, PrevSec: nil, MinStartTS: nil, MaxPrevSec: nil},
{100, kv.TransactionOption{TxnScope: oracle.GlobalTxnScope, StartTS: &i, PrevSec: nil, MinStartTS: nil, MaxPrevSec: nil}},
// PrevSec setted
{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: &i, MinStartTS: nil, MaxPrevSec: nil},
{200, kv.TransactionOption{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: &i, MinStartTS: nil, MaxPrevSec: nil}},
// MinStartTS setted, global
{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: &i, MaxPrevSec: nil},
{101, kv.TransactionOption{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: &i, MaxPrevSec: nil}},
// MinStartTS setted, local
{TxnScope: oracle.LocalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: &i, MaxPrevSec: nil},
{102, kv.TransactionOption{TxnScope: oracle.LocalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: &i, MaxPrevSec: nil}},
// MaxPrevSec setted
// however we need to add more cases to check the behavior when it fall backs to MinStartTS setted
// see `TestMaxPrevSecFallback`
{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: &i},
{200, kv.TransactionOption{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: &i}},
// nothing setted
{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: nil},
}
bo := NewBackofferWithVars(context.Background(), tsoMaxBackoff, nil)
stalenessTimestamp, _ := s.store.getStalenessTimestamp(bo, oracle.GlobalTxnScope, 100)
expectedTs := []uint64{
100,
stalenessTimestamp,

101,
102,

stalenessTimestamp,
// it's too hard to figure out the value `getTimestampWithRetry` returns
// so we just check whether it is greater than stalenessTimestamp
0,
{300, kv.TransactionOption{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: nil}},
}
for i, cs := range cases {
expected := expectedTs[i]
result, _ := extractStartTs(s.store, cs)
if expected == 0 {
c.Assert(result, Greater, stalenessTimestamp)
} else {
c.Assert(result, Equals, expected)
}
for _, cs := range cases {
expected := cs.expectedTS
result, _ := extractStartTs(s.store, cs.option)
c.Assert(result, Equals, expected)
}

c.Assert(failpoint.Disable("github.com/pingcap/tidb/store/tikv/MockStalenessTimestamp"), IsNil)
c.Assert(failpoint.Disable("github.com/pingcap/tidb/store/tikv/MockCurrentTimestamp"), IsNil)
}

func (s *extractStartTsSuite) TestMaxPrevSecFallback(c *C) {
s.store.setSafeTS(2, 0x8000000000000002)
s.store.setSafeTS(3, 0x8000000000000001)

i := uint64(100)
cases := []kv.TransactionOption{
{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: &i},
{TxnScope: oracle.LocalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: &i},
cases := []struct {
expectedTS uint64
option kv.TransactionOption
}{
{0x8000000000000001, kv.TransactionOption{TxnScope: oracle.GlobalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: &i}},
{0x8000000000000002, kv.TransactionOption{TxnScope: oracle.LocalTxnScope, StartTS: nil, PrevSec: nil, MinStartTS: nil, MaxPrevSec: &i}},
}
expectedTs := []uint64{0x8000000000000001, 0x8000000000000002}
for i, cs := range cases {
expected := expectedTs[i]
result, _ := extractStartTs(s.store, cs)
c.Assert(result, Equals, expected)
for _, cs := range cases {
result, _ := extractStartTs(s.store, cs.option)
c.Assert(result, Equals, cs.expectedTS)
}
}
14 changes: 14 additions & 0 deletions store/tikv/kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ func (s *KVStore) CurrentTimestamp(txnScope string) (uint64, error) {
}

func (s *KVStore) getTimestampWithRetry(bo *Backoffer, txnScope string) (uint64, error) {
failpoint.Inject("MockCurrentTimestamp", func(val failpoint.Value) {
if v, ok := val.(int); ok {
failpoint.Return(uint64(v), nil)
} else {
panic("MockCurrentTimestamp should be a number, try use this failpoint with \"return(ts)\"")
}
})
if span := opentracing.SpanFromContext(bo.ctx); span != nil && span.Tracer() != nil {
span1 := span.Tracer().StartSpan("TiKVStore.getTimestampWithRetry", opentracing.ChildOf(span.Context()))
defer span1.Finish()
Expand Down Expand Up @@ -264,6 +271,13 @@ func (s *KVStore) getTimestampWithRetry(bo *Backoffer, txnScope string) (uint64,
}

func (s *KVStore) getStalenessTimestamp(bo *Backoffer, txnScope string, prevSec uint64) (uint64, error) {
failpoint.Inject("MockStalenessTimestamp", func(val failpoint.Value) {
if v, ok := val.(int); ok {
failpoint.Return(uint64(v), nil)
} else {
panic("MockStalenessTimestamp should be a number, try use this failpoint with \"return(ts)\"")
}
})
for {
startTS, err := s.oracle.GetStaleTimestamp(bo.ctx, txnScope, prevSec)
if err == nil {
Expand Down

0 comments on commit 68d0a25

Please sign in to comment.