Skip to content

Commit

Permalink
gov, params: refactor tests (#9137)
Browse files Browse the repository at this point in the history
* gov, params: refactor tests

* wrap up params tests

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
fedekunze and mergify[bot] authored Apr 30, 2021
1 parent 4f4c035 commit e25f80d
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 156 deletions.
77 changes: 30 additions & 47 deletions x/gov/keeper/proposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,51 @@ 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()
}

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
Expand All @@ -78,35 +64,32 @@ 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_________________")

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++
}
}
Expand All @@ -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)
}
}
})
Expand Down
176 changes: 67 additions & 109 deletions x/params/proposal_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 testInput struct {
ctx sdk.Context
cdc *codec.LegacyAmino
keeper keeper.Keeper
}

var (
_ types.ParamSet = (*testParams)(nil)

keyMaxValidators = "MaxValidators"
keySlashingRate = "SlashingRate"
testSubspace = "TestSubspace"
)
type HandlerTestSuite struct {
suite.Suite

type testParamsSlashingRate struct {
DoubleSign uint16 `json:"double_sign,omitempty" yaml:"double_sign,omitempty"`
Downtime uint16 `json:"downtime,omitempty" yaml:"downtime,omitempty"`
app *simapp.SimApp
ctx sdk.Context
govHandler govtypes.Handler
}

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 (suite *HandlerTestSuite) SetupTest() {
suite.app = simapp.Setup(false)
suite.ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{})
suite.govHandler = params.NewParamChangeProposalHandler(suite.app.ParamsKeeper)
}

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,
)
}

func newTestInput(t *testing.T) testInput {
cdc := codec.NewLegacyAmino()
proposal.RegisterLegacyAminoCodec(cdc)

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), &param)
require.Equal(t, param, uint16(1))
return proposal.NewParameterChangeProposal("title", "description", changes)
}

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), &param)
require.Equal(t, testParamsSlashingRate{0, 7}, param)

tp = testProposal(proposal.NewParamChange(testSubspace, keySlashingRate, `{"double_sign": 10}`))
require.NoError(t, hdlr(input.ctx, tp))
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,
},
}

ss.Get(input.ctx, []byte(keySlashingRate), &param)
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()
}
})
}
}

0 comments on commit e25f80d

Please sign in to comment.