Skip to content

Commit 0674711

Browse files
committed
logstore: add basic datadriven test
Epic: none Release note: none
1 parent 2a89ecb commit 0674711

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

pkg/kv/kvserver/logstore/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,18 @@ go_test(
5151
srcs = [
5252
"bytes_tracker_test.go",
5353
"logstore_bench_test.go",
54+
"logstore_test.go",
5455
"sideload_test.go",
5556
"sync_waiter_test.go",
5657
],
58+
data = glob(["testdata/**"]),
5759
embed = [":logstore"],
5860
deps = [
61+
"//pkg/keys",
5962
"//pkg/kv/kvpb",
6063
"//pkg/kv/kvserver/kvserverbase",
6164
"//pkg/kv/kvserver/kvserverpb",
65+
"//pkg/kv/kvserver/print",
6266
"//pkg/kv/kvserver/raftentry",
6367
"//pkg/kv/kvserver/raftlog",
6468
"//pkg/raft",
@@ -68,6 +72,7 @@ go_test(
6872
"//pkg/storage",
6973
"//pkg/storage/fs",
7074
"//pkg/testutils",
75+
"//pkg/testutils/echotest",
7176
"//pkg/util/humanizeutil",
7277
"//pkg/util/leaktest",
7378
"//pkg/util/log",
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright 2025 The Cockroach Authors.
2+
//
3+
// Use of this software is governed by the CockroachDB Software License
4+
// included in the /LICENSE file.
5+
6+
package logstore
7+
8+
import (
9+
"context"
10+
"fmt"
11+
"path/filepath"
12+
"strings"
13+
"testing"
14+
15+
"github.com/cockroachdb/cockroach/pkg/keys"
16+
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverpb"
17+
"github.com/cockroachdb/cockroach/pkg/kv/kvserver/print"
18+
"github.com/cockroachdb/cockroach/pkg/raft/raftpb"
19+
"github.com/cockroachdb/cockroach/pkg/roachpb"
20+
"github.com/cockroachdb/cockroach/pkg/storage"
21+
"github.com/cockroachdb/cockroach/pkg/testutils/echotest"
22+
"github.com/stretchr/testify/require"
23+
)
24+
25+
func TestRaftStorageWrites(t *testing.T) {
26+
ctx := context.Background()
27+
const rangeID = roachpb.RangeID(123)
28+
sl := NewStateLoader(rangeID)
29+
eng := storage.NewDefaultInMemForTesting()
30+
defer eng.Close()
31+
32+
trunc := kvserverpb.RaftTruncatedState{Index: 100, Term: 20}
33+
state := RaftState{LastIndex: trunc.Index, LastTerm: trunc.Term}
34+
var output string
35+
36+
printCommand := func(name, batch string) {
37+
output += fmt.Sprintf(">> %s\n%s\nState:%+v RaftTruncatedState:%+v\n",
38+
name, batch, state, trunc)
39+
}
40+
printCommand("init", "")
41+
42+
writeBatch := func(prepare func(rw storage.ReadWriter)) string {
43+
t.Helper()
44+
batch := eng.NewBatch()
45+
defer batch.Close()
46+
prepare(batch)
47+
wb := kvserverpb.WriteBatch{Data: batch.Repr()}
48+
str, err := print.DecodeWriteBatch(&wb)
49+
require.NoError(t, err)
50+
require.NoError(t, batch.Commit(true))
51+
return str
52+
}
53+
stats := func() int64 {
54+
t.Helper()
55+
prefix := keys.RaftLogPrefix(rangeID)
56+
prefixEnd := prefix.PrefixEnd()
57+
ms, err := storage.ComputeStats(ctx, eng, prefix, prefixEnd, 0 /* nowNanos */)
58+
require.NoError(t, err)
59+
return ms.SysBytes
60+
}
61+
62+
write := func(name string, hs raftpb.HardState, entries []raftpb.Entry) {
63+
t.Helper()
64+
var newState RaftState
65+
batch := writeBatch(func(rw storage.ReadWriter) {
66+
require.NoError(t, storeHardState(ctx, rw, sl, hs))
67+
var err error
68+
newState, err = logAppend(ctx, sl.RaftLogPrefix(), rw, state, entries)
69+
require.NoError(t, err)
70+
})
71+
state = newState
72+
require.Equal(t, stats(), state.ByteSize)
73+
printCommand(name, batch)
74+
}
75+
truncate := func(name string, ts kvserverpb.RaftTruncatedState) {
76+
t.Helper()
77+
batch := writeBatch(func(rw storage.ReadWriter) {
78+
require.NoError(t, Compact(ctx, trunc, ts, sl, rw))
79+
})
80+
trunc = ts
81+
state.ByteSize = stats()
82+
printCommand(name, batch)
83+
}
84+
85+
write("append (100,103]", raftpb.HardState{
86+
Term: 21, Vote: 3, Commit: 100, Lead: 3, LeadEpoch: 5,
87+
}, []raftpb.Entry{
88+
{Index: 101, Term: 20},
89+
{Index: 102, Term: 21},
90+
{Index: 103, Term: 21},
91+
})
92+
write("append (101,102] with overlap", raftpb.HardState{
93+
Term: 22, Commit: 100,
94+
}, []raftpb.Entry{
95+
{Index: 102, Term: 22},
96+
})
97+
write("append (102,105]", raftpb.HardState{}, []raftpb.Entry{
98+
{Index: 103, Term: 22},
99+
{Index: 104, Term: 22},
100+
{Index: 105, Term: 22},
101+
})
102+
truncate("truncate at 103", kvserverpb.RaftTruncatedState{Index: 103, Term: 22})
103+
truncate("truncate all", kvserverpb.RaftTruncatedState{Index: 105, Term: 22})
104+
105+
// TODO(pav-kv): print the engine content as well.
106+
107+
output = strings.ReplaceAll(output, "\n\n", "\n")
108+
output = strings.ReplaceAll(output, "\n\n", "\n")
109+
echotest.Require(t, output, filepath.Join("testdata", t.Name()+".txt"))
110+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
echo
2+
----
3+
>> init
4+
State:{LastIndex:100 LastTerm:20 ByteSize:0} RaftTruncatedState:{Index:100 Term:20}
5+
>> append (100,103]
6+
Put: 0,0 /Local/RangeID/123/u/RaftHardState (0x0169f67b757266746800): term:21 vote:3 commit:100 lead:3 lead_epoch:5
7+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:101 (0x0169f67b757266746c000000000000006500): Term:20 Index:101 Type:EntryNormal : EMPTY
8+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:102 (0x0169f67b757266746c000000000000006600): Term:21 Index:102 Type:EntryNormal : EMPTY
9+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:103 (0x0169f67b757266746c000000000000006700): Term:21 Index:103 Type:EntryNormal : EMPTY
10+
State:{LastIndex:103 LastTerm:21 ByteSize:129} RaftTruncatedState:{Index:100 Term:20}
11+
>> append (101,102] with overlap
12+
Put: 0,0 /Local/RangeID/123/u/RaftHardState (0x0169f67b757266746800): term:22 vote:0 commit:100 lead:0 lead_epoch:0
13+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:102 (0x0169f67b757266746c000000000000006600): Term:22 Index:102 Type:EntryNormal : EMPTY
14+
Delete (Sized at 43): 0,0 /Local/RangeID/123/u/RaftLog/logIndex:103 (0x0169f67b757266746c000000000000006700):
15+
State:{LastIndex:102 LastTerm:22 ByteSize:86} RaftTruncatedState:{Index:100 Term:20}
16+
>> append (102,105]
17+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:103 (0x0169f67b757266746c000000000000006700): Term:22 Index:103 Type:EntryNormal : EMPTY
18+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:104 (0x0169f67b757266746c000000000000006800): Term:22 Index:104 Type:EntryNormal : EMPTY
19+
Put: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:105 (0x0169f67b757266746c000000000000006900): Term:22 Index:105 Type:EntryNormal : EMPTY
20+
State:{LastIndex:105 LastTerm:22 ByteSize:215} RaftTruncatedState:{Index:100 Term:20}
21+
>> truncate at 103
22+
Delete: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:101 (0x0169f67b757266746c000000000000006500):
23+
Delete: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:102 (0x0169f67b757266746c000000000000006600):
24+
Delete: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:103 (0x0169f67b757266746c000000000000006700):
25+
Put: 0,0 /Local/RangeID/123/u/RaftTruncatedState (0x0169f67b757266747400): index:103 term:22
26+
State:{LastIndex:105 LastTerm:22 ByteSize:86} RaftTruncatedState:{Index:103 Term:22}
27+
>> truncate all
28+
Delete: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:104 (0x0169f67b757266746c000000000000006800):
29+
Delete: 0,0 /Local/RangeID/123/u/RaftLog/logIndex:105 (0x0169f67b757266746c000000000000006900):
30+
Put: 0,0 /Local/RangeID/123/u/RaftTruncatedState (0x0169f67b757266747400): index:105 term:22
31+
State:{LastIndex:105 LastTerm:22 ByteSize:0} RaftTruncatedState:{Index:105 Term:22}

0 commit comments

Comments
 (0)