cosmos-sdk/x/params/keeper_test.go
Alexander Bezobchuk 5ca93ac574 Merge PR #4206: Param Change Proposal
* Add params error types

* Update param module keeper to take a codespace

* Update imports

* Implement SetRaw and SetRawWithSubkey

* Implement ParamChange and update aliases

* Add types codec

* Implement ParameterChangeProposal

* Implement TestParameterChangeProposal

* Fix linting errors

* Update tags

* Implement content

* Updata params aliases

* Finish params handler and proposal types

* Move deposit and vote logic to types package

* Move proposal type to types package

* Move errors to types package

* Update proposal

* Move gov messages to types package

* Minor updates to naming

* Move keys to types package

* Move codec to types package

* Move proposal types to types package

* Update aliases

* Add governance alias types

* Implement governance router

* Update gov aliases

* Update gov keeper

* Update private functions needed for the keeper

* Update godocs

* Update the gov message handler

* Update Gaia app

* Make updates to auth

* Update the message codec in the keeper

* Update gov end blocker

* Update types tests

* Minor tweaks

* Add legacy genesis logic

* Update gov aliases

* Move gov keys to types package

* Revertt to using gov/types in params

* Implement params handler test

* Update governance tests

* Fix endblocker tests

* Fix governance querier tests

* Add seal support to gov router

* Update simulationCreateMsgSubmitProposal

* Disable software upgrade proposals

* Move params keys to types package

* Implement param module proposal client logic

* Update gov client logic

* Update gaia app client hooks

* Fix linting errors

* Fix ValidateBasic

* Remove legacy files

* Update paramchange to use strings

* Update paramchange cli cmd

* Update ValidateBasic and errors

* Use PostCommands when adding child cmds

* Fix codec logic

* Update params client and handler

* Update IsValidProposalType

* Update SubmitProposal to test exec

* Implement TestGaiaCLISubmitParamChangeProposal

* Implement TestSubmitParamChangeProposal

* Update swagger.yaml

* Update gaiacli.md

* Update gov spec docs

* Fix linting errors

* Fix unit tests

* Add pending log entries

* Update docs

* Update docs

* Update client/lcd/swagger-ui/swagger.yaml

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update cmd/gaia/cli_test/test_helpers.go

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update client/lcd/test_helpers.go

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update x/gov/types/proposal.go

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Address PR comments

* Update docs/cosmos-hub/gaiacli.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update gov docs to include quorum notes

* Add logs to handleParameterChangeProposal

* Update docs/spec/governance/02_state.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Support and use new StatusFailed when proposal passes but fails exec

* Add docs/notes warning on param validity

* Update docs

* Update docs/spec/governance/02_state.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Update docs/spec/governance/02_state.md

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Minor doc update

* Update x/gov/client/cli/tx.go

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Fix usage of fromAddr

* Rige code style  suggestion

* Update x/params/types/proposal.go

Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com>

* Fix CI lint errors

* Update NewModuleClient godoc

* Add godoc to rtr.Seal() call

* Rename files

* Rename NewProposalHandler
2019-04-30 12:31:38 -04:00

219 lines
7.4 KiB
Go

package params
import (
"reflect"
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func defaultContext(key sdk.StoreKey, tkey sdk.StoreKey) sdk.Context {
db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db)
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
cms.MountStoreWithDB(tkey, sdk.StoreTypeTransient, db)
cms.LoadLatestVersion()
ctx := sdk.NewContext(cms, abci.Header{}, false, log.NewNopLogger())
return ctx
}
type invalid struct{}
type s struct {
I int
}
func createTestCodec() *codec.Codec {
cdc := codec.New()
sdk.RegisterCodec(cdc)
cdc.RegisterConcrete(s{}, "test/s", nil)
cdc.RegisterConcrete(invalid{}, "test/invalid", nil)
return cdc
}
func TestKeeper(t *testing.T) {
kvs := []struct {
key string
param int64
}{
{"key1", 10},
{"key2", 55},
{"key3", 182},
{"key4", 17582},
{"key5", 2768554},
{"key6", 1157279},
{"key7", 9058701},
}
table := NewKeyTable(
[]byte("key1"), int64(0),
[]byte("key2"), int64(0),
[]byte("key3"), int64(0),
[]byte("key4"), int64(0),
[]byte("key5"), int64(0),
[]byte("key6"), int64(0),
[]byte("key7"), int64(0),
[]byte("extra1"), bool(false),
[]byte("extra2"), string(""),
)
cdc := codec.New()
skey := sdk.NewKVStoreKey("test")
tkey := sdk.NewTransientStoreKey("transient_test")
ctx := defaultContext(skey, tkey)
keeper := NewKeeper(cdc, skey, tkey, DefaultCodespace)
store := prefix.NewStore(ctx.KVStore(skey), []byte("test/"))
space := keeper.Subspace("test").WithKeyTable(table)
// Set params
for i, kv := range kvs {
require.NotPanics(t, func() { space.Set(ctx, []byte(kv.key), kv.param) }, "space.Set panics, tc #%d", i)
}
// Test space.Get
for i, kv := range kvs {
var param int64
require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), &param) }, "space.Get panics, tc #%d", i)
require.Equal(t, kv.param, param, "stored param not equal, tc #%d", i)
}
// Test space.GetRaw
for i, kv := range kvs {
var param int64
bz := space.GetRaw(ctx, []byte(kv.key))
err := cdc.UnmarshalJSON(bz, &param)
require.Nil(t, err, "err is not nil, tc #%d", i)
require.Equal(t, kv.param, param, "stored param not equal, tc #%d", i)
}
// Test store.Get equals space.Get
for i, kv := range kvs {
var param int64
bz := store.Get([]byte(kv.key))
require.NotNil(t, bz, "KVStore.Get returns nil, tc #%d", i)
err := cdc.UnmarshalJSON(bz, &param)
require.NoError(t, err, "UnmarshalJSON returns error, tc #%d", i)
require.Equal(t, kv.param, param, "stored param not equal, tc #%d", i)
}
// Test invalid space.Get
for i, kv := range kvs {
var param bool
require.Panics(t, func() { space.Get(ctx, []byte(kv.key), &param) }, "invalid space.Get not panics, tc #%d", i)
}
// Test invalid space.Set
for i, kv := range kvs {
require.Panics(t, func() { space.Set(ctx, []byte(kv.key), true) }, "invalid space.Set not panics, tc #%d", i)
}
// Test GetSubspace
for i, kv := range kvs {
var gparam, param int64
gspace, ok := keeper.GetSubspace("test")
require.True(t, ok, "cannot retrieve subspace, tc #%d", i)
require.NotPanics(t, func() { gspace.Get(ctx, []byte(kv.key), &gparam) })
require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), &param) })
require.Equal(t, gparam, param, "GetSubspace().Get not equal with space.Get, tc #%d", i)
require.NotPanics(t, func() { gspace.Set(ctx, []byte(kv.key), int64(i)) })
require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), &param) })
require.Equal(t, int64(i), param, "GetSubspace().Set not equal with space.Get, tc #%d", i)
}
}
func indirect(ptr interface{}) interface{} {
return reflect.ValueOf(ptr).Elem().Interface()
}
func TestSubspace(t *testing.T) {
cdc := createTestCodec()
key := sdk.NewKVStoreKey("test")
tkey := sdk.NewTransientStoreKey("transient_test")
ctx := defaultContext(key, tkey)
keeper := NewKeeper(cdc, key, tkey, DefaultCodespace)
kvs := []struct {
key string
param interface{}
zero interface{}
ptr interface{}
}{
{"string", "test", "", new(string)},
{"bool", true, false, new(bool)},
{"int16", int16(1), int16(0), new(int16)},
{"int32", int32(1), int32(0), new(int32)},
{"int64", int64(1), int64(0), new(int64)},
{"uint16", uint16(1), uint16(0), new(uint16)},
{"uint32", uint32(1), uint32(0), new(uint32)},
{"uint64", uint64(1), uint64(0), new(uint64)},
{"int", sdk.NewInt(1), *new(sdk.Int), new(sdk.Int)},
{"uint", sdk.NewUint(1), *new(sdk.Uint), new(sdk.Uint)},
{"dec", sdk.NewDec(1), *new(sdk.Dec), new(sdk.Dec)},
{"struct", s{1}, s{0}, new(s)},
}
table := NewKeyTable(
[]byte("string"), string(""),
[]byte("bool"), bool(false),
[]byte("int16"), int16(0),
[]byte("int32"), int32(0),
[]byte("int64"), int64(0),
[]byte("uint16"), uint16(0),
[]byte("uint32"), uint32(0),
[]byte("uint64"), uint64(0),
[]byte("int"), sdk.Int{},
[]byte("uint"), sdk.Uint{},
[]byte("dec"), sdk.Dec{},
[]byte("struct"), s{},
)
store := prefix.NewStore(ctx.KVStore(key), []byte("test/"))
space := keeper.Subspace("test").WithKeyTable(table)
// Test space.Set, space.Modified
for i, kv := range kvs {
require.False(t, space.Modified(ctx, []byte(kv.key)), "space.Modified returns true before setting, tc #%d", i)
require.NotPanics(t, func() { space.Set(ctx, []byte(kv.key), kv.param) }, "space.Set panics, tc #%d", i)
require.True(t, space.Modified(ctx, []byte(kv.key)), "space.Modified returns false after setting, tc #%d", i)
}
// Test space.Get, space.GetIfExists
for i, kv := range kvs {
require.NotPanics(t, func() { space.GetIfExists(ctx, []byte("invalid"), kv.ptr) }, "space.GetIfExists panics when no value exists, tc #%d", i)
require.Equal(t, kv.zero, indirect(kv.ptr), "space.GetIfExists unmarshalls when no value exists, tc #%d", i)
require.Panics(t, func() { space.Get(ctx, []byte("invalid"), kv.ptr) }, "invalid space.Get not panics when no value exists, tc #%d", i)
require.Equal(t, kv.zero, indirect(kv.ptr), "invalid space.Get unmarshalls when no value exists, tc #%d", i)
require.NotPanics(t, func() { space.GetIfExists(ctx, []byte(kv.key), kv.ptr) }, "space.GetIfExists panics, tc #%d", i)
require.Equal(t, kv.param, indirect(kv.ptr), "stored param not equal, tc #%d", i)
require.NotPanics(t, func() { space.Get(ctx, []byte(kv.key), kv.ptr) }, "space.Get panics, tc #%d", i)
require.Equal(t, kv.param, indirect(kv.ptr), "stored param not equal, tc #%d", i)
require.Panics(t, func() { space.Get(ctx, []byte("invalid"), kv.ptr) }, "invalid space.Get not panics when no value exists, tc #%d", i)
require.Equal(t, kv.param, indirect(kv.ptr), "invalid space.Get unmarshalls when no value existt, tc #%d", i)
require.Panics(t, func() { space.Get(ctx, []byte(kv.key), nil) }, "invalid space.Get not panics when the pointer is nil, tc #%d", i)
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)
}
// Test store.Get equals space.Get
for i, kv := range kvs {
bz := store.Get([]byte(kv.key))
require.NotNil(t, bz, "store.Get() returns nil, tc #%d", i)
err := cdc.UnmarshalJSON(bz, kv.ptr)
require.NoError(t, err, "cdc.UnmarshalJSON() returns error, tc #%d", i)
require.Equal(t, kv.param, indirect(kv.ptr), "stored param not equal, tc #%d", i)
}
}