diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index c1f18fe89e0c..85b9db48d5c8 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" @@ -15,6 +16,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/genaccounts" + "github.com/cosmos/cosmos-sdk/x/supply" ) // Setup initializes a new SimApp. A Nop logger is set in SimApp. @@ -69,6 +71,30 @@ func SetupWithGenesisAccounts(genAccs genaccounts.GenesisAccounts) *SimApp { return app } +// AddTestAddrs constructs and returns accNum amount of accounts with an +// initial balance of accAmt +func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { + testAddrs := make([]sdk.AccAddress, accNum) + for i := 0; i < accNum; i++ { + pk := ed25519.GenPrivKey().PubKey() + testAddrs[i] = sdk.AccAddress(pk.Address()) + } + + initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt)) + totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt.MulRaw(int64(len(testAddrs))))) + prevSupply := app.SupplyKeeper.GetSupply(ctx) + app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(prevSupply.GetTotal().Add(totalSupply))) + + // fill all the addresses with some coins, set the loose pool tokens simultaneously + for _, addr := range testAddrs { + _, err := app.BankKeeper.AddCoins(ctx, addr, initCoins) + if err != nil { + panic(err) + } + } + return testAddrs +} + // CheckBalance checks the balance of an account. func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, exp sdk.Coins) { ctxCheck := app.BaseApp.NewContext(true, abci.Header{}) diff --git a/x/crisis/handler_test.go b/x/crisis/handler_test.go index fa4a0f5670b2..b2448a0df3df 100644 --- a/x/crisis/handler_test.go +++ b/x/crisis/handler_test.go @@ -2,16 +2,19 @@ package crisis_test import ( "fmt" - "strings" "testing" "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/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/crisis" distr "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/supply" ) var ( @@ -21,95 +24,90 @@ var ( addrs = distr.TestAddrs ) -func CreateTestInput(t *testing.T) (sdk.Context, crisis.Keeper, auth.AccountKeeper, distr.Keeper) { +func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) { + db := dbm.NewMemDB() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, 1) + ctx := app.NewContext(true, abci.Header{}) - communityTax := sdk.NewDecWithPrec(2, 2) - ctx, accKeeper, _, distrKeeper, _, paramsKeeper, supplyKeeper := - distr.CreateTestInputAdvanced(t, false, 10, communityTax) + constantFee := sdk.NewInt64Coin(sdk.DefaultBondDenom, 10) + app.CrisisKeeper.SetConstantFee(ctx, constantFee) + app.StakingKeeper.SetParams(ctx, staking.DefaultParams()) - paramSpace := paramsKeeper.Subspace(crisis.DefaultParamspace) - crisisKeeper := crisis.NewKeeper(paramSpace, 1, supplyKeeper, auth.FeeCollectorName) - constantFee := sdk.NewInt64Coin("stake", 10000000) - crisisKeeper.SetConstantFee(ctx, constantFee) + app.CrisisKeeper.RegisterRoute(testModuleName, dummyRouteWhichPasses.Route, dummyRouteWhichPasses.Invar) + app.CrisisKeeper.RegisterRoute(testModuleName, dummyRouteWhichFails.Route, dummyRouteWhichFails.Invar) - crisisKeeper.RegisterRoute(testModuleName, dummyRouteWhichPasses.Route, dummyRouteWhichPasses.Invar) - crisisKeeper.RegisterRoute(testModuleName, dummyRouteWhichFails.Route, dummyRouteWhichFails.Invar) - - // set the community pool to pay back the constant fee feePool := distr.InitialFeePool() feePool.CommunityPool = sdk.NewDecCoins(sdk.NewCoins(constantFee)) - distrKeeper.SetFeePool(ctx, feePool) + app.DistrKeeper.SetFeePool(ctx, feePool) + app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(sdk.Coins{})) + + addrs := simapp.AddTestAddrs(app, ctx, 1, sdk.NewInt(10000)) - return ctx, crisisKeeper, accKeeper, distrKeeper + return app, ctx, addrs } //____________________________________________________________________________ -func TestHandleMsgVerifyInvariantWithNotEnoughSenderCoins(t *testing.T) { - ctx, crisisKeeper, accKeeper, _ := CreateTestInput(t) - sender := addrs[0] - coin := accKeeper.GetAccount(ctx, sender).GetCoins()[0] - excessCoins := sdk.NewCoin(coin.Denom, coin.Amount.AddRaw(1)) - crisisKeeper.SetConstantFee(ctx, excessCoins) - - h := crisis.NewHandler(crisisKeeper) - msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route) - require.False(t, h(ctx, msg).IsOK()) -} - -func TestHandleMsgVerifyInvariantWithBadInvariant(t *testing.T) { - ctx, crisisKeeper, _, _ := CreateTestInput(t) +func TestHandleMsgVerifyInvariant(t *testing.T) { + app, ctx, addrs := createTestApp() sender := addrs[0] - h := crisis.NewHandler(crisisKeeper) - msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, "route-that-doesnt-exist") - res := h(ctx, msg) - require.False(t, res.IsOK()) + cases := []struct { + name string + msg sdk.Msg + expectedResult string + }{ + {"bad invariant route", crisis.NewMsgVerifyInvariant(sender, testModuleName, "route-that-doesnt-exist"), "fail"}, + {"invariant broken", crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route), "panic"}, + {"invariant passing", crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route), "pass"}, + {"invalid msg", sdk.NewTestMsg(), "fail"}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + h := crisis.NewHandler(app.CrisisKeeper) + + switch tc.expectedResult { + case "fail": + res := h(ctx, tc.msg) + require.False(t, res.IsOK()) + case "pass": + res := h(ctx, tc.msg) + require.True(t, res.IsOK()) + case "panic": + require.Panics(t, func() { + _ = h(ctx, tc.msg) + }) + } + }) + } } -func TestHandleMsgVerifyInvariantWithInvariantBroken(t *testing.T) { - ctx, crisisKeeper, _, _ := CreateTestInput(t) +func TestHandleMsgVerifyInvariantWithNotEnoughSenderCoins(t *testing.T) { + app, ctx, addrs := createTestApp() sender := addrs[0] + coin := app.AccountKeeper.GetAccount(ctx, sender).GetCoins()[0] + excessCoins := sdk.NewCoin(coin.Denom, coin.Amount.AddRaw(1)) + app.CrisisKeeper.SetConstantFee(ctx, excessCoins) - h := crisis.NewHandler(crisisKeeper) - msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route) - var res sdk.Result - require.Panics(t, func() { - res = h(ctx, msg) - }, fmt.Sprintf("%v", res)) + h := crisis.NewHandler(app.CrisisKeeper) + msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route) + require.False(t, h(ctx, msg).IsOK()) } func TestHandleMsgVerifyInvariantWithInvariantBrokenAndNotEnoughPoolCoins(t *testing.T) { - ctx, crisisKeeper, _, distrKeeper := CreateTestInput(t) + app, ctx, addrs := createTestApp() sender := addrs[0] // set the community pool to empty - feePool := distrKeeper.GetFeePool(ctx) + feePool := app.DistrKeeper.GetFeePool(ctx) feePool.CommunityPool = sdk.DecCoins{} - distrKeeper.SetFeePool(ctx, feePool) + app.DistrKeeper.SetFeePool(ctx, feePool) - h := crisis.NewHandler(crisisKeeper) + h := crisis.NewHandler(app.CrisisKeeper) msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route) var res sdk.Result require.Panics(t, func() { res = h(ctx, msg) }, fmt.Sprintf("%v", res)) } - -func TestHandleMsgVerifyInvariantWithInvariantNotBroken(t *testing.T) { - ctx, crisisKeeper, _, _ := CreateTestInput(t) - sender := addrs[0] - - h := crisis.NewHandler(crisisKeeper) - msg := crisis.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route) - require.True(t, h(ctx, msg).IsOK()) -} - -func TestInvalidMsg(t *testing.T) { - k := crisis.Keeper{} - h := crisis.NewHandler(k) - - res := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) - require.False(t, res.IsOK()) - require.True(t, strings.Contains(res.Log, "unrecognized crisis message type")) -} diff --git a/x/crisis/internal/keeper/integration_test.go b/x/crisis/internal/keeper/integration_test.go new file mode 100644 index 000000000000..339244325e55 --- /dev/null +++ b/x/crisis/internal/keeper/integration_test.go @@ -0,0 +1,33 @@ +package keeper_test + +import ( + 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" + "github.com/cosmos/cosmos-sdk/simapp" +) + +func createTestApp() *simapp.SimApp { + db := dbm.NewMemDB() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, 5) + // init chain must be called to stop deliverState from being nil + genesisState := simapp.NewDefaultGenesisState() + stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState) + if err != nil { + panic(err) + } + + // Initialize the chain + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + AppStateBytes: stateBytes, + }, + ) + app.Commit() + app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: app.LastBlockHeight() + 1}}) + + return app +} diff --git a/x/crisis/internal/keeper/keeper_test.go b/x/crisis/internal/keeper/keeper_test.go index 44a2a50f9f3f..80f292008bfb 100644 --- a/x/crisis/internal/keeper/keeper_test.go +++ b/x/crisis/internal/keeper/keeper_test.go @@ -1,56 +1,38 @@ -package keeper +package keeper_test import ( "testing" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" + abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/crisis/internal/types" - "github.com/cosmos/cosmos-sdk/x/params" ) -func testPassingInvariant(_ sdk.Context) (string, bool) { - return "", false -} - -func testFailingInvariant(_ sdk.Context) (string, bool) { - return "", true -} - -func testKeeper(checkPeriod uint) Keeper { - cdc := codec.New() - paramsKeeper := params.NewKeeper( - cdc, sdk.NewKVStoreKey(params.StoreKey), sdk.NewTransientStoreKey(params.TStoreKey), params.DefaultCodespace, - ) - - return NewKeeper(paramsKeeper.Subspace(types.DefaultParamspace), checkPeriod, nil, "test") -} - func TestLogger(t *testing.T) { - k := testKeeper(5) + app := createTestApp() - ctx := sdk.Context{}.WithLogger(log.NewNopLogger()) - require.Equal(t, ctx.Logger(), k.Logger(ctx)) + ctx := app.NewContext(true, abci.Header{}) + require.Equal(t, ctx.Logger(), app.CrisisKeeper.Logger(ctx)) } func TestInvariants(t *testing.T) { - k := testKeeper(5) - require.Equal(t, k.InvCheckPeriod(), uint(5)) + app := createTestApp() + require.Equal(t, app.CrisisKeeper.InvCheckPeriod(), uint(5)) - k.RegisterRoute("testModule", "testRoute", testPassingInvariant) - require.Len(t, k.Routes(), 1) + // SimApp has 11 registered invariants + orgInvRoutes := app.CrisisKeeper.Routes() + app.CrisisKeeper.RegisterRoute("testModule", "testRoute", func(sdk.Context) (string, bool) { return "", false }) + require.Equal(t, len(app.CrisisKeeper.Routes()), len(orgInvRoutes)+1) } func TestAssertInvariants(t *testing.T) { - k := testKeeper(5) - ctx := sdk.Context{}.WithLogger(log.NewNopLogger()) + app := createTestApp() + ctx := app.NewContext(true, abci.Header{}) - k.RegisterRoute("testModule", "testRoute1", testPassingInvariant) - require.NotPanics(t, func() { k.AssertInvariants(ctx) }) + app.CrisisKeeper.RegisterRoute("testModule", "testRoute1", func(sdk.Context) (string, bool) { return "", false }) + require.NotPanics(t, func() { app.CrisisKeeper.AssertInvariants(ctx) }) - k.RegisterRoute("testModule", "testRoute2", testFailingInvariant) - require.Panics(t, func() { k.AssertInvariants(ctx) }) + app.CrisisKeeper.RegisterRoute("testModule", "testRoute2", func(sdk.Context) (string, bool) { return "", true }) + require.Panics(t, func() { app.CrisisKeeper.AssertInvariants(ctx) }) }