package simulation_test import ( "math/rand" "testing" "time" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" "github.com/cosmos/cosmos-sdk/x/nft" nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper" "github.com/cosmos/cosmos-sdk/x/nft/simulation" "github.com/cosmos/cosmos-sdk/x/nft/testutil" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" ) type SimTestSuite struct { suite.Suite ctx sdk.Context app *runtime.App codec codec.Codec interfaceRegistry codectypes.InterfaceRegistry accountKeeper authkeeper.AccountKeeper bankKeeper bankkeeper.Keeper stakingKeeper *stakingkeeper.Keeper nftKeeper nftkeeper.Keeper } func (suite *SimTestSuite) SetupTest() { app, err := simtestutil.Setup( testutil.AppConfig, &suite.codec, &suite.interfaceRegistry, &suite.accountKeeper, &suite.bankKeeper, &suite.stakingKeeper, &suite.nftKeeper, ) suite.Require().NoError(err) suite.app = app suite.ctx = app.BaseApp.NewContext(false, tmproto.Header{}) } func (suite *SimTestSuite) TestWeightedOperations() { weightedOps := simulation.WeightedOperations( suite.interfaceRegistry, make(simtypes.AppParams), suite.codec, suite.accountKeeper, suite.bankKeeper, suite.nftKeeper, ) // setup 3 accounts s := rand.NewSource(1) r := rand.New(s) accs := suite.getTestingAccounts(r, 3) expected := []struct { weight int opMsgRoute string opMsgName string }{ {simulation.WeightSend, simulation.TypeMsgSend, simulation.TypeMsgSend}, } for i, w := range weightedOps { operationMsg, _, err := w.Op()(r, suite.app.BaseApp, suite.ctx, accs, "") suite.Require().NoError(err) // the following checks are very much dependent from the ordering of the output given // by WeightedOperations. if the ordering in WeightedOperations changes some tests // will fail suite.Require().Equal(expected[i].weight, w.Weight(), "weight should be the same") suite.Require().Equal(expected[i].opMsgRoute, operationMsg.Route, "route should be the same") suite.Require().Equal(expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same") } } func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Account { accounts := simtypes.RandomAccounts(r, n) initAmt := suite.stakingKeeper.TokensFromConsensusPower(suite.ctx, 200000) initCoins := sdk.NewCoins(sdk.NewCoin("stake", initAmt)) // add coins to the accounts for _, account := range accounts { acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, account.Address) suite.accountKeeper.SetAccount(suite.ctx, acc) suite.Require().NoError(banktestutil.FundAccount(suite.bankKeeper, suite.ctx, account.Address, initCoins)) } return accounts } func (suite *SimTestSuite) TestSimulateMsgSend() { s := rand.NewSource(1) r := rand.New(s) accounts := suite.getTestingAccounts(r, 2) blockTime := time.Now().UTC() ctx := suite.ctx.WithBlockTime(blockTime) // begin new block suite.app.BeginBlock(abci.RequestBeginBlock{ Header: tmproto.Header{ Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash, }, }) // execute operation registry := suite.interfaceRegistry op := simulation.SimulateMsgSend(codec.NewProtoCodec(registry), suite.accountKeeper, suite.bankKeeper, suite.nftKeeper) operationMsg, futureOperations, err := op(r, suite.app.BaseApp, ctx, accounts, "") suite.Require().NoError(err) var msg nft.MsgSend suite.codec.UnmarshalJSON(operationMsg.Msg, &msg) suite.Require().True(operationMsg.OK) suite.Require().Len(futureOperations, 0) } func TestSimTestSuite(t *testing.T) { suite.Run(t, new(SimTestSuite)) }