github.com/cosmos/cosmos-sdk@v0.50.10/types/query/fuzz_test.go (about) 1 package query_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 fuzz "github.com/google/gofuzz" 8 9 "cosmossdk.io/math" 10 "cosmossdk.io/store/prefix" 11 12 sdk "github.com/cosmos/cosmos-sdk/types" 13 "github.com/cosmos/cosmos-sdk/types/address" 14 "github.com/cosmos/cosmos-sdk/types/query" 15 "github.com/cosmos/cosmos-sdk/x/bank/testutil" 16 "github.com/cosmos/cosmos-sdk/x/bank/types" 17 ) 18 19 type fuzzTestSuite struct { 20 paginationTestSuite 21 } 22 23 func FuzzPagination(f *testing.F) { 24 if testing.Short() { 25 f.Skip("In -short mode") 26 } 27 28 suite := new(fuzzTestSuite) 29 suite.SetT(new(testing.T)) 30 suite.SetupTest() 31 32 gf := fuzz.New() 33 // 1. Set up some seeds. 34 seeds := []*query.PageRequest{ 35 new(query.PageRequest), 36 { 37 Offset: 0, 38 Limit: 10, 39 }, 40 } 41 42 // 1.5. Use the inprocess fuzzer to mutate variables. 43 for i := 0; i < 1000; i++ { 44 qr := new(query.PageRequest) 45 gf.Fuzz(qr) 46 seeds = append(seeds, qr) 47 } 48 49 // 2. Now serialize the fuzzers to bytes so that future mutations 50 // can occur. 51 for _, seed := range seeds { 52 seedBlob, err := suite.cdc.Marshal(seed) 53 if err == nil { // Some seeds could have been invalid so only add those that marshal. 54 f.Add(seedBlob) 55 } 56 } 57 58 // 3. Setup the keystore. 59 var balances sdk.Coins 60 for i := 0; i < 5; i++ { 61 denom := fmt.Sprintf("foo%ddenom", i) 62 balances = append(balances, sdk.NewInt64Coin(denom, int64(100+i))) 63 } 64 65 balances = balances.Sort() 66 addr1 := sdk.AccAddress([]byte("addr1")) 67 acc1 := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr1) 68 suite.accountKeeper.SetAccount(suite.ctx, acc1) 69 err := testutil.FundAccount(suite.ctx, suite.bankKeeper, addr1, balances) 70 if err != nil { // should return no error 71 f.Fatal(err) 72 } 73 74 // 4. Now run that fuzzer! 75 f.Fuzz(func(t *testing.T, pagBz []byte) { 76 qr := new(query.PageRequest) 77 if err := suite.cdc.Unmarshal(pagBz, qr); err != nil { 78 // Some pagination requests won't unmarshal and that's okay. 79 return 80 } 81 82 // Now try to paginate it. 83 req := types.NewQueryAllBalancesRequest(addr1, qr, false) 84 balResult := sdk.NewCoins() 85 authStore := suite.ctx.KVStore(suite.app.UnsafeFindStoreKey(types.StoreKey)) 86 balancesStore := prefix.NewStore(authStore, types.BalancesPrefix) 87 accountStore := prefix.NewStore(balancesStore, address.MustLengthPrefix(addr1)) 88 _, _ = query.Paginate(accountStore, req.Pagination, func(key, value []byte) error { 89 var amount math.Int 90 err := amount.Unmarshal(value) 91 if err != nil { 92 return err 93 } 94 balResult = append(balResult, sdk.NewCoin(string(key), amount)) 95 return nil 96 }) 97 }) 98 }