diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a7bbb4909..5495e8480b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ longer panics if the store to load contains substores that we didn't explicitly * (modules) [\#4762](https://github.com/cosmos/cosmos-sdk/issues/4762) Deprecate remove and add permissions in ModuleAccount. * (modules) [\#4760](https://github.com/cosmos/cosmos-sdk/issues/4760) update `x/auth` to match module spec. * (modules) [\#4814](https://github.com/cosmos/cosmos-sdk/issues/4814) Add security contact to Validator description. +* (modules) [\#4875](https://github.com/cosmos/cosmos-sdk/issues/4875) refactor integration tests to use SimApp and separate test package * (sdk) [\#4566](https://github.com/cosmos/cosmos-sdk/issues/4566) Export simulation's parameters and app state to JSON in order to reproduce bugs and invariants. * (sdk) [\#4640](https://github.com/cosmos/cosmos-sdk/issues/4640) improve import/export simulation errors by extending `DiffKVStores` to return an array of `KVPairs` that are then compared to check for inconsistencies. * (sdk) [\#4717](https://github.com/cosmos/cosmos-sdk/issues/4717) refactor `x/slashing` to match the new module spec diff --git a/simapp/helpers.go b/simapp/helpers.go new file mode 100644 index 0000000000..7e5c8d23e1 --- /dev/null +++ b/simapp/helpers.go @@ -0,0 +1,33 @@ +package simapp + +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" +) + +// Setup initializes a new SimApp. A Nop logger is set in SimApp. +func Setup(isCheckTx bool) *SimApp { + db := dbm.NewMemDB() + app := NewSimApp(log.NewNopLogger(), db, nil, true, 0) + if !isCheckTx { + // init chain must be called to stop deliverState from being nil + genesisState := NewDefaultGenesisState() + stateBytes, err := codec.MarshalJSONIndent(app.cdc, genesisState) + if err != nil { + panic(err) + } + + // Initialize the chain + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + AppStateBytes: stateBytes, + }, + ) + } + + return app +} diff --git a/x/supply/internal/keeper/bank_test.go b/x/supply/internal/keeper/bank_test.go index c331e1e277..f0cb48f1fc 100644 --- a/x/supply/internal/keeper/bank_test.go +++ b/x/supply/internal/keeper/bank_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "testing" @@ -6,11 +6,13 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" + keep "github.com/cosmos/cosmos-sdk/x/supply/internal/keeper" "github.com/cosmos/cosmos-sdk/x/supply/internal/types" ) const initialPower = int64(100) +// create module accounts for testing var ( holderAcc = types.NewEmptyModuleAccount(holder) burnerAcc = types.NewEmptyModuleAccount(types.Burner, types.Burner) @@ -22,9 +24,9 @@ var ( initCoins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) ) -func getCoinsByName(ctx sdk.Context, k Keeper, moduleName string) sdk.Coins { - moduleAddress := k.GetModuleAddress(moduleName) - macc := k.ak.GetAccount(ctx, moduleAddress) +func getCoinsByName(ctx sdk.Context, sk keep.Keeper, ak types.AccountKeeper, moduleName string) sdk.Coins { + moduleAddress := sk.GetModuleAddress(moduleName) + macc := ak.GetAccount(ctx, moduleAddress) if macc == nil { return sdk.Coins(nil) } @@ -32,13 +34,15 @@ func getCoinsByName(ctx sdk.Context, k Keeper, moduleName string) sdk.Coins { } func TestSendCoins(t *testing.T) { - nAccs := int64(4) - ctx, ak, keeper := createTestInput(t, false, initialPower, nAccs) + app, ctx := createTestApp(false) + keeper := app.SupplyKeeper + ak := app.AccountKeeper baseAcc := ak.NewAccountWithAddress(ctx, types.NewModuleAddress("baseAcc")) err := holderAcc.SetCoins(initCoins) require.NoError(t, err) + keeper.SetSupply(ctx, types.NewSupply(initCoins)) keeper.SetModuleAccount(ctx, holderAcc) keeper.SetModuleAccount(ctx, burnerAcc) @@ -59,24 +63,25 @@ func TestSendCoins(t *testing.T) { err = keeper.SendCoinsFromModuleToModule(ctx, holderAcc.GetName(), types.Burner, initCoins) require.NoError(t, err) - require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, holderAcc.GetName())) - require.Equal(t, initCoins, getCoinsByName(ctx, keeper, types.Burner)) + require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, ak, holderAcc.GetName())) + require.Equal(t, initCoins, getCoinsByName(ctx, keeper, ak, types.Burner)) err = keeper.SendCoinsFromModuleToAccount(ctx, types.Burner, baseAcc.GetAddress(), initCoins) require.NoError(t, err) - require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, types.Burner)) + require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, ak, types.Burner)) - require.Equal(t, initCoins, keeper.ak.GetAccount(ctx, baseAcc.GetAddress()).GetCoins()) + require.Equal(t, initCoins, ak.GetAccount(ctx, baseAcc.GetAddress()).GetCoins()) err = keeper.SendCoinsFromAccountToModule(ctx, baseAcc.GetAddress(), types.Burner, initCoins) require.NoError(t, err) - require.Equal(t, sdk.Coins(nil), keeper.ak.GetAccount(ctx, baseAcc.GetAddress()).GetCoins()) - require.Equal(t, initCoins, getCoinsByName(ctx, keeper, types.Burner)) + require.Equal(t, sdk.Coins(nil), ak.GetAccount(ctx, baseAcc.GetAddress()).GetCoins()) + require.Equal(t, initCoins, getCoinsByName(ctx, keeper, ak, types.Burner)) } func TestMintCoins(t *testing.T) { - nAccs := int64(4) - ctx, _, keeper := createTestInput(t, false, initialPower, nAccs) + app, ctx := createTestApp(false) + keeper := app.SupplyKeeper + ak := app.AccountKeeper keeper.SetModuleAccount(ctx, burnerAcc) keeper.SetModuleAccount(ctx, minterAcc) @@ -93,7 +98,7 @@ func TestMintCoins(t *testing.T) { err := keeper.MintCoins(ctx, types.Minter, initCoins) require.NoError(t, err) - require.Equal(t, initCoins, getCoinsByName(ctx, keeper, types.Minter)) + require.Equal(t, initCoins, getCoinsByName(ctx, keeper, ak, types.Minter)) require.Equal(t, initialSupply.GetTotal().Add(initCoins), keeper.GetSupply(ctx).GetTotal()) // test same functionality on module account with multiple permissions @@ -101,17 +106,19 @@ func TestMintCoins(t *testing.T) { err = keeper.MintCoins(ctx, multiPermAcc.GetName(), initCoins) require.NoError(t, err) - require.Equal(t, initCoins, getCoinsByName(ctx, keeper, multiPermAcc.GetName())) + require.Equal(t, initCoins, getCoinsByName(ctx, keeper, ak, multiPermAcc.GetName())) require.Equal(t, initialSupply.GetTotal().Add(initCoins), keeper.GetSupply(ctx).GetTotal()) require.Panics(t, func() { keeper.MintCoins(ctx, types.Burner, initCoins) }) } func TestBurnCoins(t *testing.T) { - nAccs := int64(4) - ctx, _, keeper := createTestInput(t, false, initialPower, nAccs) + app, ctx := createTestApp(false) + keeper := app.SupplyKeeper + ak := app.AccountKeeper require.NoError(t, burnerAcc.SetCoins(initCoins)) + keeper.SetSupply(ctx, types.NewSupply(initCoins)) keeper.SetModuleAccount(ctx, burnerAcc) initialSupply := keeper.GetSupply(ctx) @@ -125,7 +132,7 @@ func TestBurnCoins(t *testing.T) { err := keeper.BurnCoins(ctx, types.Burner, initCoins) require.NoError(t, err) - require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, types.Burner)) + require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, ak, types.Burner)) require.Equal(t, initialSupply.GetTotal().Sub(initCoins), keeper.GetSupply(ctx).GetTotal()) // test same functionality on module account with multiple permissions @@ -138,6 +145,6 @@ func TestBurnCoins(t *testing.T) { err = keeper.BurnCoins(ctx, multiPermAcc.GetName(), initCoins) require.NoError(t, err) - require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, multiPermAcc.GetName())) + require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, ak, multiPermAcc.GetName())) require.Equal(t, initialSupply.GetTotal().Sub(initCoins), keeper.GetSupply(ctx).GetTotal()) } diff --git a/x/supply/internal/keeper/common_test.go b/x/supply/internal/keeper/common_test.go deleted file mode 100644 index 2846c7644c..0000000000 --- a/x/supply/internal/keeper/common_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package keeper - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" - - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" - "github.com/cosmos/cosmos-sdk/x/auth" - authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/params" - "github.com/cosmos/cosmos-sdk/x/supply/internal/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// nolint: deadcode unused -var ( - multiPerm = "multiple permissions account" - randomPerm = "random permission" - holder = "holder" -) - -// nolint: deadcode unused -// create a codec used only for testing -func makeTestCodec() *codec.Codec { - var cdc = codec.New() - - bank.RegisterCodec(cdc) - auth.RegisterCodec(cdc) - types.RegisterCodec(cdc) - sdk.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) - - return cdc -} - -// nolint: deadcode unused -func createTestInput(t *testing.T, isCheckTx bool, initPower int64, nAccs int64) (sdk.Context, auth.AccountKeeper, Keeper) { - - keyAcc := sdk.NewKVStoreKey(auth.StoreKey) - keyParams := sdk.NewKVStoreKey(params.StoreKey) - tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) - keySupply := sdk.NewKVStoreKey(types.StoreKey) - - db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) - err := ms.LoadLatestVersion() - require.Nil(t, err) - - ctx := sdk.NewContext(ms, abci.Header{ChainID: "supply-chain"}, isCheckTx, log.NewNopLogger()) - ctx = ctx.WithConsensusParams( - &abci.ConsensusParams{ - Validator: &abci.ValidatorParams{ - PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}, - }, - }, - ) - cdc := makeTestCodec() - - blacklistedAddrs := make(map[string]bool) - - pk := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace) - ak := auth.NewAccountKeeper(cdc, keyAcc, pk.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount) - bk := bank.NewBaseKeeper(ak, pk.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) - - valTokens := sdk.TokensFromConsensusPower(initPower) - - initialCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, valTokens)) - createTestAccs(ctx, int(nAccs), initialCoins, &ak) - - maccPerms := map[string][]string{ - holder: nil, - types.Minter: {types.Minter}, - types.Burner: {types.Burner}, - multiPerm: {types.Minter, types.Burner, types.Staking}, - randomPerm: {"random"}, - } - keeper := NewKeeper(cdc, keySupply, ak, bk, maccPerms) - totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, valTokens.MulRaw(nAccs))) - keeper.SetSupply(ctx, types.NewSupply(totalSupply)) - - return ctx, ak, keeper -} - -// nolint: unparam deadcode unused -func createTestAccs(ctx sdk.Context, numAccs int, initialCoins sdk.Coins, ak *auth.AccountKeeper) (accs []authexported.Account) { - for i := 0; i < numAccs; i++ { - privKey := secp256k1.GenPrivKey() - pubKey := privKey.PubKey() - addr := sdk.AccAddress(pubKey.Address()) - acc := auth.NewBaseAccountWithAddress(addr) - acc.Coins = initialCoins - acc.PubKey = pubKey - acc.AccountNumber = uint64(i) - ak.SetAccount(ctx, &acc) - } - return -} diff --git a/x/supply/internal/keeper/integration_test.go b/x/supply/internal/keeper/integration_test.go new file mode 100644 index 0000000000..a09f21e4bd --- /dev/null +++ b/x/supply/internal/keeper/integration_test.go @@ -0,0 +1,35 @@ +package keeper_test + +import ( + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + keep "github.com/cosmos/cosmos-sdk/x/supply/internal/keeper" + "github.com/cosmos/cosmos-sdk/x/supply/internal/types" +) + +var ( + multiPerm = "multiple permissions account" + randomPerm = "random permission" + holder = "holder" +) + +// nolint: deadcode unused +func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { + app := simapp.Setup(isCheckTx) + + // add module accounts to supply keeper + maccPerms := simapp.GetMaccPerms() + maccPerms[holder] = nil + maccPerms[types.Burner] = []string{types.Burner} + maccPerms[types.Minter] = []string{types.Minter} + maccPerms[multiPerm] = []string{types.Burner, types.Minter, types.Staking} + maccPerms[randomPerm] = []string{"random"} + + ctx := app.BaseApp.NewContext(isCheckTx, abci.Header{}) + app.SupplyKeeper = keep.NewKeeper(app.Codec(), app.GetKey(types.StoreKey), app.AccountKeeper, app.BankKeeper, maccPerms) + app.SupplyKeeper.SetSupply(ctx, types.NewSupply(sdk.NewCoins())) + + return app, ctx +} diff --git a/x/supply/internal/keeper/keeper_test.go b/x/supply/internal/keeper/keeper_test.go index 61e0afa596..d4ff2849e4 100644 --- a/x/supply/internal/keeper/keeper_test.go +++ b/x/supply/internal/keeper/keeper_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "testing" @@ -12,29 +12,27 @@ import ( func TestSupply(t *testing.T) { initialPower := int64(100) initTokens := sdk.TokensFromConsensusPower(initialPower) - nAccs := int64(4) - ctx, _, keeper := createTestInput(t, false, initialPower, nAccs) + app, ctx := createTestApp(false) + totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) + app.SupplyKeeper.SetSupply(ctx, types.NewSupply(totalSupply)) - total := keeper.GetSupply(ctx).GetTotal() - expectedTotal := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(nAccs))) + total := app.SupplyKeeper.GetSupply(ctx).GetTotal() - require.Equal(t, expectedTotal, total) + require.Equal(t, totalSupply, total) } func TestValidatePermissions(t *testing.T) { - nAccs := int64(0) - initialPower := int64(100) - _, _, keeper := createTestInput(t, false, initialPower, nAccs) + app, _ := createTestApp(false) - err := keeper.ValidatePermissions(multiPermAcc) + err := app.SupplyKeeper.ValidatePermissions(multiPermAcc) require.NoError(t, err) - err = keeper.ValidatePermissions(randomPermAcc) + err = app.SupplyKeeper.ValidatePermissions(randomPermAcc) require.NoError(t, err) // unregistered permissions otherAcc := types.NewEmptyModuleAccount("other", "other") - err = keeper.ValidatePermissions(otherAcc) + err = app.SupplyKeeper.ValidatePermissions(otherAcc) require.Error(t, err) } diff --git a/x/supply/internal/keeper/querier_test.go b/x/supply/internal/keeper/querier_test.go index 2a06d9ee58..92b0dcf32b 100644 --- a/x/supply/internal/keeper/querier_test.go +++ b/x/supply/internal/keeper/querier_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "fmt" @@ -8,11 +8,14 @@ import ( abci "github.com/tendermint/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + keep "github.com/cosmos/cosmos-sdk/x/supply/internal/keeper" "github.com/cosmos/cosmos-sdk/x/supply/internal/types" ) func TestNewQuerier(t *testing.T) { - ctx, _, keeper := createTestInput(t, false, 1000, 2) + app, ctx := createTestApp(false) + keeper := app.SupplyKeeper + cdc := app.Codec() supplyCoins := sdk.NewCoins( sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), @@ -28,14 +31,14 @@ func TestNewQuerier(t *testing.T) { Data: []byte{}, } - querier := NewQuerier(keeper) + querier := keep.NewQuerier(keeper) bz, err := querier(ctx, []string{"other"}, query) require.Error(t, err) require.Nil(t, bz) queryTotalSupplyParams := types.NewQueryTotalSupplyParams(1, 20) - bz, errRes := keeper.cdc.MarshalJSON(queryTotalSupplyParams) + bz, errRes := cdc.MarshalJSON(queryTotalSupplyParams) require.Nil(t, errRes) query.Path = fmt.Sprintf("/custom/supply/%s", types.QueryTotalSupply) @@ -45,7 +48,7 @@ func TestNewQuerier(t *testing.T) { require.Nil(t, err) querySupplyParams := types.NewQuerySupplyOfParams(sdk.DefaultBondDenom) - bz, errRes = keeper.cdc.MarshalJSON(querySupplyParams) + bz, errRes = cdc.MarshalJSON(querySupplyParams) require.Nil(t, errRes) query.Path = fmt.Sprintf("/custom/supply/%s", types.QuerySupplyOf) @@ -56,7 +59,9 @@ func TestNewQuerier(t *testing.T) { } func TestQuerySupply(t *testing.T) { - ctx, _, keeper := createTestInput(t, false, 1000, 2) + app, ctx := createTestApp(false) + keeper := app.SupplyKeeper + cdc := app.Codec() supplyCoins := sdk.NewCoins( sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), @@ -65,10 +70,12 @@ func TestQuerySupply(t *testing.T) { sdk.NewCoin("btc", sdk.NewInt(21000000)), ) + querier := keep.NewQuerier(keeper) + keeper.SetSupply(ctx, types.NewSupply(supplyCoins)) queryTotalSupplyParams := types.NewQueryTotalSupplyParams(1, 10) - bz, errRes := keeper.cdc.MarshalJSON(queryTotalSupplyParams) + bz, errRes := cdc.MarshalJSON(queryTotalSupplyParams) require.Nil(t, errRes) query := abci.RequestQuery{ @@ -79,22 +86,22 @@ func TestQuerySupply(t *testing.T) { query.Path = fmt.Sprintf("/custom/supply/%s", types.QueryTotalSupply) query.Data = bz - res, err := queryTotalSupply(ctx, query, keeper) + res, err := querier(ctx, []string{types.QueryTotalSupply}, query) require.Nil(t, err) var totalCoins sdk.Coins - errRes = keeper.cdc.UnmarshalJSON(res, &totalCoins) + errRes = cdc.UnmarshalJSON(res, &totalCoins) require.Nil(t, errRes) require.Equal(t, supplyCoins, totalCoins) querySupplyParams := types.NewQuerySupplyOfParams(sdk.DefaultBondDenom) - bz, errRes = keeper.cdc.MarshalJSON(querySupplyParams) + bz, errRes = cdc.MarshalJSON(querySupplyParams) require.Nil(t, errRes) query.Path = fmt.Sprintf("/custom/supply/%s", types.QuerySupplyOf) query.Data = bz - res, err = querySupplyOf(ctx, query, keeper) + res, err = querier(ctx, []string{types.QuerySupplyOf}, query) require.Nil(t, err) var supply sdk.Int