2019-11-19 12:54:31 -08:00
|
|
|
package upgrade_test
|
2019-11-08 06:40:56 -08:00
|
|
|
|
|
|
|
import (
|
2019-12-27 09:57:54 -08:00
|
|
|
"errors"
|
2019-11-08 06:40:56 -08:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
|
|
dbm "github.com/tendermint/tm-db"
|
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
2019-11-19 12:54:31 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/simapp"
|
2019-11-08 06:40:56 -08:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2019-12-27 09:57:54 -08:00
|
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
2019-11-08 06:40:56 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/types/module"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
2019-11-19 12:54:31 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/x/upgrade"
|
2019-11-08 06:40:56 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
type TestSuite struct {
|
2019-11-19 12:54:31 -08:00
|
|
|
module module.AppModule
|
|
|
|
keeper upgrade.Keeper
|
2019-11-08 06:40:56 -08:00
|
|
|
querier sdk.Querier
|
|
|
|
handler gov.Handler
|
|
|
|
ctx sdk.Context
|
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
var s TestSuite
|
|
|
|
|
|
|
|
func setupTest(height int64, skip map[int64]bool) TestSuite {
|
|
|
|
db := dbm.NewMemDB()
|
|
|
|
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, skip, 0)
|
|
|
|
genesisState := simapp.NewDefaultGenesisState()
|
|
|
|
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
app.InitChain(
|
|
|
|
abci.RequestInitChain{
|
|
|
|
Validators: []abci.ValidatorUpdate{},
|
|
|
|
AppStateBytes: stateBytes,
|
|
|
|
},
|
|
|
|
)
|
2019-11-19 12:54:31 -08:00
|
|
|
|
|
|
|
s.keeper = app.UpgradeKeeper
|
2020-01-03 06:37:29 -08:00
|
|
|
s.ctx = app.BaseApp.NewContext(false, abci.Header{Height: height, Time: time.Now()})
|
|
|
|
|
2019-11-19 12:54:31 -08:00
|
|
|
s.module = upgrade.NewAppModule(s.keeper)
|
2020-01-03 06:37:29 -08:00
|
|
|
s.querier = s.module.NewQuerierHandler()
|
|
|
|
s.handler = upgrade.NewSoftwareUpgradeProposalHandler(s.keeper)
|
|
|
|
return s
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestRequireName(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotNil(t, err)
|
|
|
|
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestRequireFutureTime(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: s.ctx.BlockHeader().Time}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotNil(t, err)
|
|
|
|
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestRequireFutureBlock(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight()}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotNil(t, err)
|
|
|
|
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestCantSetBothTimeAndHeight(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now(), Height: s.ctx.BlockHeight() + 1}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotNil(t, err)
|
|
|
|
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestDoTimeUpgrade(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
t.Log("Verify can schedule an upgrade")
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Nil(t, err)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
VerifyDoUpgrade(t)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestDoHeightUpgrade(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
t.Log("Verify can schedule an upgrade")
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Nil(t, err)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
VerifyDoUpgrade(t)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestCanOverwriteScheduleUpgrade(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
t.Log("Can overwrite plan")
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "bad_test", Height: s.ctx.BlockHeight() + 10}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Nil(t, err)
|
2019-11-19 12:54:31 -08:00
|
|
|
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Nil(t, err)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
VerifyDoUpgrade(t)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func VerifyDoUpgrade(t *testing.T) {
|
|
|
|
t.Log("Verify that a panic happens at the upgrade time/height")
|
2019-11-19 12:54:31 -08:00
|
|
|
newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now())
|
|
|
|
|
2019-11-08 06:40:56 -08:00
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Panics(t, func() {
|
2019-11-08 06:40:56 -08:00
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
t.Log("Verify that the upgrade can be successfully applied with a handler")
|
2019-11-19 12:54:31 -08:00
|
|
|
s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan upgrade.Plan) {})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotPanics(t, func() {
|
2019-11-08 06:40:56 -08:00
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
VerifyCleared(t, newCtx)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func VerifyDoUpgradeWithCtx(t *testing.T, newCtx sdk.Context, proposalName string) {
|
|
|
|
t.Log("Verify that a panic happens at the upgrade time/height")
|
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
|
|
|
require.Panics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Log("Verify that the upgrade can be successfully applied with a handler")
|
|
|
|
s.keeper.SetUpgradeHandler(proposalName, func(ctx sdk.Context, plan upgrade.Plan) {})
|
|
|
|
require.NotPanics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
VerifyCleared(t, newCtx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHaltIfTooNew(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
t.Log("Verify that we don't panic with registered plan not in database at all")
|
2019-11-08 06:40:56 -08:00
|
|
|
var called int
|
2019-11-19 12:54:31 -08:00
|
|
|
s.keeper.SetUpgradeHandler("future", func(ctx sdk.Context, plan upgrade.Plan) { called++ })
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2019-11-19 12:54:31 -08:00
|
|
|
newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now())
|
2019-11-08 06:40:56 -08:00
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotPanics(t, func() {
|
2019-11-08 06:40:56 -08:00
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Equal(t, 0, called)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
t.Log("Verify we panic if we have a registered handler ahead of time")
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "future", Height: s.ctx.BlockHeight() + 3}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Panics(t, func() {
|
2019-11-08 06:40:56 -08:00
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Equal(t, 0, called)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
t.Log("Verify we no longer panic if the plan is on time")
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2019-11-19 12:54:31 -08:00
|
|
|
futCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 3).WithBlockTime(time.Now())
|
2019-11-08 06:40:56 -08:00
|
|
|
req = abci.RequestBeginBlock{Header: futCtx.BlockHeader()}
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotPanics(t, func() {
|
2019-11-08 06:40:56 -08:00
|
|
|
s.module.BeginBlock(futCtx, req)
|
|
|
|
})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Equal(t, 1, called)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
VerifyCleared(t, futCtx)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func VerifyCleared(t *testing.T, newCtx sdk.Context) {
|
|
|
|
t.Log("Verify that the upgrade plan has been cleared")
|
2019-11-19 12:54:31 -08:00
|
|
|
bz, err := s.querier(newCtx, []string{upgrade.QueryCurrent}, abci.RequestQuery{})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, bz)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestCanClear(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
t.Log("Verify upgrade is scheduled")
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Nil(t, err)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
err = s.handler(s.ctx, upgrade.CancelSoftwareUpgradeProposal{Title: "cancel"})
|
|
|
|
require.Nil(t, err)
|
2019-11-08 06:40:56 -08:00
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
VerifyCleared(t, s.ctx)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestCantApplySameUpgradeTwice(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
2019-11-19 12:54:31 -08:00
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
2020-01-03 06:37:29 -08:00
|
|
|
require.Nil(t, err)
|
|
|
|
VerifyDoUpgrade(t)
|
|
|
|
t.Log("Verify an executed upgrade \"test\" can't be rescheduled")
|
|
|
|
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Time: time.Now()}})
|
|
|
|
require.NotNil(t, err)
|
|
|
|
require.True(t, errors.Is(sdkerrors.ErrInvalidRequest, err), err)
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestNoSpuriousUpgrades(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
t.Log("Verify that no upgrade panic is triggered in the BeginBlocker when we haven't scheduled an upgrade")
|
2019-11-08 06:40:56 -08:00
|
|
|
req := abci.RequestBeginBlock{Header: s.ctx.BlockHeader()}
|
2020-01-03 06:37:29 -08:00
|
|
|
require.NotPanics(t, func() {
|
2019-11-08 06:40:56 -08:00
|
|
|
s.module.BeginBlock(s.ctx, req)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func TestPlanStringer(t *testing.T) {
|
|
|
|
ti, err := time.Parse(time.RFC3339, "2020-01-01T00:00:00Z")
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.Equal(t, `Upgrade Plan
|
2019-11-08 06:40:56 -08:00
|
|
|
Name: test
|
|
|
|
Time: 2020-01-01T00:00:00Z
|
2020-01-03 06:37:29 -08:00
|
|
|
Info: `, upgrade.Plan{Name: "test", Time: ti}.String())
|
|
|
|
require.Equal(t, `Upgrade Plan
|
2019-11-08 06:40:56 -08:00
|
|
|
Name: test
|
|
|
|
Height: 100
|
2019-11-19 12:54:31 -08:00
|
|
|
Info: `, upgrade.Plan{Name: "test", Height: 100}.String())
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|
|
|
|
|
2020-01-03 06:37:29 -08:00
|
|
|
func VerifyNotDone(t *testing.T, newCtx sdk.Context, name string) {
|
|
|
|
t.Log("Verify that upgrade was not done")
|
|
|
|
height := s.keeper.GetDoneHeight(newCtx, name)
|
|
|
|
require.Zero(t, height)
|
|
|
|
}
|
|
|
|
|
|
|
|
func VerifyDone(t *testing.T, newCtx sdk.Context, name string) {
|
|
|
|
t.Log("Verify that the upgrade plan has been executed")
|
|
|
|
height := s.keeper.GetDoneHeight(newCtx, name)
|
|
|
|
require.NotZero(t, height)
|
|
|
|
}
|
|
|
|
|
|
|
|
func VerifySet(t *testing.T, skipUpgradeHeights map[int64]bool) {
|
|
|
|
t.Log("Verify if the skip upgrade has been set")
|
|
|
|
|
|
|
|
for k := range skipUpgradeHeights {
|
|
|
|
require.True(t, s.keeper.IsSkipHeight(k))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestContains(t *testing.T) {
|
|
|
|
var (
|
|
|
|
skipOne int64 = 11
|
|
|
|
)
|
|
|
|
s := setupTest(10, map[int64]bool{skipOne: true})
|
|
|
|
|
|
|
|
VerifySet(t, map[int64]bool{skipOne: true})
|
|
|
|
t.Log("case where array contains the element")
|
|
|
|
require.True(t, s.keeper.IsSkipHeight(11))
|
|
|
|
|
|
|
|
t.Log("case where array doesn't contain the element")
|
|
|
|
require.False(t, s.keeper.IsSkipHeight(4))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSkipUpgradeSkippingAll(t *testing.T) {
|
|
|
|
var (
|
|
|
|
skipOne int64 = 11
|
|
|
|
skipTwo int64 = 20
|
|
|
|
)
|
|
|
|
s := setupTest(10, map[int64]bool{skipOne: true, skipTwo: true})
|
|
|
|
|
|
|
|
newCtx := s.ctx
|
|
|
|
|
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: skipOne}})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
t.Log("Verify if skip upgrade flag clears upgrade plan in both cases")
|
|
|
|
VerifySet(t, map[int64]bool{skipOne: true, skipTwo: true})
|
|
|
|
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipOne)
|
|
|
|
require.NotPanics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Log("Verify a second proposal also is being cleared")
|
|
|
|
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop2", Plan: upgrade.Plan{Name: "test2", Height: skipTwo}})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipTwo)
|
|
|
|
require.NotPanics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
// To ensure verification is being done only after both upgrades are cleared
|
|
|
|
t.Log("Verify if both proposals are cleared")
|
|
|
|
VerifyCleared(t, s.ctx)
|
|
|
|
VerifyNotDone(t, s.ctx, "test")
|
|
|
|
VerifyNotDone(t, s.ctx, "test2")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpgradeSkippingOne(t *testing.T) {
|
|
|
|
var (
|
|
|
|
skipOne int64 = 11
|
|
|
|
skipTwo int64 = 20
|
|
|
|
)
|
|
|
|
s := setupTest(10, map[int64]bool{skipOne: true})
|
|
|
|
|
|
|
|
newCtx := s.ctx
|
|
|
|
|
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: skipOne}})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
t.Log("Verify if skip upgrade flag clears upgrade plan in one case and does upgrade on another")
|
|
|
|
VerifySet(t, map[int64]bool{skipOne: true})
|
|
|
|
|
|
|
|
// Setting block height of proposal test
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipOne)
|
|
|
|
require.NotPanics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Log("Verify the second proposal is not skipped")
|
|
|
|
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop2", Plan: upgrade.Plan{Name: "test2", Height: skipTwo}})
|
|
|
|
require.Nil(t, err)
|
|
|
|
// Setting block height of proposal test2
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipTwo)
|
|
|
|
VerifyDoUpgradeWithCtx(t, newCtx, "test2")
|
|
|
|
|
|
|
|
t.Log("Verify first proposal is cleared and second is done")
|
|
|
|
VerifyNotDone(t, s.ctx, "test")
|
|
|
|
VerifyDone(t, s.ctx, "test2")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpgradeSkippingOnlyTwo(t *testing.T) {
|
|
|
|
var (
|
|
|
|
skipOne int64 = 11
|
|
|
|
skipTwo int64 = 20
|
|
|
|
skipThree int64 = 25
|
|
|
|
)
|
|
|
|
s := setupTest(10, map[int64]bool{skipOne: true, skipTwo: true})
|
|
|
|
|
|
|
|
newCtx := s.ctx
|
|
|
|
|
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: skipOne}})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
t.Log("Verify if skip upgrade flag clears upgrade plan in both cases and does third upgrade")
|
|
|
|
VerifySet(t, map[int64]bool{skipOne: true, skipTwo: true})
|
|
|
|
|
|
|
|
// Setting block height of proposal test
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipOne)
|
|
|
|
require.NotPanics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
// A new proposal with height in skipUpgradeHeights
|
|
|
|
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop2", Plan: upgrade.Plan{Name: "test2", Height: skipTwo}})
|
|
|
|
require.Nil(t, err)
|
|
|
|
// Setting block height of proposal test2
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipTwo)
|
|
|
|
require.NotPanics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Log("Verify a new proposal is not skipped")
|
|
|
|
err = s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop3", Plan: upgrade.Plan{Name: "test3", Height: skipThree}})
|
|
|
|
require.Nil(t, err)
|
|
|
|
newCtx = newCtx.WithBlockHeight(skipThree)
|
|
|
|
VerifyDoUpgradeWithCtx(t, newCtx, "test3")
|
|
|
|
|
|
|
|
t.Log("Verify two proposals are cleared and third is done")
|
|
|
|
VerifyNotDone(t, s.ctx, "test")
|
|
|
|
VerifyNotDone(t, s.ctx, "test2")
|
|
|
|
VerifyDone(t, s.ctx, "test3")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpgradeWithoutSkip(t *testing.T) {
|
|
|
|
s := setupTest(10, map[int64]bool{})
|
|
|
|
newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now())
|
|
|
|
req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()}
|
|
|
|
err := s.handler(s.ctx, upgrade.SoftwareUpgradeProposal{Title: "prop", Plan: upgrade.Plan{Name: "test", Height: s.ctx.BlockHeight() + 1}})
|
|
|
|
require.Nil(t, err)
|
|
|
|
t.Log("Verify if upgrade happens without skip upgrade")
|
|
|
|
require.Panics(t, func() {
|
|
|
|
s.module.BeginBlock(newCtx, req)
|
|
|
|
})
|
|
|
|
|
|
|
|
VerifyDoUpgrade(t)
|
|
|
|
VerifyDone(t, s.ctx, "test")
|
2019-11-08 06:40:56 -08:00
|
|
|
}
|