Skip to content

Commit 21a7dff

Browse files
committed
sstable: clean up lazy loading test
Don't use unnecessary globals, and use `runIterCmd` instead of reimplementing a good chunk of it.
1 parent 4abb46f commit 21a7dff

File tree

3 files changed

+54
-155
lines changed

3 files changed

+54
-155
lines changed

sstable/data_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ func runIterCmd(
325325
}
326326
iter.SetBounds(lower, upper)
327327
kv = nil
328+
case "check-index-loaded":
329+
loaded := isLazyIndexLoaded(iter)
330+
fmt.Fprintf(&b, "check-index-loaded: %v\n", loaded)
331+
continue
328332
case "stats":
329333
// The timing is non-deterministic, so set to 0.
330334
for i := range blockkind.NumKinds {

sstable/reader_lazy_loading_test.go

Lines changed: 25 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ package sstable
77
import (
88
"context"
99
"fmt"
10-
"strings"
1110
"testing"
1211

1312
"github.com/cockroachdb/crlib/testutils/leaktest"
1413
"github.com/cockroachdb/datadriven"
1514
"github.com/cockroachdb/pebble/internal/base"
15+
"github.com/stretchr/testify/require"
1616
)
1717

1818
// TestReaderLazyLoading tests the lazy loading functionality using data-driven tests.
@@ -21,34 +21,31 @@ import (
2121
func TestReaderLazyLoading(t *testing.T) {
2222
defer leaktest.AfterTest(t)()
2323

24+
var r *Reader
25+
defer func() {
26+
if r != nil {
27+
r.Close()
28+
r = nil
29+
}
30+
}()
2431
datadriven.RunTest(t, "testdata/reader_lazy_loading", func(t *testing.T, td *datadriven.TestData) string {
2532
switch td.Cmd {
2633
case "build":
27-
return runBuildForLazyTest(t, td)
34+
if r != nil {
35+
r.Close()
36+
r = nil
37+
}
38+
r = runBuildForLazyTest(t, td)
39+
return ""
2840
case "iter-lazy":
29-
return runIterLazyCmd(t, td)
41+
return runIterLazyCmd(t, td, r)
3042
default:
3143
return fmt.Sprintf("unknown command: %s", td.Cmd)
3244
}
3345
})
3446
}
3547

36-
var (
37-
lazyTestReader *Reader
38-
lazyTestIter Iterator
39-
)
40-
41-
func runBuildForLazyTest(t *testing.T, td *datadriven.TestData) string {
42-
// Close existing reader if any
43-
if lazyTestReader != nil {
44-
lazyTestReader.Close()
45-
lazyTestReader = nil
46-
}
47-
if lazyTestIter != nil {
48-
lazyTestIter.Close()
49-
lazyTestIter = nil
50-
}
51-
48+
func runBuildForLazyTest(t *testing.T, td *datadriven.TestData) *Reader {
5249
// Build writer options with defaults
5350
writerOpts := WriterOptions{
5451
Comparer: base.DefaultComparer,
@@ -60,7 +57,7 @@ func runBuildForLazyTest(t *testing.T, td *datadriven.TestData) string {
6057

6158
// Parse command arguments
6259
if err := ParseWriterOptions(&writerOpts, td.CmdArgs...); err != nil {
63-
return err.Error()
60+
t.Fatal(err)
6461
}
6562

6663
// Add bloom filter if specified
@@ -71,129 +68,27 @@ func runBuildForLazyTest(t *testing.T, td *datadriven.TestData) string {
7168
// Build the table
7269
_, reader, err := runBuildCmd(td, &writerOpts, nil)
7370
if err != nil {
74-
return err.Error()
71+
t.Fatal(err)
7572
}
76-
77-
lazyTestReader = reader
78-
return ""
73+
return reader
7974
}
8075

81-
func runIterLazyCmd(t *testing.T, td *datadriven.TestData) string {
82-
if lazyTestReader == nil {
76+
func runIterLazyCmd(t *testing.T, td *datadriven.TestData, r *Reader) string {
77+
if r == nil {
8378
return "build must be called before iter-lazy"
8479
}
8580

86-
// Close existing iterator if any
87-
if lazyTestIter != nil {
88-
lazyTestIter.Close()
89-
lazyTestIter = nil
90-
}
91-
9281
// Create new iterator
93-
iter, err := lazyTestReader.NewPointIter(context.Background(), IterOptions{
82+
iter, err := r.NewPointIter(context.Background(), IterOptions{
9483
Transforms: NoTransforms,
9584
FilterBlockSizeLimit: AlwaysUseFilterBlock,
9685
Env: NoReadEnv,
97-
ReaderProvider: MakeTrivialReaderProvider(lazyTestReader),
86+
ReaderProvider: MakeTrivialReaderProvider(r),
9887
BlobContext: AssertNoBlobHandles,
9988
})
100-
if err != nil {
101-
return err.Error()
102-
}
103-
lazyTestIter = iter
104-
105-
// Process the operations
106-
var output strings.Builder
107-
lines := strings.Split(strings.TrimSpace(td.Input), "\n")
108-
109-
for i, line := range lines {
110-
line = strings.TrimSpace(line)
111-
if line == "" {
112-
continue
113-
}
114-
115-
if i > 0 {
116-
output.WriteString("\n")
117-
}
118-
119-
switch {
120-
case line == "check-index-loaded":
121-
loaded := isLazyIndexLoaded(iter)
122-
output.WriteString(fmt.Sprintf("index-loaded: %v", loaded))
123-
124-
case line == "first":
125-
kv := iter.First()
126-
if kv != nil {
127-
output.WriteString(fmt.Sprintf("first: <%s:%d>:%s", kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
128-
} else {
129-
output.WriteString("first: .")
130-
}
131-
132-
case line == "last":
133-
kv := iter.Last()
134-
if kv != nil {
135-
output.WriteString(fmt.Sprintf("last: <%s:%d>:%s", kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
136-
} else {
137-
output.WriteString("last: .")
138-
}
139-
140-
case strings.HasPrefix(line, "seek-ge "):
141-
key := strings.TrimPrefix(line, "seek-ge ")
142-
kv := iter.SeekGE([]byte(key), base.SeekGEFlagsNone)
143-
if kv != nil {
144-
output.WriteString(fmt.Sprintf("seek-ge %s: <%s:%d>:%s", key, kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
145-
} else {
146-
output.WriteString(fmt.Sprintf("seek-ge %s: .", key))
147-
}
148-
149-
case strings.HasPrefix(line, "seek-lt "):
150-
key := strings.TrimPrefix(line, "seek-lt ")
151-
kv := iter.SeekLT([]byte(key), base.SeekLTFlagsNone)
152-
if kv != nil {
153-
output.WriteString(fmt.Sprintf("seek-lt %s: <%s:%d>:%s", key, kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
154-
} else {
155-
output.WriteString(fmt.Sprintf("seek-lt %s: .", key))
156-
}
157-
158-
case strings.HasPrefix(line, "seek-prefix-ge "):
159-
parts := strings.Fields(line)
160-
if len(parts) != 3 {
161-
return fmt.Sprintf("seek-prefix-ge requires prefix and key: %s", line)
162-
}
163-
prefix, key := parts[1], parts[2]
164-
kv := iter.SeekPrefixGE([]byte(prefix), []byte(key), base.SeekGEFlagsNone)
165-
if kv != nil {
166-
output.WriteString(fmt.Sprintf("seek-prefix-ge %s: <%s:%d>:%s", key, kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
167-
} else {
168-
output.WriteString(fmt.Sprintf("seek-prefix-ge %s: .", key))
169-
}
170-
171-
case line == "next":
172-
kv := iter.Next()
173-
if kv != nil {
174-
output.WriteString(fmt.Sprintf("next: <%s:%d>:%s", kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
175-
} else {
176-
output.WriteString("next: .")
177-
}
178-
179-
case line == "prev":
180-
kv := iter.Prev()
181-
if kv != nil {
182-
output.WriteString(fmt.Sprintf("prev: <%s:%d>:%s", kv.K.UserKey, kv.K.SeqNum(), kv.InPlaceValue()))
183-
} else {
184-
output.WriteString("prev: .")
185-
}
186-
187-
default:
188-
return fmt.Sprintf("unknown iter-lazy operation: %s", line)
189-
}
190-
191-
if err := iter.Error(); err != nil {
192-
output.WriteString(fmt.Sprintf(" <err: %s>", err))
193-
}
194-
}
89+
require.NoError(t, err)
19590

196-
return output.String()
91+
return runIterCmd(td, iter, true /* printValue */, runIterCmdShowCommands)
19792
}
19893

19994
// isLazyIndexLoaded checks if the index block has been loaded for lazy iterators

sstable/testdata/reader_lazy_loading

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,41 @@ e.SET.5:E
1111
iter-lazy
1212
check-index-loaded
1313
----
14-
index-loaded: false
14+
check-index-loaded: false
1515

1616
iter-lazy
1717
first
1818
check-index-loaded
1919
----
20-
first: <a:1>:A
21-
index-loaded: true
20+
first: <a:1>:A
21+
check-index-loaded: true
2222

2323
iter-lazy
2424
check-index-loaded
2525
seek-ge c
2626
check-index-loaded
2727
----
28-
index-loaded: false
29-
seek-ge c: <c:3>:C
30-
index-loaded: true
28+
check-index-loaded: false
29+
seek-ge c: <c:3>:C
30+
check-index-loaded: true
3131

3232
iter-lazy
3333
check-index-loaded
3434
last
3535
check-index-loaded
3636
----
37-
index-loaded: false
38-
last: <e:5>:E
39-
index-loaded: true
37+
check-index-loaded: false
38+
last: <e:5>:E
39+
check-index-loaded: true
4040

4141
iter-lazy
4242
check-index-loaded
4343
seek-lt d
4444
check-index-loaded
4545
----
46-
index-loaded: false
47-
seek-lt d: <c:3>:C
48-
index-loaded: true
46+
check-index-loaded: false
47+
seek-lt d: <c:3>:C
48+
check-index-loaded: true
4949

5050
# Test with column blocks format
5151
build table-format=Pebble,v5 bloom-filter
@@ -59,23 +59,23 @@ j.SET.10:J
5959
iter-lazy
6060
check-index-loaded
6161
----
62-
index-loaded: false
62+
check-index-loaded: false
6363

6464
iter-lazy
6565
first
6666
check-index-loaded
6767
----
68-
first: <f:6>:F
69-
index-loaded: true
68+
first: <f:6>:F
69+
check-index-loaded: true
7070

7171
iter-lazy
7272
check-index-loaded
7373
seek-ge h
7474
check-index-loaded
7575
----
76-
index-loaded: false
77-
seek-ge h: <h:8>:H
78-
index-loaded: true
76+
check-index-loaded: false
77+
seek-ge h: <h:8>:H
78+
check-index-loaded: true
7979

8080
# Test bloom filter optimization - index might not be loaded for misses
8181
build table-format=Pebble,v3 bloom-filter
@@ -86,18 +86,18 @@ m.SET.13:M
8686

8787
iter-lazy
8888
check-index-loaded
89-
seek-prefix-ge nonexistent_key nonexistent_key
89+
seek-prefix-ge nonexistent_key
9090
check-index-loaded
9191
----
92-
index-loaded: false
92+
check-index-loaded: false
9393
seek-prefix-ge nonexistent_key: .
94-
index-loaded: false
94+
check-index-loaded: false
9595

9696
iter-lazy
9797
check-index-loaded
98-
seek-prefix-ge k k
98+
seek-prefix-ge k
9999
check-index-loaded
100100
----
101-
index-loaded: false
102-
seek-prefix-ge k: <k:11>:K
103-
index-loaded: true
101+
check-index-loaded: false
102+
seek-prefix-ge k: <k:11>:K
103+
check-index-loaded: true

0 commit comments

Comments
 (0)