From 3348876f46c66c9502d16793bb61b729559ecc91 Mon Sep 17 00:00:00 2001 From: Oleg Nikonychev Date: Mon, 3 Jun 2024 21:53:54 +0400 Subject: [PATCH 1/5] test(evm): grpc_query full coverage --- x/evm/evmtest/eth.go | 2 +- x/evm/keeper/grpc_query_test.go | 634 ++++++++++++++++++++++++++++---- x/evm/keeper/keeper_test.go | 2 +- 3 files changed, 569 insertions(+), 69 deletions(-) diff --git a/x/evm/evmtest/eth.go b/x/evm/evmtest/eth.go index f525c6184..e9f9717c5 100644 --- a/x/evm/evmtest/eth.go +++ b/x/evm/evmtest/eth.go @@ -40,7 +40,7 @@ func NewEthAccInfo() EthPrivKeyAcc { } func EthAddrToNibiruAddr(ethAddr gethcommon.Address) sdk.AccAddress { - return sdk.AccAddress(ethAddr.Bytes()) + return ethAddr.Bytes() } type EthPrivKeyAcc struct { diff --git a/x/evm/keeper/grpc_query_test.go b/x/evm/keeper/grpc_query_test.go index 1592b58ec..42f2b9472 100644 --- a/x/evm/keeper/grpc_query_test.go +++ b/x/evm/keeper/grpc_query_test.go @@ -1,19 +1,21 @@ package keeper_test import ( + "crypto/ecdsa" "encoding/json" - "fmt" + "math/big" + "regexp" "cosmossdk.io/math" + "github.com/NibiruChain/collections" sdk "github.com/cosmos/cosmos-sdk/types" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - - "github.com/NibiruChain/collections" + "github.com/ethereum/go-ethereum/crypto" + gethparams "github.com/ethereum/go-ethereum/params" srvconfig "github.com/NibiruChain/nibiru/app/server/config" "github.com/NibiruChain/nibiru/eth" - "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/common/testutil/testapp" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" @@ -21,6 +23,31 @@ import ( func InvalidEthAddr() string { return "0x0000" } +func TraceNibiTransfer() string { + return `{ + "gas": 21000, + "failed": false, + "returnValue": "", + "structLogs": [] + }` +} + +func TraceERC20Transfer() string { + return `{ + "gas": 35062, + "failed": false, + "returnValue": "0000000000000000000000000000000000000000000000000000000000000001", + "structLogs": [ + { + "pc": 0, + "op": "PUSH1", + "gas": 30578, + "gasCost": 3, + "depth": 1, + "stack": [] + }` +} + type TestCase[In, Out any] struct { name string // setup: Optional setup function to create the scenario @@ -50,7 +77,7 @@ func (s *KeeperSuite) TestQueryNibiruAccount() { wantErr: "not a valid ethereum hex addr", }, { - name: "happy", + name: "happy: not existing account", scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { ethAcc := evmtest.NewEthAccInfo() req = &evm.QueryNibiruAccountRequest{ @@ -65,6 +92,26 @@ func (s *KeeperSuite) TestQueryNibiruAccount() { }, wantErr: "", }, + { + name: "happy: existing account", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + ethAcc := evmtest.NewEthAccInfo() + accountKeeper := deps.Chain.AccountKeeper + account := accountKeeper.NewAccountWithAddress(deps.Ctx, ethAcc.NibiruAddr) + accountKeeper.SetAccount(deps.Ctx, account) + + req = &evm.QueryNibiruAccountRequest{ + Address: ethAcc.EthAddr.String(), + } + wantResp = &evm.QueryNibiruAccountResponse{ + Address: ethAcc.NibiruAddr.String(), + Sequence: account.GetSequence(), + AccountNumber: account.GetAccountNumber(), + } + return req, wantResp + }, + wantErr: "", + }, } for _, tc := range testCases { @@ -167,6 +214,19 @@ func (s *KeeperSuite) TestQueryValidatorAccount() { }, wantErr: "decoding bech32 failed", }, + { + name: "sad: validator account not found", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.QueryValidatorAccountRequest{ + ConsAddress: "nibivalcons1ea4ef7wsatlnaj9ry3zylymxv53f9ntrjecc40", + } + wantResp = &evm.QueryValidatorAccountResponse{ + AccountAddress: sdk.AccAddress(gethcommon.Address{}.Bytes()).String(), + } + return req, wantResp + }, + wantErr: "validator not found", + }, { name: "happy: default values", setup: func(deps *evmtest.TestDeps) {}, @@ -385,46 +445,6 @@ func (s *KeeperSuite) TestQueryCode() { } } -// AssertModuleParamsEqual errors if the fields don't match. This function avoids -// failing the "EqualValues" check due to comparisons between nil and empty -// slices: `[]string(nil)` and `[]string{}`. -func AssertModuleParamsEqual(want, got evm.Params) error { - errs := []error{} - { - want, got := want.EvmDenom, got.EvmDenom - if want != got { - errs = append(errs, ErrModuleParamsEquality( - "evm_denom", want, got)) - } - } - { - want, got := want.EnableCreate, got.EnableCreate - if want != got { - errs = append(errs, ErrModuleParamsEquality( - "enable_create", want, got)) - } - } - { - want, got := want.EnableCall, got.EnableCall - if want != got { - errs = append(errs, ErrModuleParamsEquality( - "enable_call", want, got)) - } - } - { - want, got := want.ChainConfig, got.ChainConfig - if want != got { - errs = append(errs, ErrModuleParamsEquality( - "chain_config", want, got)) - } - } - return common.CombineErrors(errs...) -} - -func ErrModuleParamsEquality(field string, want, got any) error { - return fmt.Errorf(`failed AssetModuleParamsEqual on field %s: want "%v", got "%v"`, field, want, got) -} - func (s *KeeperSuite) TestQueryParams() { deps := evmtest.NewTestDeps() want := evm.DefaultParams() @@ -447,38 +467,518 @@ func (s *KeeperSuite) TestQueryParams() { s.Require().True(want.Equal(got), "want %s, got %s", want, got) } -func (s *KeeperSuite) TestEthCall_ERC20_Happy() { - deps := evmtest.NewTestDeps() - fungibleTokenContract := evmtest.SmartContract_FunToken.Load(s.T()) +func (s *KeeperSuite) TestQueryEthCall() { + type In = *evm.EthCallRequest + type Out = *evm.MsgEthereumTxResponse + testCases := []TestCase[In, Out]{ + { + name: "sad: msg invalid msg", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + return nil, nil + }, + wantErr: "InvalidArgument", + }, + { + name: "sad: invalid args", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + return &evm.EthCallRequest{Args: []byte("invalid")}, nil + }, + wantErr: "InvalidArgument", + }, + { + name: "happy: eth call for erc20 token transfer", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + fungibleTokenContract := evmtest.SmartContract_FunToken.Load(s.T()) - s.T().Log("Populate the supply and acc balance") - contractConstructorArgs, err := fungibleTokenContract.ABI.Pack( - "", - ) + jsonTxArgs, err := json.Marshal(&evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + Data: (*hexutil.Bytes)(&fungibleTokenContract.Bytecode), + }) + s.Require().NoError(err) + return &evm.EthCallRequest{Args: jsonTxArgs}, &evm.MsgEthereumTxResponse{ + Hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + } + }, + wantErr: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + if tc.setup != nil { + tc.setup(&deps) + } + req, wantResp := tc.scenario(&deps) + gotResp, err := deps.Chain.EvmKeeper.EthCall(deps.GoCtx(), req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.Assert().Empty(wantResp.VmError) + s.Assert().Equal(wantResp.Hash, gotResp.Hash) + }) + } +} + +func (s *KeeperSuite) TestQueryBalance() { + type In = *evm.QueryBalanceRequest + type Out = *evm.QueryBalanceResponse + testCases := []TestCase[In, Out]{ + { + name: "sad: msg validation", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.QueryBalanceRequest{ + Address: InvalidEthAddr(), + } + wantResp = &evm.QueryBalanceResponse{ + Balance: "0", + } + return req, wantResp + }, + wantErr: "InvalidArgument", + }, + { + name: "happy: zero balance", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.QueryBalanceRequest{ + Address: evmtest.NewEthAccInfo().EthAddr.String(), + } + wantResp = &evm.QueryBalanceResponse{ + Balance: "0", + } + return req, wantResp + }, + wantErr: "", + }, + { + name: "happy: non zero balance", + setup: func(deps *evmtest.TestDeps) { + chain := deps.Chain + ethAddr := deps.Sender.EthAddr + + // fund account with 420 tokens + coins := sdk.Coins{sdk.NewInt64Coin(evm.DefaultEVMDenom, 420)} + err := chain.BankKeeper.MintCoins(deps.Ctx, evm.ModuleName, coins) + s.NoError(err) + err = chain.BankKeeper.SendCoinsFromModuleToAccount( + deps.Ctx, evm.ModuleName, ethAddr.Bytes(), coins) + s.Require().NoError(err) + }, + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.QueryBalanceRequest{ + Address: deps.Sender.EthAddr.Hex(), + } + wantResp = &evm.QueryBalanceResponse{ + Balance: "420", + } + return req, wantResp + }, + wantErr: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + if tc.setup != nil { + tc.setup(&deps) + } + req, wantResp := tc.scenario(&deps) + goCtx := sdk.WrapSDKContext(deps.Ctx) + gotResp, err := deps.K.Balance(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.EqualValues(wantResp, gotResp) + }) + } +} + +func (s *KeeperSuite) TestQueryBaseFee() { + type In = *evm.QueryBaseFeeRequest + type Out = *evm.QueryBaseFeeResponse + testCases := []TestCase[In, Out]{ + { + name: "happy: base fee value", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.QueryBaseFeeRequest{} + zeroFee := math.NewInt(0) + wantResp = &evm.QueryBaseFeeResponse{ + BaseFee: &zeroFee, + } + return req, wantResp + }, + wantErr: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + if tc.setup != nil { + tc.setup(&deps) + } + req, wantResp := tc.scenario(&deps) + goCtx := sdk.WrapSDKContext(deps.Ctx) + gotResp, err := deps.K.BaseFee(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.EqualValues(wantResp, gotResp) + }) + } +} + +func (s *KeeperSuite) TestEstimateGasForEvmCallType() { + type In = *evm.EthCallRequest + type Out = *evm.EstimateGasResponse + testCases := []TestCase[In, Out]{ + { + name: "sad: nil query", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = nil + wantResp = nil + return req, wantResp + }, + wantErr: "InvalidArgument", + }, + { + name: "sad: insufficient gas cap", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.EthCallRequest{ + GasCap: gethparams.TxGas - 1, + } + return req, nil + }, + wantErr: "InvalidArgument", + }, + { + name: "sad: invalid args", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + req = &evm.EthCallRequest{ + Args: []byte{0, 0, 0}, + GasCap: gethparams.TxGas, + } + return req, nil + }, + wantErr: "InvalidArgument", + }, + { + name: "happy: estimate gas for transfer", + setup: func(deps *evmtest.TestDeps) { + chain := deps.Chain + ethAddr := deps.Sender.EthAddr + coins := sdk.Coins{sdk.NewInt64Coin(evm.DefaultEVMDenom, 1000)} + err := chain.BankKeeper.MintCoins(deps.Ctx, evm.ModuleName, coins) + s.NoError(err) + err = chain.BankKeeper.SendCoinsFromModuleToAccount( + deps.Ctx, evm.ModuleName, ethAddr.Bytes(), coins) + s.Require().NoError(err) + }, + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + recipient := evmtest.NewEthAccInfo().EthAddr + amountToSend := hexutil.Big(*big.NewInt(10)) + gasLimitArg := hexutil.Uint64(100000) + + jsonTxArgs, err := json.Marshal(&evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + To: &recipient, + Value: &amountToSend, + Gas: &gasLimitArg, + }) + s.Require().NoError(err) + req = &evm.EthCallRequest{ + Args: jsonTxArgs, + GasCap: gethparams.TxGas, + } + wantResp = &evm.EstimateGasResponse{ + Gas: gethparams.TxGas, + } + return req, wantResp + }, + wantErr: "", + }, + { + name: "sad: insufficient balance for transfer", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + recipient := evmtest.NewEthAccInfo().EthAddr + amountToSend := hexutil.Big(*big.NewInt(10)) + + jsonTxArgs, err := json.Marshal(&evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + To: &recipient, + Value: &amountToSend, + }) + s.Require().NoError(err) + req = &evm.EthCallRequest{ + Args: jsonTxArgs, + GasCap: gethparams.TxGas, + } + wantResp = nil + return req, wantResp + }, + wantErr: "insufficient balance for transfer", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + if tc.setup != nil { + tc.setup(&deps) + } + req, wantResp := tc.scenario(&deps) + goCtx := sdk.WrapSDKContext(deps.Ctx) + gotResp, err := deps.K.EstimateGas(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.EqualValues(wantResp, gotResp) + }) + } +} + +func (s *KeeperSuite) TestTestTraceTx() { + type In = *evm.QueryTraceTxRequest + type Out = string + + testCases := []TestCase[In, Out]{ + { + name: "sad: nil query", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + return nil, "" + }, + wantErr: "InvalidArgument", + }, + { + name: "happy: simple nibi transfer tx", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + txMsg := s.ExecuteNibiTransfer(deps) + req = &evm.QueryTraceTxRequest{ + Msg: txMsg, + } + wantResp = TraceNibiTransfer() + return req, wantResp + }, + wantErr: "", + }, + { + "happy: trace erc-20 transfer tx", + nil, + func(deps *evmtest.TestDeps) (req In, wantResp Out) { + txMsg, predecessors := s.ExecuteERC20Transfer(deps) + + req = &evm.QueryTraceTxRequest{ + Msg: txMsg, + Predecessors: predecessors, + } + wantResp = TraceERC20Transfer() + return req, wantResp + }, + "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + if tc.setup != nil { + tc.setup(&deps) + } + req, wantResp := tc.scenario(&deps) + goCtx := sdk.WrapSDKContext(deps.Ctx) + gotResp, err := deps.K.TraceTx(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.Assert().NotNil(gotResp) + s.Assert().NotNil(gotResp.Data) + + // Replace spaces in want resp + re := regexp.MustCompile(`[\s\n\r]+`) + wantResp = re.ReplaceAllString(wantResp, "") + actualResp := string(gotResp.Data) + if len(actualResp) > 1000 { + actualResp = actualResp[:len(wantResp)] + } + s.Assert().Equal(wantResp, actualResp) + }) + } +} + +func (s *KeeperSuite) TestTestTraceBlock() { + type In = *evm.QueryTraceBlockRequest + type Out = string + testCases := []TestCase[In, Out]{ + { + name: "sad: nil query", + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + return nil, "" + }, + wantErr: "InvalidArgument", + }, + { + name: "happy: simple nibi transfer tx", + setup: nil, + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + txMsg := s.ExecuteNibiTransfer(deps) + req = &evm.QueryTraceBlockRequest{ + Txs: []*evm.MsgEthereumTx{ + txMsg, + }, + } + wantResp = "[{\"result\":" + TraceNibiTransfer() + "}]" + return req, wantResp + }, + wantErr: "", + }, + { + name: "happy: trace erc-20 transfer tx", + setup: nil, + scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { + txMsg, _ := s.ExecuteERC20Transfer(deps) + req = &evm.QueryTraceBlockRequest{ + Txs: []*evm.MsgEthereumTx{ + txMsg, + }, + } + wantResp = "[{\"result\":" + TraceERC20Transfer() // no end as it's trimmed + return req, wantResp + }, + wantErr: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := evmtest.NewTestDeps() + if tc.setup != nil { + tc.setup(&deps) + } + req, wantResp := tc.scenario(&deps) + goCtx := sdk.WrapSDKContext(deps.Ctx) + gotResp, err := deps.K.TraceBlock(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.Assert().NotNil(gotResp) + s.Assert().NotNil(gotResp.Data) + + // Replace spaces in want resp + re := regexp.MustCompile(`[\s\n\r]+`) + wantResp = re.ReplaceAllString(wantResp, "") + actualResp := string(gotResp.Data) + if len(actualResp) > 1000 { + actualResp = actualResp[:len(wantResp)] + } + s.Assert().Equal(wantResp, actualResp) + }) + } +} + +// ExecuteNibiTransfer executes nibi transfer +func (s *KeeperSuite) ExecuteNibiTransfer(deps *evmtest.TestDeps) *evm.MsgEthereumTx { + nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr) + recipient := GenerateEthAddress() + + txArgs := evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + To: &recipient, + Nonce: (*hexutil.Uint64)(&nonce), + } + ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps) + s.NoError(err) + + resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) s.Require().NoError(err) + s.Require().Empty(resp.VmError) + return ethTxMsg +} - bytecode := fungibleTokenContract.Bytecode - bytecode = append(bytecode, contractConstructorArgs...) +// ExecuteERC20Transfer deploys contract, executes transfer and returns tx hash +func (s *KeeperSuite) ExecuteERC20Transfer(deps *evmtest.TestDeps) (*evm.MsgEthereumTx, []*evm.MsgEthereumTx) { + // TX 1: Deploy ERC-20 contract + contractData := evmtest.SmartContract_FunToken.Load(s.T()) + nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr) + txArgs := evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + Nonce: (*hexutil.Uint64)(&nonce), + Data: (*hexutil.Bytes)(&contractData.Bytecode), + } + ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps) + s.NoError(err) - jsonTxArgs, err := json.Marshal(&evm.JsonTxArgs{ - From: &deps.Sender.EthAddr, - Data: (*hexutil.Bytes)(&bytecode), - }) + resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) s.Require().NoError(err) + s.Require().Empty(resp.VmError) - _, err = deps.Chain.EvmKeeper.EstimateGas(deps.GoCtx(), &evm.EthCallRequest{ - Args: jsonTxArgs, - GasCap: srvconfig.DefaultGasCap, - ProposerAddress: []byte{}, - ChainId: deps.Chain.EvmKeeper.EthChainID(deps.Ctx).Int64(), - }) + // Contract address is deterministic + contractAddress := crypto.CreateAddress(deps.Sender.EthAddr, nonce) + deps.Chain.Commit() + predecessors := []*evm.MsgEthereumTx{ + ethTxMsg, + } + + // TX 2: execute ERC-20 contract transfer + input, err := contractData.ABI.Pack( + "transfer", GenerateEthAddress(), new(big.Int).SetUint64(1000), + ) + s.NoError(err) + nonce = deps.StateDB().GetNonce(deps.Sender.EthAddr) + txArgs = evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + To: &contractAddress, + Nonce: (*hexutil.Uint64)(&nonce), + Data: (*hexutil.Bytes)(&input), + } + ethTxMsg, err = GenerateAndSignEthTxMsg(txArgs, deps) + s.NoError(err) + + resp, err = deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) s.Require().NoError(err) + s.Require().Empty(resp.VmError) - _, err = deps.Chain.EvmKeeper.EthCall(deps.GoCtx(), &evm.EthCallRequest{ - Args: jsonTxArgs, + return ethTxMsg, predecessors +} + +// GenerateAndSignEthTxMsg estimates gas, sets gas limit and sings the tx +func GenerateAndSignEthTxMsg(txArgs evm.JsonTxArgs, deps *evmtest.TestDeps) (*evm.MsgEthereumTx, error) { + estimateArgs, err := json.Marshal(&txArgs) + if err != nil { + return nil, err + } + res, err := deps.Chain.EvmKeeper.EstimateGas(deps.GoCtx(), &evm.EthCallRequest{ + Args: estimateArgs, GasCap: srvconfig.DefaultGasCap, ProposerAddress: []byte{}, ChainId: deps.Chain.EvmKeeper.EthChainID(deps.Ctx).Int64(), }) - s.Require().NoError(err) + if err != nil { + return nil, err + } + txArgs.Gas = (*hexutil.Uint64)(&res.Gas) + + txMsg := txArgs.ToTransaction() + gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) + keyringSigner := deps.Sender.KeyringSigner + return txMsg, txMsg.Sign(gethSigner, keyringSigner) +} + +func GenerateEthAddress() gethcommon.Address { + privateKey, _ := crypto.GenerateKey() + publicKey := privateKey.Public() + publicKeyECDSA, _ := publicKey.(*ecdsa.PublicKey) + return crypto.PubkeyToAddress(*publicKeyECDSA) } diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index caa757d22..164ca6db6 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -10,7 +10,7 @@ type KeeperSuite struct { suite.Suite } -// TestKeeperSuite: Runs all of the tests in the suite. +// TestKeeperSuite: Runs all the tests in the suite. func TestKeeperSuite(t *testing.T) { s := new(KeeperSuite) suite.Run(t, s) From 3fd45ce323c97f999d6754ef454e51077854a918 Mon Sep 17 00:00:00 2001 From: Oleg Nikonychev Date: Mon, 3 Jun 2024 21:56:23 +0400 Subject: [PATCH 2/5] chore: changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69ef93180..1449853f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1889](https://github.com/NibiruChain/nibiru/pull/1889) - feat: implemented basic evm tx methods - [#1895](https://github.com/NibiruChain/nibiru/pull/1895) - refactor(geth): Reference go-ethereum as a submodule for easier change tracking with upstream - [#1901](https://github.com/NibiruChain/nibiru/pull/1901) - test(evm): more e2e test contracts for edge cases +- [#1907](https://github.com/NibiruChain/nibiru/pull/1907) - test(evm): grpc_query full coverage #### Dapp modules: perp, spot, oracle, etc From 43378584dfec2f207afdc619f2d27df35816c304 Mon Sep 17 00:00:00 2001 From: Oleg Nikonychev Date: Wed, 5 Jun 2024 13:14:34 +0400 Subject: [PATCH 3/5] chore: refactored eth util methods --- x/evm/evmtest/tx.go | 101 ++++++++++++++++++++++++++++-- x/evm/keeper/grpc_query_test.go | 106 ++------------------------------ 2 files changed, 99 insertions(+), 108 deletions(-) diff --git a/x/evm/evmtest/tx.go b/x/evm/evmtest/tx.go index ef38c5825..0181b2bbe 100644 --- a/x/evm/evmtest/tx.go +++ b/x/evm/evmtest/tx.go @@ -2,24 +2,25 @@ package evmtest import ( + "encoding/json" "fmt" "math/big" + "testing" gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" gethcore "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" gethparams "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/require" + + srvconfig "github.com/NibiruChain/nibiru/app/server/config" "github.com/NibiruChain/nibiru/x/evm" ) type GethTxType = uint8 -var ( - GethTxType_LegacyTx GethTxType = gethcore.LegacyTxType - GethTxType_AccessListTx GethTxType = gethcore.AccessListTxType - GethTxType_DynamicFeeTx GethTxType = gethcore.DynamicFeeTxType -) - func NewEthTx( deps *TestDeps, txData gethcore.TxData, nonce uint64, ) (ethCoreTx *gethcore.Transaction, err error) { @@ -131,3 +132,91 @@ func NewEthTxMsgFromTxData( ethTxMsg.From = deps.Sender.EthAddr.Hex() return ethTxMsg, ethTxMsg.Sign(deps.GethSigner(), deps.Sender.KeyringSigner) } + +// ExecuteNibiTransfer executes nibi transfer +func ExecuteNibiTransfer(deps *TestDeps, t *testing.T) *evm.MsgEthereumTx { + nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr) + recipient := NewEthAccInfo().EthAddr + + txArgs := evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + To: &recipient, + Nonce: (*hexutil.Uint64)(&nonce), + } + ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps) + require.NoError(t, err) + + resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) + require.NoError(t, err) + require.Empty(t, resp.VmError) + return ethTxMsg +} + +// ExecuteERC20Transfer deploys contract, executes transfer and returns tx hash +func ExecuteERC20Transfer(deps *TestDeps, t *testing.T) (*evm.MsgEthereumTx, []*evm.MsgEthereumTx) { + // TX 1: Deploy ERC-20 contract + contractData := SmartContract_FunToken.Load(t) + nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr) + txArgs := evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + Nonce: (*hexutil.Uint64)(&nonce), + Data: (*hexutil.Bytes)(&contractData.Bytecode), + } + ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps) + require.NoError(t, err) + + resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) + require.NoError(t, err) + require.Empty(t, resp.VmError) + + // Contract address is deterministic + contractAddress := crypto.CreateAddress(deps.Sender.EthAddr, nonce) + deps.Chain.Commit() + predecessors := []*evm.MsgEthereumTx{ + ethTxMsg, + } + + // TX 2: execute ERC-20 contract transfer + input, err := contractData.ABI.Pack( + "transfer", NewEthAccInfo().EthAddr, new(big.Int).SetUint64(1000), + ) + require.NoError(t, err) + nonce = deps.StateDB().GetNonce(deps.Sender.EthAddr) + txArgs = evm.JsonTxArgs{ + From: &deps.Sender.EthAddr, + To: &contractAddress, + Nonce: (*hexutil.Uint64)(&nonce), + Data: (*hexutil.Bytes)(&input), + } + ethTxMsg, err = GenerateAndSignEthTxMsg(txArgs, deps) + require.NoError(t, err) + + resp, err = deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) + require.NoError(t, err) + require.Empty(t, resp.VmError) + + return ethTxMsg, predecessors +} + +// GenerateAndSignEthTxMsg estimates gas, sets gas limit and sings the tx +func GenerateAndSignEthTxMsg(txArgs evm.JsonTxArgs, deps *TestDeps) (*evm.MsgEthereumTx, error) { + estimateArgs, err := json.Marshal(&txArgs) + if err != nil { + return nil, err + } + res, err := deps.Chain.EvmKeeper.EstimateGas(deps.GoCtx(), &evm.EthCallRequest{ + Args: estimateArgs, + GasCap: srvconfig.DefaultGasCap, + ProposerAddress: []byte{}, + ChainId: deps.Chain.EvmKeeper.EthChainID(deps.Ctx).Int64(), + }) + if err != nil { + return nil, err + } + txArgs.Gas = (*hexutil.Uint64)(&res.Gas) + + txMsg := txArgs.ToTransaction() + gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) + keyringSigner := deps.Sender.KeyringSigner + return txMsg, txMsg.Sign(gethSigner, keyringSigner) +} diff --git a/x/evm/keeper/grpc_query_test.go b/x/evm/keeper/grpc_query_test.go index 42f2b9472..e695140c3 100644 --- a/x/evm/keeper/grpc_query_test.go +++ b/x/evm/keeper/grpc_query_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "crypto/ecdsa" "encoding/json" "math/big" "regexp" @@ -11,10 +10,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" gethparams "github.com/ethereum/go-ethereum/params" - srvconfig "github.com/NibiruChain/nibiru/app/server/config" "github.com/NibiruChain/nibiru/eth" "github.com/NibiruChain/nibiru/x/common/testutil/testapp" "github.com/NibiruChain/nibiru/x/evm" @@ -761,7 +758,7 @@ func (s *KeeperSuite) TestTestTraceTx() { { name: "happy: simple nibi transfer tx", scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { - txMsg := s.ExecuteNibiTransfer(deps) + txMsg := evmtest.ExecuteNibiTransfer(deps, s.T()) req = &evm.QueryTraceTxRequest{ Msg: txMsg, } @@ -774,7 +771,7 @@ func (s *KeeperSuite) TestTestTraceTx() { "happy: trace erc-20 transfer tx", nil, func(deps *evmtest.TestDeps) (req In, wantResp Out) { - txMsg, predecessors := s.ExecuteERC20Transfer(deps) + txMsg, predecessors := evmtest.ExecuteERC20Transfer(deps, s.T()) req = &evm.QueryTraceTxRequest{ Msg: txMsg, @@ -831,7 +828,7 @@ func (s *KeeperSuite) TestTestTraceBlock() { name: "happy: simple nibi transfer tx", setup: nil, scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { - txMsg := s.ExecuteNibiTransfer(deps) + txMsg := evmtest.ExecuteNibiTransfer(deps, s.T()) req = &evm.QueryTraceBlockRequest{ Txs: []*evm.MsgEthereumTx{ txMsg, @@ -846,7 +843,7 @@ func (s *KeeperSuite) TestTestTraceBlock() { name: "happy: trace erc-20 transfer tx", setup: nil, scenario: func(deps *evmtest.TestDeps) (req In, wantResp Out) { - txMsg, _ := s.ExecuteERC20Transfer(deps) + txMsg, _ := evmtest.ExecuteERC20Transfer(deps, s.T()) req = &evm.QueryTraceBlockRequest{ Txs: []*evm.MsgEthereumTx{ txMsg, @@ -887,98 +884,3 @@ func (s *KeeperSuite) TestTestTraceBlock() { }) } } - -// ExecuteNibiTransfer executes nibi transfer -func (s *KeeperSuite) ExecuteNibiTransfer(deps *evmtest.TestDeps) *evm.MsgEthereumTx { - nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr) - recipient := GenerateEthAddress() - - txArgs := evm.JsonTxArgs{ - From: &deps.Sender.EthAddr, - To: &recipient, - Nonce: (*hexutil.Uint64)(&nonce), - } - ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps) - s.NoError(err) - - resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) - s.Require().NoError(err) - s.Require().Empty(resp.VmError) - return ethTxMsg -} - -// ExecuteERC20Transfer deploys contract, executes transfer and returns tx hash -func (s *KeeperSuite) ExecuteERC20Transfer(deps *evmtest.TestDeps) (*evm.MsgEthereumTx, []*evm.MsgEthereumTx) { - // TX 1: Deploy ERC-20 contract - contractData := evmtest.SmartContract_FunToken.Load(s.T()) - nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr) - txArgs := evm.JsonTxArgs{ - From: &deps.Sender.EthAddr, - Nonce: (*hexutil.Uint64)(&nonce), - Data: (*hexutil.Bytes)(&contractData.Bytecode), - } - ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps) - s.NoError(err) - - resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) - s.Require().NoError(err) - s.Require().Empty(resp.VmError) - - // Contract address is deterministic - contractAddress := crypto.CreateAddress(deps.Sender.EthAddr, nonce) - deps.Chain.Commit() - predecessors := []*evm.MsgEthereumTx{ - ethTxMsg, - } - - // TX 2: execute ERC-20 contract transfer - input, err := contractData.ABI.Pack( - "transfer", GenerateEthAddress(), new(big.Int).SetUint64(1000), - ) - s.NoError(err) - nonce = deps.StateDB().GetNonce(deps.Sender.EthAddr) - txArgs = evm.JsonTxArgs{ - From: &deps.Sender.EthAddr, - To: &contractAddress, - Nonce: (*hexutil.Uint64)(&nonce), - Data: (*hexutil.Bytes)(&input), - } - ethTxMsg, err = GenerateAndSignEthTxMsg(txArgs, deps) - s.NoError(err) - - resp, err = deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg) - s.Require().NoError(err) - s.Require().Empty(resp.VmError) - - return ethTxMsg, predecessors -} - -// GenerateAndSignEthTxMsg estimates gas, sets gas limit and sings the tx -func GenerateAndSignEthTxMsg(txArgs evm.JsonTxArgs, deps *evmtest.TestDeps) (*evm.MsgEthereumTx, error) { - estimateArgs, err := json.Marshal(&txArgs) - if err != nil { - return nil, err - } - res, err := deps.Chain.EvmKeeper.EstimateGas(deps.GoCtx(), &evm.EthCallRequest{ - Args: estimateArgs, - GasCap: srvconfig.DefaultGasCap, - ProposerAddress: []byte{}, - ChainId: deps.Chain.EvmKeeper.EthChainID(deps.Ctx).Int64(), - }) - if err != nil { - return nil, err - } - txArgs.Gas = (*hexutil.Uint64)(&res.Gas) - - txMsg := txArgs.ToTransaction() - gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx)) - keyringSigner := deps.Sender.KeyringSigner - return txMsg, txMsg.Sign(gethSigner, keyringSigner) -} - -func GenerateEthAddress() gethcommon.Address { - privateKey, _ := crypto.GenerateKey() - publicKey := privateKey.Public() - publicKeyECDSA, _ := publicKey.(*ecdsa.PublicKey) - return crypto.PubkeyToAddress(*publicKeyECDSA) -} From 917083558b04e67f563dd0f12c4918e2b43ecf7c Mon Sep 17 00:00:00 2001 From: Oleg Nikonychev Date: Wed, 5 Jun 2024 13:55:14 +0400 Subject: [PATCH 4/5] fix: removed hardcoded gas value in grpc_query test --- x/evm/keeper/grpc_query_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x/evm/keeper/grpc_query_test.go b/x/evm/keeper/grpc_query_test.go index e695140c3..97d87d0dc 100644 --- a/x/evm/keeper/grpc_query_test.go +++ b/x/evm/keeper/grpc_query_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "encoding/json" + "fmt" "math/big" "regexp" @@ -21,12 +22,12 @@ import ( func InvalidEthAddr() string { return "0x0000" } func TraceNibiTransfer() string { - return `{ - "gas": 21000, + return fmt.Sprintf(`{ + "gas": %d, "failed": false, "returnValue": "", "structLogs": [] - }` + }`, gethparams.TxGas) } func TraceERC20Transfer() string { @@ -447,6 +448,7 @@ func (s *KeeperSuite) TestQueryParams() { want := evm.DefaultParams() deps.K.SetParams(deps.Ctx, want) gotResp, err := deps.K.Params(deps.GoCtx(), nil) + s.NoError(err) got := gotResp.Params s.Require().NoError(err) From 376596d61b44856cf0866486f7984d561ffe820c Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Wed, 5 Jun 2024 20:58:40 -0500 Subject: [PATCH 5/5] Squashed commit of the following: commit b5687130ff5f3d020a3b14d219fec3a816579c30 Author: Unique-Divine Date: Wed Jun 5 20:57:44 2024 -0500 chore: run tidy commit 1f1f9385952c4a170f744726bed8a3ee7c376028 Merge: 3e3cc837 bbcc6f8c Author: Unique-Divine Date: Wed Jun 5 19:16:30 2024 -0500 Merge branch 'main' into ud/fix-race-condition commit 3e3cc837b204971c58c775fe25d28fd01bce4021 Author: Unique-Divine Date: Wed Jun 5 19:15:40 2024 -0500 chore: changelog commit 3876ccb431aac5c9991a3540d764061cb52a0857 Author: Unique-Divine Date: Wed Jun 5 19:04:00 2024 -0500 refactor: more consistent test names commit aaa0a19f103a12c60f226a5057779a74d680e61c Author: Unique-Divine Date: Wed Jun 5 18:53:09 2024 -0500 test(oracle): Fix missing tear down step for oracle integration test commit 8c3c35eafc41d29becba1379d1f9ca5e984d8d9a Author: Unique-Divine Date: Wed Jun 5 17:55:56 2024 -0500 chore: add test comands to justfile commit 4916282353300b2dbf639e599cfbc3685cda01f6 Merge: 64ed0a29 e7e708d7 Author: Unique-Divine Date: Fri May 31 09:35:33 2024 -0500 Merge branch 'main' into ud/fix-race-condition commit 64ed0a29c918c4c1402eceddc13998ed4a156712 Author: Unique-Divine Date: Fri May 31 01:44:55 2024 -0500 fix(gosdk): tests parallel race condition --- CHANGELOG.md | 1 + app/evmante_fees.go | 4 +-- app/wasmext/wasm_cli_test/cli_test.go | 16 ++++++----- eth/rpc/rpcapi/eth_api_test.go | 38 ++++++++++++++------------- gosdk/gosdk_test.go | 25 +++++++----------- justfile | 16 +++++++++++ x/common/testutil/cli/network.go | 22 ++++++++-------- x/common/testutil/cli/network_test.go | 32 ++++++++++------------ x/common/testutil/cli/tx_test.go | 6 ++--- x/oracle/integration/app_test.go | 27 ++++++++++++------- x/sudo/cli/cli_test.go | 20 +++++++------- x/tokenfactory/cli/cli_test.go | 23 +++++++++------- 12 files changed, 125 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0da2ae025..a93175709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1859](https://github.com/NibiruChain/nibiru/pull/1859) - refactor(oracle): add oracle slashing events - [#1893](https://github.com/NibiruChain/nibiru/pull/1893) - feat(gosdk): migrate Go-sdk into the Nibiru blockchain repo. - [#1899](https://github.com/NibiruChain/nibiru/pull/1899) - build(deps): cometbft v0.37.5, cosmos-sdk v0.47.11, proto-builder v0.14.0 +- [#1913](https://github.com/NibiruChain/nibiru/pull/1913) - fix(tests): race condition from heavy Network tests ### Dependencies diff --git a/app/evmante_fees.go b/app/evmante_fees.go index 9728fa160..da9d9d61c 100644 --- a/app/evmante_fees.go +++ b/app/evmante_fees.go @@ -13,9 +13,7 @@ import ( "github.com/NibiruChain/nibiru/x/evm" ) -var ( - _ sdk.AnteDecorator = EthMinGasPriceDecorator{} -) +var _ sdk.AnteDecorator = EthMinGasPriceDecorator{} // EthMinGasPriceDecorator will check if the transaction's fee is at least as large // as the MinGasPrices param. If fee is too low, decorator returns error and tx diff --git a/app/wasmext/wasm_cli_test/cli_test.go b/app/wasmext/wasm_cli_test/cli_test.go index 825c99715..72069d17d 100644 --- a/app/wasmext/wasm_cli_test/cli_test.go +++ b/app/wasmext/wasm_cli_test/cli_test.go @@ -31,14 +31,16 @@ var commonArgs = []string{ sdk.NewCoins(sdk.NewCoin(denoms.NIBI, math.NewInt(10_000_000))).String()), } -type IntegrationTestSuite struct { +var _ suite.TearDownAllSuite = (*TestSuite)(nil) + +type TestSuite struct { suite.Suite cfg testutilcli.Config network *testutilcli.Network } -func (s *IntegrationTestSuite) SetupSuite() { +func (s *TestSuite) SetupSuite() { testutil.BeforeIntegrationSuite(s.T()) testapp.EnsureNibiruPrefix() @@ -52,12 +54,12 @@ func (s *IntegrationTestSuite) SetupSuite() { s.Require().NoError(s.network.WaitForNextBlock()) } -func (s *IntegrationTestSuite) TearDownSuite() { +func (s *TestSuite) TearDownSuite() { s.T().Log("tearing down integration test suite") s.network.Cleanup() } -func (s *IntegrationTestSuite) TestWasmHappyPath() { +func (s *TestSuite) TestWasmHappyPath() { s.requiredDeployedContractsLen(0) _, err := s.deployWasmContract("testdata/cw_nameservice.wasm") @@ -70,7 +72,7 @@ func (s *IntegrationTestSuite) TestWasmHappyPath() { } // deployWasmContract deploys a wasm contract located in path. -func (s *IntegrationTestSuite) deployWasmContract(path string) (uint64, error) { +func (s *TestSuite) deployWasmContract(path string) (uint64, error) { val := s.network.Validators[0] codec := val.ClientCtx.Codec @@ -124,7 +126,7 @@ func (s *IntegrationTestSuite) deployWasmContract(path string) (uint64, error) { } // requiredDeployedContractsLen checks the number of deployed contracts. -func (s *IntegrationTestSuite) requiredDeployedContractsLen(total int) { +func (s *TestSuite) requiredDeployedContractsLen(total int) { val := s.network.Validators[0] var queryCodeResponse types.QueryCodesResponse err := testutilcli.ExecQuery( @@ -138,5 +140,5 @@ func (s *IntegrationTestSuite) requiredDeployedContractsLen(total int) { } func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) + suite.Run(t, new(TestSuite)) } diff --git a/eth/rpc/rpcapi/eth_api_test.go b/eth/rpc/rpcapi/eth_api_test.go index a34aae621..8b9527038 100644 --- a/eth/rpc/rpcapi/eth_api_test.go +++ b/eth/rpc/rpcapi/eth_api_test.go @@ -29,7 +29,9 @@ import ( "github.com/NibiruChain/nibiru/x/common/testutil/testapp" ) -type IntegrationSuite struct { +var _ suite.TearDownAllSuite = (*TestSuite)(nil) + +type TestSuite struct { suite.Suite cfg testutilcli.Config network *testutilcli.Network @@ -43,12 +45,12 @@ type IntegrationSuite struct { contractData evmtest.CompiledEvmContract } -func TestSuite_IntegrationSuite_RunAll(t *testing.T) { - suite.Run(t, new(IntegrationSuite)) +func TestSuite_RunAll(t *testing.T) { + suite.Run(t, new(TestSuite)) } // SetupSuite initialize network -func (s *IntegrationSuite) SetupSuite() { +func (s *TestSuite) SetupSuite() { testutil.BeforeIntegrationSuite(s.T()) testapp.EnsureNibiruPrefix() @@ -76,14 +78,14 @@ func (s *IntegrationSuite) SetupSuite() { } // Test_ChainID EVM method: eth_chainId -func (s *IntegrationSuite) Test_ChainID() { +func (s *TestSuite) Test_ChainID() { ethChainID, err := s.ethClient.ChainID(context.Background()) s.NoError(err) s.Equal(appconst.ETH_CHAIN_ID_DEFAULT, ethChainID.Int64()) } // Test_BlockNumber EVM method: eth_blockNumber -func (s *IntegrationSuite) Test_BlockNumber() { +func (s *TestSuite) Test_BlockNumber() { networkBlockNumber, err := s.network.LatestHeight() s.NoError(err) @@ -93,7 +95,7 @@ func (s *IntegrationSuite) Test_BlockNumber() { } // Test_BlockByNumber EVM method: eth_getBlockByNumber -func (s *IntegrationSuite) Test_BlockByNumber() { +func (s *TestSuite) Test_BlockByNumber() { networkBlockNumber, err := s.network.LatestHeight() s.NoError(err) @@ -105,7 +107,7 @@ func (s *IntegrationSuite) Test_BlockByNumber() { } // Test_BalanceAt EVM method: eth_getBalance -func (s *IntegrationSuite) Test_BalanceAt() { +func (s *TestSuite) Test_BalanceAt() { testAccEthAddr := gethcommon.BytesToAddress(testutilcli.NewAccount(s.network, "new-user")) // New user balance should be 0 @@ -122,7 +124,7 @@ func (s *IntegrationSuite) Test_BalanceAt() { } // Test_StorageAt EVM method: eth_getStorageAt -func (s *IntegrationSuite) Test_StorageAt() { +func (s *TestSuite) Test_StorageAt() { storage, err := s.ethClient.StorageAt( context.Background(), s.fundedAccEthAddr, gethcommon.Hash{}, nil, ) @@ -132,7 +134,7 @@ func (s *IntegrationSuite) Test_StorageAt() { } // Test_PendingStorageAt EVM method: eth_getStorageAt | pending -func (s *IntegrationSuite) Test_PendingStorageAt() { +func (s *TestSuite) Test_PendingStorageAt() { storage, err := s.ethClient.PendingStorageAt( context.Background(), s.fundedAccEthAddr, gethcommon.Hash{}, ) @@ -143,7 +145,7 @@ func (s *IntegrationSuite) Test_PendingStorageAt() { } // Test_CodeAt EVM method: eth_getCode -func (s *IntegrationSuite) Test_CodeAt() { +func (s *TestSuite) Test_CodeAt() { code, err := s.ethClient.CodeAt(context.Background(), s.fundedAccEthAddr, nil) s.NoError(err) @@ -152,7 +154,7 @@ func (s *IntegrationSuite) Test_CodeAt() { } // Test_PendingCodeAt EVM method: eth_getCode -func (s *IntegrationSuite) Test_PendingCodeAt() { +func (s *TestSuite) Test_PendingCodeAt() { code, err := s.ethClient.PendingCodeAt(context.Background(), s.fundedAccEthAddr) s.NoError(err) @@ -161,7 +163,7 @@ func (s *IntegrationSuite) Test_PendingCodeAt() { } // Test_EstimateGas EVM method: eth_estimateGas -func (s *IntegrationSuite) Test_EstimateGas() { +func (s *TestSuite) Test_EstimateGas() { testAccEthAddr := gethcommon.BytesToAddress(testutilcli.NewAccount(s.network, "new-user")) gasLimit := uint64(21000) msg := geth.CallMsg{ @@ -176,14 +178,14 @@ func (s *IntegrationSuite) Test_EstimateGas() { } // Test_SuggestGasPrice EVM method: eth_gasPrice -func (s *IntegrationSuite) Test_SuggestGasPrice() { +func (s *TestSuite) Test_SuggestGasPrice() { // TODO: the backend method is stubbed to 0 _, err := s.ethClient.SuggestGasPrice(context.Background()) s.NoError(err) } // Test_SimpleTransferTransaction EVM method: eth_sendRawTransaction -func (s *IntegrationSuite) Test_SimpleTransferTransaction() { +func (s *TestSuite) Test_SimpleTransferTransaction() { chainID, err := s.ethClient.ChainID(context.Background()) s.NoError(err) nonce, err := s.ethClient.PendingNonceAt(context.Background(), s.fundedAccEthAddr) @@ -230,7 +232,7 @@ func (s *IntegrationSuite) Test_SimpleTransferTransaction() { } // Test_SmartContract includes contract deployment, query, execution -func (s *IntegrationSuite) Test_SmartContract() { +func (s *TestSuite) Test_SmartContract() { chainID, err := s.ethClient.ChainID(context.Background()) s.NoError(err) nonce, err := s.ethClient.NonceAt(context.Background(), s.fundedAccEthAddr, nil) @@ -295,12 +297,12 @@ func (s *IntegrationSuite) Test_SmartContract() { s.assertERC20Balance(contractAddress, recipientAddr, recipientBalance) } -func (s *IntegrationSuite) TearDownSuite() { +func (s *TestSuite) TearDownSuite() { s.T().Log("tearing down integration test suite") s.network.Cleanup() } -func (s *IntegrationSuite) assertERC20Balance( +func (s *TestSuite) assertERC20Balance( contractAddress gethcommon.Address, userAddress gethcommon.Address, expectedBalance *big.Int, diff --git a/gosdk/gosdk_test.go b/gosdk/gosdk_test.go index 68bd6072d..1a0ab5dfb 100644 --- a/gosdk/gosdk_test.go +++ b/gosdk/gosdk_test.go @@ -21,7 +21,10 @@ import ( // NibiruClientSuite // -------------------------------------------------- -var _ suite.SetupAllSuite = (*TestSuite)(nil) +var ( + _ suite.SetupAllSuite = (*TestSuite)(nil) + _ suite.TearDownAllSuite = (*TestSuite)(nil) +) type TestSuite struct { suite.Suite @@ -33,7 +36,7 @@ type TestSuite struct { val *cli.Validator } -func TestNibiruClientTestSuite_RunAll(t *testing.T) { +func TestSuite_RunAll(t *testing.T) { suite.Run(t, new(TestSuite)) } @@ -46,6 +49,8 @@ func (s *TestSuite) RPCEndpoint() string { func (s *TestSuite) SetupSuite() { testutil.BeforeIntegrationSuite(s.T()) + s.Run("DoTestGetGrpcConnection_NoNetwork", s.DoTestGetGrpcConnection_NoNetwork) + nibiru, err := gosdk.CreateBlockchain(s.T()) s.NoError(err) s.network = nibiru.Network @@ -141,21 +146,9 @@ func (s *TestSuite) TearDownSuite() { s.network.Cleanup() } -// -------------------------------------------------- -// NibiruClientSuite_NoNetwork -// -------------------------------------------------- - -type NibiruClientSuite_NoNetwork struct { - suite.Suite -} - -func TestNibiruClientSuite_NoNetwork_RunAll(t *testing.T) { - suite.Run(t, new(NibiruClientSuite_NoNetwork)) -} - -func (s *NibiruClientSuite_NoNetwork) TestGetGrpcConnection_NoNetwork() { +func (s *TestSuite) DoTestGetGrpcConnection_NoNetwork() { grpcConn, err := gosdk.GetGRPCConnection( - gosdk.DefaultNetworkInfo.GrpcEndpoint, true, 2, + gosdk.DefaultNetworkInfo.GrpcEndpoint+"notendpoint", true, 2, ) s.Error(err) s.Nil(grpcConn) diff --git a/justfile b/justfile index af0ff7d44..fbdcef302 100644 --- a/justfile +++ b/justfile @@ -16,6 +16,10 @@ install-clean: build: make build +# Cleans the Go cache, modcache, and testcashe +clean-cache: + go clean -cache -testcache -modcache + alias b := build # Generate protobuf code (Golang) for Nibiru @@ -82,3 +86,15 @@ test-release: release-publish: make release + +# Run Go tests (short mode) +test-unit: + go test ./... -short + +# Run Go tests (short mode) + coverage +test-coverage-unit: + make test-coverage-unit + +# Run Go tests, including live network tests + coverage +test-coverage-integration: + make test-coverage-integration diff --git a/x/common/testutil/cli/network.go b/x/common/testutil/cli/network.go index d43e264eb..8dbe769a5 100644 --- a/x/common/testutil/cli/network.go +++ b/x/common/testutil/cli/network.go @@ -224,7 +224,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { buf := bufio.NewReader(os.Stdin) // generate private keys, node IDs, and initial transactions - for i := 0; i < cfg.NumValidators; i++ { + for valIdx := 0; valIdx < cfg.NumValidators; valIdx++ { appCfg := serverconfig.DefaultConfig() appCfg.Pruning = cfg.PruningStrategy appCfg.MinGasPrices = cfg.MinGasPrices @@ -243,7 +243,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { appCfg.GRPC.Enable = false appCfg.GRPCWeb.Enable = false apiListenAddr := "" - if i == 0 { + if valIdx == 0 { if cfg.APIAddress != "" { apiListenAddr = cfg.APIAddress } else { @@ -309,7 +309,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { ctx.Logger = loggerNoOp - nodeDirName := fmt.Sprintf("node%d", i) + nodeDirName := fmt.Sprintf("node%d", valIdx) nodeDir := filepath.Join(network.BaseDir, nodeDirName, "simd") clientDir := filepath.Join(network.BaseDir, nodeDirName, "simcli") gentxsDir := filepath.Join(network.BaseDir, "gentxs") @@ -326,7 +326,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { tmCfg.SetRoot(nodeDir) tmCfg.Moniker = nodeDirName - monikers[i] = nodeDirName + monikers[valIdx] = nodeDirName proxyAddr, _, err := server.FreeTCPAddr() if err != nil { @@ -348,8 +348,8 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { return nil, err } - nodeIDs[i] = nodeID - valPubKeys[i] = pubKey + nodeIDs[valIdx] = nodeID + valPubKeys[valIdx] = pubKey kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, clientDir, buf, cfg.Codec, cfg.KeyringOptions...) if err != nil { @@ -363,8 +363,8 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { } var mnemonic string - if i < len(cfg.Mnemonics) { - mnemonic = cfg.Mnemonics[i] + if valIdx < len(cfg.Mnemonics) { + mnemonic = cfg.Mnemonics[valIdx] } addr, secret, err := sdktestutil.GenerateSaveCoinKey(kb, nodeDirName, mnemonic, true, algo) @@ -404,7 +404,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { createValMsg, err := stakingtypes.NewMsgCreateValidator( sdk.ValAddress(addr), - valPubKeys[i], + valPubKeys[valIdx], sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), stakingtypes.NewDescription(nodeDirName, "", "", "", ""), stakingtypes.NewCommissionRates(commission, math.LegacyOneDec(), math.LegacyOneDec()), @@ -419,7 +419,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { return nil, err } - memo := fmt.Sprintf("%s@%s:%s", nodeIDs[i], p2pURL.Hostname(), p2pURL.Port()) + memo := fmt.Sprintf("%s@%s:%s", nodeIDs[valIdx], p2pURL.Hostname(), p2pURL.Port()) fee := sdk.NewCoins(sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), math.ZeroInt())) txBuilder := cfg.TxConfig.NewTxBuilder() err = txBuilder.SetMsgs(createValMsg) @@ -464,7 +464,7 @@ func New(logger Logger, baseDir string, cfg Config) (*Network, error) { WithTxConfig(cfg.TxConfig). WithAccountRetriever(cfg.AccountRetriever) - network.Validators[i] = &Validator{ + network.Validators[valIdx] = &Validator{ AppConfig: appCfg, ClientCtx: clientCtx, Ctx: ctx, diff --git a/x/common/testutil/cli/network_test.go b/x/common/testutil/cli/network_test.go index 6bafe6370..f2a17bee4 100644 --- a/x/common/testutil/cli/network_test.go +++ b/x/common/testutil/cli/network_test.go @@ -16,31 +16,27 @@ import ( "github.com/stretchr/testify/suite" + "github.com/NibiruChain/nibiru/x/common/testutil" "github.com/NibiruChain/nibiru/x/common/testutil/cli" "github.com/NibiruChain/nibiru/x/common/testutil/genesis" ) func TestIntegrationTestSuite_RunAll(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) + suite.Run(t, new(TestSuite)) } -type IntegrationTestSuite struct { +// Assert network cleanup +var _ suite.TearDownAllSuite = (*TestSuite)(nil) + +type TestSuite struct { suite.Suite network *cli.Network cfg *cli.Config } -func (s *IntegrationTestSuite) SetupSuite() { - /* Make test skip if -short is not used: - All tests: `go test ./...` - Unit tests only: `go test ./... -short` - Integration tests only: `go test ./... -run Integration` - https://stackoverflow.com/a/41407042/13305627 */ - if testing.Short() { - s.T().Skip("skipping integration test suite") - } - s.T().Log("setting up integration test suite") +func (s *TestSuite) SetupSuite() { + testutil.BeforeIntegrationSuite(s.T()) encConfig := app.MakeEncodingConfig() cfg := new(cli.Config) @@ -60,12 +56,12 @@ func (s *IntegrationTestSuite) SetupSuite() { s.Require().NoError(err) } -func (s *IntegrationTestSuite) TearDownSuite() { +func (s *TestSuite) TearDownSuite() { s.T().Log("tearing down integration test suite") s.network.Cleanup() } -func (s *IntegrationTestSuite) TestNetwork_Liveness() { +func (s *TestSuite) TestNetwork_Liveness() { height, err := s.network.WaitForHeightWithTimeout(4, time.Minute) s.Require().NoError(err, "expected to reach 4 blocks; got %d", height) @@ -73,7 +69,7 @@ func (s *IntegrationTestSuite) TestNetwork_Liveness() { s.NoError(err) } -func (s *IntegrationTestSuite) TestNetwork_LatestHeight() { +func (s *TestSuite) TestNetwork_LatestHeight() { height, err := s.network.LatestHeight() s.NoError(err) s.Positive(height) @@ -83,7 +79,7 @@ func (s *IntegrationTestSuite) TestNetwork_LatestHeight() { s.Error(err) } -func (s *IntegrationTestSuite) TestLogMnemonic() { +func (s *TestSuite) TestLogMnemonic() { kring, algo, nodeDirName := cli.NewKeyring(s.T()) var cdc sdkcodec.Codec = codec.MakeEncodingConfig().Codec @@ -101,7 +97,7 @@ func (s *IntegrationTestSuite) TestLogMnemonic() { }, secret) } -func (s *IntegrationTestSuite) TestValidatorGetSecret() { +func (s *TestSuite) TestValidatorGetSecret() { val := s.network.Validators[0] secret := val.SecretMnemonic() secretSlice := val.SecretMnemonicSlice() @@ -132,7 +128,7 @@ func (ml *mockLogger) Logf(format string, args ...interface{}) { ml.Logs = append(ml.Logs, fmt.Sprintf(format, args...)) } -func (s *IntegrationTestSuite) TestNewAccount() { +func (s *TestSuite) TestNewAccount() { s.NotPanics(func() { addr := cli.NewAccount(s.network, "newacc") s.NoError(sdk.VerifyAddressFormat(addr)) diff --git a/x/common/testutil/cli/tx_test.go b/x/common/testutil/cli/tx_test.go index e226c8fab..f14262b23 100644 --- a/x/common/testutil/cli/tx_test.go +++ b/x/common/testutil/cli/tx_test.go @@ -14,7 +14,7 @@ import ( "github.com/NibiruChain/nibiru/x/common/testutil/cli" ) -func (s *IntegrationTestSuite) TestSendTx() { +func (s *TestSuite) TestSendTx() { fromAddr := s.network.Validators[0].Address toAddr := testutil.AccAddress() sendCoin := sdk.NewCoin(denoms.NIBI, math.NewInt(42)) @@ -28,7 +28,7 @@ func (s *IntegrationTestSuite) TestSendTx() { s.EqualValues(0, txResp.Code) } -func (s *IntegrationTestSuite) TestExecTx() { +func (s *TestSuite) TestExecTx() { fromAddr := s.network.Validators[0].Address toAddr := testutil.AccAddress() sendCoin := sdk.NewCoin(denoms.NIBI, math.NewInt(69)) @@ -62,7 +62,7 @@ func (s *IntegrationTestSuite) TestExecTx() { }) } -func (s *IntegrationTestSuite) TestFillWalletFromValidator() { +func (s *TestSuite) TestFillWalletFromValidator() { toAddr := testutil.AccAddress() val := s.network.Validators[0] funds := sdk.NewCoins( diff --git a/x/oracle/integration/app_test.go b/x/oracle/integration/app_test.go index d8e46a3be..45f6a70c0 100644 --- a/x/oracle/integration/app_test.go +++ b/x/oracle/integration/app_test.go @@ -20,18 +20,20 @@ import ( "github.com/NibiruChain/nibiru/x/oracle/types" ) -type IntegrationTestSuite struct { +var _ suite.TearDownAllSuite = (*TestSuite)(nil) + +type TestSuite struct { suite.Suite cfg testutilcli.Config network *testutilcli.Network } -func (s *IntegrationTestSuite) SetupSuite() { +func (s *TestSuite) SetupSuite() { testutil.BeforeIntegrationSuite(s.T()) } -func (s *IntegrationTestSuite) SetupTest() { +func (s *TestSuite) SetupTest() { testapp.EnsureNibiruPrefix() homeDir := s.T().TempDir() @@ -60,7 +62,7 @@ func (s *IntegrationTestSuite) SetupTest() { require.NoError(s.T(), err) } -func (s *IntegrationTestSuite) TestSuccessfulVoting() { +func (s *TestSuite) TestSuccessfulVoting() { // assuming validators have equal power // we use the weighted median. // what happens is that prices are ordered @@ -105,7 +107,7 @@ func (s *IntegrationTestSuite) TestSuccessfulVoting() { ) } -func (s *IntegrationTestSuite) sendPrevotes(prices []map[asset.Pair]sdk.Dec) []string { +func (s *TestSuite) sendPrevotes(prices []map[asset.Pair]sdk.Dec) []string { strVotes := make([]string, len(prices)) for i, val := range s.network.Validators { raw := prices[i] @@ -129,7 +131,7 @@ func (s *IntegrationTestSuite) sendPrevotes(prices []map[asset.Pair]sdk.Dec) []s return strVotes } -func (s *IntegrationTestSuite) sendVotes(rates []string) { +func (s *TestSuite) sendVotes(rates []string) { for i, val := range s.network.Validators { _, err := s.network.BroadcastMsgs(val.Address, &types.MsgAggregateExchangeRateVote{ Salt: "1", @@ -141,7 +143,7 @@ func (s *IntegrationTestSuite) sendVotes(rates []string) { } } -func (s *IntegrationTestSuite) waitVoteRevealBlock() { +func (s *TestSuite) waitVoteRevealBlock() { params, err := types.NewQueryClient(s.network.Validators[0].ClientCtx).Params(context.Background(), &types.QueryParamsRequest{}) require.NoError(s.T(), err) @@ -157,11 +159,11 @@ func (s *IntegrationTestSuite) waitVoteRevealBlock() { } // it's an alias, but it exists to give better understanding of what we're doing in test cases scenarios -func (s *IntegrationTestSuite) waitPriceUpdateBlock() { +func (s *TestSuite) waitPriceUpdateBlock() { s.waitVoteRevealBlock() } -func (s *IntegrationTestSuite) currentPrices() map[asset.Pair]sdk.Dec { +func (s *TestSuite) currentPrices() map[asset.Pair]sdk.Dec { rawRates, err := types.NewQueryClient(s.network.Validators[0].ClientCtx).ExchangeRates(context.Background(), &types.QueryExchangeRatesRequest{}) require.NoError(s.T(), err) @@ -175,5 +177,10 @@ func (s *IntegrationTestSuite) currentPrices() map[asset.Pair]sdk.Dec { } func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) + suite.Run(t, new(TestSuite)) +} + +func (s *TestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() } diff --git a/x/sudo/cli/cli_test.go b/x/sudo/cli/cli_test.go index dc27bd6e2..bc7df60f6 100644 --- a/x/sudo/cli/cli_test.go +++ b/x/sudo/cli/cli_test.go @@ -80,7 +80,9 @@ func (MsgEditSudoersPlus) Exec( return network.ExecTxCmd(cli.CmdEditSudoers(), from, args) } -type IntegrationSuite struct { +var _ suite.TearDownAllSuite = (*TestSuite)(nil) + +type TestSuite struct { suite.Suite cfg testutilcli.Config network *testutilcli.Network @@ -94,14 +96,14 @@ type Account struct { } func TestSuite_IntegrationSuite_RunAll(t *testing.T) { - suite.Run(t, new(IntegrationSuite)) + suite.Run(t, new(TestSuite)) } // ——————————————————————————————————————————————————————————————————— // IntegrationSuite - Setup // ——————————————————————————————————————————————————————————————————— -func (s *IntegrationSuite) SetupSuite() { +func (s *TestSuite) SetupSuite() { testutil.BeforeIntegrationSuite(s.T()) testapp.EnsureNibiruPrefix() @@ -122,7 +124,7 @@ func (s *IntegrationSuite) SetupSuite() { s.AddRootToKeyring(s.root) } -func (s *IntegrationSuite) FundRoot(root Account) { +func (s *TestSuite) FundRoot(root Account) { val := s.network.Validators[0] funds := sdk.NewCoins( sdk.NewInt64Coin(denoms.NIBI, 420*common.TO_MICRO), @@ -133,7 +135,7 @@ func (s *IntegrationSuite) FundRoot(root Account) { )) } -func (s *IntegrationSuite) AddRootToKeyring(root Account) { +func (s *TestSuite) AddRootToKeyring(root Account) { s.T().Log("add the x/sudo root account to the clientCtx.Keyring") // Encrypt the x/sudo root account's private key to get its "armor" passphrase := root.passphrase @@ -150,7 +152,7 @@ func (s *IntegrationSuite) AddRootToKeyring(root Account) { // IntegrationSuite - Tests // ——————————————————————————————————————————————————————————————————— -func (s *IntegrationSuite) TestCmdEditSudoers() { +func (s *TestSuite) TestCmdEditSudoers() { val := s.network.Validators[0] _, contractAddrs := testutil.PrivKeyAddressPairs(3) @@ -221,7 +223,7 @@ func (s *IntegrationSuite) TestCmdEditSudoers() { } } -func (s *IntegrationSuite) Test_ZCmdChangeRoot() { +func (s *TestSuite) Test_ZCmdChangeRoot() { val := s.network.Validators[0] sudoers, err := testutilcli.QuerySudoers(val.ClientCtx) @@ -242,7 +244,7 @@ func (s *IntegrationSuite) Test_ZCmdChangeRoot() { // TestMarshal_EditSudoers verifies that the expected proto.Message for // the EditSudoders fn marshals and unmarshals properly from JSON. // This unmarshaling is used in the main body of the CmdEditSudoers command. -func (s *IntegrationSuite) TestMarshal_EditSudoers() { +func (s *TestSuite) TestMarshal_EditSudoers() { t := s.T() t.Log("create valid example json for the message") @@ -270,7 +272,7 @@ func (s *IntegrationSuite) TestMarshal_EditSudoers() { require.NoError(t, newMsg.ValidateBasic(), newMsg.String()) } -func (s *IntegrationSuite) TearDownSuite() { +func (s *TestSuite) TearDownSuite() { s.T().Log("tearing down integration test suite") s.network.Cleanup() } diff --git a/x/tokenfactory/cli/cli_test.go b/x/tokenfactory/cli/cli_test.go index c7d432cb4..40773f9b8 100644 --- a/x/tokenfactory/cli/cli_test.go +++ b/x/tokenfactory/cli/cli_test.go @@ -17,9 +17,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -var _ suite.SetupAllSuite = (*IntegrationTestSuite)(nil) +var ( + _ suite.SetupAllSuite = (*TestSuite)(nil) + _ suite.TearDownAllSuite = (*TestSuite)(nil) +) -type IntegrationTestSuite struct { +type TestSuite struct { suite.Suite cfg testutilcli.Config @@ -28,17 +31,17 @@ type IntegrationTestSuite struct { } func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) + suite.Run(t, new(TestSuite)) } // TestTokenFactory: Runs the test suite with a deterministic order. -func (s *IntegrationTestSuite) TestTokenFactory() { +func (s *TestSuite) TestTokenFactory() { s.Run("CreateDenomTest", s.CreateDenomTest) s.Run("MintBurnTest", s.MintBurnTest) s.Run("ChangeAdminTest", s.ChangeAdminTest) } -func (s *IntegrationTestSuite) SetupSuite() { +func (s *TestSuite) SetupSuite() { testutil.BeforeIntegrationSuite(s.T()) testapp.EnsureNibiruPrefix() encodingConfig := app.MakeEncodingConfig() @@ -54,7 +57,7 @@ func (s *IntegrationTestSuite) SetupSuite() { s.NoError(s.network.WaitForNextBlock()) } -func (s *IntegrationTestSuite) CreateDenomTest() { +func (s *TestSuite) CreateDenomTest() { creator := s.val.Address createDenom := func(subdenom string, wantErr bool) { _, err := s.network.ExecTxCmd( @@ -88,7 +91,7 @@ func (s *IntegrationTestSuite) CreateDenomTest() { s.ElementsMatch(denoms, wantDenoms) } -func (s *IntegrationTestSuite) MintBurnTest() { +func (s *TestSuite) MintBurnTest() { creator := s.val.Address mint := func(coin string, mintTo string, wantErr bool) { mintToArg := fmt.Sprintf("--mint-to=%s", mintTo) @@ -145,7 +148,7 @@ func (s *IntegrationTestSuite) MintBurnTest() { burn(coin.String(), creator.String(), wantErr) // happy } -func (s *IntegrationTestSuite) ChangeAdminTest() { +func (s *TestSuite) ChangeAdminTest() { creator := s.val.Address admin := creator newAdmin := testutil.AccAddress() @@ -179,7 +182,7 @@ func (s *IntegrationTestSuite) ChangeAdminTest() { s.Equal(infoResp.Admin, newAdmin.String()) } -func (s *IntegrationTestSuite) TestQueryModuleParams() { +func (s *TestSuite) TestQueryModuleParams() { paramResp := new(types.QueryParamsResponse) s.NoError( s.network.ExecQuery( @@ -189,7 +192,7 @@ func (s *IntegrationTestSuite) TestQueryModuleParams() { s.Equal(paramResp.Params, types.DefaultModuleParams()) } -func (s *IntegrationTestSuite) TearDownSuite() { +func (s *TestSuite) TearDownSuite() { s.T().Log("tearing down integration test suite") s.network.Cleanup() }