@@ -3,6 +3,7 @@ package traversal_test
3
3
import (
4
4
"testing"
5
5
6
+ qt "github.com/frankban/quicktest"
6
7
. "github.com/warpfork/go-wish"
7
8
8
9
_ "github.com/ipld/go-ipld-prime/codec/dagjson"
@@ -257,3 +258,67 @@ func TestWalkMatching(t *testing.T) {
257
258
Wish (t , order , ShouldEqual , 7 )
258
259
})
259
260
}
261
+
262
+ func TestWalkBudgets (t * testing.T ) {
263
+ ssb := builder .NewSelectorSpecBuilder (basicnode .Prototype .Any )
264
+ t .Run ("node-budget-halts" , func (t * testing.T ) {
265
+ ss := ssb .ExploreFields (func (efsb builder.ExploreFieldsSpecBuilder ) {
266
+ efsb .Insert ("foo" , ssb .Matcher ())
267
+ efsb .Insert ("bar" , ssb .Matcher ())
268
+ })
269
+ s , err := ss .Selector ()
270
+ qt .Assert (t , err , qt .Equals , nil )
271
+ var order int
272
+ prog := traversal.Progress {}
273
+ prog .Budget = & traversal.Budget {
274
+ NodeBudget : 2 , // should reach root, then "foo", then stop.
275
+ }
276
+ err = prog .WalkMatching (middleMapNode , s , func (prog traversal.Progress , n datamodel.Node ) error {
277
+ switch order {
278
+ case 0 :
279
+ qt .Assert (t , n , qt .CmpEquals (), basicnode .NewBool (true ))
280
+ qt .Assert (t , prog .Path .String (), qt .Equals , "foo" )
281
+ }
282
+ order ++
283
+ return nil
284
+ })
285
+ qt .Check (t , order , qt .Equals , 1 ) // because it should've stopped early
286
+ qt .Assert (t , err , qt .Not (qt .Equals ), nil )
287
+ qt .Check (t , err .Error (), qt .Equals , `traversal budget exceeded: budget for nodes reached zero as we reached path "bar"` )
288
+ })
289
+ t .Run ("link-budget-halts" , func (t * testing.T ) {
290
+ ss := ssb .ExploreAll (ssb .Matcher ())
291
+ s , err := ss .Selector ()
292
+ qt .Assert (t , err , qt .Equals , nil )
293
+ var order int
294
+ lsys := cidlink .DefaultLinkSystem ()
295
+ lsys .StorageReadOpener = (& store ).OpenRead
296
+ err = traversal.Progress {
297
+ Cfg : & traversal.Config {
298
+ LinkSystem : lsys ,
299
+ LinkTargetNodePrototypeChooser : basicnode .Chooser ,
300
+ },
301
+ Budget : & traversal.Budget {
302
+ NodeBudget : 9000 ,
303
+ LinkBudget : 3 ,
304
+ },
305
+ }.WalkMatching (middleListNode , s , func (prog traversal.Progress , n datamodel.Node ) error {
306
+ switch order {
307
+ case 0 :
308
+ qt .Assert (t , n , qt .CmpEquals (), basicnode .NewString ("alpha" ))
309
+ qt .Assert (t , prog .Path .String (), qt .Equals , "0" )
310
+ case 1 :
311
+ qt .Assert (t , n , qt .CmpEquals (), basicnode .NewString ("alpha" ))
312
+ qt .Assert (t , prog .Path .String (), qt .Equals , "1" )
313
+ case 2 :
314
+ qt .Assert (t , n , qt .CmpEquals (), basicnode .NewString ("beta" ))
315
+ qt .Assert (t , prog .Path .String (), qt .Equals , "2" )
316
+ }
317
+ order ++
318
+ return nil
319
+ })
320
+ qt .Check (t , order , qt .Equals , 3 )
321
+ qt .Assert (t , err , qt .Not (qt .Equals ), nil )
322
+ qt .Check (t , err .Error (), qt .Equals , `traversal budget exceeded: budget for links reached zero as we reached path "3" (link: "baguqeeyexkjwnfy")` )
323
+ })
324
+ }
0 commit comments