Skip to content

Commit

Permalink
test(gov): Refactor x/gov keeper tests to use mocks (#12988)
Browse files Browse the repository at this point in the history
## Description

ref: #12752 

- [x] Move some keeper tests into `tests/integration/gov/keeper`, see #12988 (comment)
- [x] Don't use simapp in `x/gov/keeper` tests, use mocks instead
- [x] Find 0 "simapp" occurence in x/gov/keeper. (Note: other occurrences of simapp are removed in  #13043)



---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
amaury1093 authored Aug 25, 2022
1 parent 1fb6f0b commit fc7ee0b
Show file tree
Hide file tree
Showing 16 changed files with 1,738 additions and 494 deletions.
3 changes: 2 additions & 1 deletion scripts/mockgen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ $mockgen_cmd -source=x/bank/types/expected_keepers.go -package testutil -destina
$mockgen_cmd -source=x/group/testutil/expected_keepers.go -package testutil -destination x/group/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/evidence/types/expected_keepers.go -package testutil -destination x/evidence/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/slashing/types/expected_keepers.go -package testutil -destination x/slashing/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/genutil/types/expected_keepers.go -package testutil -destination x/genutil/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/genutil/types/expected_keepers.go -package testutil -destination x/genutil/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/gov/testutil/expected_keepers.go -package testutil -destination x/gov/testutil/expected_keepers_mocks.go
79 changes: 79 additions & 0 deletions tests/integration/gov/keeper/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package keeper_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/simapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

var (
_, _, addr = testdata.KeyTestPubAddr()
govAcct = authtypes.NewModuleAddress(types.ModuleName)
TestProposal = getTestProposal()
)

func getTestProposal() []sdk.Msg {
legacyProposalMsg, err := v1.NewLegacyContent(v1beta1.NewTextProposal("Title", "description"), authtypes.NewModuleAddress(types.ModuleName).String())
if err != nil {
panic(err)
}

return []sdk.Msg{
banktypes.NewMsgSend(govAcct, addr, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000)))),
legacyProposalMsg,
}
}

func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress) {
addrs := simapp.AddTestAddrsIncremental(app, ctx, 5, sdk.NewInt(30000000))
valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs)
pks := simtestutil.CreateTestPubKeys(5)
cdc := moduletestutil.MakeTestEncodingConfig().Codec

app.StakingKeeper = stakingkeeper.NewKeeper(
cdc,
app.GetKey(stakingtypes.StoreKey),
app.AccountKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(types.ModuleName).String(),
)

val1, err := stakingtypes.NewValidator(valAddrs[0], pks[0], stakingtypes.Description{})
require.NoError(t, err)
val2, err := stakingtypes.NewValidator(valAddrs[1], pks[1], stakingtypes.Description{})
require.NoError(t, err)
val3, err := stakingtypes.NewValidator(valAddrs[2], pks[2], stakingtypes.Description{})
require.NoError(t, err)

app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidator(ctx, val3)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val1)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val2)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val3)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val2)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val3)

_, _ = app.StakingKeeper.Delegate(ctx, addrs[0], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[0]), stakingtypes.Unbonded, val1, true)
_, _ = app.StakingKeeper.Delegate(ctx, addrs[1], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[1]), stakingtypes.Unbonded, val2, true)
_, _ = app.StakingKeeper.Delegate(ctx, addrs[2], app.StakingKeeper.TokensFromConsensusPower(ctx, powers[2]), stakingtypes.Unbonded, val3, true)

_ = staking.EndBlocker(ctx, app.StakingKeeper)

return addrs, valAddrs
}
245 changes: 245 additions & 0 deletions tests/integration/gov/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
package keeper_test

import (
gocontext "context"
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

func (suite *KeeperTestSuite) TestGRPCQueryTally() {
app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient

addrs, _ := createValidators(suite.T(), ctx, app, []int64{5, 5, 5})

var (
req *v1.QueryTallyResultRequest
expRes *v1.QueryTallyResultResponse
proposal v1.Proposal
)

testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &v1.QueryTallyResultRequest{}
},
false,
},
{
"zero proposal id request",
func() {
req = &v1.QueryTallyResultRequest{ProposalId: 0}
},
false,
},
{
"query non existed proposal",
func() {
req = &v1.QueryTallyResultRequest{ProposalId: 1}
},
false,
},
{
"create a proposal and get tally",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, "")
suite.Require().NoError(err)
suite.Require().NotNil(proposal)

req = &v1.QueryTallyResultRequest{ProposalId: proposal.Id}

tallyResult := v1.EmptyTallyResult()
expRes = &v1.QueryTallyResultResponse{
Tally: &tallyResult,
}
},
true,
},
{
"request tally after few votes",
func() {
proposal.Status = v1.StatusVotingPeriod
app.GovKeeper.SetProposal(ctx, proposal)

suite.Require().NoError(app.GovKeeper.AddVote(ctx, proposal.Id, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), ""))
suite.Require().NoError(app.GovKeeper.AddVote(ctx, proposal.Id, addrs[1], v1.NewNonSplitVoteOption(v1.OptionYes), ""))
suite.Require().NoError(app.GovKeeper.AddVote(ctx, proposal.Id, addrs[2], v1.NewNonSplitVoteOption(v1.OptionYes), ""))

req = &v1.QueryTallyResultRequest{ProposalId: proposal.Id}

expRes = &v1.QueryTallyResultResponse{
Tally: &v1.TallyResult{
YesCount: sdk.NewInt(3 * 5 * 1000000).String(),
NoCount: "0",
AbstainCount: "0",
NoWithVetoCount: "0",
},
}
},
true,
},
{
"request final tally after status changed",
func() {
proposal.Status = v1.StatusPassed
app.GovKeeper.SetProposal(ctx, proposal)
proposal, _ = app.GovKeeper.GetProposal(ctx, proposal.Id)

req = &v1.QueryTallyResultRequest{ProposalId: proposal.Id}

expRes = &v1.QueryTallyResultResponse{
Tally: proposal.FinalTallyResult,
}
},
true,
},
}

for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()

tally, err := queryClient.TallyResult(gocontext.Background(), req)

if testCase.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.String(), tally.String())
} else {
suite.Require().Error(err)
suite.Require().Nil(tally)
}
})
}
}

func (suite *KeeperTestSuite) TestLegacyGRPCQueryTally() {
app, ctx, queryClient := suite.app, suite.ctx, suite.legacyQueryClient

addrs, _ := createValidators(suite.T(), ctx, app, []int64{5, 5, 5})

var (
req *v1beta1.QueryTallyResultRequest
expRes *v1beta1.QueryTallyResultResponse
proposal v1.Proposal
)

testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &v1beta1.QueryTallyResultRequest{}
},
false,
},
{
"zero proposal id request",
func() {
req = &v1beta1.QueryTallyResultRequest{ProposalId: 0}
},
false,
},
{
"query non existed proposal",
func() {
req = &v1beta1.QueryTallyResultRequest{ProposalId: 1}
},
false,
},
{
"create a proposal and get tally",
func() {
var err error
proposal, err = app.GovKeeper.SubmitProposal(ctx, TestProposal, "")
suite.Require().NoError(err)
suite.Require().NotNil(proposal)

req = &v1beta1.QueryTallyResultRequest{ProposalId: proposal.Id}

tallyResult := v1beta1.EmptyTallyResult()
expRes = &v1beta1.QueryTallyResultResponse{
Tally: tallyResult,
}
},
true,
},
{
"request tally after few votes",
func() {
proposal.Status = v1.StatusVotingPeriod
app.GovKeeper.SetProposal(ctx, proposal)

suite.Require().NoError(app.GovKeeper.AddVote(ctx, proposal.Id, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), ""))
suite.Require().NoError(app.GovKeeper.AddVote(ctx, proposal.Id, addrs[1], v1.NewNonSplitVoteOption(v1.OptionYes), ""))
suite.Require().NoError(app.GovKeeper.AddVote(ctx, proposal.Id, addrs[2], v1.NewNonSplitVoteOption(v1.OptionYes), ""))

req = &v1beta1.QueryTallyResultRequest{ProposalId: proposal.Id}

expRes = &v1beta1.QueryTallyResultResponse{
Tally: v1beta1.TallyResult{
Yes: sdk.NewInt(3 * 5 * 1000000),
No: sdk.NewInt(0),
Abstain: sdk.NewInt(0),
NoWithVeto: sdk.NewInt(0),
},
}
},
true,
},
{
"request final tally after status changed",
func() {
proposal.Status = v1.StatusPassed
app.GovKeeper.SetProposal(ctx, proposal)
proposal, _ = app.GovKeeper.GetProposal(ctx, proposal.Id)

req = &v1beta1.QueryTallyResultRequest{ProposalId: proposal.Id}

expRes = &v1beta1.QueryTallyResultResponse{
Tally: v1TallyToV1Beta1Tally(*proposal.FinalTallyResult),
}
},
true,
},
}

for _, testCase := range testCases {
suite.Run(fmt.Sprintf("Case %s", testCase.msg), func() {
testCase.malleate()

tally, err := queryClient.TallyResult(gocontext.Background(), req)

if testCase.expPass {
suite.Require().NoError(err)
suite.Require().Equal(expRes.String(), tally.String())
} else {
suite.Require().Error(err)
suite.Require().Nil(tally)
}
})
}
}

func v1TallyToV1Beta1Tally(t v1.TallyResult) v1beta1.TallyResult {
yes, _ := sdk.NewIntFromString(t.YesCount)
no, _ := sdk.NewIntFromString(t.NoCount)
noWithVeto, _ := sdk.NewIntFromString(t.NoWithVetoCount)
abstain, _ := sdk.NewIntFromString(t.AbstainCount)
return v1beta1.TallyResult{
Yes: yes,
No: no,
NoWithVeto: noWithVeto,
Abstain: abstain,
}
}
Loading

0 comments on commit fc7ee0b

Please sign in to comment.