From e25f80d34c38861389603a39dc5bb1f1a401ec38 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Fri, 30 Apr 2021 04:41:25 -0400 Subject: [PATCH] gov, params: refactor tests (#9137) * gov, params: refactor tests * wrap up params tests Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- x/gov/keeper/proposal_test.go | 77 +++++-------- x/params/proposal_handler_test.go | 176 ++++++++++++------------------ 2 files changed, 97 insertions(+), 156 deletions(-) diff --git a/x/gov/keeper/proposal_test.go b/x/gov/keeper/proposal_test.go index 7f62d5a56c..a40303fceb 100644 --- a/x/gov/keeper/proposal_test.go +++ b/x/gov/keeper/proposal_test.go @@ -4,54 +4,43 @@ import ( "errors" "fmt" "strings" - "testing" "time" - "github.com/stretchr/testify/require" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/gov/types" ) -func TestGetSetProposal(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - +func (suite *KeeperTestSuite) TestGetSetProposal() { tp := TestProposal - proposal, err := app.GovKeeper.SubmitProposal(ctx, tp) - require.NoError(t, err) + proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tp) + suite.Require().NoError(err) proposalID := proposal.ProposalId - app.GovKeeper.SetProposal(ctx, proposal) + suite.app.GovKeeper.SetProposal(suite.ctx, proposal) - gotProposal, ok := app.GovKeeper.GetProposal(ctx, proposalID) - require.True(t, ok) - require.True(t, proposal.Equal(gotProposal)) + gotProposal, ok := suite.app.GovKeeper.GetProposal(suite.ctx, proposalID) + suite.Require().True(ok) + suite.Require().True(proposal.Equal(gotProposal)) } -func TestActivateVotingPeriod(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - +func (suite *KeeperTestSuite) TestActivateVotingPeriod() { tp := TestProposal - proposal, err := app.GovKeeper.SubmitProposal(ctx, tp) - require.NoError(t, err) + proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tp) + suite.Require().NoError(err) - require.True(t, proposal.VotingStartTime.Equal(time.Time{})) + suite.Require().True(proposal.VotingStartTime.Equal(time.Time{})) - app.GovKeeper.ActivateVotingPeriod(ctx, proposal) + suite.app.GovKeeper.ActivateVotingPeriod(suite.ctx, proposal) - require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time)) + suite.Require().True(proposal.VotingStartTime.Equal(suite.ctx.BlockHeader().Time)) - proposal, ok := app.GovKeeper.GetProposal(ctx, proposal.ProposalId) - require.True(t, ok) + proposal, ok := suite.app.GovKeeper.GetProposal(suite.ctx, proposal.ProposalId) + suite.Require().True(ok) - activeIterator := app.GovKeeper.ActiveProposalQueueIterator(ctx, proposal.VotingEndTime) - require.True(t, activeIterator.Valid()) + activeIterator := suite.app.GovKeeper.ActiveProposalQueueIterator(suite.ctx, proposal.VotingEndTime) + suite.Require().True(activeIterator.Valid()) proposalID := types.GetProposalIDFromBytes(activeIterator.Value()) - require.Equal(t, proposalID, proposal.ProposalId) + suite.Require().Equal(proposalID, proposal.ProposalId) activeIterator.Close() } @@ -59,10 +48,7 @@ type invalidProposalRoute struct{ types.TextProposal } func (invalidProposalRoute) ProposalRoute() string { return "nonexistingroute" } -func TestSubmitProposal(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - +func (suite *KeeperTestSuite) TestSubmitProposal() { testCases := []struct { content types.Content expectedErr error @@ -78,16 +64,13 @@ func TestSubmitProposal(t *testing.T) { } for i, tc := range testCases { - _, err := app.GovKeeper.SubmitProposal(ctx, tc.content) - require.True(t, errors.Is(tc.expectedErr, err), "tc #%d; got: %v, expected: %v", i, err, tc.expectedErr) + _, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, tc.content) + suite.Require().True(errors.Is(tc.expectedErr, err), "tc #%d; got: %v, expected: %v", i, err, tc.expectedErr) } } -func TestGetProposalsFiltered(t *testing.T) { +func (suite *KeeperTestSuite) TestGetProposalsFiltered() { proposalID := uint64(1) - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - status := []types.ProposalStatus{types.StatusDepositPeriod, types.StatusVotingPeriod} addr1 := sdk.AccAddress("foo_________________") @@ -95,18 +78,18 @@ func TestGetProposalsFiltered(t *testing.T) { for _, s := range status { for i := 0; i < 50; i++ { p, err := types.NewProposal(TestProposal, proposalID, time.Now(), time.Now()) - require.NoError(t, err) + suite.Require().NoError(err) p.Status = s if i%2 == 0 { d := types.NewDeposit(proposalID, addr1, nil) v := types.NewVote(proposalID, addr1, types.NewNonSplitVoteOption(types.OptionYes)) - app.GovKeeper.SetDeposit(ctx, d) - app.GovKeeper.SetVote(ctx, v) + suite.app.GovKeeper.SetDeposit(suite.ctx, d) + suite.app.GovKeeper.SetVote(suite.ctx, v) } - app.GovKeeper.SetProposal(ctx, p) + suite.app.GovKeeper.SetProposal(suite.ctx, p) proposalID++ } } @@ -130,13 +113,13 @@ func TestGetProposalsFiltered(t *testing.T) { } for i, tc := range testCases { - t.Run(fmt.Sprintf("Test Case %d", i), func(t *testing.T) { - proposals := app.GovKeeper.GetProposalsFiltered(ctx, tc.params) - require.Len(t, proposals, tc.expectedNumResults) + suite.Run(fmt.Sprintf("Test Case %d", i), func() { + proposals := suite.app.GovKeeper.GetProposalsFiltered(suite.ctx, tc.params) + suite.Require().Len(proposals, tc.expectedNumResults) for _, p := range proposals { if types.ValidProposalStatus(tc.params.ProposalStatus) { - require.Equal(t, tc.params.ProposalStatus, p.Status) + suite.Require().Equal(tc.params.ProposalStatus, p.Status) } } }) diff --git a/x/params/proposal_handler_test.go b/x/params/proposal_handler_test.go index b4295d2e2d..b5c79669a6 100644 --- a/x/params/proposal_handler_test.go +++ b/x/params/proposal_handler_test.go @@ -3,132 +3,90 @@ package params_test import ( "testing" - "github.com/cosmos/cosmos-sdk/simapp" + "github.com/stretchr/testify/suite" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/params" - "github.com/cosmos/cosmos-sdk/x/params/keeper" - "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func validateNoOp(_ interface{}) error { return nil } +type HandlerTestSuite struct { + suite.Suite -type testInput struct { - ctx sdk.Context - cdc *codec.LegacyAmino - keeper keeper.Keeper + app *simapp.SimApp + ctx sdk.Context + govHandler govtypes.Handler } -var ( - _ types.ParamSet = (*testParams)(nil) - - keyMaxValidators = "MaxValidators" - keySlashingRate = "SlashingRate" - testSubspace = "TestSubspace" -) - -type testParamsSlashingRate struct { - DoubleSign uint16 `json:"double_sign,omitempty" yaml:"double_sign,omitempty"` - Downtime uint16 `json:"downtime,omitempty" yaml:"downtime,omitempty"` +func (suite *HandlerTestSuite) SetupTest() { + suite.app = simapp.Setup(false) + suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}) + suite.govHandler = params.NewParamChangeProposalHandler(suite.app.ParamsKeeper) } -type testParams struct { - MaxValidators uint16 `json:"max_validators" yaml:"max_validators"` // maximum number of validators (max uint16 = 65535) - SlashingRate testParamsSlashingRate `json:"slashing_rate" yaml:"slashing_rate"` -} - -func (tp *testParams) ParamSetPairs() types.ParamSetPairs { - return types.ParamSetPairs{ - types.NewParamSetPair([]byte(keyMaxValidators), &tp.MaxValidators, validateNoOp), - types.NewParamSetPair([]byte(keySlashingRate), &tp.SlashingRate, validateNoOp), - } +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) } func testProposal(changes ...proposal.ParamChange) *proposal.ParameterChangeProposal { - return proposal.NewParameterChangeProposal( - "Test", - "description", - changes, - ) + return proposal.NewParameterChangeProposal("title", "description", changes) } -func newTestInput(t *testing.T) testInput { - cdc := codec.NewLegacyAmino() - proposal.RegisterLegacyAminoCodec(cdc) +func (suite *HandlerTestSuite) TestProposalHandler() { + testCases := []struct { + name string + proposal *proposal.ParameterChangeProposal + onHandle func() + expErr bool + }{ + { + "all fields", + testProposal(proposal.NewParamChange(stakingtypes.ModuleName, string(stakingtypes.KeyMaxValidators), "1")), + func() { + maxVals := suite.app.StakingKeeper.MaxValidators(suite.ctx) + suite.Require().Equal(uint32(1), maxVals) + }, + false, + }, + { + "invalid type", + testProposal(proposal.NewParamChange(stakingtypes.ModuleName, string(stakingtypes.KeyMaxValidators), "-")), + func() {}, + true, + }, + { + "omit empty fields", + testProposal(proposal.ParamChange{ + Subspace: govtypes.ModuleName, + Key: string(govtypes.ParamStoreKeyDepositParams), + Value: `{"min_deposit": [{"denom": "uatom","amount": "64000000"}]}`, + }), + func() { + depositParams := suite.app.GovKeeper.GetDepositParams(suite.ctx) + suite.Require().Equal(govtypes.DepositParams{ + MinDeposit: sdk.NewCoins(sdk.NewCoin("uatom", sdk.NewInt(64000000))), + MaxDepositPeriod: govtypes.DefaultPeriod, + }, depositParams) + }, + false, + }, + } - db := dbm.NewMemDB() - cms := store.NewCommitMultiStore(db) - - keyParams := sdk.NewKVStoreKey("params") - tKeyParams := sdk.NewTransientStoreKey("transient_params") - - cms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) - cms.MountStoreWithDB(tKeyParams, sdk.StoreTypeTransient, db) - - err := cms.LoadLatestVersion() - require.Nil(t, err) - - encCfg := simapp.MakeTestEncodingConfig() - keeper := keeper.NewKeeper(encCfg.Marshaler, encCfg.Amino, keyParams, tKeyParams) - ctx := sdk.NewContext(cms, tmproto.Header{}, false, log.NewNopLogger()) - - return testInput{ctx, cdc, keeper} -} - -func TestProposalHandlerPassed(t *testing.T) { - input := newTestInput(t) - ss := input.keeper.Subspace(testSubspace).WithKeyTable( - types.NewKeyTable().RegisterParamSet(&testParams{}), - ) - - tp := testProposal(proposal.NewParamChange(testSubspace, keyMaxValidators, "1")) - hdlr := params.NewParamChangeProposalHandler(input.keeper) - require.NoError(t, hdlr(input.ctx, tp)) - - var param uint16 - ss.Get(input.ctx, []byte(keyMaxValidators), ¶m) - require.Equal(t, param, uint16(1)) -} - -func TestProposalHandlerFailed(t *testing.T) { - input := newTestInput(t) - ss := input.keeper.Subspace(testSubspace).WithKeyTable( - types.NewKeyTable().RegisterParamSet(&testParams{}), - ) - - tp := testProposal(proposal.NewParamChange(testSubspace, keyMaxValidators, "invalidType")) - hdlr := params.NewParamChangeProposalHandler(input.keeper) - require.Error(t, hdlr(input.ctx, tp)) - - require.False(t, ss.Has(input.ctx, []byte(keyMaxValidators))) -} - -func TestProposalHandlerUpdateOmitempty(t *testing.T) { - input := newTestInput(t) - ss := input.keeper.Subspace(testSubspace).WithKeyTable( - types.NewKeyTable().RegisterParamSet(&testParams{}), - ) - - hdlr := params.NewParamChangeProposalHandler(input.keeper) - var param testParamsSlashingRate - - tp := testProposal(proposal.NewParamChange(testSubspace, keySlashingRate, `{"downtime": 7}`)) - require.NoError(t, hdlr(input.ctx, tp)) - - ss.Get(input.ctx, []byte(keySlashingRate), ¶m) - require.Equal(t, testParamsSlashingRate{0, 7}, param) - - tp = testProposal(proposal.NewParamChange(testSubspace, keySlashingRate, `{"double_sign": 10}`)) - require.NoError(t, hdlr(input.ctx, tp)) - - ss.Get(input.ctx, []byte(keySlashingRate), ¶m) - require.Equal(t, testParamsSlashingRate{10, 7}, param) + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + err := suite.govHandler(suite.ctx, tc.proposal) + if tc.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + tc.onHandle() + } + }) + } }