github.com/Finschia/finschia-sdk@v0.48.1/x/bank/simulation/operations_test.go (about)

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