github.com/Finschia/finschia-sdk@v0.49.1/x/bank/simulation/operations_test.go (about) 1 package simulation_test 2 3 import ( 4 "math/rand" 5 "testing" 6 7 ocabci "github.com/Finschia/ostracon/abci/types" 8 "github.com/stretchr/testify/suite" 9 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 10 11 "github.com/Finschia/finschia-sdk/simapp" 12 simappparams "github.com/Finschia/finschia-sdk/simapp/params" 13 sdk "github.com/Finschia/finschia-sdk/types" 14 simtypes "github.com/Finschia/finschia-sdk/types/simulation" 15 "github.com/Finschia/finschia-sdk/x/bank/simulation" 16 "github.com/Finschia/finschia-sdk/x/bank/types" 17 ) 18 19 type SimTestSuite struct { 20 suite.Suite 21 22 ctx sdk.Context 23 app *simapp.SimApp 24 } 25 26 func (suite *SimTestSuite) SetupTest() { 27 checkTx := false 28 app := simapp.Setup(checkTx) 29 suite.app = app 30 suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{}) 31 } 32 33 // TestWeightedOperations tests the weights of the operations. 34 func (suite *SimTestSuite) TestWeightedOperations() { 35 cdc := suite.app.AppCodec() 36 appParams := make(simtypes.AppParams) 37 38 weightesOps := simulation.WeightedOperations(appParams, cdc, suite.app.AccountKeeper, suite.app.BankKeeper) 39 40 // setup 3 accounts 41 s := rand.NewSource(1) 42 r := rand.New(s) 43 accs := suite.getTestingAccounts(r, 3) 44 45 expected := []struct { 46 weight int 47 opMsgRoute string 48 opMsgName string 49 }{ 50 {simappparams.DefaultWeightMsgSend, types.ModuleName, types.TypeMsgSend}, 51 {simappparams.DefaultWeightMsgMultiSend, types.ModuleName, types.TypeMsgMultiSend}, 52 } 53 54 for i, w := range weightesOps { 55 operationMsg, _, _ := w.Op()(r, suite.app.BaseApp, suite.ctx, accs, "") 56 // the following checks are very much dependent from the ordering of the output given 57 // by WeightedOperations. if the ordering in WeightedOperations changes some tests 58 // will fail 59 suite.Require().Equal(expected[i].weight, w.Weight(), "weight should be the same") 60 suite.Require().Equal(expected[i].opMsgRoute, operationMsg.Route, "route should be the same") 61 suite.Require().Equal(expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same") 62 } 63 } 64 65 // TestSimulateMsgSend tests the normal scenario of a valid message of type TypeMsgSend. 66 // Abonormal scenarios, where the message is created by an errors, are not tested here. 67 func (suite *SimTestSuite) TestSimulateMsgSend() { 68 // setup 3 accounts 69 s := rand.NewSource(1) 70 r := rand.New(s) 71 accounts := suite.getTestingAccounts(r, 3) 72 73 // begin a new block 74 suite.app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}}) 75 76 // execute operation 77 op := simulation.SimulateMsgSend(suite.app.AccountKeeper, suite.app.BankKeeper) 78 operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") 79 suite.Require().NoError(err) 80 81 var msg types.MsgSend 82 err = types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) 83 suite.Require().NoError(err) 84 85 suite.Require().True(operationMsg.OK) 86 suite.Require().Equal("65337742stake", msg.Amount.String()) 87 suite.Require().Equal("link1ghekyjucln7y67ntx7cf27m9dpuxxemnqk82wt", msg.FromAddress) 88 suite.Require().Equal("link1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7fmx8x8", msg.ToAddress) 89 suite.Require().Equal(types.TypeMsgSend, msg.Type()) 90 suite.Require().Equal(types.ModuleName, msg.Route()) 91 suite.Require().Len(futureOperations, 0) 92 } 93 94 // TestSimulateMsgSend tests the normal scenario of a valid message of type TypeMsgMultiSend. 95 // Abonormal scenarios, where the message is created by an errors, are not tested here. 96 func (suite *SimTestSuite) TestSimulateMsgMultiSend() { 97 // setup 3 accounts 98 s := rand.NewSource(1) 99 r := rand.New(s) 100 accounts := suite.getTestingAccounts(r, 3) 101 102 // begin a new block 103 suite.app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}}) 104 105 // execute operation 106 op := simulation.SimulateMsgMultiSend(suite.app.AccountKeeper, suite.app.BankKeeper) 107 operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") 108 require := suite.Require() 109 require.NoError(err) 110 111 var msg types.MsgMultiSend 112 err = types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) 113 require.NoError(err) 114 115 require.True(operationMsg.OK) 116 require.Len(msg.Inputs, 3) 117 require.Equal("link1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7fmx8x8", msg.Inputs[1].Address) 118 require.Equal("185121068stake", msg.Inputs[1].Coins.String()) 119 require.Len(msg.Outputs, 2) 120 require.Equal("link1ghekyjucln7y67ntx7cf27m9dpuxxemnqk82wt", msg.Outputs[1].Address) 121 require.Equal("260469617stake", msg.Outputs[1].Coins.String()) 122 require.Equal(types.TypeMsgMultiSend, msg.Type()) 123 require.Equal(types.ModuleName, msg.Route()) 124 require.Len(futureOperations, 0) 125 } 126 127 // Since the allowedReceivingModAcc value of the distribution module is set to true, change it to test in which the result is true. 128 func (suite *SimTestSuite) TestSimulateModuleAccountMsgSend() { 129 const ( 130 accCount = 1 131 moduleAccCount = 1 132 ) 133 134 s := rand.NewSource(1) 135 r := rand.New(s) 136 accounts := suite.getTestingAccounts(r, accCount) 137 138 // begin a new block 139 suite.app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}}) 140 141 // execute operation 142 op := simulation.SimulateMsgSendToModuleAccount(suite.app.AccountKeeper, suite.app.BankKeeper, moduleAccCount) 143 144 s = rand.NewSource(1) 145 r = rand.New(s) 146 147 operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") 148 suite.Require().Error(err) 149 150 var msg types.MsgSend 151 err = types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) 152 suite.Require().Error(err) 153 154 suite.Require().False(operationMsg.OK) 155 suite.Require().Equal(operationMsg.Comment, "invalid transfers") 156 suite.Require().Equal(types.TypeMsgSend, msg.Type()) 157 suite.Require().Equal(types.ModuleName, msg.Route()) 158 suite.Require().Len(futureOperations, 0) 159 } 160 161 // Since the allowedReceivingModAcc value of the distribution module is set to true, change it to test in which the result is true. 162 func (suite *SimTestSuite) TestSimulateMsgMultiSendToModuleAccount() { 163 const ( 164 accCount = 2 165 mAccCount = 2 166 ) 167 168 s := rand.NewSource(1) 169 r := rand.New(s) 170 accounts := suite.getTestingAccounts(r, accCount) 171 172 // begin a new block 173 suite.app.BeginBlock(ocabci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}}) 174 175 // execute operation 176 op := simulation.SimulateMsgMultiSendToModuleAccount(suite.app.AccountKeeper, suite.app.BankKeeper, mAccCount) 177 178 operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "") 179 suite.Require().Error(err) 180 181 var msg types.MsgMultiSend 182 err = types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) 183 suite.Require().Error(err) 184 185 suite.Require().False(operationMsg.OK) // sending tokens to a module account should fail 186 suite.Require().Equal(operationMsg.Comment, "invalid transfers") 187 suite.Require().Equal(types.TypeMsgMultiSend, msg.Type()) 188 suite.Require().Equal(types.ModuleName, msg.Route()) 189 suite.Require().Len(futureOperations, 0) 190 } 191 192 func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Account { 193 accounts := simtypes.RandomAccounts(r, n) 194 195 initAmt := suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 200) 196 initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) 197 198 // add coins to the accounts 199 for _, account := range accounts { 200 acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, account.Address) 201 suite.app.AccountKeeper.SetAccount(suite.ctx, acc) 202 suite.Require().NoError(simapp.FundAccount(suite.app, suite.ctx, account.Address, initCoins)) 203 } 204 205 return accounts 206 } 207 208 func TestSimTestSuite(t *testing.T) { 209 suite.Run(t, new(SimTestSuite)) 210 }