github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/split_trigger_helper_test.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package kvserver
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  	"testing"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    19  	"github.com/cockroachdb/cockroach/pkg/testutils"
    20  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    21  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    22  	"github.com/stretchr/testify/assert"
    23  	"go.etcd.io/etcd/raft/raftpb"
    24  )
    25  
    26  type testMsgAppDropper struct {
    27  	initialized bool
    28  	ticks       int
    29  	lhs         bool
    30  
    31  	startKey string // set by ShouldDrop
    32  }
    33  
    34  func (td *testMsgAppDropper) Args() (initialized bool, ticks int) {
    35  	return td.initialized, td.ticks
    36  }
    37  
    38  func (td *testMsgAppDropper) ShouldDrop(startKey roachpb.RKey) (fmt.Stringer, bool) {
    39  	if len(startKey) == 0 {
    40  		panic("empty startKey")
    41  	}
    42  	td.startKey = string(startKey)
    43  	return &Replica{}, td.lhs
    44  }
    45  
    46  func TestMaybeDropMsgApp(t *testing.T) {
    47  	defer leaktest.AfterTest(t)()
    48  
    49  	testCases := map[testMsgAppDropper]bool{
    50  		// Already load'ed.
    51  		{initialized: true}: false,
    52  		// Left hand side not found.
    53  		{initialized: false}: false,
    54  		// Drop message to wait for trigger.
    55  		{initialized: false, lhs: true}: true,
    56  		// Drop message to wait for trigger.
    57  		{initialized: false, lhs: true, ticks: maxDelaySplitTriggerTicks}: true,
    58  		// Escape hatch fires.
    59  		{initialized: false, lhs: true, ticks: maxDelaySplitTriggerTicks + 1}: false,
    60  	}
    61  
    62  	msgHeartbeat := &raftpb.Message{
    63  		Type: raftpb.MsgHeartbeat,
    64  	}
    65  	msgApp := &raftpb.Message{
    66  		Type: raftpb.MsgApp,
    67  	}
    68  	ctx := context.Background()
    69  	for dropper, exp := range testCases {
    70  		t.Run(fmt.Sprintf("%v", dropper), func(t *testing.T) {
    71  			assert.Equal(t, false, maybeDropMsgApp(ctx, &dropper, msgHeartbeat, nil))
    72  			assert.Equal(t, false, maybeDropMsgApp(ctx, &dropper, msgApp, nil))
    73  			assert.Equal(t, "", dropper.startKey)
    74  			startKey := roachpb.RKey("foo")
    75  			assert.Equal(t, exp, maybeDropMsgApp(ctx, &dropper, msgApp, startKey))
    76  			if exp {
    77  				assert.Equal(t, string(startKey), dropper.startKey)
    78  			}
    79  		})
    80  	}
    81  }
    82  
    83  // TestProtoZeroNilSlice verifies that the proto encoding round-trips empty and
    84  // nil byte slices correctly.
    85  func TestProtoZeroNilSlice(t *testing.T) {
    86  	defer leaktest.AfterTest(t)()
    87  
    88  	testutils.RunTrueAndFalse(t, "isNil", func(t *testing.T, isNil bool) {
    89  		msg := &RaftMessageRequest{}
    90  		if !isNil {
    91  			msg.RangeStartKey = roachpb.RKey("foo")
    92  		}
    93  		b, err := protoutil.Marshal(msg)
    94  		assert.NoError(t, err)
    95  		out := &RaftMessageRequest{}
    96  		assert.NoError(t, protoutil.Unmarshal(b, out))
    97  		assert.Equal(t, isNil, out.RangeStartKey == nil)
    98  	})
    99  }