github.com/cosmos/cosmos-sdk@v0.50.10/x/params/types/subspace_test.go (about) 1 package types_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "testing" 7 "time" 8 9 cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" 10 dbm "github.com/cosmos/cosmos-db" 11 "github.com/stretchr/testify/suite" 12 13 "cosmossdk.io/log" 14 "cosmossdk.io/store" 15 "cosmossdk.io/store/metrics" 16 storetypes "cosmossdk.io/store/types" 17 18 "github.com/cosmos/cosmos-sdk/codec" 19 sdk "github.com/cosmos/cosmos-sdk/types" 20 moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" 21 paramsmodule "github.com/cosmos/cosmos-sdk/x/params" 22 "github.com/cosmos/cosmos-sdk/x/params/types" 23 ) 24 25 type SubspaceTestSuite struct { 26 suite.Suite 27 28 cdc codec.Codec 29 amino *codec.LegacyAmino 30 ctx sdk.Context 31 ss types.Subspace 32 } 33 34 func (suite *SubspaceTestSuite) SetupTest() { 35 db := dbm.NewMemDB() 36 37 ms := store.NewCommitMultiStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics()) 38 ms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) 39 ms.MountStoreWithDB(tkey, storetypes.StoreTypeTransient, db) 40 suite.NoError(ms.LoadLatestVersion()) 41 42 encodingConfig := moduletestutil.MakeTestEncodingConfig(paramsmodule.AppModuleBasic{}) 43 suite.cdc = encodingConfig.Codec 44 suite.amino = encodingConfig.Amino 45 46 ss := types.NewSubspace(suite.cdc, suite.amino, key, tkey, "testsubspace") 47 suite.ctx = sdk.NewContext(ms, cmtproto.Header{}, false, log.NewNopLogger()) 48 suite.ss = ss.WithKeyTable(paramKeyTable()) 49 } 50 51 func (suite *SubspaceTestSuite) TestKeyTable() { 52 suite.Require().True(suite.ss.HasKeyTable()) 53 suite.Require().Panics(func() { 54 suite.ss.WithKeyTable(paramKeyTable()) 55 }) 56 suite.Require().NotPanics(func() { 57 ss := types.NewSubspace(suite.cdc, suite.amino, key, tkey, "testsubspace2") 58 _ = ss.WithKeyTable(paramKeyTable()) 59 }) 60 } 61 62 func (suite *SubspaceTestSuite) TestGetSet() { 63 var v time.Duration 64 t := time.Hour * 48 65 66 suite.Require().Panics(func() { 67 suite.ss.Get(suite.ctx, keyUnbondingTime, &v) 68 }) 69 suite.Require().NotEqual(t, v) 70 suite.Require().NotPanics(func() { 71 suite.ss.Set(suite.ctx, keyUnbondingTime, t) 72 }) 73 suite.Require().NotPanics(func() { 74 suite.ss.Get(suite.ctx, keyUnbondingTime, &v) 75 }) 76 suite.Require().Equal(t, v) 77 } 78 79 func (suite *SubspaceTestSuite) TestGetIfExists() { 80 var v time.Duration 81 82 suite.Require().NotPanics(func() { 83 suite.ss.GetIfExists(suite.ctx, keyUnbondingTime, &v) 84 }) 85 suite.Require().Equal(time.Duration(0), v) 86 } 87 88 func (suite *SubspaceTestSuite) TestGetRaw() { 89 t := time.Hour * 48 90 91 suite.Require().NotPanics(func() { 92 suite.ss.Set(suite.ctx, keyUnbondingTime, t) 93 }) 94 suite.Require().NotPanics(func() { 95 res := suite.ss.GetRaw(suite.ctx, keyUnbondingTime) 96 suite.Require().Equal("2231373238303030303030303030303022", fmt.Sprintf("%X", res)) 97 }) 98 } 99 100 func (suite *SubspaceTestSuite) TestIterateKeys() { 101 suite.Require().NotPanics(func() { 102 suite.ss.Set(suite.ctx, keyUnbondingTime, time.Second) 103 }) 104 suite.Require().NotPanics(func() { 105 suite.ss.Set(suite.ctx, keyMaxValidators, uint16(50)) 106 }) 107 suite.Require().NotPanics(func() { 108 suite.ss.Set(suite.ctx, keyBondDenom, "stake") 109 }) 110 111 var keys [][]byte 112 suite.ss.IterateKeys(suite.ctx, func(key []byte) bool { 113 keys = append(keys, key) 114 return false 115 }) 116 suite.Require().Len(keys, 3) 117 suite.Require().Contains(keys, keyUnbondingTime) 118 suite.Require().Contains(keys, keyMaxValidators) 119 suite.Require().Contains(keys, keyBondDenom) 120 121 var keys2 [][]byte 122 suite.ss.IterateKeys(suite.ctx, func(key []byte) bool { 123 if bytes.Equal(key, keyUnbondingTime) { 124 return true 125 } 126 127 keys2 = append(keys2, key) 128 return false 129 }) 130 suite.Require().Len(keys2, 2) 131 suite.Require().Contains(keys2, keyMaxValidators) 132 suite.Require().Contains(keys2, keyBondDenom) 133 } 134 135 func (suite *SubspaceTestSuite) TestHas() { 136 t := time.Hour * 48 137 138 suite.Require().False(suite.ss.Has(suite.ctx, keyUnbondingTime)) 139 suite.Require().NotPanics(func() { 140 suite.ss.Set(suite.ctx, keyUnbondingTime, t) 141 }) 142 suite.Require().True(suite.ss.Has(suite.ctx, keyUnbondingTime)) 143 } 144 145 func (suite *SubspaceTestSuite) TestModified() { 146 t := time.Hour * 48 147 148 suite.Require().False(suite.ss.Modified(suite.ctx, keyUnbondingTime)) 149 suite.Require().NotPanics(func() { 150 suite.ss.Set(suite.ctx, keyUnbondingTime, t) 151 }) 152 suite.Require().True(suite.ss.Modified(suite.ctx, keyUnbondingTime)) 153 } 154 155 func (suite *SubspaceTestSuite) TestUpdate() { 156 suite.Require().Panics(func() { 157 suite.ss.Update(suite.ctx, []byte("invalid_key"), nil) 158 }) 159 160 t := time.Hour * 48 161 suite.Require().NotPanics(func() { 162 suite.ss.Set(suite.ctx, keyUnbondingTime, t) 163 }) 164 165 bad := time.Minute * 5 166 167 bz, err := suite.amino.MarshalJSON(bad) 168 suite.Require().NoError(err) 169 suite.Require().Error(suite.ss.Update(suite.ctx, keyUnbondingTime, bz)) 170 171 good := time.Hour * 360 172 bz, err = suite.amino.MarshalJSON(good) 173 suite.Require().NoError(err) 174 suite.Require().NoError(suite.ss.Update(suite.ctx, keyUnbondingTime, bz)) 175 176 var v time.Duration 177 178 suite.Require().NotPanics(func() { 179 suite.ss.Get(suite.ctx, keyUnbondingTime, &v) 180 }) 181 suite.Require().Equal(good, v) 182 } 183 184 func (suite *SubspaceTestSuite) TestGetParamSet() { 185 a := params{ 186 UnbondingTime: time.Hour * 48, 187 MaxValidators: 100, 188 BondDenom: "stake", 189 } 190 suite.Require().NotPanics(func() { 191 suite.ss.Set(suite.ctx, keyUnbondingTime, a.UnbondingTime) 192 suite.ss.Set(suite.ctx, keyMaxValidators, a.MaxValidators) 193 suite.ss.Set(suite.ctx, keyBondDenom, a.BondDenom) 194 }) 195 196 b := params{} 197 suite.Require().NotPanics(func() { 198 suite.ss.GetParamSet(suite.ctx, &b) 199 }) 200 suite.Require().Equal(a.UnbondingTime, b.UnbondingTime) 201 suite.Require().Equal(a.MaxValidators, b.MaxValidators) 202 suite.Require().Equal(a.BondDenom, b.BondDenom) 203 } 204 205 func (suite *SubspaceTestSuite) TestGetParamSetIfExists() { 206 a := params{ 207 UnbondingTime: time.Hour * 48, 208 MaxValidators: 100, 209 BondDenom: "stake", 210 } 211 suite.Require().NotPanics(func() { 212 suite.ss.Set(suite.ctx, keyUnbondingTime, a.UnbondingTime) 213 suite.ss.Set(suite.ctx, keyMaxValidators, a.MaxValidators) 214 suite.ss.Set(suite.ctx, keyBondDenom, a.BondDenom) 215 }) 216 217 b := paramsV2{} 218 suite.Require().NotPanics(func() { 219 suite.ss.GetParamSetIfExists(suite.ctx, &b) 220 }) 221 suite.Require().Equal(a.UnbondingTime, b.UnbondingTime) 222 suite.Require().Equal(a.MaxValidators, b.MaxValidators) 223 suite.Require().Equal(a.BondDenom, b.BondDenom) 224 suite.Require().Zero(b.MaxRedelegationEntries) 225 suite.Require().False(suite.ss.Has(suite.ctx, keyMaxRedelegationEntries), "key from the new param version should not yet exist") 226 } 227 228 func (suite *SubspaceTestSuite) TestSetParamSet() { 229 testCases := []struct { 230 name string 231 ps types.ParamSet 232 }{ 233 {"invalid unbonding time", ¶ms{time.Hour * 1, 100, "stake"}}, 234 {"invalid bond denom", ¶ms{time.Hour * 48, 100, ""}}, 235 } 236 237 for _, tc := range testCases { 238 tc := tc 239 suite.Run(tc.name, func() { 240 suite.Require().Panics(func() { 241 suite.ss.SetParamSet(suite.ctx, tc.ps) 242 }) 243 }) 244 } 245 246 a := params{ 247 UnbondingTime: time.Hour * 48, 248 MaxValidators: 100, 249 BondDenom: "stake", 250 } 251 suite.Require().NotPanics(func() { 252 suite.ss.SetParamSet(suite.ctx, &a) 253 }) 254 255 b := params{} 256 suite.Require().NotPanics(func() { 257 suite.ss.GetParamSet(suite.ctx, &b) 258 }) 259 suite.Require().Equal(a.UnbondingTime, b.UnbondingTime) 260 suite.Require().Equal(a.MaxValidators, b.MaxValidators) 261 suite.Require().Equal(a.BondDenom, b.BondDenom) 262 } 263 264 func (suite *SubspaceTestSuite) TestName() { 265 suite.Require().Equal("testsubspace", suite.ss.Name()) 266 } 267 268 func TestKeeperTestSuite(t *testing.T) { 269 suite.Run(t, new(SubspaceTestSuite)) 270 }