@@ -7,12 +7,12 @@ package sstable
77import (
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 (
2121func 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
0 commit comments