Skip to content

Commit

Permalink
Merge branch 'master' into wait-leader
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-chi-bot authored Jun 24, 2022
2 parents 95d8400 + 1bcdafe commit 1db9ec4
Show file tree
Hide file tree
Showing 23 changed files with 574 additions and 532 deletions.
28 changes: 14 additions & 14 deletions client/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,41 @@ import (
)

const (
defaultWaitFor = time.Second * 20
defaultSleepInterval = time.Millisecond * 100
defaultWaitFor = time.Second * 20
defaultTickInterval = time.Millisecond * 100
)

// WaitOp represents available options when execute Eventually.
type WaitOp struct {
waitFor time.Duration
sleepInterval time.Duration
waitFor time.Duration
tickInterval time.Duration
}

// WaitOption configures WaitOp
// WaitOption configures WaitOp.
type WaitOption func(op *WaitOp)

// WithSleepInterval specify the sleep duration
func WithSleepInterval(sleep time.Duration) WaitOption {
return func(op *WaitOp) { op.sleepInterval = sleep }
}

// WithWaitFor specify the max wait for duration
// WithWaitFor specify the max wait duration.
func WithWaitFor(waitFor time.Duration) WaitOption {
return func(op *WaitOp) { op.waitFor = waitFor }
}

// WithTickInterval specify the tick interval to check the condition.
func WithTickInterval(tickInterval time.Duration) WaitOption {
return func(op *WaitOp) { op.tickInterval = tickInterval }
}

// Eventually asserts that given condition will be met in a period of time.
func Eventually(re *require.Assertions, condition func() bool, opts ...WaitOption) {
option := &WaitOp{
waitFor: defaultWaitFor,
sleepInterval: defaultSleepInterval,
waitFor: defaultWaitFor,
tickInterval: defaultTickInterval,
}
for _, opt := range opts {
opt(option)
}
re.Eventually(
condition,
option.waitFor,
option.sleepInterval,
option.tickInterval,
)
}
4 changes: 2 additions & 2 deletions pkg/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ func TestExpireRegionCache(t *testing.T) {
re.True(ok)
re.Equal(expV, v2.(string))

cache.PutWithTTL(11, "11", 1*time.Second)
cache.PutWithTTL(11, "11", time.Second)
time.Sleep(5 * time.Second)
k, v, success = cache.pop()
re.False(success)
re.Nil(k)
re.Nil(v)

// Test Get
cache.PutWithTTL(1, 1, 1*time.Second)
cache.PutWithTTL(1, 1, time.Second)
cache.PutWithTTL(2, "v2", 5*time.Second)
cache.PutWithTTL(3, 3.0, 5*time.Second)

Expand Down
58 changes: 13 additions & 45 deletions pkg/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,80 +19,48 @@ import (
"strings"
"time"

"github.com/pingcap/check"
"github.com/pingcap/kvproto/pkg/pdpb"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)

const (
defaultWaitRetryTimes = 200
defaultSleepInterval = time.Millisecond * 100
defaultWaitFor = time.Second * 20
defaultWaitFor = time.Second * 20
defaultTickInterval = time.Millisecond * 100
)

// CheckFunc is a condition checker that passed to WaitUntil. Its implementation
// may call c.Fatal() to abort the test, or c.Log() to add more information.
type CheckFunc func() bool

// WaitOp represents available options when execute WaitUntil
// WaitOp represents available options when execute Eventually.
type WaitOp struct {
retryTimes int
sleepInterval time.Duration
waitFor time.Duration
waitFor time.Duration
tickInterval time.Duration
}

// WaitOption configures WaitOp
// WaitOption configures WaitOp.
type WaitOption func(op *WaitOp)

// WithRetryTimes specify the retry times
func WithRetryTimes(retryTimes int) WaitOption {
return func(op *WaitOp) { op.retryTimes = retryTimes }
}

// WithSleepInterval specify the sleep duration
func WithSleepInterval(sleep time.Duration) WaitOption {
return func(op *WaitOp) { op.sleepInterval = sleep }
}

// WithWaitFor specify the max wait for duration
// WithWaitFor specify the max wait duration.
func WithWaitFor(waitFor time.Duration) WaitOption {
return func(op *WaitOp) { op.waitFor = waitFor }
}

// WaitUntil repeatedly evaluates f() for a period of time, util it returns true.
// NOTICE: this function will be removed soon, please use `Eventually` instead.
func WaitUntil(c *check.C, f CheckFunc, opts ...WaitOption) {
c.Log("wait start")
option := &WaitOp{
retryTimes: defaultWaitRetryTimes,
sleepInterval: defaultSleepInterval,
}
for _, opt := range opts {
opt(option)
}
for i := 0; i < option.retryTimes; i++ {
if f() {
return
}
time.Sleep(option.sleepInterval)
}
c.Fatal("wait timeout")
// WithTickInterval specify the tick interval to check the condition.
func WithTickInterval(tickInterval time.Duration) WaitOption {
return func(op *WaitOp) { op.tickInterval = tickInterval }
}

// Eventually asserts that given condition will be met in a period of time.
func Eventually(re *require.Assertions, condition func() bool, opts ...WaitOption) {
option := &WaitOp{
waitFor: defaultWaitFor,
sleepInterval: defaultSleepInterval,
waitFor: defaultWaitFor,
tickInterval: defaultTickInterval,
}
for _, opt := range opts {
opt(option)
}
re.Eventually(
condition,
option.waitFor,
option.sleepInterval,
option.tickInterval,
)
}

Expand Down
10 changes: 9 additions & 1 deletion pkg/typeutil/comparison.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

package typeutil

import "time"
import (
"math"
"time"
)

// MinUint64 returns the min value between two variables whose type are uint64.
func MinUint64(a, b uint64) uint64 {
Expand Down Expand Up @@ -52,3 +55,8 @@ func StringsEqual(a, b []string) bool {
}
return true
}

// Float64Equal checks if two float64 are equal.
func Float64Equal(a, b float64) bool {
return math.Abs(a-b) <= 1e-6
}
9 changes: 9 additions & 0 deletions pkg/typeutil/comparison_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package typeutil

import (
"math/rand"
"testing"
"time"

Expand Down Expand Up @@ -44,3 +45,11 @@ func TestMinDuration(t *testing.T) {
re.Equal(time.Second, MinDuration(time.Second, time.Minute))
re.Equal(time.Second, MinDuration(time.Second, time.Second))
}

func TestEqualFloat(t *testing.T) {
t.Parallel()
re := require.New(t)
f1 := rand.Float64()
re.True(Float64Equal(f1, f1*1.000))
re.True(Float64Equal(f1, f1/1.000))
}
23 changes: 0 additions & 23 deletions scripts/check-test.sh
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
#!/bin/bash

# TODO: remove this script after migrating all tests to the new test framework.

# Check if there are any packages foget to add `TestingT` when use "github.com/pingcap/check".

res=$(diff <(grep -rl --include=\*_test.go "github.com/pingcap/check" . | xargs -L 1 dirname | sort -u) \
<(grep -rl --include=\*_test.go -E "^\s*(check\.)?TestingT\(" . | xargs -L 1 dirname | sort -u))

if [ "$res" ]; then
echo "following packages may be lost TestingT:"
echo "$res" | awk '{if(NF>1){print $2}}'
exit 1
fi

# Check if there are duplicated `TestingT` in package.

res=$(grep -r --include=\*_test.go "TestingT(t)" . | cut -f1 | xargs -L 1 dirname | sort | uniq -d)

if [ "$res" ]; then
echo "following packages may have duplicated TestingT:"
echo "$res"
exit 1
fi

# Check if there is any inefficient assert function usage in package.

res=$(grep -rn --include=\*_test.go -E "(re|suite|require)\.(True|False)\((t, )?reflect\.DeepEqual\(" . | sort -u) \
Expand Down
34 changes: 17 additions & 17 deletions server/api/label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (suite *strictlyLabelsStoreTestSuite) SetupSuite() {
}

func (suite *strictlyLabelsStoreTestSuite) TestStoreMatch() {
cases := []struct {
testCases := []struct {
store *metapb.Store
valid bool
expectError string
Expand Down Expand Up @@ -276,21 +276,21 @@ func (suite *strictlyLabelsStoreTestSuite) TestStoreMatch() {
},
}

for _, t := range cases {
for _, testCase := range testCases {
_, err := suite.grpcSvr.PutStore(context.Background(), &pdpb.PutStoreRequest{
Header: &pdpb.RequestHeader{ClusterId: suite.svr.ClusterID()},
Store: &metapb.Store{
Id: t.store.Id,
Address: fmt.Sprintf("tikv%d", t.store.Id),
State: t.store.State,
Labels: t.store.Labels,
Version: t.store.Version,
Id: testCase.store.Id,
Address: fmt.Sprintf("tikv%d", testCase.store.Id),
State: testCase.store.State,
Labels: testCase.store.Labels,
Version: testCase.store.Version,
},
})
if t.valid {
if testCase.valid {
suite.NoError(err)
} else {
suite.Contains(err.Error(), t.expectError)
suite.Contains(err.Error(), testCase.expectError)
}
}

Expand All @@ -300,21 +300,21 @@ func (suite *strictlyLabelsStoreTestSuite) TestStoreMatch() {
fmt.Sprintf("%s/config", suite.urlPrefix),
[]byte(`{"enable-placement-rules":"true"}`),
tu.StatusOK(suite.Require())))
for _, t := range cases {
for _, testCase := range testCases {
_, err := suite.grpcSvr.PutStore(context.Background(), &pdpb.PutStoreRequest{
Header: &pdpb.RequestHeader{ClusterId: suite.svr.ClusterID()},
Store: &metapb.Store{
Id: t.store.Id,
Address: fmt.Sprintf("tikv%d", t.store.Id),
State: t.store.State,
Labels: t.store.Labels,
Version: t.store.Version,
Id: testCase.store.Id,
Address: fmt.Sprintf("tikv%d", testCase.store.Id),
State: testCase.store.State,
Labels: testCase.store.Labels,
Version: testCase.store.Version,
},
})
if t.valid {
if testCase.valid {
suite.NoError(err)
} else {
suite.Contains(err.Error(), t.expectError)
suite.Contains(err.Error(), testCase.expectError)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion server/api/tso_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (suite *tsoTestSuite) TestTransferAllocator() {
suite.svr.GetTSOAllocatorManager().ClusterDCLocationChecker()
_, err := suite.svr.GetTSOAllocatorManager().GetAllocator("dc-1")
return err == nil
}, tu.WithRetryTimes(5), tu.WithSleepInterval(3*time.Second))
}, tu.WithWaitFor(15*time.Second), tu.WithTickInterval(3*time.Second))
addr := suite.urlPrefix + "/tso/allocator/transfer/pd1?dcLocation=dc-1"
err := tu.CheckPostJSON(testDialClient, addr, nil, tu.StatusOK(re))
suite.NoError(err)
Expand Down
41 changes: 15 additions & 26 deletions server/schedule/healthy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,20 @@ package schedule

import (
"context"
"testing"

. "github.com/pingcap/check"
"github.com/pingcap/kvproto/pkg/metapb"
"github.com/pingcap/kvproto/pkg/pdpb"
"github.com/stretchr/testify/require"
"github.com/tikv/pd/pkg/mock/mockcluster"
"github.com/tikv/pd/server/config"
"github.com/tikv/pd/server/core"
)

var _ = Suite(&testRegionHealthySuite{})

type testRegionHealthySuite struct {
ctx context.Context
cancel context.CancelFunc
}

func (s *testRegionHealthySuite) SetUpSuite(c *C) {
s.ctx, s.cancel = context.WithCancel(context.Background())
}

func (s *testRegionHealthySuite) TearDownSuite(c *C) {
s.cancel()
}

func (s *testRegionHealthySuite) TestIsRegionHealthy(c *C) {
func TestIsRegionHealthy(t *testing.T) {
re := require.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
peers := func(ids ...uint64) []*metapb.Peer {
var peers []*metapb.Peer
for _, id := range ids {
Expand Down Expand Up @@ -70,7 +59,7 @@ func (s *testRegionHealthySuite) TestIsRegionHealthy(c *C) {
}

// healthy only check down peer and pending peer
cases := []testCase{
testCases := []testCase{
{region(peers(1, 2, 3)), true, true, true, true, true, true},
{region(peers(1, 2, 3), core.WithPendingPeers(peers(1))), false, true, true, false, true, true},
{region(peers(1, 2, 3), core.WithLearners(peers(1))), true, true, false, true, true, false},
Expand All @@ -80,19 +69,19 @@ func (s *testRegionHealthySuite) TestIsRegionHealthy(c *C) {
}

opt := config.NewTestOptions()
tc := mockcluster.NewCluster(s.ctx, opt)
tc := mockcluster.NewCluster(ctx, opt)
tc.AddRegionStore(1, 1)
tc.AddRegionStore(2, 1)
tc.AddRegionStore(3, 1)
tc.AddRegionStore(4, 1)
for _, t := range cases {
for _, testCase := range testCases {
tc.SetEnablePlacementRules(false)
c.Assert(IsRegionHealthy(t.region), Equals, t.healthy1)
c.Assert(IsRegionHealthyAllowPending(t.region), Equals, t.healthyAllowPending1)
c.Assert(IsRegionReplicated(tc, t.region), Equals, t.replicated1)
re.Equal(testCase.healthy1, IsRegionHealthy(testCase.region))
re.Equal(testCase.healthyAllowPending1, IsRegionHealthyAllowPending(testCase.region))
re.Equal(testCase.replicated1, IsRegionReplicated(tc, testCase.region))
tc.SetEnablePlacementRules(true)
c.Assert(IsRegionHealthy(t.region), Equals, t.healthy2)
c.Assert(IsRegionHealthyAllowPending(t.region), Equals, t.healthyAllowPending2)
c.Assert(IsRegionReplicated(tc, t.region), Equals, t.replicated2)
re.Equal(testCase.healthy2, IsRegionHealthy(testCase.region))
re.Equal(testCase.healthyAllowPending2, IsRegionHealthyAllowPending(testCase.region))
re.Equal(testCase.replicated2, IsRegionReplicated(tc, testCase.region))
}
}
Loading

0 comments on commit 1db9ec4

Please sign in to comment.