github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/replica_raft_truncation_test.go (about) 1 // Copyright 2019 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 "bytes" 15 "context" 16 "fmt" 17 "testing" 18 19 "github.com/cockroachdb/cockroach/pkg/keys" 20 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/stateloader" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/storage" 23 "github.com/cockroachdb/cockroach/pkg/util/hlc" 24 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 25 "github.com/cockroachdb/datadriven" 26 "github.com/stretchr/testify/assert" 27 ) 28 29 func TestHandleTruncatedStateBelowRaft(t *testing.T) { 30 defer leaktest.AfterTest(t)() 31 32 // This test verifies the expected behavior of the downstream-of-Raft log 33 // truncation code, in particular regarding the 34 // VersionUnreplicatedRaftTruncatedState migration. 35 36 ctx := context.Background() 37 38 // neither exists (migration) 39 // old one exists (no migration) 40 // new one exists (migrated already) 41 // truncstate regresses 42 43 var prevTruncatedState roachpb.RaftTruncatedState 44 datadriven.Walk(t, "testdata/truncated_state_migration", func(t *testing.T, path string) { 45 const rangeID = 12 46 loader := stateloader.Make(rangeID) 47 eng := storage.NewDefaultInMem() 48 defer eng.Close() 49 50 datadriven.RunTest(t, path, func(t *testing.T, d *datadriven.TestData) string { 51 switch d.Cmd { 52 case "prev": 53 d.ScanArgs(t, "index", &prevTruncatedState.Index) 54 d.ScanArgs(t, "term", &prevTruncatedState.Term) 55 return "" 56 case "put": 57 var index uint64 58 var term uint64 59 var legacy bool 60 d.ScanArgs(t, "index", &index) 61 d.ScanArgs(t, "term", &term) 62 d.ScanArgs(t, "legacy", &legacy) 63 64 truncState := &roachpb.RaftTruncatedState{ 65 Index: index, 66 Term: term, 67 } 68 69 if legacy { 70 assert.NoError(t, loader.SetLegacyRaftTruncatedState(ctx, eng, nil, truncState)) 71 } else { 72 assert.NoError(t, loader.SetRaftTruncatedState(ctx, eng, truncState)) 73 } 74 return "" 75 case "handle": 76 var buf bytes.Buffer 77 78 var index uint64 79 var term uint64 80 d.ScanArgs(t, "index", &index) 81 d.ScanArgs(t, "term", &term) 82 83 newTruncatedState := &roachpb.RaftTruncatedState{ 84 Index: index, 85 Term: term, 86 } 87 88 apply, err := handleTruncatedStateBelowRaft(ctx, &prevTruncatedState, newTruncatedState, loader, eng) 89 if err != nil { 90 return err.Error() 91 } 92 fmt.Fprintf(&buf, "apply: %t\n", apply) 93 94 for _, key := range []roachpb.Key{ 95 keys.RaftTruncatedStateLegacyKey(rangeID), 96 keys.RaftTruncatedStateKey(rangeID), 97 } { 98 var truncatedState roachpb.RaftTruncatedState 99 ok, err := storage.MVCCGetProto(ctx, eng, key, hlc.Timestamp{}, &truncatedState, storage.MVCCGetOptions{}) 100 if err != nil { 101 t.Fatal(err) 102 } 103 if !ok { 104 continue 105 } 106 fmt.Fprintf(&buf, "%s -> index=%d term=%d\n", key, truncatedState.Index, truncatedState.Term) 107 } 108 return buf.String() 109 default: 110 } 111 return fmt.Sprintf("unsupported: %s", d.Cmd) 112 }) 113 }) 114 }