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  }