Merge PR #4448: Implement Gov EndBlocker Failed Handler Test

This commit is contained in:
Alexander Bezobchuk 2019-05-30 14:31:35 -04:00 committed by GitHub
parent b44392b01a
commit 2414413e0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 0 deletions

View File

@ -279,3 +279,50 @@ func TestProposalPassedEndblocker(t *testing.T) {
resTags := EndBlocker(ctx, input.keeper)
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])
}

View File

@ -2,6 +2,7 @@ package gov
import (
"bytes"
"fmt"
"log"
"sort"
"testing"
@ -155,6 +156,28 @@ func testProposal() Content {
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)
func ProposalEqual(proposalA Proposal, proposalB Proposal) bool {
return bytes.Equal(types.ModuleCdc.MustMarshalBinaryBare(proposalA),