Merge PR #4448: Implement Gov EndBlocker Failed Handler Test
This commit is contained in:
parent
b44392b01a
commit
2414413e0b
|
@ -279,3 +279,50 @@ func TestProposalPassedEndblocker(t *testing.T) {
|
||||||
resTags := EndBlocker(ctx, input.keeper)
|
resTags := EndBlocker(ctx, input.keeper)
|
||||||
require.Equal(t, sdk.MakeTag(tags.ProposalResult, tags.ActionProposalPassed), resTags[1])
|
require.Equal(t, sdk.MakeTag(tags.ProposalResult, tags.ActionProposalPassed), resTags[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndBlockerProposalHandlerFailed(t *testing.T) {
|
||||||
|
input := getMockApp(t, 1, GenesisState{}, nil)
|
||||||
|
SortAddresses(input.addrs)
|
||||||
|
|
||||||
|
// hijack the router to one that will fail in a proposal's handler
|
||||||
|
input.keeper.router = NewRouter().AddRoute(RouterKey, badProposalHandler)
|
||||||
|
|
||||||
|
handler := NewHandler(input.keeper)
|
||||||
|
stakingHandler := staking.NewHandler(input.sk)
|
||||||
|
|
||||||
|
header := abci.Header{Height: input.mApp.LastBlockHeight() + 1}
|
||||||
|
input.mApp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
||||||
|
ctx := input.mApp.BaseApp.NewContext(false, abci.Header{})
|
||||||
|
|
||||||
|
valAddr := sdk.ValAddress(input.addrs[0])
|
||||||
|
|
||||||
|
input.keeper.ck.SetSendEnabled(ctx, true)
|
||||||
|
createValidators(t, stakingHandler, ctx, []sdk.ValAddress{valAddr}, []int64{10})
|
||||||
|
staking.EndBlocker(ctx, input.sk)
|
||||||
|
|
||||||
|
// Create a proposal where the handler will pass for the test proposal
|
||||||
|
// because the value of contextKeyBadProposal is true.
|
||||||
|
ctx = ctx.WithValue(contextKeyBadProposal, true)
|
||||||
|
proposal, err := input.keeper.SubmitProposal(ctx, testProposal())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromTendermintPower(10)))
|
||||||
|
newDepositMsg := NewMsgDeposit(input.addrs[0], proposal.ProposalID, proposalCoins)
|
||||||
|
res := handler(ctx, newDepositMsg)
|
||||||
|
require.True(t, res.IsOK())
|
||||||
|
|
||||||
|
err = input.keeper.AddVote(ctx, proposal.ProposalID, input.addrs[0], OptionYes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
newHeader := ctx.BlockHeader()
|
||||||
|
newHeader.Time = ctx.BlockHeader().Time.Add(input.keeper.GetDepositParams(ctx).MaxDepositPeriod).Add(input.keeper.GetVotingParams(ctx).VotingPeriod)
|
||||||
|
ctx = ctx.WithBlockHeader(newHeader)
|
||||||
|
|
||||||
|
// Set the contextKeyBadProposal value to false so that the handler will fail
|
||||||
|
// during the processing of the proposal in the EndBlocker.
|
||||||
|
ctx = ctx.WithValue(contextKeyBadProposal, false)
|
||||||
|
|
||||||
|
// validate that the proposal fails/has been rejected
|
||||||
|
resTags := EndBlocker(ctx, input.keeper)
|
||||||
|
require.Equal(t, sdk.MakeTag(tags.ProposalResult, tags.ActionProposalFailed), resTags[1])
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package gov
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -155,6 +156,28 @@ func testProposal() Content {
|
||||||
return NewTextProposal("Test", "description")
|
return NewTextProposal("Test", "description")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contextKeyBadProposal = "contextKeyBadProposal"
|
||||||
|
|
||||||
|
// badProposalHandler implements a governance proposal handler that is identical
|
||||||
|
// to the actual handler except this fails if the context doesn't contain a value
|
||||||
|
// for the key contextKeyBadProposal or if the value is false.
|
||||||
|
func badProposalHandler(ctx sdk.Context, c Content) sdk.Error {
|
||||||
|
switch c.ProposalType() {
|
||||||
|
case ProposalTypeText, ProposalTypeSoftwareUpgrade:
|
||||||
|
v := ctx.Value(contextKeyBadProposal)
|
||||||
|
|
||||||
|
if v == nil || !v.(bool) {
|
||||||
|
return sdk.ErrInternal("proposal failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
errMsg := fmt.Sprintf("unrecognized gov proposal type: %s", c.ProposalType())
|
||||||
|
return sdk.ErrUnknownRequest(errMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checks if two proposals are equal (note: slow, for tests only)
|
// checks if two proposals are equal (note: slow, for tests only)
|
||||||
func ProposalEqual(proposalA Proposal, proposalB Proposal) bool {
|
func ProposalEqual(proposalA Proposal, proposalB Proposal) bool {
|
||||||
return bytes.Equal(types.ModuleCdc.MustMarshalBinaryBare(proposalA),
|
return bytes.Equal(types.ModuleCdc.MustMarshalBinaryBare(proposalA),
|
||||||
|
|
Loading…
Reference in New Issue