github.com/Finschia/finschia-sdk@v0.48.1/x/params/keeper/keeper_test.go (about) 1 package keeper_test 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 "github.com/stretchr/testify/suite" 9 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 10 11 "github.com/Finschia/finschia-sdk/baseapp" 12 "github.com/Finschia/finschia-sdk/simapp" 13 "github.com/Finschia/finschia-sdk/store/prefix" 14 sdk "github.com/Finschia/finschia-sdk/types" 15 "github.com/Finschia/finschia-sdk/x/params/types" 16 "github.com/Finschia/finschia-sdk/x/params/types/proposal" 17 ) 18 19 type KeeperTestSuite struct { 20 suite.Suite 21 22 app *simapp.SimApp 23 ctx sdk.Context 24 25 queryClient proposal.QueryClient 26 } 27 28 func (suite *KeeperTestSuite) SetupTest() { 29 suite.app, suite.ctx = createTestApp(true) 30 31 queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) 32 proposal.RegisterQueryServer(queryHelper, suite.app.ParamsKeeper) 33 suite.queryClient = proposal.NewQueryClient(queryHelper) 34 } 35 36 func TestKeeperTestSuite(t *testing.T) { 37 suite.Run(t, new(KeeperTestSuite)) 38 } 39 40 // returns context and app 41 func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { 42 app := simapp.Setup(isCheckTx) 43 ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) 44 45 return app, ctx 46 } 47 48 func validateNoOp(_ interface{}) error { return nil } 49 50 func TestKeeper(t *testing.T) { 51 kvs := []struct { 52 key string 53 param int64 54 }{ 55 {"key1", 10}, 56 {"key2", 55}, 57 {"key3", 182}, 58 {"key4", 17582}, 59 {"key5", 2768554}, 60 {"key6", 1157279}, 61 {"key7", 9058701}, 62 } 63 64 table := types.NewKeyTable( 65 types.NewParamSetPair([]byte("key1"), int64(0), validateNoOp), 66 types.NewParamSetPair([]byte("key2"), int64(0), validateNoOp), 67 types.NewParamSetPair([]byte("key3"), int64(0), validateNoOp), 68 types.NewParamSetPair([]byte("key4"), int64(0), validateNoOp), 69 types.NewParamSetPair([]byte("key5"), int64(0), validateNoOp), 70 types.NewParamSetPair([]byte("key6"), int64(0), validateNoOp), 71 types.NewParamSetPair([]byte("key7"), int64(0), validateNoOp), 72 types.NewParamSetPair([]byte("extra1"), bool(false), validateNoOp), 73 types.NewParamSetPair([]byte("extra2"), string(""), validateNoOp), 74 ) 75 76 cdc, ctx, skey, keeper := testComponents() 77 78 store := prefix.NewStore(ctx.KVStore(skey), []byte("test/")) 79 space := keeper.Subspace("test") 80 require.False(t, space.HasKeyTable()) 81 space = space.WithKeyTable(table) 82 require.True(t, space.HasKeyTable()) 83 84 // Set params 85 for i, kv := range kvs { 86 kv := kv 87 require.NotPanics(t, func() { space.Set(ctx, []byte(kv.key), kv.param) }, "space.Set panics, tc #%d", i) 88 } 89 90 // Test space.Get 91 for i, kv := range kvs { 92 i, kv := i, kv 93 var param int64 94 require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), ¶m) }, "space.Get panics, tc #%d", i) 95 require.Equal(t, kv.param, param, "stored param not equal, tc #%d", i) 96 } 97 98 // Test space.GetRaw 99 for i, kv := range kvs { 100 var param int64 101 bz := space.GetRaw(ctx, []byte(kv.key)) 102 err := cdc.UnmarshalJSON(bz, ¶m) 103 require.Nil(t, err, "err is not nil, tc #%d", i) 104 require.Equal(t, kv.param, param, "stored param not equal, tc #%d", i) 105 } 106 107 // Test store.Get equals space.Get 108 for i, kv := range kvs { 109 var param int64 110 bz := store.Get([]byte(kv.key)) 111 require.NotNil(t, bz, "KVStore.Get returns nil, tc #%d", i) 112 err := cdc.UnmarshalJSON(bz, ¶m) 113 require.NoError(t, err, "UnmarshalJSON returns error, tc #%d", i) 114 require.Equal(t, kv.param, param, "stored param not equal, tc #%d", i) 115 } 116 117 // Test invalid space.Get 118 for i, kv := range kvs { 119 kv := kv 120 var param bool 121 require.Panics(t, func() { space.Get(ctx, []byte(kv.key), ¶m) }, "invalid space.Get not panics, tc #%d", i) 122 } 123 124 // Test invalid space.Set 125 for i, kv := range kvs { 126 kv := kv 127 require.Panics(t, func() { space.Set(ctx, []byte(kv.key), true) }, "invalid space.Set not panics, tc #%d", i) 128 } 129 130 // Test GetSubspace 131 for i, kv := range kvs { 132 i, kv := i, kv 133 var gparam, param int64 134 gspace, ok := keeper.GetSubspace("test") 135 require.True(t, ok, "cannot retrieve subspace, tc #%d", i) 136 137 require.NotPanics(t, func() { gspace.Get(ctx, []byte(kv.key), &gparam) }) 138 require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), ¶m) }) 139 require.Equal(t, gparam, param, "GetSubspace().Get not equal with space.Get, tc #%d", i) 140 141 require.NotPanics(t, func() { gspace.Set(ctx, []byte(kv.key), int64(i)) }) 142 require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), ¶m) }) 143 require.Equal(t, int64(i), param, "GetSubspace().Set not equal with space.Get, tc #%d", i) 144 } 145 } 146 147 func indirect(ptr interface{}) interface{} { 148 return reflect.ValueOf(ptr).Elem().Interface() 149 } 150 151 func TestSubspace(t *testing.T) { 152 cdc, ctx, key, keeper := testComponents() 153 154 kvs := []struct { 155 key string 156 param interface{} 157 zero interface{} 158 ptr interface{} 159 }{ 160 {"string", "test", "", new(string)}, 161 {"bool", true, false, new(bool)}, 162 {"int16", int16(1), int16(0), new(int16)}, 163 {"int32", int32(1), int32(0), new(int32)}, 164 {"int64", int64(1), int64(0), new(int64)}, 165 {"uint16", uint16(1), uint16(0), new(uint16)}, 166 {"uint32", uint32(1), uint32(0), new(uint32)}, 167 {"uint64", uint64(1), uint64(0), new(uint64)}, 168 {"int", sdk.NewInt(1), *new(sdk.Int), new(sdk.Int)}, 169 {"uint", sdk.NewUint(1), *new(sdk.Uint), new(sdk.Uint)}, 170 {"dec", sdk.NewDec(1), *new(sdk.Dec), new(sdk.Dec)}, 171 {"struct", s{1}, s{0}, new(s)}, 172 } 173 174 table := types.NewKeyTable( 175 types.NewParamSetPair([]byte("string"), "", validateNoOp), 176 types.NewParamSetPair([]byte("bool"), false, validateNoOp), 177 types.NewParamSetPair([]byte("int16"), int16(0), validateNoOp), 178 types.NewParamSetPair([]byte("int32"), int32(0), validateNoOp), 179 types.NewParamSetPair([]byte("int64"), int64(0), validateNoOp), 180 types.NewParamSetPair([]byte("uint16"), uint16(0), validateNoOp), 181 types.NewParamSetPair([]byte("uint32"), uint32(0), validateNoOp), 182 types.NewParamSetPair([]byte("uint64"), uint64(0), validateNoOp), 183 types.NewParamSetPair([]byte("int"), sdk.Int{}, validateNoOp), 184 types.NewParamSetPair([]byte("uint"), sdk.Uint{}, validateNoOp), 185 types.NewParamSetPair([]byte("dec"), sdk.Dec{}, validateNoOp), 186 types.NewParamSetPair([]byte("struct"), s{}, validateNoOp), 187 ) 188 189 store := prefix.NewStore(ctx.KVStore(key), []byte("test/")) 190 space := keeper.Subspace("test").WithKeyTable(table) 191 192 // Test space.Set 193 for i, kv := range kvs { 194 i, kv := i, kv 195 require.NotPanics(t, func() { space.Set(ctx, []byte(kv.key), kv.param) }, "space.Set panics, tc #%d", i) 196 } 197 198 // Test space.Get, space.GetIfExists 199 for i, kv := range kvs { 200 i, kv := i, kv 201 require.NotPanics(t, func() { space.GetIfExists(ctx, []byte("invalid"), kv.ptr) }, "space.GetIfExists panics when no value exists, tc #%d", i) 202 require.Equal(t, kv.zero, indirect(kv.ptr), "space.GetIfExists unmarshalls when no value exists, tc #%d", i) 203 require.Panics(t, func() { space.Get(ctx, []byte("invalid"), kv.ptr) }, "invalid space.Get not panics when no value exists, tc #%d", i) 204 require.Equal(t, kv.zero, indirect(kv.ptr), "invalid space.Get unmarshalls when no value exists, tc #%d", i) 205 206 require.NotPanics(t, func() { space.GetIfExists(ctx, []byte(kv.key), kv.ptr) }, "space.GetIfExists panics, tc #%d", i) 207 require.Equal(t, kv.param, indirect(kv.ptr), "stored param not equal, tc #%d", i) 208 require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), kv.ptr) }, "space.Get panics, tc #%d", i) 209 require.Equal(t, kv.param, indirect(kv.ptr), "stored param not equal, tc #%d", i) 210 211 require.Panics(t, func() { space.Get(ctx, []byte("invalid"), kv.ptr) }, "invalid space.Get not panics when no value exists, tc #%d", i) 212 require.Equal(t, kv.param, indirect(kv.ptr), "invalid space.Get unmarshalls when no value existt, tc #%d", i) 213 214 require.Panics(t, func() { space.Get(ctx, []byte(kv.key), nil) }, "invalid space.Get not panics when the pointer is nil, tc #%d", i) 215 require.Panics(t, func() { space.Get(ctx, []byte(kv.key), new(invalid)) }, "invalid space.Get not panics when the pointer is different type, tc #%d", i) 216 } 217 218 // Test store.Get equals space.Get 219 for i, kv := range kvs { 220 bz := store.Get([]byte(kv.key)) 221 require.NotNil(t, bz, "store.Get() returns nil, tc #%d", i) 222 err := cdc.UnmarshalJSON(bz, kv.ptr) 223 require.NoError(t, err, "cdc.UnmarshalJSON() returns error, tc #%d", i) 224 require.Equal(t, kv.param, indirect(kv.ptr), "stored param not equal, tc #%d", i) 225 } 226 } 227 228 type paramJSON struct { 229 Param1 int64 `json:"param1,omitempty" yaml:"param1,omitempty"` 230 Param2 string `json:"param2,omitempty" yaml:"param2,omitempty"` 231 } 232 233 func TestJSONUpdate(t *testing.T) { 234 _, ctx, _, keeper := testComponents() 235 236 key := []byte("key") 237 238 space := keeper.Subspace("test").WithKeyTable(types.NewKeyTable(types.NewParamSetPair(key, paramJSON{}, validateNoOp))) 239 240 var param paramJSON 241 242 err := space.Update(ctx, key, []byte(`{"param1": "10241024"}`)) 243 require.NoError(t, err) 244 space.Get(ctx, key, ¶m) 245 require.Equal(t, paramJSON{10241024, ""}, param) 246 247 err = space.Update(ctx, key, []byte(`{"param2": "helloworld"}`)) 248 require.NoError(t, err) 249 space.Get(ctx, key, ¶m) 250 require.Equal(t, paramJSON{10241024, "helloworld"}, param) 251 252 err = space.Update(ctx, key, []byte(`{"param1": "20482048"}`)) 253 require.NoError(t, err) 254 space.Get(ctx, key, ¶m) 255 require.Equal(t, paramJSON{20482048, "helloworld"}, param) 256 257 err = space.Update(ctx, key, []byte(`{"param1": "40964096", "param2": "goodbyeworld"}`)) 258 require.NoError(t, err) 259 space.Get(ctx, key, ¶m) 260 require.Equal(t, paramJSON{40964096, "goodbyeworld"}, param) 261 }