github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/roachpb/data_test.go (about)

     1  // Copyright 2014 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 roachpb
    12  
    13  import (
    14  	"bytes"
    15  	"math"
    16  	"math/rand"
    17  	"reflect"
    18  	"sort"
    19  	"strconv"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/cockroachdb/apd"
    24  	"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
    25  	"github.com/cockroachdb/cockroach/pkg/testutils/zerofields"
    26  	"github.com/cockroachdb/cockroach/pkg/util"
    27  	"github.com/cockroachdb/cockroach/pkg/util/bitarray"
    28  	"github.com/cockroachdb/cockroach/pkg/util/duration"
    29  	"github.com/cockroachdb/cockroach/pkg/util/encoding"
    30  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    31  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    32  	"github.com/cockroachdb/cockroach/pkg/util/log"
    33  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    34  	"github.com/cockroachdb/cockroach/pkg/util/randutil"
    35  	"github.com/cockroachdb/cockroach/pkg/util/uuid"
    36  	"github.com/kr/pretty"
    37  	"github.com/stretchr/testify/require"
    38  	"go.etcd.io/etcd/raft/raftpb"
    39  )
    40  
    41  func makeTS(walltime int64, logical int32) hlc.Timestamp {
    42  	return hlc.Timestamp{
    43  		WallTime: walltime,
    44  		Logical:  logical,
    45  	}
    46  }
    47  
    48  // TestKeyNext tests that the method for creating lexicographic
    49  // successors to byte slices works as expected.
    50  func TestKeyNext(t *testing.T) {
    51  	a := Key("a")
    52  	aNext := a.Next()
    53  	if a.Equal(aNext) {
    54  		t.Errorf("expected key not equal to next")
    55  	}
    56  	if bytes.Compare(a, aNext) >= 0 {
    57  		t.Errorf("expected next key to be greater")
    58  	}
    59  
    60  	extraCap := make([]byte, 2, 4)
    61  	extraCap[0] = 'x'
    62  	extraCap[1] = 'o'
    63  
    64  	noExtraCap := make([]byte, 2)
    65  	noExtraCap[0] = 'x'
    66  	noExtraCap[1] = 'o'
    67  
    68  	testCases := []struct {
    69  		key           Key
    70  		next          Key
    71  		expReallocate int // 0 for don't test, -1 for not expected, 1 for expected.
    72  	}{
    73  		{nil, Key("\x00"), 0},
    74  		{Key(""), Key("\x00"), 0},
    75  		{Key("test key"), Key("test key\x00"), 0},
    76  		{Key("\xff"), Key("\xff\x00"), 0},
    77  		{Key("xoxo\x00"), Key("xoxo\x00\x00"), 0},
    78  		{Key(extraCap), Key("xo\x00"), -1},
    79  		{Key(noExtraCap), Key("xo\x00"), 1},
    80  	}
    81  	for i, c := range testCases {
    82  		next := c.key.Next()
    83  		if !bytes.Equal(next, c.next) {
    84  			t.Errorf("%d: unexpected next bytes for %q: %q", i, c.key, next)
    85  		}
    86  		if c.expReallocate != 0 {
    87  			if expect, reallocated := c.expReallocate > 0, (&next[0] != &c.key[0]); expect != reallocated {
    88  				t.Errorf("%d: unexpected next reallocation = %t, found reallocation = %t", i, expect, reallocated)
    89  			}
    90  		}
    91  	}
    92  }
    93  
    94  func TestKeyPrefixEnd(t *testing.T) {
    95  	a := Key("a1")
    96  	aNext := a.Next()
    97  	aEnd := a.PrefixEnd()
    98  	if bytes.Compare(a, aEnd) >= 0 {
    99  		t.Errorf("expected end key to be greater")
   100  	}
   101  	if bytes.Compare(aNext, aEnd) >= 0 {
   102  		t.Errorf("expected end key to be greater than next")
   103  	}
   104  
   105  	testCases := []struct {
   106  		key Key
   107  		end Key
   108  	}{
   109  		{Key{}, KeyMax},
   110  		{Key{0}, Key{0x01}},
   111  		{Key{0xff}, Key{0xff}},
   112  		{Key{0xff, 0xff}, Key{0xff, 0xff}},
   113  		{KeyMax, KeyMax},
   114  		{Key{0xff, 0xfe}, Key{0xff, 0xff}},
   115  		{Key{0x00, 0x00}, Key{0x00, 0x01}},
   116  		{Key{0x00, 0xff}, Key{0x01}},
   117  		{Key{0x00, 0xff, 0xff}, Key{0x01}},
   118  	}
   119  	for i, c := range testCases {
   120  		if !bytes.Equal(c.key.PrefixEnd(), c.end) {
   121  			t.Errorf("%d: unexpected prefix end bytes for %q: %q", i, c.key, c.key.PrefixEnd())
   122  		}
   123  	}
   124  }
   125  
   126  func TestKeyEqual(t *testing.T) {
   127  	a1 := Key("a1")
   128  	a2 := Key("a2")
   129  	if !a1.Equal(a1) {
   130  		t.Errorf("expected keys equal")
   131  	}
   132  	if a1.Equal(a2) {
   133  		t.Errorf("expected different keys not equal")
   134  	}
   135  }
   136  
   137  func TestKeyLess(t *testing.T) {
   138  	testCases := []struct {
   139  		a, b Key
   140  		less bool
   141  	}{
   142  		{nil, Key("\x00"), true},
   143  		{Key(""), Key("\x00"), true},
   144  		{Key("a"), Key("b"), true},
   145  		{Key("a\x00"), Key("a"), false},
   146  		{Key("a\x00"), Key("a\x01"), true},
   147  	}
   148  	for i, c := range testCases {
   149  		if (bytes.Compare(c.a, c.b) < 0) != c.less {
   150  			t.Fatalf("%d: unexpected %q < %q: %t", i, c.a, c.b, c.less)
   151  		}
   152  	}
   153  }
   154  
   155  func TestKeyCompare(t *testing.T) {
   156  	testCases := []struct {
   157  		a, b    Key
   158  		compare int
   159  	}{
   160  		{nil, nil, 0},
   161  		{nil, Key("\x00"), -1},
   162  		{Key("\x00"), Key("\x00"), 0},
   163  		{Key(""), Key("\x00"), -1},
   164  		{Key("a"), Key("b"), -1},
   165  		{Key("a\x00"), Key("a"), 1},
   166  		{Key("a\x00"), Key("a\x01"), -1},
   167  	}
   168  	for i, c := range testCases {
   169  		if c.a.Compare(c.b) != c.compare {
   170  			t.Fatalf("%d: unexpected %q.Compare(%q): %d", i, c.a, c.b, c.compare)
   171  		}
   172  	}
   173  }
   174  
   175  // TestNextKey tests that the method for creating successors of a Key
   176  // works as expected.
   177  func TestNextKey(t *testing.T) {
   178  	testCases := []struct {
   179  		key  Key
   180  		next Key
   181  	}{
   182  		{nil, Key("\x00")},
   183  		{Key(""), Key("\x00")},
   184  		{Key("test key"), Key("test key\x00")},
   185  		{Key("\xff\xff"), Key("\xff\xff\x00")},
   186  		{Key("xoxo\x00"), Key("xoxo\x00\x00")},
   187  	}
   188  	for i, c := range testCases {
   189  		if !c.key.Next().Equal(c.next) {
   190  			t.Fatalf("%d: unexpected next key for %q: %s", i, c.key, c.key.Next())
   191  		}
   192  	}
   193  }
   194  
   195  func TestIsPrev(t *testing.T) {
   196  	for i, tc := range []struct {
   197  		k, m Key
   198  		ok   bool
   199  	}{
   200  		{k: Key(""), m: Key{0}, ok: true},
   201  		{k: nil, m: nil, ok: false},
   202  		{k: Key("a"), m: Key{'a', 0, 0}, ok: false},
   203  		{k: Key{'z', 'a', 0}, m: Key{'z', 'a'}, ok: false},
   204  		{k: Key("bro"), m: Key{'b', 'r', 'o', 0}, ok: true},
   205  		{k: Key("foo"), m: Key{'b', 'a', 'r', 0}, ok: false},
   206  	} {
   207  		if tc.ok != tc.k.IsPrev(tc.m) {
   208  			t.Errorf("%d: wanted %t", i, tc.ok)
   209  		}
   210  	}
   211  }
   212  
   213  func TestValueDataEquals(t *testing.T) {
   214  	strVal := func(s string) *Value {
   215  		var v Value
   216  		v.SetString(s)
   217  		return &v
   218  	}
   219  
   220  	a := strVal("val1")
   221  
   222  	b := strVal("val1")
   223  	b.InitChecksum([]byte("key1"))
   224  
   225  	c := strVal("val1")
   226  	c.InitChecksum([]byte("key2"))
   227  
   228  	// Different values.
   229  	d := strVal("val2")
   230  
   231  	e := strVal("val2")
   232  	e.InitChecksum([]byte("key1"))
   233  
   234  	// Different tags.
   235  	f := strVal("val1")
   236  	f.setTag(ValueType_INT)
   237  
   238  	g := strVal("val1")
   239  	g.setTag(ValueType_INT)
   240  	g.InitChecksum([]byte("key1"))
   241  
   242  	for i, tc := range []struct {
   243  		v1, v2 *Value
   244  		eq     bool
   245  	}{
   246  		{v1: a, v2: b, eq: true},
   247  		{v1: a, v2: c, eq: true},
   248  		{v1: a, v2: d, eq: false},
   249  		{v1: a, v2: e, eq: false},
   250  		{v1: a, v2: f, eq: false},
   251  		{v1: a, v2: g, eq: false},
   252  		{v1: b, v2: c, eq: true},
   253  		{v1: b, v2: d, eq: false},
   254  		{v1: b, v2: e, eq: false},
   255  		{v1: b, v2: f, eq: false},
   256  		{v1: b, v2: g, eq: false},
   257  		{v1: c, v2: d, eq: false},
   258  		{v1: c, v2: e, eq: false},
   259  		{v1: c, v2: f, eq: false},
   260  		{v1: c, v2: g, eq: false},
   261  		{v1: d, v2: e, eq: true},
   262  		{v1: d, v2: f, eq: false},
   263  		{v1: d, v2: g, eq: false},
   264  		{v1: e, v2: f, eq: false},
   265  		{v1: e, v2: g, eq: false},
   266  		{v1: f, v2: g, eq: true},
   267  	} {
   268  		if tc.eq != tc.v1.EqualData(*tc.v2) {
   269  			t.Errorf("%d: wanted eq=%t", i, tc.eq)
   270  		}
   271  		// Test symmetry.
   272  		if tc.eq != tc.v2.EqualData(*tc.v1) {
   273  			t.Errorf("%d: wanted eq=%t", i, tc.eq)
   274  		}
   275  	}
   276  }
   277  
   278  func TestValueChecksumEmpty(t *testing.T) {
   279  	k := []byte("key")
   280  	v := Value{}
   281  	// Before initializing checksum, always works.
   282  	if err := v.Verify(k); err != nil {
   283  		t.Error(err)
   284  	}
   285  	if err := v.Verify([]byte("key2")); err != nil {
   286  		t.Error(err)
   287  	}
   288  	v.InitChecksum(k)
   289  	if err := v.Verify(k); err != nil {
   290  		t.Error(err)
   291  	}
   292  }
   293  
   294  func TestValueChecksumWithBytes(t *testing.T) {
   295  	k := []byte("key")
   296  	v := MakeValueFromString("abc")
   297  	v.InitChecksum(k)
   298  	if err := v.Verify(k); err != nil {
   299  		t.Error(err)
   300  	}
   301  	// Try a different key; should fail.
   302  	if err := v.Verify([]byte("key2")); err == nil {
   303  		t.Error("expected checksum verification failure on different key")
   304  	}
   305  	// Mess with the value. In order to corrupt the data for testing purposes we
   306  	// have to ensure we overwrite the data without touching the checksum.
   307  	copy(v.RawBytes[headerSize:], "cba")
   308  	if err := v.Verify(k); err == nil {
   309  		t.Error("expected checksum verification failure on different value")
   310  	}
   311  	// Test ClearChecksum and reinitialization of checksum.
   312  	v.ClearChecksum()
   313  	v.InitChecksum(k)
   314  	if err := v.Verify(k); err != nil {
   315  		t.Error(err)
   316  	}
   317  }
   318  
   319  func TestSetGetChecked(t *testing.T) {
   320  	v := Value{}
   321  
   322  	v.SetBytes(nil)
   323  	if _, err := v.GetBytes(); err != nil {
   324  		t.Fatal(err)
   325  	}
   326  
   327  	f := 1.1
   328  	v.SetFloat(f)
   329  	if r, err := v.GetFloat(); err != nil {
   330  		t.Fatal(err)
   331  	} else if f != r {
   332  		t.Errorf("set %f on a value and extracted it, expected %f back, but got %f", f, f, r)
   333  	}
   334  
   335  	b := true
   336  	v.SetBool(b)
   337  	if r, err := v.GetBool(); err != nil {
   338  		t.Fatal(err)
   339  	} else if b != r {
   340  		t.Errorf("set %t on a value and extracted it, expected %t back, but got %t", b, b, r)
   341  	}
   342  
   343  	i := int64(1)
   344  	v.SetInt(i)
   345  	if r, err := v.GetInt(); err != nil {
   346  		t.Fatal(err)
   347  	} else if i != r {
   348  		t.Errorf("set %d on a value and extracted it, expected %d back, but got %d", i, i, r)
   349  	}
   350  
   351  	dec := apd.New(11, -1)
   352  	if err := v.SetDecimal(dec); err != nil {
   353  		t.Fatal(err)
   354  	}
   355  	if r, err := v.GetDecimal(); err != nil {
   356  		t.Fatal(err)
   357  	} else if dec.Cmp(&r) != 0 {
   358  		t.Errorf("set %s on a value and extracted it, expected %s back, but got %s", dec, dec, &r)
   359  	}
   360  
   361  	if err := v.SetProto(&Value{}); err != nil {
   362  		t.Fatal(err)
   363  	}
   364  	if err := v.GetProto(&Value{}); err != nil {
   365  		t.Fatal(err)
   366  	}
   367  	if _, err := v.GetBytes(); err != nil {
   368  		t.Fatal(err)
   369  	}
   370  
   371  	if err := v.SetProto(&InternalTimeSeriesData{}); err != nil {
   372  		t.Fatal(err)
   373  	}
   374  	if _, err := v.GetTimeseries(); err != nil {
   375  		t.Fatal(err)
   376  	}
   377  
   378  	ti := time.Time{}
   379  	v.SetTime(ti)
   380  	if r, err := v.GetTime(); err != nil {
   381  		t.Fatal(err)
   382  	} else if !ti.Equal(r) {
   383  		t.Errorf("set %s on a value and extracted it, expected %s back, but got %s", ti, ti, r)
   384  	}
   385  }
   386  
   387  func TestTransactionBumpEpoch(t *testing.T) {
   388  	origNow := makeTS(10, 1)
   389  	txn := MakeTransaction("test", Key("a"), 1, origNow, 0)
   390  	// Advance the txn timestamp.
   391  	txn.WriteTimestamp = txn.WriteTimestamp.Add(10, 2)
   392  	txn.BumpEpoch()
   393  	if a, e := txn.Epoch, enginepb.TxnEpoch(1); a != e {
   394  		t.Errorf("expected epoch %d; got %d", e, a)
   395  	}
   396  }
   397  
   398  // TestTransactionObservedTimestamp verifies that txn.{Get,Update}ObservedTimestamp work as
   399  // advertised.
   400  func TestTransactionObservedTimestamp(t *testing.T) {
   401  	var txn Transaction
   402  	rng, seed := randutil.NewPseudoRand()
   403  	t.Logf("running with seed %d", seed)
   404  	ids := append([]int{109, 104, 102, 108, 1000}, rand.Perm(100)...)
   405  	timestamps := make(map[NodeID]hlc.Timestamp, len(ids))
   406  	for i := 0; i < len(ids); i++ {
   407  		timestamps[NodeID(i)] = hlc.Timestamp{WallTime: rng.Int63()}
   408  	}
   409  	for i, n := range ids {
   410  		nodeID := NodeID(n)
   411  		if ts, ok := txn.GetObservedTimestamp(nodeID); ok {
   412  			t.Fatalf("%d: false positive hit %s in %v", nodeID, ts, ids[:i+1])
   413  		}
   414  		txn.UpdateObservedTimestamp(nodeID, timestamps[nodeID])
   415  		txn.UpdateObservedTimestamp(nodeID, hlc.MaxTimestamp) // should be noop
   416  		if exp, act := i+1, len(txn.ObservedTimestamps); act != exp {
   417  			t.Fatalf("%d: expected %d entries, got %d: %v", nodeID, exp, act, txn.ObservedTimestamps)
   418  		}
   419  	}
   420  	for _, m := range ids {
   421  		checkID := NodeID(m)
   422  		expTS := timestamps[checkID]
   423  		if actTS, _ := txn.GetObservedTimestamp(checkID); actTS != expTS {
   424  			t.Fatalf("%d: expected %s, got %s", checkID, expTS, actTS)
   425  		}
   426  	}
   427  
   428  	var emptyTxn Transaction
   429  	ts := hlc.Timestamp{WallTime: 1, Logical: 2}
   430  	emptyTxn.UpdateObservedTimestamp(NodeID(1), ts)
   431  	if actTS, _ := emptyTxn.GetObservedTimestamp(NodeID(1)); actTS != ts {
   432  		t.Fatalf("unexpected: %s (wanted %s)", actTS, ts)
   433  	}
   434  }
   435  
   436  func TestFastPathObservedTimestamp(t *testing.T) {
   437  	var txn Transaction
   438  	nodeID := NodeID(1)
   439  	if _, ok := txn.GetObservedTimestamp(nodeID); ok {
   440  		t.Errorf("fetched observed timestamp where none should exist")
   441  	}
   442  	expTS := hlc.Timestamp{WallTime: 10}
   443  	txn.UpdateObservedTimestamp(nodeID, expTS)
   444  	if ts, ok := txn.GetObservedTimestamp(nodeID); !ok || !ts.Equal(expTS) {
   445  		t.Errorf("expected %s; got %s", expTS, ts)
   446  	}
   447  	expTS = hlc.Timestamp{WallTime: 9}
   448  	txn.UpdateObservedTimestamp(nodeID, expTS)
   449  	if ts, ok := txn.GetObservedTimestamp(nodeID); !ok || !ts.Equal(expTS) {
   450  		t.Errorf("expected %s; got %s", expTS, ts)
   451  	}
   452  }
   453  
   454  var nonZeroTxn = Transaction{
   455  	TxnMeta: enginepb.TxnMeta{
   456  		Key:            Key("foo"),
   457  		ID:             uuid.MakeV4(),
   458  		Epoch:          2,
   459  		WriteTimestamp: makeTS(20, 21),
   460  		MinTimestamp:   makeTS(10, 11),
   461  		Priority:       957356782,
   462  		Sequence:       123,
   463  	},
   464  	Name:                    "name",
   465  	Status:                  COMMITTED,
   466  	LastHeartbeat:           makeTS(1, 2),
   467  	DeprecatedOrigTimestamp: makeTS(30, 31),
   468  	ReadTimestamp:           makeTS(20, 22),
   469  	MaxTimestamp:            makeTS(40, 41),
   470  	ObservedTimestamps:      []ObservedTimestamp{{NodeID: 1, Timestamp: makeTS(1, 2)}},
   471  	WriteTooOld:             true,
   472  	LockSpans:               []Span{{Key: []byte("a"), EndKey: []byte("b")}},
   473  	InFlightWrites:          []SequencedWrite{{Key: []byte("c"), Sequence: 1}},
   474  	CommitTimestampFixed:    true,
   475  	IgnoredSeqNums:          []enginepb.IgnoredSeqNumRange{{Start: 888, End: 999}},
   476  }
   477  
   478  func TestTransactionUpdate(t *testing.T) {
   479  	txn := nonZeroTxn
   480  	if err := zerofields.NoZeroField(txn); err != nil {
   481  		t.Fatal(err)
   482  	}
   483  
   484  	// Updating an empty Transaction copies all fields.
   485  	var txn2 Transaction
   486  	txn2.Update(&txn)
   487  
   488  	expTxn2 := txn
   489  	require.Equal(t, expTxn2, txn2)
   490  
   491  	// Updating a Transaction at an earlier epoch replaces all epoch-scoped fields.
   492  	var txn3 Transaction
   493  	txn3.ID = txn.ID
   494  	txn3.Epoch = txn.Epoch - 1
   495  	txn3.Status = STAGING
   496  	txn3.Name = "carl"
   497  	txn3.Priority = 123
   498  	txn3.Update(&txn)
   499  
   500  	expTxn3 := txn
   501  	expTxn3.Name = "carl"
   502  	require.Equal(t, expTxn3, txn3)
   503  
   504  	// Updating a Transaction at the same epoch forwards all epoch-scoped fields.
   505  	var txn4 Transaction
   506  	txn4.ID = txn.ID
   507  	txn4.Epoch = txn.Epoch
   508  	txn4.Status = STAGING
   509  	txn4.Sequence = txn.Sequence + 10
   510  	txn4.Name = "carl"
   511  	txn4.Priority = 123
   512  	txn4.Update(&txn)
   513  
   514  	expTxn4 := txn
   515  	expTxn4.Name = "carl"
   516  	expTxn4.Sequence = txn.Sequence + 10
   517  	require.Equal(t, expTxn4, txn4)
   518  
   519  	// Test the updates to the WriteTooOld field. The WriteTooOld field is
   520  	// supposed to be dictated by the transaction with the higher ReadTimestamp,
   521  	// or it's cumulative when the ReadTimestamps are equal.
   522  	{
   523  		txn2 := txn
   524  		txn2.ReadTimestamp = txn2.ReadTimestamp.Add(-1, 0)
   525  		txn2.WriteTooOld = false
   526  		txn2.Update(&txn)
   527  		require.True(t, txn2.WriteTooOld)
   528  	}
   529  	{
   530  		txn2 := txn
   531  		txn2.WriteTooOld = false
   532  		txn2.Update(&txn)
   533  		require.True(t, txn2.WriteTooOld)
   534  	}
   535  	{
   536  		txn2 := txn
   537  		txn2.ReadTimestamp = txn2.ReadTimestamp.Add(1, 0)
   538  		txn2.WriteTooOld = false
   539  		txn2.Update(&txn)
   540  		require.False(t, txn2.WriteTooOld)
   541  	}
   542  
   543  	// Updating a Transaction at a future epoch ignores all epoch-scoped fields.
   544  	var txn5 Transaction
   545  	txn5.ID = txn.ID
   546  	txn5.Epoch = txn.Epoch + 1
   547  	txn5.Status = PENDING
   548  	txn5.Sequence = txn.Sequence - 10
   549  	txn5.Name = "carl"
   550  	txn5.Priority = 123
   551  	txn5.Update(&txn)
   552  
   553  	expTxn5 := txn
   554  	expTxn5.Name = "carl"
   555  	expTxn5.Epoch = txn.Epoch + 1
   556  	expTxn5.Status = PENDING
   557  	expTxn5.Sequence = txn.Sequence - 10
   558  	expTxn5.LockSpans = nil
   559  	expTxn5.InFlightWrites = nil
   560  	expTxn5.IgnoredSeqNums = nil
   561  	expTxn5.WriteTooOld = false
   562  	expTxn5.CommitTimestampFixed = false
   563  	require.Equal(t, expTxn5, txn5)
   564  
   565  	// Updating a different transaction fatals.
   566  	var exited bool
   567  	log.SetExitFunc(true /* hideStack */, func(int) { exited = true })
   568  	defer log.ResetExitFunc()
   569  
   570  	var txn6 Transaction
   571  	txn6.ID = uuid.MakeV4()
   572  	origTxn6 := txn6
   573  	txn6.Update(&txn)
   574  
   575  	require.Equal(t, origTxn6, txn6)
   576  	require.True(t, exited)
   577  }
   578  
   579  func TestTransactionUpdateMinTimestamp(t *testing.T) {
   580  	txn := nonZeroTxn
   581  	var txn2 Transaction
   582  	txn2.Update(&txn)
   583  
   584  	if a, e := txn2.MinTimestamp, txn.MinTimestamp; a != e {
   585  		t.Errorf("expected min timestamp %s; got %s", e, a)
   586  	}
   587  
   588  	txn3 := nonZeroTxn
   589  	txn3.MinTimestamp = nonZeroTxn.MinTimestamp.Prev()
   590  	txn.Update(&txn3)
   591  
   592  	if a, e := txn.MinTimestamp, txn3.MinTimestamp; a != e {
   593  		t.Errorf("expected min timestamp %s; got %s", e, a)
   594  	}
   595  }
   596  
   597  func TestTransactionUpdateStaging(t *testing.T) {
   598  	txn := nonZeroTxn
   599  	txn.Status = PENDING
   600  
   601  	txn2 := nonZeroTxn
   602  	txn2.Status = STAGING
   603  
   604  	// In same epoch, PENDING < STAGING.
   605  	txn.Update(&txn2)
   606  	if a, e := txn.Status, STAGING; a != e {
   607  		t.Errorf("expected status %s; got %s", e, a)
   608  	}
   609  
   610  	txn2.Status = PENDING
   611  	txn.Update(&txn2)
   612  	if a, e := txn.Status, STAGING; a != e {
   613  		t.Errorf("expected status %s; got %s", e, a)
   614  	}
   615  
   616  	// In later epoch, PENDING > STAGING.
   617  	txn2.Epoch++
   618  	txn.Update(&txn2)
   619  	if a, e := txn.Status, PENDING; a != e {
   620  		t.Errorf("expected status %s; got %s", e, a)
   621  	}
   622  
   623  	txn2.Status = STAGING
   624  	txn.Update(&txn2)
   625  	if a, e := txn.Status, STAGING; a != e {
   626  		t.Errorf("expected status %s; got %s", e, a)
   627  	}
   628  
   629  	txn2.Status = COMMITTED
   630  	txn.Update(&txn2)
   631  	if a, e := txn.Status, COMMITTED; a != e {
   632  		t.Errorf("expected status %s; got %s", e, a)
   633  	}
   634  }
   635  
   636  // TestTransactionUpdateAbortedOldEpoch tests that Transaction.Update propagates
   637  // an ABORTED status even when that status comes from a proto with an old epoch.
   638  // Once a transaction is ABORTED, it will stay aborted, even if its coordinator
   639  // doesn't know this at the time that it increments its epoch and retries.
   640  func TestTransactionUpdateAbortedOldEpoch(t *testing.T) {
   641  	txn := nonZeroTxn
   642  	txn.Status = ABORTED
   643  
   644  	txnRestart := txn
   645  	txnRestart.Epoch++
   646  	txnRestart.Status = PENDING
   647  	txnRestart.Update(&txn)
   648  
   649  	expTxn := txn
   650  	expTxn.Epoch++
   651  	expTxn.Status = ABORTED
   652  	require.Equal(t, expTxn, txnRestart)
   653  }
   654  
   655  func TestTransactionClone(t *testing.T) {
   656  	txnPtr := nonZeroTxn.Clone()
   657  	txn := *txnPtr
   658  
   659  	fields := util.EqualPtrFields(reflect.ValueOf(nonZeroTxn), reflect.ValueOf(txn), "")
   660  	sort.Strings(fields)
   661  
   662  	// Verify that the only equal pointer fields after cloning are the ones
   663  	// listed below. If this test fails, please update the list below and/or
   664  	// Transaction.Clone().
   665  	expFields := []string{
   666  		"IgnoredSeqNums",
   667  		"InFlightWrites",
   668  		"InFlightWrites.Key",
   669  		"LockSpans",
   670  		"LockSpans.EndKey",
   671  		"LockSpans.Key",
   672  		"ObservedTimestamps",
   673  		"TxnMeta.Key",
   674  	}
   675  	if !reflect.DeepEqual(expFields, fields) {
   676  		t.Fatalf("%s != %s", expFields, fields)
   677  	}
   678  	if !reflect.DeepEqual(nonZeroTxn, txn) {
   679  		t.Fatalf("e = %v, v = %v", nonZeroTxn, txn)
   680  	}
   681  }
   682  
   683  func TestTransactionRestart(t *testing.T) {
   684  	txn := nonZeroTxn
   685  	txn.Restart(1, 1, makeTS(25, 1))
   686  
   687  	expTxn := nonZeroTxn
   688  	expTxn.Epoch++
   689  	expTxn.Sequence = 0
   690  	expTxn.WriteTimestamp = makeTS(25, 1)
   691  	expTxn.ReadTimestamp = makeTS(25, 1)
   692  	expTxn.DeprecatedOrigTimestamp = expTxn.ReadTimestamp
   693  	expTxn.WriteTooOld = false
   694  	expTxn.CommitTimestampFixed = false
   695  	expTxn.LockSpans = nil
   696  	expTxn.InFlightWrites = nil
   697  	expTxn.IgnoredSeqNums = nil
   698  	require.Equal(t, expTxn, txn)
   699  }
   700  
   701  // TestTransactionRecordRoundtrips tests a few properties about Transaction
   702  // and TransactionRecord protos. Remember that the latter is wire compatible
   703  // with the former and contains a subset of its protos.
   704  //
   705  // Assertions:
   706  // 1. Transaction->TransactionRecord->Transaction is lossless for the fields
   707  //    in TransactionRecord. It drops all other fields.
   708  // 2. TransactionRecord->Transaction->TransactionRecord is lossless.
   709  //    Fields not in TransactionRecord are set as zero values.
   710  // 3. Transaction messages can be decoded as TransactionRecord messages.
   711  //    Fields not in TransactionRecord are dropped.
   712  // 4. TransactionRecord messages can be decoded as Transaction messages.
   713  //    Fields not in TransactionRecord are decoded as zero values.
   714  func TestTransactionRecordRoundtrips(t *testing.T) {
   715  	// Verify that converting from a Transaction to a TransactionRecord
   716  	// strips out fields but is lossless for the desired fields.
   717  	txn := nonZeroTxn
   718  	txnRecord := txn.AsRecord()
   719  	if err := zerofields.NoZeroField(txnRecord); err != nil {
   720  		t.Error(err)
   721  	}
   722  	if !reflect.DeepEqual(txnRecord.TxnMeta, txn.TxnMeta) {
   723  		t.Errorf("txnRecord.TxnMeta = %v, txn.TxnMeta = %v", txnRecord.TxnMeta, txn.TxnMeta)
   724  	}
   725  	if !reflect.DeepEqual(txnRecord.Status, txn.Status) {
   726  		t.Errorf("txnRecord.Status = %v, txn.Status = %v", txnRecord.Status, txn.Status)
   727  	}
   728  	if !reflect.DeepEqual(txnRecord.LastHeartbeat, txn.LastHeartbeat) {
   729  		t.Errorf("txnRecord.LastHeartbeat = %v, txn.LastHeartbeat = %v", txnRecord.LastHeartbeat, txn.LastHeartbeat)
   730  	}
   731  	if !reflect.DeepEqual(txnRecord.LockSpans, txn.LockSpans) {
   732  		t.Errorf("txnRecord.LockSpans = %v, txn.LockSpans = %v", txnRecord.LockSpans, txn.LockSpans)
   733  	}
   734  	if !reflect.DeepEqual(txnRecord.InFlightWrites, txn.InFlightWrites) {
   735  		t.Errorf("txnRecord.InFlightWrites = %v, txn.InFlightWrites = %v", txnRecord.InFlightWrites, txn.InFlightWrites)
   736  	}
   737  	if !reflect.DeepEqual(txnRecord.IgnoredSeqNums, txn.IgnoredSeqNums) {
   738  		t.Errorf("txnRecord.IgnoredSeqNums = %v, txn.IgnoredSeqNums = %v", txnRecord.IgnoredSeqNums, txn.IgnoredSeqNums)
   739  	}
   740  
   741  	// Verify that converting through a Transaction message and back
   742  	// to a TransactionRecord is a lossless round trip.
   743  	txn2 := txnRecord.AsTransaction()
   744  	txnRecord2 := txn2.AsRecord()
   745  	if !reflect.DeepEqual(txnRecord, txnRecord2) {
   746  		t.Errorf("txnRecord = %v, txnRecord2 = %v", txnRecord, txnRecord2)
   747  	}
   748  
   749  	// Verify that encoded Transaction messages can be decoded as
   750  	// TransactionRecord messages.
   751  	txnBytes, err := protoutil.Marshal(&txn)
   752  	if err != nil {
   753  		t.Fatal(err)
   754  	}
   755  	var txnRecord3 TransactionRecord
   756  	if err := protoutil.Unmarshal(txnBytes, &txnRecord3); err != nil {
   757  		t.Fatal(err)
   758  	}
   759  	if !reflect.DeepEqual(txnRecord, txnRecord3) {
   760  		t.Errorf("txnRecord = %v, txnRecord3 = %v", txnRecord, txnRecord3)
   761  	}
   762  
   763  	// Verify that encoded TransactionRecord messages can be decoded
   764  	// as Transaction messages.
   765  	txnRecordBytes, err := protoutil.Marshal(&txnRecord)
   766  	if err != nil {
   767  		t.Fatal(err)
   768  	}
   769  	var txn3 Transaction
   770  	if err := protoutil.Unmarshal(txnRecordBytes, &txn3); err != nil {
   771  		t.Fatal(err)
   772  	}
   773  	if !reflect.DeepEqual(txn2, txn3) {
   774  		t.Errorf("txn2 = %v, txn3 = %v", txn2, txn3)
   775  	}
   776  }
   777  
   778  // checkVal verifies if a value is close to an expected value, within a fraction (e.g. if
   779  // fraction=0.1, it checks if val is within 10% of expected).
   780  func checkVal(val, expected, errFraction float64) bool {
   781  	return val > expected*(1-errFraction) && val < expected*(1+errFraction)
   782  }
   783  
   784  // TestMakePriority verifies that setting user priority of P results
   785  // in MakePriority returning priorities that are P times more likely
   786  // to be higher than a priority with user priority = 1.
   787  func TestMakePriority(t *testing.T) {
   788  	// Verify min & max.
   789  	if a, e := MakePriority(MinUserPriority), enginepb.MinTxnPriority; a != e {
   790  		t.Errorf("expected min txn priority %d; got %d", e, a)
   791  	}
   792  	if a, e := MakePriority(MaxUserPriority), enginepb.MaxTxnPriority; a != e {
   793  		t.Errorf("expected max txn priority %d; got %d", e, a)
   794  	}
   795  
   796  	userPs := []UserPriority{
   797  		0.0011,
   798  		0.01,
   799  		0.1,
   800  		0.5,
   801  		0, // Same as 1.0 (special cased below)
   802  		1.0,
   803  		2.0,
   804  		10.0,
   805  		100.0,
   806  		999.0,
   807  	}
   808  
   809  	// Generate values for all priorities.
   810  	const trials = 100000
   811  	values := make([][trials]enginepb.TxnPriority, len(userPs))
   812  	for i, userPri := range userPs {
   813  		for tr := 0; tr < trials; tr++ {
   814  			p := MakePriority(userPri)
   815  			if p == enginepb.MinTxnPriority {
   816  				t.Fatalf("unexpected min txn priority")
   817  			}
   818  			if p == enginepb.MaxTxnPriority {
   819  				t.Fatalf("unexpected max txn priority")
   820  			}
   821  			values[i][tr] = p
   822  		}
   823  	}
   824  
   825  	// Check win-vs-loss ratios for all pairs
   826  	for i, p1 := range userPs {
   827  		for j, p2 := range userPs {
   828  			if i >= j {
   829  				continue
   830  			}
   831  
   832  			// Special case to verify that specifying 0 has same effect as specifying 1.
   833  			if p1 == 0 {
   834  				p1 = 1
   835  			}
   836  			if p2 == 0 {
   837  				p2 = 1
   838  			}
   839  			priRatio := float64(p1 / p2)
   840  
   841  			// Don't verify extreme ratios (we don't have enough resolution or trials)
   842  			if math.Max(priRatio, 1/priRatio) >= 1000 {
   843  				continue
   844  			}
   845  			wins := 0
   846  			for t := 0; t < trials; t++ {
   847  				if values[i][t] > values[j][t] {
   848  					wins++
   849  				}
   850  			}
   851  
   852  			winRatio := float64(wins) / float64(trials-wins)
   853  
   854  			t.Logf("%f vs %f: %d wins, %d losses (winRatio=%f, priRatio=%f)",
   855  				p1, p2, wins, trials-wins, winRatio, priRatio)
   856  			if !checkVal(winRatio, priRatio, 0.2) {
   857  				t.Errorf("Error (%f vs %f: %d wins, %d losses): winRatio=%f not "+
   858  					"close to priRatio=%f", p1, p2, wins, trials-wins, winRatio, priRatio)
   859  			}
   860  		}
   861  	}
   862  }
   863  
   864  // TestMakePriorityExplicit verifies that setting priority to a negative
   865  // value sets it exactly.
   866  func TestMakePriorityExplicit(t *testing.T) {
   867  	explicitPs := []struct {
   868  		userPri UserPriority
   869  		expPri  enginepb.TxnPriority
   870  	}{
   871  		{-math.MaxInt32, math.MaxInt32},
   872  		{-math.MaxInt32 + 1, math.MaxInt32 - 1},
   873  		{-2, 2},
   874  		{-1, 1},
   875  	}
   876  	for i, p := range explicitPs {
   877  		if pri := MakePriority(p.userPri); pri != p.expPri {
   878  			t.Errorf("%d: explicit priority %d doesn't match expected %d", i, pri, p.expPri)
   879  		}
   880  	}
   881  }
   882  
   883  // TestMakePriorityLimits verifies that min & max priorities are
   884  // enforced and yield txn priority limits.
   885  func TestMakePriorityLimits(t *testing.T) {
   886  	userPs := []UserPriority{
   887  		0.000000001,
   888  		0.00001,
   889  		0.00009,
   890  		10001,
   891  		100000,
   892  		math.MaxFloat64,
   893  	}
   894  	for _, userPri := range userPs {
   895  		expected := enginepb.MinTxnPriority
   896  		if userPri > 1 {
   897  			expected = enginepb.MaxTxnPriority
   898  		}
   899  		if actual := MakePriority(userPri); actual != expected {
   900  			t.Errorf("%f: expected txn priority %d; got %d", userPri, expected, actual)
   901  		}
   902  	}
   903  }
   904  
   905  func TestLeaseEquivalence(t *testing.T) {
   906  	r1 := ReplicaDescriptor{NodeID: 1, StoreID: 1, ReplicaID: 1}
   907  	r2 := ReplicaDescriptor{NodeID: 2, StoreID: 2, ReplicaID: 2}
   908  	ts1 := makeTS(1, 1)
   909  	ts2 := makeTS(2, 1)
   910  	ts3 := makeTS(3, 1)
   911  
   912  	epoch1 := Lease{Replica: r1, Start: ts1, Epoch: 1}
   913  	epoch2 := Lease{Replica: r1, Start: ts1, Epoch: 2}
   914  	expire1 := Lease{Replica: r1, Start: ts1, Expiration: ts2.Clone()}
   915  	expire2 := Lease{Replica: r1, Start: ts1, Expiration: ts3.Clone()}
   916  	epoch2TS2 := Lease{Replica: r2, Start: ts2, Epoch: 2}
   917  	expire2TS2 := Lease{Replica: r2, Start: ts2, Expiration: ts3.Clone()}
   918  
   919  	proposed1 := Lease{Replica: r1, Start: ts1, Epoch: 1, ProposedTS: ts1.Clone()}
   920  	proposed2 := Lease{Replica: r1, Start: ts1, Epoch: 2, ProposedTS: ts1.Clone()}
   921  	proposed3 := Lease{Replica: r1, Start: ts1, Epoch: 1, ProposedTS: ts2.Clone()}
   922  
   923  	stasis1 := Lease{Replica: r1, Start: ts1, Epoch: 1, DeprecatedStartStasis: ts1.Clone()}
   924  	stasis2 := Lease{Replica: r1, Start: ts1, Epoch: 1, DeprecatedStartStasis: ts2.Clone()}
   925  
   926  	r1Voter, r1Learner := r1, r1
   927  	r1Voter.Type = ReplicaTypeVoterFull()
   928  	r1Learner.Type = ReplicaTypeLearner()
   929  	epoch1Voter := Lease{Replica: r1Voter, Start: ts1, Epoch: 1}
   930  	epoch1Learner := Lease{Replica: r1Learner, Start: ts1, Epoch: 1}
   931  
   932  	testCases := []struct {
   933  		l, ol      Lease
   934  		expSuccess bool
   935  	}{
   936  		{epoch1, epoch1, true},             // same epoch lease
   937  		{expire1, expire1, true},           // same expiration lease
   938  		{epoch1, epoch2, false},            // different epoch leases
   939  		{epoch1, epoch2TS2, false},         // different epoch leases
   940  		{expire1, expire2TS2, false},       // different expiration leases
   941  		{expire1, expire2, true},           // same expiration lease, extended
   942  		{expire2, expire1, false},          // same expiration lease, extended but backwards
   943  		{epoch1, expire1, false},           // epoch and expiration leases
   944  		{expire1, epoch1, false},           // expiration and epoch leases
   945  		{proposed1, proposed1, true},       // exact leases with identical timestamps
   946  		{proposed1, proposed2, false},      // same proposed timestamps, but diff epochs
   947  		{proposed1, proposed3, true},       // different proposed timestamps, same lease
   948  		{stasis1, stasis2, true},           // same lease, different stasis timestamps
   949  		{epoch1, epoch1Voter, true},        // same epoch lease, different replica type
   950  		{epoch1, epoch1Learner, true},      // same epoch lease, different replica type
   951  		{epoch1Voter, epoch1Learner, true}, // same epoch lease, different replica type
   952  	}
   953  
   954  	for i, tc := range testCases {
   955  		if ok := tc.l.Equivalent(tc.ol); tc.expSuccess != ok {
   956  			t.Errorf("%d: expected success? %t; got %t", i, tc.expSuccess, ok)
   957  		}
   958  	}
   959  
   960  	// #18689 changed the nullability of the DeprecatedStartStasis, ProposedTS, and Expiration
   961  	// field. It introduced a bug whose regression is caught below where a zero Expiration and a nil
   962  	// Expiration in an epoch-based lease led to mistakenly considering leases non-equivalent.
   963  	prePRLease := Lease{
   964  		Start: hlc.Timestamp{WallTime: 10},
   965  		Epoch: 123,
   966  
   967  		// The bug-trigger.
   968  		Expiration: new(hlc.Timestamp),
   969  
   970  		// Similar potential bug triggers, but these were actually handled correctly.
   971  		DeprecatedStartStasis: new(hlc.Timestamp),
   972  		ProposedTS:            &hlc.Timestamp{WallTime: 10},
   973  	}
   974  	postPRLease := prePRLease
   975  	postPRLease.DeprecatedStartStasis = nil
   976  	postPRLease.Expiration = nil
   977  
   978  	if !postPRLease.Equivalent(prePRLease) || !prePRLease.Equivalent(postPRLease) {
   979  		t.Fatalf("leases not equivalent but should be despite diff(pre,post) = %s", pretty.Diff(prePRLease, postPRLease))
   980  	}
   981  }
   982  
   983  func TestLeaseEqual(t *testing.T) {
   984  	type expectedLease struct {
   985  		Start                 hlc.Timestamp
   986  		Expiration            *hlc.Timestamp
   987  		Replica               ReplicaDescriptor
   988  		DeprecatedStartStasis *hlc.Timestamp
   989  		ProposedTS            *hlc.Timestamp
   990  		Epoch                 int64
   991  		Sequence              LeaseSequence
   992  	}
   993  	// Verify that the lease structure does not change unexpectedly. If a compile
   994  	// error occurs on the following line of code, update the expectedLease
   995  	// structure AND update Lease.Equal.
   996  	var _ = expectedLease(Lease{})
   997  
   998  	// Verify that nil == &hlc.Timestamp{} for the Expiration and
   999  	// DeprecatedStartStasis fields. See #19843.
  1000  	a := Lease{}
  1001  	b := Lease{
  1002  		Expiration:            &hlc.Timestamp{},
  1003  		DeprecatedStartStasis: &hlc.Timestamp{},
  1004  	}
  1005  	if !a.Equal(b) {
  1006  		t.Fatalf("unexpectedly did not compare equal: %s", pretty.Diff(a, b))
  1007  	}
  1008  
  1009  	if !(*Lease)(nil).Equal(nil) {
  1010  		t.Fatalf("unexpectedly did not compare equal")
  1011  	}
  1012  	if !(*Lease)(nil).Equal((*Lease)(nil)) {
  1013  		t.Fatalf("unexpectedly did not compare equal")
  1014  	}
  1015  	if (*Lease)(nil).Equal(Lease{}) {
  1016  		t.Fatalf("expectedly compared equal")
  1017  	}
  1018  	if (*Lease)(nil).Equal(&Lease{}) {
  1019  		t.Fatalf("expectedly compared equal")
  1020  	}
  1021  	if (&Lease{}).Equal(nil) {
  1022  		t.Fatalf("expectedly compared equal")
  1023  	}
  1024  	if (&Lease{}).Equal((*Lease)(nil)) {
  1025  		t.Fatalf("expectedly compared equal")
  1026  	}
  1027  
  1028  	ts := hlc.Timestamp{Logical: 1}
  1029  	testCases := []Lease{
  1030  		{Start: ts},
  1031  		{Expiration: &ts},
  1032  		{Replica: ReplicaDescriptor{NodeID: 1}},
  1033  		{DeprecatedStartStasis: &ts},
  1034  		{ProposedTS: &ts},
  1035  		{Epoch: 1},
  1036  		{Sequence: 1},
  1037  	}
  1038  	for _, c := range testCases {
  1039  		t.Run("", func(t *testing.T) {
  1040  			if c.Equal(Lease{}) {
  1041  				t.Fatalf("unexpected equality: %s", pretty.Diff(c, Lease{}))
  1042  			}
  1043  		})
  1044  	}
  1045  }
  1046  
  1047  func TestSpanOverlaps(t *testing.T) {
  1048  	sA := Span{Key: []byte("a")}
  1049  	sD := Span{Key: []byte("d")}
  1050  	sAtoC := Span{Key: []byte("a"), EndKey: []byte("c")}
  1051  	sBtoD := Span{Key: []byte("b"), EndKey: []byte("d")}
  1052  	// Invalid spans.
  1053  	sCtoA := Span{Key: []byte("c"), EndKey: []byte("a")}
  1054  	sDtoB := Span{Key: []byte("d"), EndKey: []byte("b")}
  1055  
  1056  	testData := []struct {
  1057  		s1, s2   Span
  1058  		overlaps bool
  1059  	}{
  1060  		{sA, sA, true},
  1061  		{sA, sD, false},
  1062  		{sA, sBtoD, false},
  1063  		{sBtoD, sA, false},
  1064  		{sD, sBtoD, false},
  1065  		{sBtoD, sD, false},
  1066  		{sA, sAtoC, true},
  1067  		{sAtoC, sA, true},
  1068  		{sAtoC, sAtoC, true},
  1069  		{sAtoC, sBtoD, true},
  1070  		{sBtoD, sAtoC, true},
  1071  		// Invalid spans.
  1072  		{sAtoC, sDtoB, false},
  1073  		{sDtoB, sAtoC, false},
  1074  		{sBtoD, sCtoA, false},
  1075  		{sCtoA, sBtoD, false},
  1076  	}
  1077  	for i, test := range testData {
  1078  		if o := test.s1.Overlaps(test.s2); o != test.overlaps {
  1079  			t.Errorf("%d: expected overlap %t; got %t between %s vs. %s", i, test.overlaps, o, test.s1, test.s2)
  1080  		}
  1081  	}
  1082  }
  1083  
  1084  func TestSpanCombine(t *testing.T) {
  1085  	sA := Span{Key: []byte("a")}
  1086  	sD := Span{Key: []byte("d")}
  1087  	sAtoC := Span{Key: []byte("a"), EndKey: []byte("c")}
  1088  	sAtoD := Span{Key: []byte("a"), EndKey: []byte("d")}
  1089  	sAtoDNext := Span{Key: []byte("a"), EndKey: Key([]byte("d")).Next()}
  1090  	sBtoD := Span{Key: []byte("b"), EndKey: []byte("d")}
  1091  	sBtoDNext := Span{Key: []byte("b"), EndKey: Key([]byte("d")).Next()}
  1092  	// Invalid spans.
  1093  	sCtoA := Span{Key: []byte("c"), EndKey: []byte("a")}
  1094  	sDtoB := Span{Key: []byte("d"), EndKey: []byte("b")}
  1095  
  1096  	testData := []struct {
  1097  		s1, s2   Span
  1098  		combined Span
  1099  	}{
  1100  		{sA, sA, sA},
  1101  		{sA, sD, sAtoDNext},
  1102  		{sA, sBtoD, sAtoD},
  1103  		{sBtoD, sA, sAtoD},
  1104  		{sD, sBtoD, sBtoDNext},
  1105  		{sBtoD, sD, sBtoDNext},
  1106  		{sA, sAtoC, sAtoC},
  1107  		{sAtoC, sA, sAtoC},
  1108  		{sAtoC, sAtoC, sAtoC},
  1109  		{sAtoC, sBtoD, sAtoD},
  1110  		{sBtoD, sAtoC, sAtoD},
  1111  		// Invalid spans.
  1112  		{sAtoC, sDtoB, Span{}},
  1113  		{sDtoB, sAtoC, Span{}},
  1114  		{sBtoD, sCtoA, Span{}},
  1115  		{sCtoA, sBtoD, Span{}},
  1116  	}
  1117  	for i, test := range testData {
  1118  		if combined := test.s1.Combine(test.s2); !combined.Equal(test.combined) {
  1119  			t.Errorf("%d: expected combined %s; got %s between %s vs. %s", i, test.combined, combined, test.s1, test.s2)
  1120  		}
  1121  	}
  1122  }
  1123  
  1124  // TestSpanContains verifies methods to check whether a key
  1125  // or key range is contained within the span.
  1126  func TestSpanContains(t *testing.T) {
  1127  	s := Span{Key: []byte("a"), EndKey: []byte("b")}
  1128  
  1129  	testData := []struct {
  1130  		start, end string
  1131  		contains   bool
  1132  	}{
  1133  		// Single keys.
  1134  		{"a", "", true},
  1135  		{"aa", "", true},
  1136  		{"`", "", false},
  1137  		{"b", "", false},
  1138  		{"c", "", false},
  1139  		// Key ranges.
  1140  		{"a", "b", true},
  1141  		{"a", "aa", true},
  1142  		{"aa", "b", true},
  1143  		{"0", "9", false},
  1144  		{"`", "a", false},
  1145  		{"b", "bb", false},
  1146  		{"0", "bb", false},
  1147  		{"aa", "bb", false},
  1148  		{"b", "a", false},
  1149  	}
  1150  	for i, test := range testData {
  1151  		if s.Contains(sp(test.start, test.end)) != test.contains {
  1152  			t.Errorf("%d: expected span %q-%q within range to be %v",
  1153  				i, test.start, test.end, test.contains)
  1154  		}
  1155  	}
  1156  }
  1157  
  1158  func TestSpanSplitOnKey(t *testing.T) {
  1159  	s := Span{Key: []byte("b"), EndKey: []byte("c")}
  1160  
  1161  	testData := []struct {
  1162  		split []byte
  1163  		left  Span
  1164  		right Span
  1165  	}{
  1166  		// Split on start/end key should fail.
  1167  		{
  1168  			[]byte("b"),
  1169  			s,
  1170  			Span{},
  1171  		},
  1172  		{
  1173  			[]byte("c"),
  1174  			s,
  1175  			Span{},
  1176  		},
  1177  
  1178  		// Before start key.
  1179  		{
  1180  			[]byte("a"),
  1181  			s,
  1182  			Span{},
  1183  		},
  1184  		// After end key.
  1185  		{
  1186  			[]byte("d"),
  1187  			s,
  1188  			Span{},
  1189  		},
  1190  
  1191  		// Simple split.
  1192  		{
  1193  			[]byte("bb"),
  1194  			sp("b", "bb"),
  1195  			sp("bb", "c"),
  1196  		},
  1197  	}
  1198  	for testIdx, test := range testData {
  1199  		t.Run(strconv.Itoa(testIdx), func(t *testing.T) {
  1200  			actualL, actualR := s.SplitOnKey(test.split)
  1201  			if !test.left.EqualValue(actualL) {
  1202  				t.Fatalf("expected left span after split to be %v, got %v", test.left, actualL)
  1203  			}
  1204  
  1205  			if !test.right.EqualValue(actualR) {
  1206  				t.Fatalf("expected right span after split to be %v, got %v", test.right, actualL)
  1207  			}
  1208  		})
  1209  	}
  1210  }
  1211  
  1212  func TestSpanValid(t *testing.T) {
  1213  	testData := []struct {
  1214  		start, end []byte
  1215  		valid      bool
  1216  	}{
  1217  		{[]byte("a"), nil, true},
  1218  		{[]byte("a"), []byte("b"), true},
  1219  		{[]byte(""), []byte(""), false},
  1220  		{[]byte(""), []byte("a"), true},
  1221  		{[]byte("a"), []byte("a"), false},
  1222  		{[]byte("b"), []byte("aa"), false},
  1223  	}
  1224  	for i, test := range testData {
  1225  		s := Span{Key: test.start, EndKey: test.end}
  1226  		if test.valid != s.Valid() {
  1227  			t.Errorf("%d: expected span %q-%q to return %t for Valid, instead got %t",
  1228  				i, test.start, test.end, test.valid, s.Valid())
  1229  		}
  1230  	}
  1231  }
  1232  
  1233  // TestRSpanContains verifies methods to check whether a key
  1234  // or key range is contained within the span.
  1235  func TestRSpanContains(t *testing.T) {
  1236  	rs := RSpan{Key: []byte("a"), EndKey: []byte("b")}
  1237  
  1238  	testData := []struct {
  1239  		start, end []byte
  1240  		contains   bool
  1241  	}{
  1242  		// Single keys.
  1243  		{[]byte("a"), []byte("a"), true},
  1244  		{[]byte("a"), nil, true},
  1245  		{[]byte("aa"), []byte("aa"), true},
  1246  		{[]byte("`"), []byte("`"), false},
  1247  		{[]byte("b"), []byte("b"), false},
  1248  		{[]byte("b"), nil, false},
  1249  		{[]byte("c"), []byte("c"), false},
  1250  		// Key ranges.
  1251  		{[]byte("a"), []byte("b"), true},
  1252  		{[]byte("a"), []byte("aa"), true},
  1253  		{[]byte("aa"), []byte("b"), true},
  1254  		{[]byte("0"), []byte("9"), false},
  1255  		{[]byte("`"), []byte("a"), false},
  1256  		{[]byte("b"), []byte("bb"), false},
  1257  		{[]byte("0"), []byte("bb"), false},
  1258  		{[]byte("aa"), []byte("bb"), false},
  1259  		{[]byte("b"), []byte("a"), false},
  1260  	}
  1261  	for i, test := range testData {
  1262  		if bytes.Equal(test.start, test.end) {
  1263  			if rs.ContainsKey(test.start) != test.contains {
  1264  				t.Errorf("%d: expected key %q within range", i, test.start)
  1265  			}
  1266  		}
  1267  		if rs.ContainsKeyRange(test.start, test.end) != test.contains {
  1268  			t.Errorf("%d: expected key %q within range", i, test.start)
  1269  		}
  1270  	}
  1271  }
  1272  
  1273  // TestRSpanContainsKeyInverted verifies ContainsKeyInverted to check whether a key
  1274  // is contained within the span.
  1275  func TestRSpanContainsKeyInverted(t *testing.T) {
  1276  	rs := RSpan{Key: []byte("b"), EndKey: []byte("c")}
  1277  
  1278  	testData := []struct {
  1279  		key      RKey
  1280  		contains bool
  1281  	}{
  1282  		// Single keys.
  1283  		{RKey("a"), false},
  1284  		{RKey("b"), false},
  1285  		{RKey("bb"), true},
  1286  		{RKey("c"), true},
  1287  		{RKey("c").Next(), false},
  1288  	}
  1289  	for i, test := range testData {
  1290  		if rs.ContainsKeyInverted(test.key) != test.contains {
  1291  			t.Errorf("%d: expected key %q within range", i, test.key)
  1292  		}
  1293  	}
  1294  }
  1295  
  1296  // TestRSpanIntersect verifies rSpan.intersect.
  1297  func TestRSpanIntersect(t *testing.T) {
  1298  	rs := RSpan{Key: RKey("b"), EndKey: RKey("e")}
  1299  
  1300  	testData := []struct {
  1301  		startKey, endKey RKey
  1302  		expected         RSpan
  1303  	}{
  1304  		// Partially overlapping.
  1305  		{RKey("a"), RKey("c"), RSpan{Key: RKey("b"), EndKey: RKey("c")}},
  1306  		{RKey("d"), RKey("f"), RSpan{Key: RKey("d"), EndKey: RKey("e")}},
  1307  		// Descriptor surrounds the span.
  1308  		{RKey("a"), RKey("f"), RSpan{Key: RKey("b"), EndKey: RKey("e")}},
  1309  		// Span surrounds the descriptor.
  1310  		{RKey("c"), RKey("d"), RSpan{Key: RKey("c"), EndKey: RKey("d")}},
  1311  		// Descriptor has the same range as the span.
  1312  		{RKey("b"), RKey("e"), RSpan{Key: RKey("b"), EndKey: RKey("e")}},
  1313  	}
  1314  
  1315  	for i, test := range testData {
  1316  		desc := RangeDescriptor{}
  1317  		desc.StartKey = test.startKey
  1318  		desc.EndKey = test.endKey
  1319  
  1320  		actual, err := rs.Intersect(&desc)
  1321  		if err != nil {
  1322  			t.Error(err)
  1323  			continue
  1324  		}
  1325  		if !actual.Equal(test.expected) {
  1326  			t.Errorf("%d: expected %+v but got %+v", i, test.expected, actual)
  1327  		}
  1328  	}
  1329  
  1330  	// Error scenarios
  1331  	errorTestData := []struct {
  1332  		startKey, endKey RKey
  1333  	}{
  1334  		{RKey("a"), RKey("b")},
  1335  		{RKey("e"), RKey("f")},
  1336  		{RKey("f"), RKey("g")},
  1337  	}
  1338  	for i, test := range errorTestData {
  1339  		desc := RangeDescriptor{}
  1340  		desc.StartKey = test.startKey
  1341  		desc.EndKey = test.endKey
  1342  		if _, err := rs.Intersect(&desc); err == nil {
  1343  			t.Errorf("%d: unexpected success", i)
  1344  		}
  1345  	}
  1346  }
  1347  
  1348  func BenchmarkValueSetBytes(b *testing.B) {
  1349  	v := Value{}
  1350  	bytes := make([]byte, 16)
  1351  
  1352  	for i := 0; i < b.N; i++ {
  1353  		v.SetBytes(bytes)
  1354  	}
  1355  }
  1356  
  1357  func BenchmarkValueSetFloat(b *testing.B) {
  1358  	v := Value{}
  1359  	f := 1.1
  1360  
  1361  	for i := 0; i < b.N; i++ {
  1362  		v.SetFloat(f)
  1363  	}
  1364  }
  1365  
  1366  func BenchmarkValueSetBool(b *testing.B) {
  1367  	v := Value{}
  1368  	bo := true
  1369  
  1370  	for i := 0; i < b.N; i++ {
  1371  		v.SetBool(bo)
  1372  	}
  1373  }
  1374  
  1375  func BenchmarkValueSetInt(b *testing.B) {
  1376  	v := Value{}
  1377  	in := int64(1)
  1378  
  1379  	for i := 0; i < b.N; i++ {
  1380  		v.SetInt(in)
  1381  	}
  1382  }
  1383  
  1384  func BenchmarkValueSetProto(b *testing.B) {
  1385  	v := Value{}
  1386  	p := &Value{}
  1387  
  1388  	for i := 0; i < b.N; i++ {
  1389  		if err := v.SetProto(p); err != nil {
  1390  			b.Fatal(err)
  1391  		}
  1392  	}
  1393  }
  1394  
  1395  func BenchmarkValueSetTime(b *testing.B) {
  1396  	v := Value{}
  1397  	ti := time.Time{}
  1398  
  1399  	for i := 0; i < b.N; i++ {
  1400  		v.SetTime(ti)
  1401  	}
  1402  }
  1403  
  1404  func BenchmarkValueSetDecimal(b *testing.B) {
  1405  	v := Value{}
  1406  	dec := apd.New(11, -1)
  1407  
  1408  	for i := 0; i < b.N; i++ {
  1409  		if err := v.SetDecimal(dec); err != nil {
  1410  			b.Fatal(err)
  1411  		}
  1412  	}
  1413  }
  1414  
  1415  func BenchmarkValueSetTuple(b *testing.B) {
  1416  	v := Value{}
  1417  	bytes := make([]byte, 16)
  1418  
  1419  	for i := 0; i < b.N; i++ {
  1420  		v.SetTuple(bytes)
  1421  	}
  1422  }
  1423  
  1424  func BenchmarkValueGetBytes(b *testing.B) {
  1425  	v := Value{}
  1426  	bytes := make([]byte, 16)
  1427  	v.SetBytes(bytes)
  1428  
  1429  	for i := 0; i < b.N; i++ {
  1430  		if _, err := v.GetBytes(); err != nil {
  1431  			b.Fatal(err)
  1432  		}
  1433  	}
  1434  }
  1435  
  1436  func BenchmarkValueGetFloat(b *testing.B) {
  1437  	v := Value{}
  1438  	f := 1.1
  1439  	v.SetFloat(f)
  1440  
  1441  	for i := 0; i < b.N; i++ {
  1442  		if _, err := v.GetFloat(); err != nil {
  1443  			b.Fatal(err)
  1444  		}
  1445  	}
  1446  }
  1447  
  1448  func BenchmarkValueGetBool(b *testing.B) {
  1449  	v := Value{}
  1450  	bo := true
  1451  	v.SetBool(bo)
  1452  
  1453  	for i := 0; i < b.N; i++ {
  1454  		if _, err := v.GetBool(); err != nil {
  1455  			b.Fatal(err)
  1456  		}
  1457  	}
  1458  }
  1459  
  1460  func BenchmarkValueGetInt(b *testing.B) {
  1461  	v := Value{}
  1462  	in := int64(1)
  1463  	v.SetInt(in)
  1464  
  1465  	for i := 0; i < b.N; i++ {
  1466  		if _, err := v.GetInt(); err != nil {
  1467  			b.Fatal(err)
  1468  		}
  1469  	}
  1470  }
  1471  
  1472  func BenchmarkValueGetProto(b *testing.B) {
  1473  	v := Value{}
  1474  	p, dst := &Value{}, &Value{}
  1475  	if err := v.SetProto(p); err != nil {
  1476  		b.Fatal(err)
  1477  	}
  1478  
  1479  	for i := 0; i < b.N; i++ {
  1480  		if err := v.GetProto(dst); err != nil {
  1481  			b.Fatal(err)
  1482  		}
  1483  	}
  1484  }
  1485  
  1486  func BenchmarkValueGetTime(b *testing.B) {
  1487  	v := Value{}
  1488  	ti := time.Time{}
  1489  	v.SetTime(ti)
  1490  
  1491  	for i := 0; i < b.N; i++ {
  1492  		if _, err := v.GetTime(); err != nil {
  1493  			b.Fatal(err)
  1494  		}
  1495  	}
  1496  }
  1497  
  1498  func BenchmarkValueGetDecimal(b *testing.B) {
  1499  	v := Value{}
  1500  	dec := apd.New(11, -1)
  1501  	if err := v.SetDecimal(dec); err != nil {
  1502  		b.Fatal(err)
  1503  	}
  1504  
  1505  	for i := 0; i < b.N; i++ {
  1506  		if _, err := v.GetDecimal(); err != nil {
  1507  			b.Fatal(err)
  1508  		}
  1509  	}
  1510  }
  1511  
  1512  func BenchmarkValueGetTuple(b *testing.B) {
  1513  	v := Value{}
  1514  	bytes := make([]byte, 16)
  1515  	v.SetTuple(bytes)
  1516  
  1517  	for i := 0; i < b.N; i++ {
  1518  		if _, err := v.GetTuple(); err != nil {
  1519  			b.Fatal(err)
  1520  		}
  1521  	}
  1522  }
  1523  
  1524  func TestValuePrettyPrint(t *testing.T) {
  1525  	var boolValue Value
  1526  	boolValue.SetBool(true)
  1527  
  1528  	var intValue Value
  1529  	intValue.SetInt(7)
  1530  
  1531  	var floatValue Value
  1532  	floatValue.SetFloat(6.28)
  1533  
  1534  	var timeValue Value
  1535  	timeValue.SetTime(time.Date(2016, 6, 29, 16, 2, 50, 5, time.UTC))
  1536  
  1537  	var decimalValue Value
  1538  	_ = decimalValue.SetDecimal(apd.New(628, -2))
  1539  
  1540  	var durationValue Value
  1541  	_ = durationValue.SetDuration(duration.DecodeDuration(1, 2, 3))
  1542  
  1543  	var tupleValue Value
  1544  	tupleBytes := encoding.EncodeBytesValue(encoding.EncodeIntValue(nil, 1, 8), 2, []byte("foo"))
  1545  	tupleValue.SetTuple(tupleBytes)
  1546  
  1547  	var bytesValuePrintable, bytesValueNonPrintable Value
  1548  	bytesValuePrintable.SetBytes([]byte("abc"))
  1549  	bytesValueNonPrintable.SetBytes([]byte{0x89})
  1550  
  1551  	var bitArrayValue Value
  1552  	ba := bitarray.MakeBitArrayFromInt64(8, 58, 7)
  1553  	bitArrayValue.SetBitArray(ba)
  1554  
  1555  	var errValue Value
  1556  	errValue.SetInt(7)
  1557  	errValue.setTag(ValueType_FLOAT)
  1558  
  1559  	var errTagValue Value
  1560  	errTagValue.SetInt(7)
  1561  	errTagValue.setTag(ValueType(99))
  1562  
  1563  	tests := []struct {
  1564  		v        Value
  1565  		expected string
  1566  	}{
  1567  		{boolValue, "/INT/1"},
  1568  		{intValue, "/INT/7"},
  1569  		{floatValue, "/FLOAT/6.28"},
  1570  		{timeValue, "/TIME/2016-06-29T16:02:50.000000005Z"},
  1571  		{decimalValue, "/DECIMAL/6.28"},
  1572  		{durationValue, "/DURATION/1 mon 2 days 00:00:00+3ns"},
  1573  		{MakeValueFromBytes([]byte{0x1, 0x2, 0xF, 0xFF}), "/BYTES/0x01020fff"},
  1574  		{MakeValueFromString("foo"), "/BYTES/foo"},
  1575  		{tupleValue, "/TUPLE/1:1:Int/8/2:3:Bytes/foo"},
  1576  		{bytesValuePrintable, "/BYTES/abc"},
  1577  		{bytesValueNonPrintable, "/BYTES/0x89"},
  1578  		{bitArrayValue, "/BITARRAY/B00111010"},
  1579  		{errValue, "/<err: float64 value should be exactly 8 bytes: 1>"},
  1580  		{errTagValue, "/<err: unknown tag: 99>"},
  1581  	}
  1582  
  1583  	for i, test := range tests {
  1584  		if str := test.v.PrettyPrint(); str != test.expected {
  1585  			t.Errorf("%d: got %q expected %q", i, str, test.expected)
  1586  		}
  1587  	}
  1588  }
  1589  
  1590  func TestUpdateObservedTimestamps(t *testing.T) {
  1591  	f := func(nodeID NodeID, walltime int64) ObservedTimestamp {
  1592  		return ObservedTimestamp{
  1593  			NodeID: nodeID,
  1594  			Timestamp: hlc.Timestamp{
  1595  				WallTime: walltime,
  1596  			},
  1597  		}
  1598  	}
  1599  
  1600  	testCases := []struct {
  1601  		input    observedTimestampSlice
  1602  		expected observedTimestampSlice
  1603  	}{
  1604  		{nil, nil},
  1605  		{
  1606  			observedTimestampSlice{f(1, 1)},
  1607  			observedTimestampSlice{f(1, 1)},
  1608  		},
  1609  		{
  1610  			observedTimestampSlice{f(1, 1), f(1, 2)},
  1611  			observedTimestampSlice{f(1, 1)},
  1612  		},
  1613  		{
  1614  			observedTimestampSlice{f(1, 2), f(1, 1)},
  1615  			observedTimestampSlice{f(1, 1)},
  1616  		},
  1617  		{
  1618  			observedTimestampSlice{f(1, 1), f(2, 1)},
  1619  			observedTimestampSlice{f(1, 1), f(2, 1)},
  1620  		},
  1621  		{
  1622  			observedTimestampSlice{f(2, 1), f(1, 1)},
  1623  			observedTimestampSlice{f(1, 1), f(2, 1)},
  1624  		},
  1625  		{
  1626  			observedTimestampSlice{f(1, 1), f(2, 1), f(3, 1)},
  1627  			observedTimestampSlice{f(1, 1), f(2, 1), f(3, 1)},
  1628  		},
  1629  		{
  1630  			observedTimestampSlice{f(3, 1), f(2, 1), f(1, 1)},
  1631  			observedTimestampSlice{f(1, 1), f(2, 1), f(3, 1)},
  1632  		},
  1633  		{
  1634  			observedTimestampSlice{f(2, 1), f(3, 1), f(1, 1)},
  1635  			observedTimestampSlice{f(1, 1), f(2, 1), f(3, 1)},
  1636  		},
  1637  	}
  1638  	for _, c := range testCases {
  1639  		t.Run("", func(t *testing.T) {
  1640  			var s observedTimestampSlice
  1641  			for _, v := range c.input {
  1642  				s = s.update(v.NodeID, v.Timestamp)
  1643  			}
  1644  			if !reflect.DeepEqual(c.expected, s) {
  1645  				t.Fatalf("%s", pretty.Diff(c.expected, s))
  1646  			}
  1647  		})
  1648  	}
  1649  }
  1650  
  1651  func TestChangeReplicasTrigger_String(t *testing.T) {
  1652  	defer leaktest.AfterTest(t)()
  1653  
  1654  	vi := VOTER_INCOMING
  1655  	vo := VOTER_OUTGOING
  1656  	vd := VOTER_DEMOTING
  1657  	l := LEARNER
  1658  	repl1 := ReplicaDescriptor{NodeID: 1, StoreID: 2, ReplicaID: 3, Type: &vi}
  1659  	repl2 := ReplicaDescriptor{NodeID: 4, StoreID: 5, ReplicaID: 6, Type: &vo}
  1660  	learner := ReplicaDescriptor{NodeID: 7, StoreID: 8, ReplicaID: 9, Type: &l}
  1661  	repl3 := ReplicaDescriptor{NodeID: 10, StoreID: 11, ReplicaID: 12, Type: &vd}
  1662  	crt := ChangeReplicasTrigger{
  1663  		InternalAddedReplicas:   []ReplicaDescriptor{repl1},
  1664  		InternalRemovedReplicas: []ReplicaDescriptor{repl2, repl3},
  1665  		Desc: &RangeDescriptor{
  1666  			RangeID:  1,
  1667  			StartKey: RKey("a"),
  1668  			EndKey:   RKey("b"),
  1669  			InternalReplicas: []ReplicaDescriptor{
  1670  				repl1,
  1671  				repl2,
  1672  				learner,
  1673  				repl3,
  1674  			},
  1675  			NextReplicaID: 10,
  1676  			Generation:    5,
  1677  		},
  1678  	}
  1679  	act := crt.String()
  1680  	exp := "ENTER_JOINT(r6 r12 l12 v3) ADD_REPLICA[(n1,s2):3VOTER_INCOMING], " +
  1681  		"REMOVE_REPLICA[(n4,s5):6VOTER_OUTGOING (n10,s11):12VOTER_DEMOTING]: " +
  1682  		"after=[(n1,s2):3VOTER_INCOMING (n4,s5):6VOTER_OUTGOING (n7,s8):9LEARNER " +
  1683  		"(n10,s11):12VOTER_DEMOTING] next=10"
  1684  	require.Equal(t, exp, act)
  1685  
  1686  	crt.InternalRemovedReplicas = nil
  1687  	crt.InternalAddedReplicas = nil
  1688  	repl1.Type = ReplicaTypeVoterFull()
  1689  	crt.Desc.SetReplicas(MakeReplicaDescriptors([]ReplicaDescriptor{repl1, learner}))
  1690  	act = crt.String()
  1691  	require.Empty(t, crt.Added())
  1692  	require.Empty(t, crt.Removed())
  1693  	exp = "LEAVE_JOINT: after=[(n1,s2):3 (n7,s8):9LEARNER] next=10"
  1694  	require.Equal(t, exp, act)
  1695  }
  1696  
  1697  type mockCRT struct {
  1698  	v2 bool
  1699  	ChangeReplicasTrigger
  1700  }
  1701  
  1702  func (m mockCRT) alwaysV2() bool {
  1703  	return m.v2
  1704  }
  1705  
  1706  func TestChangeReplicasTrigger_ConfChange(t *testing.T) {
  1707  	defer leaktest.AfterTest(t)()
  1708  
  1709  	sl := func(alt ...interface{}) []ReplicaDescriptor {
  1710  		t.Helper()
  1711  		if len(alt)%2 != 0 {
  1712  			t.Fatal("need pairs")
  1713  		}
  1714  		var rDescs []ReplicaDescriptor
  1715  		for i := 0; i < len(alt); i += 2 {
  1716  			typ := alt[i].(ReplicaType)
  1717  			id := alt[i+1].(int)
  1718  			rDescs = append(rDescs, ReplicaDescriptor{
  1719  				Type:      &typ,
  1720  				NodeID:    NodeID(3 * id),
  1721  				StoreID:   StoreID(2 * id),
  1722  				ReplicaID: ReplicaID(id),
  1723  			})
  1724  		}
  1725  		return rDescs
  1726  	}
  1727  
  1728  	type in struct {
  1729  		v2              bool
  1730  		add, del, repls []ReplicaDescriptor
  1731  	}
  1732  
  1733  	mk := func(in in) mockCRT {
  1734  		m := mockCRT{v2: in.v2}
  1735  		m.ChangeReplicasTrigger.InternalAddedReplicas = in.add
  1736  		m.ChangeReplicasTrigger.InternalRemovedReplicas = in.del
  1737  		m.Desc = &RangeDescriptor{}
  1738  		m.Desc.SetReplicas(MakeReplicaDescriptors(in.repls))
  1739  		return m
  1740  	}
  1741  
  1742  	vf1 := sl(VOTER_FULL, 1)
  1743  	vo1 := sl(VOTER_OUTGOING, 1)
  1744  	vi1 := sl(VOTER_INCOMING, 1)
  1745  	vl1 := sl(LEARNER, 1)
  1746  
  1747  	testCases := []struct {
  1748  		crt mockCRT
  1749  		exp raftpb.ConfChangeI
  1750  		err string
  1751  	}{
  1752  		// A replica of type VOTER_OUTGOING being added makes no sense.
  1753  		{crt: mk(in{add: vo1, repls: vo1}), err: "can't add replica in state VOTER_OUTGOING"},
  1754  		// But an incoming one can be added, and the result must be a joint change.
  1755  		{crt: mk(in{add: vi1, repls: vi1}), exp: raftpb.ConfChangeV2{
  1756  			Transition: raftpb.ConfChangeTransitionJointExplicit,
  1757  			Changes:    []raftpb.ConfChangeSingle{{Type: raftpb.ConfChangeAddNode, NodeID: 1}},
  1758  		}},
  1759  		// A replica of type VOTER_INCOMING being removed makes no sense.
  1760  		{crt: mk(in{del: vi1}), err: "can't remove replica in state VOTER_INCOMING"},
  1761  		// But during a joint removal we can see VOTER_OUTGOING.
  1762  		{crt: mk(in{del: vo1, repls: vo1}), exp: raftpb.ConfChangeV2{
  1763  			Transition: raftpb.ConfChangeTransitionJointExplicit,
  1764  			Changes:    []raftpb.ConfChangeSingle{{Type: raftpb.ConfChangeRemoveNode, NodeID: 1}},
  1765  		}},
  1766  
  1767  		// Adding a voter via the V1 path.
  1768  		{crt: mk(in{add: vf1, repls: vf1}), exp: raftpb.ConfChange{
  1769  			Type:   raftpb.ConfChangeAddNode,
  1770  			NodeID: 1,
  1771  		}},
  1772  		// Adding a learner via the V1 path.
  1773  		{crt: mk(in{add: vl1, repls: vl1}), exp: raftpb.ConfChange{
  1774  			Type:   raftpb.ConfChangeAddLearnerNode,
  1775  			NodeID: 1,
  1776  		}},
  1777  
  1778  		// Removing a voter or learner via the V1 path but falsely the replica is still in the descriptor.
  1779  		{crt: mk(in{del: vf1, repls: vf1}), err: "(n3,s2):1 must no longer be present in descriptor"},
  1780  		{crt: mk(in{del: vl1, repls: vl1}), err: "(n3,s2):1LEARNER must no longer be present in descriptor"},
  1781  		// Well-formed examples.
  1782  		{crt: mk(in{del: vf1}), exp: raftpb.ConfChange{
  1783  			Type:   raftpb.ConfChangeRemoveNode,
  1784  			NodeID: 1,
  1785  		}},
  1786  		{crt: mk(in{del: vl1}), exp: raftpb.ConfChange{
  1787  			Type:   raftpb.ConfChangeRemoveNode,
  1788  			NodeID: 1,
  1789  		}},
  1790  		// Adding a voter via the V2 path but without joint consensus.
  1791  		{crt: mk(in{v2: true, add: vf1, repls: vf1}), exp: raftpb.ConfChangeV2{
  1792  			Transition: raftpb.ConfChangeTransitionAuto,
  1793  			Changes: []raftpb.ConfChangeSingle{{
  1794  				Type:   raftpb.ConfChangeAddNode,
  1795  				NodeID: 1,
  1796  			}},
  1797  		}},
  1798  		// Ditto, but with joint consensus requested.
  1799  		{crt: mk(in{v2: true, add: vi1, repls: vi1}), exp: raftpb.ConfChangeV2{
  1800  			Transition: raftpb.ConfChangeTransitionJointExplicit,
  1801  			Changes: []raftpb.ConfChangeSingle{{
  1802  				Type:   raftpb.ConfChangeAddNode,
  1803  				NodeID: 1,
  1804  			}},
  1805  		}},
  1806  
  1807  		// Adding a learner via the V2 path and without joint consensus. (There is currently
  1808  		// no way to request joint consensus when adding a single learner, but there is no
  1809  		// reason one would ever want that).
  1810  		{crt: mk(in{v2: true, add: vl1, repls: vl1}), exp: raftpb.ConfChangeV2{
  1811  			Transition: raftpb.ConfChangeTransitionAuto,
  1812  			Changes: []raftpb.ConfChangeSingle{{
  1813  				Type:   raftpb.ConfChangeAddLearnerNode,
  1814  				NodeID: 1,
  1815  			}},
  1816  		}},
  1817  
  1818  		// Removing a voter or learner via the V2 path without joint consensus.
  1819  		// Note that this means that the replica is not in the desc any more.
  1820  		{crt: mk(in{v2: true, del: vf1}), exp: raftpb.ConfChangeV2{
  1821  			Transition: raftpb.ConfChangeTransitionAuto,
  1822  			Changes: []raftpb.ConfChangeSingle{{
  1823  				Type:   raftpb.ConfChangeRemoveNode,
  1824  				NodeID: 1,
  1825  			}},
  1826  		}},
  1827  		{crt: mk(in{v2: true, del: vl1}), exp: raftpb.ConfChangeV2{
  1828  			Transition: raftpb.ConfChangeTransitionAuto,
  1829  			Changes: []raftpb.ConfChangeSingle{{
  1830  				Type:   raftpb.ConfChangeRemoveNode,
  1831  				NodeID: 1,
  1832  			}},
  1833  		}},
  1834  
  1835  		// Ditto but with joint consensus. (This can happen only with a voter;
  1836  		// learners disappear immediately).
  1837  		{crt: mk(in{v2: true, del: vo1, repls: vo1}), exp: raftpb.ConfChangeV2{
  1838  			Transition: raftpb.ConfChangeTransitionJointExplicit,
  1839  			Changes: []raftpb.ConfChangeSingle{{
  1840  				Type:   raftpb.ConfChangeRemoveNode,
  1841  				NodeID: 1,
  1842  			}},
  1843  		}},
  1844  
  1845  		// Run a more complex change (necessarily) via the V2 path.
  1846  		{crt: mk(in{
  1847  			add: sl( // Additions.
  1848  				VOTER_INCOMING, 6, LEARNER, 4, VOTER_INCOMING, 3,
  1849  			),
  1850  			del: sl(
  1851  				// Removals.
  1852  				LEARNER, 2, VOTER_OUTGOING, 8, VOTER_DEMOTING, 9,
  1853  			),
  1854  			repls: sl(
  1855  				// Replicas.
  1856  				VOTER_FULL, 1,
  1857  				VOTER_INCOMING, 6, // added
  1858  				VOTER_INCOMING, 3, // added
  1859  				VOTER_DEMOTING, 9, // removing
  1860  				LEARNER, 4, // added
  1861  				VOTER_OUTGOING, 8, // removing
  1862  				VOTER_FULL, 10,
  1863  			)}),
  1864  			exp: raftpb.ConfChangeV2{
  1865  				Transition: raftpb.ConfChangeTransitionJointExplicit,
  1866  				Changes: []raftpb.ConfChangeSingle{
  1867  					{NodeID: 2, Type: raftpb.ConfChangeRemoveNode},
  1868  					{NodeID: 8, Type: raftpb.ConfChangeRemoveNode},
  1869  					{NodeID: 9, Type: raftpb.ConfChangeRemoveNode},
  1870  					{NodeID: 9, Type: raftpb.ConfChangeAddLearnerNode},
  1871  					{NodeID: 6, Type: raftpb.ConfChangeAddNode},
  1872  					{NodeID: 4, Type: raftpb.ConfChangeAddLearnerNode},
  1873  					{NodeID: 3, Type: raftpb.ConfChangeAddNode},
  1874  				}},
  1875  		},
  1876  
  1877  		// Leave a joint config.
  1878  		{
  1879  			crt: mk(in{repls: sl(VOTER_FULL, 1)}),
  1880  			exp: raftpb.ConfChangeV2{},
  1881  		},
  1882  		// If we're asked to leave a joint state but the descriptor is still joint,
  1883  		// that's a problem.
  1884  		{
  1885  			crt: mk(in{v2: true, repls: sl(VOTER_INCOMING, 1)}),
  1886  			err: "descriptor enters joint state, but trigger is requesting to leave one",
  1887  		},
  1888  		{
  1889  			crt: mk(in{v2: true, repls: sl(VOTER_OUTGOING, 1)}),
  1890  			err: "descriptor enters joint state, but trigger is requesting to leave one",
  1891  		},
  1892  	}
  1893  
  1894  	for _, test := range testCases {
  1895  		t.Run("", func(t *testing.T) {
  1896  			cc, err := confChangeImpl(test.crt, nil /* payload */)
  1897  			if test.err == "" {
  1898  				require.NoError(t, err)
  1899  				require.Equal(t, test.exp, cc)
  1900  			} else {
  1901  				require.EqualError(t, err, test.err)
  1902  			}
  1903  		})
  1904  	}
  1905  }
  1906  
  1907  // TestAsLockUpdates verifies that AsLockUpdates propagates all the important
  1908  // fields from a txn to each intent.
  1909  func TestAsLockUpdates(t *testing.T) {
  1910  	defer leaktest.AfterTest(t)()
  1911  
  1912  	ts := hlc.Timestamp{WallTime: 1}
  1913  	txn := MakeTransaction("hello", Key("k"), 0, ts, 0)
  1914  
  1915  	txn.Status = COMMITTED
  1916  	txn.IgnoredSeqNums = []enginepb.IgnoredSeqNumRange{{Start: 0, End: 0}}
  1917  
  1918  	spans := []Span{{Key: Key("a"), EndKey: Key("b")}}
  1919  	for _, intent := range AsLockUpdates(&txn, spans) {
  1920  		require.Equal(t, txn.Status, intent.Status)
  1921  		require.Equal(t, txn.IgnoredSeqNums, intent.IgnoredSeqNums)
  1922  		require.Equal(t, txn.TxnMeta, intent.Txn)
  1923  	}
  1924  }
  1925  
  1926  func TestAddIgnoredSeqNumRange(t *testing.T) {
  1927  	type r = enginepb.IgnoredSeqNumRange
  1928  
  1929  	mr := func(a, b enginepb.TxnSeq) r {
  1930  		return r{Start: a, End: b}
  1931  	}
  1932  
  1933  	testData := []struct {
  1934  		list     []r
  1935  		newRange r
  1936  		exp      []r
  1937  	}{
  1938  		{
  1939  			[]r{},
  1940  			mr(1, 2),
  1941  			[]r{mr(1, 2)},
  1942  		},
  1943  		{
  1944  			[]r{mr(1, 2)},
  1945  			mr(1, 4),
  1946  			[]r{mr(1, 4)},
  1947  		},
  1948  		{
  1949  			[]r{mr(1, 2), mr(3, 6)},
  1950  			mr(8, 10),
  1951  			[]r{mr(1, 2), mr(3, 6), mr(8, 10)},
  1952  		},
  1953  		{
  1954  			[]r{mr(1, 2), mr(5, 6)},
  1955  			mr(3, 8),
  1956  			[]r{mr(1, 2), mr(3, 8)},
  1957  		},
  1958  		{
  1959  			[]r{mr(1, 2), mr(5, 6)},
  1960  			mr(1, 8),
  1961  			[]r{mr(1, 8)},
  1962  		},
  1963  	}
  1964  
  1965  	for _, tc := range testData {
  1966  		txn := Transaction{
  1967  			IgnoredSeqNums: tc.list,
  1968  		}
  1969  		txn.AddIgnoredSeqNumRange(tc.newRange)
  1970  		require.Equal(t, tc.exp, txn.IgnoredSeqNums)
  1971  	}
  1972  }