From 97a77a47dc703ade2122764565f60b682f1ab0a5 Mon Sep 17 00:00:00 2001 From: likhita-809 <78951027+likhita-809@users.noreply.github.com> Date: Mon, 12 Sep 2022 20:57:32 +0530 Subject: [PATCH] refactor(genutil): CLI tests using Tendermint Mock (#13190) * wip * wip * wip: add more tests * refactor tests * add expCmdOutput field to tests struct * remove unnecessary code Co-authored-by: Marko --- .../genutil/{client/testutil => }/cli_test.go | 5 +- .../testutil => tests/e2e/genutil}/migrate.go | 2 +- .../testutil => tests/e2e/genutil}/suite.go | 2 +- .../e2e/genutil}/validate_genesis.go | 2 +- x/genutil/client/cli/gentx_test.go | 170 ++++++++++++++++++ x/genutil/client/cli/migrate_test.go | 60 +++++++ x/genutil/client/cli/validate_genesis_test.go | 103 +++++++++++ 7 files changed, 338 insertions(+), 6 deletions(-) rename tests/e2e/genutil/{client/testutil => }/cli_test.go (69%) rename {x/genutil/client/testutil => tests/e2e/genutil}/migrate.go (98%) rename {x/genutil/client/testutil => tests/e2e/genutil}/suite.go (99%) rename {x/genutil/client/testutil => tests/e2e/genutil}/validate_genesis.go (99%) create mode 100644 x/genutil/client/cli/gentx_test.go create mode 100644 x/genutil/client/cli/migrate_test.go create mode 100644 x/genutil/client/cli/validate_genesis_test.go diff --git a/tests/e2e/genutil/client/testutil/cli_test.go b/tests/e2e/genutil/cli_test.go similarity index 69% rename from tests/e2e/genutil/client/testutil/cli_test.go rename to tests/e2e/genutil/cli_test.go index d76884e268..50f57ad8df 100644 --- a/tests/e2e/genutil/client/testutil/cli_test.go +++ b/tests/e2e/genutil/cli_test.go @@ -1,14 +1,13 @@ //go:build e2e // +build e2e -package testutil +package genutil import ( "testing" "cosmossdk.io/simapp" "github.com/cosmos/cosmos-sdk/testutil/network" - "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" "github.com/stretchr/testify/suite" ) @@ -16,5 +15,5 @@ import ( func TestIntegrationTestSuite(t *testing.T) { cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) cfg.NumValidators = 1 - suite.Run(t, testutil.NewIntegrationTestSuite(cfg)) + suite.Run(t, NewIntegrationTestSuite(cfg)) } diff --git a/x/genutil/client/testutil/migrate.go b/tests/e2e/genutil/migrate.go similarity index 98% rename from x/genutil/client/testutil/migrate.go rename to tests/e2e/genutil/migrate.go index e5dd0f2d13..f664c4299b 100644 --- a/x/genutil/client/testutil/migrate.go +++ b/tests/e2e/genutil/migrate.go @@ -1,4 +1,4 @@ -package testutil +package genutil import ( "testing" diff --git a/x/genutil/client/testutil/suite.go b/tests/e2e/genutil/suite.go similarity index 99% rename from x/genutil/client/testutil/suite.go rename to tests/e2e/genutil/suite.go index e09937176f..6560192400 100644 --- a/x/genutil/client/testutil/suite.go +++ b/tests/e2e/genutil/suite.go @@ -1,4 +1,4 @@ -package testutil +package genutil import ( "fmt" diff --git a/x/genutil/client/testutil/validate_genesis.go b/tests/e2e/genutil/validate_genesis.go similarity index 99% rename from x/genutil/client/testutil/validate_genesis.go rename to tests/e2e/genutil/validate_genesis.go index c537dbf9dc..affb4dc4b4 100644 --- a/x/genutil/client/testutil/validate_genesis.go +++ b/tests/e2e/genutil/validate_genesis.go @@ -1,4 +1,4 @@ -package testutil +package genutil import ( "github.com/cosmos/cosmos-sdk/testutil" diff --git a/x/genutil/client/cli/gentx_test.go b/x/genutil/client/cli/gentx_test.go new file mode 100644 index 0000000000..5b9bef9f6d --- /dev/null +++ b/x/genutil/client/cli/gentx_test.go @@ -0,0 +1,170 @@ +package cli_test + +import ( + "bytes" + "context" + "fmt" + "io" + "path/filepath" + "testing" + + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + tmbytes "github.com/tendermint/tendermint/libs/bytes" + rpcclient "github.com/tendermint/tendermint/rpc/client" + rpcclientmock "github.com/tendermint/tendermint/rpc/client/mock" + coretypes "github.com/tendermint/tendermint/rpc/core/types" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + stakingcli "github.com/cosmos/cosmos-sdk/x/staking/client/cli" +) + +var _ client.TendermintRPC = (*mockTendermintRPC)(nil) + +type mockTendermintRPC struct { + rpcclientmock.Client + + responseQuery abci.ResponseQuery +} + +func newMockTendermintRPC(respQuery abci.ResponseQuery) mockTendermintRPC { + return mockTendermintRPC{responseQuery: respQuery} +} + +func (_ mockTendermintRPC) BroadcastTxCommit(_ context.Context, _ tmtypes.Tx) (*coretypes.ResultBroadcastTxCommit, error) { + return &coretypes.ResultBroadcastTxCommit{}, nil +} + +func (m mockTendermintRPC) ABCIQueryWithOptions( + _ context.Context, + _ string, _ tmbytes.HexBytes, + _ rpcclient.ABCIQueryOptions, +) (*coretypes.ResultABCIQuery, error) { + return &coretypes.ResultABCIQuery{Response: m.responseQuery}, nil +} + +type CLITestSuite struct { + suite.Suite + + kr keyring.Keyring + encCfg testutilmod.TestEncodingConfig + baseCtx client.Context + clientCtx client.Context +} + +func TestCLITestSuite(t *testing.T) { + suite.Run(t, new(CLITestSuite)) +} + +func (s *CLITestSuite) SetupSuite() { + s.encCfg = testutilmod.MakeTestEncodingConfig(genutil.AppModuleBasic{}) + s.kr = keyring.NewInMemory(s.encCfg.Codec) + s.baseCtx = client.Context{}. + WithKeyring(s.kr). + WithTxConfig(s.encCfg.TxConfig). + WithCodec(s.encCfg.Codec). + WithClient(mockTendermintRPC{Client: rpcclientmock.Client{}}). + WithAccountRetriever(client.MockAccountRetriever{}). + WithOutput(io.Discard). + WithChainID("test-chain") + + var outBuf bytes.Buffer + ctxGen := func() client.Context { + bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{}) + c := newMockTendermintRPC(abci.ResponseQuery{ + Value: bz, + }) + return s.baseCtx.WithClient(c) + } + s.clientCtx = ctxGen().WithOutput(&outBuf) + +} + +func (s *CLITestSuite) TestGenTxCmd() { + amount := sdk.NewCoin("stake", sdk.NewInt(12)) + + tests := []struct { + name string + args []string + expCmdOutput string + }{ + { + name: "invalid commission rate returns error", + args: []string{ + fmt.Sprintf("--%s=%s", flags.FlagChainID, s.baseCtx.ChainID), + fmt.Sprintf("--%s=1", stakingcli.FlagCommissionRate), + "node0", + amount.String(), + }, + expCmdOutput: fmt.Sprintf("--%s=%s --%s=1 %s %s", flags.FlagChainID, s.baseCtx.ChainID, stakingcli.FlagCommissionRate, "node0", amount.String()), + }, + { + name: "valid gentx", + args: []string{ + fmt.Sprintf("--%s=%s", flags.FlagChainID, s.baseCtx.ChainID), + "node0", + amount.String(), + }, + expCmdOutput: fmt.Sprintf("--%s=%s %s %s", flags.FlagChainID, s.baseCtx.ChainID, "node0", amount.String()), + }, + { + name: "invalid pubkey", + args: []string{ + fmt.Sprintf("--%s=%s", flags.FlagChainID, "test-chain-1"), + fmt.Sprintf("--%s={\"key\":\"BOIkjkFruMpfOFC9oNPhiJGfmY2pHF/gwHdLDLnrnS0=\"}", stakingcli.FlagPubKey), + "node0", + amount.String(), + }, + expCmdOutput: fmt.Sprintf("--%s=test-chain-1 --%s={\"key\":\"BOIkjkFruMpfOFC9oNPhiJGfmY2pHF/gwHdLDLnrnS0=\"} %s %s ", flags.FlagChainID, stakingcli.FlagPubKey, "node0", amount.String()), + }, + { + name: "valid pubkey flag", + args: []string{ + fmt.Sprintf("--%s=%s", flags.FlagChainID, "test-chain-1"), + fmt.Sprintf("--%s={\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"BOIkjkFruMpfOFC9oNPhiJGfmY2pHF/gwHdLDLnrnS0=\"}", stakingcli.FlagPubKey), + "node0", + amount.String(), + }, + expCmdOutput: fmt.Sprintf("--%s=test-chain-1 --%s={\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"BOIkjkFruMpfOFC9oNPhiJGfmY2pHF/gwHdLDLnrnS0=\"} %s %s ", flags.FlagChainID, stakingcli.FlagPubKey, "node0", amount.String()), + }, + } + + for _, tc := range tests { + tc := tc + + dir := s.T().TempDir() + genTxFile := filepath.Join(dir, "myTx") + tc.args = append(tc.args, fmt.Sprintf("--%s=%s", flags.FlagOutputDocument, genTxFile)) + + s.Run(tc.name, func() { + + clientCtx := s.clientCtx + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd := cli.GenTxCmd( + module.NewBasicManager(), + clientCtx.TxConfig, + banktypes.GenesisBalancesIterator{}, + clientCtx.HomeDir, + ) + cmd.SetContext(ctx) + cmd.SetArgs(tc.args) + + s.Require().NoError(client.SetCmdClientContextHandler(clientCtx, cmd)) + + if len(tc.args) != 0 { + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + } + }) + } +} diff --git a/x/genutil/client/cli/migrate_test.go b/x/genutil/client/cli/migrate_test.go new file mode 100644 index 0000000000..0740a04ee8 --- /dev/null +++ b/x/genutil/client/cli/migrate_test.go @@ -0,0 +1,60 @@ +package cli_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/testutil" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" +) + +func TestGetMigrationCallback(t *testing.T) { + for _, version := range cli.GetMigrationVersions() { + require.NotNil(t, cli.GetMigrationCallback(version)) + } +} + +func (s *CLITestSuite) TestMigrateGenesis() { + testCases := []struct { + name string + genesis string + target string + expErr bool + expErrMsg string + check func(jsonOut string) + }{ + { + "migrate 0.37 to 0.42", + v037Exported, + "v0.42", + true, "Make sure that you have correctly migrated all Tendermint consensus params", func(_ string) {}, + }, + { + "migrate 0.42 to 0.43", + v040Valid, + "v0.43", + false, "", + func(jsonOut string) { + // Make sure the json output contains the ADR-037 gov weighted votes. + s.Require().Contains(jsonOut, "\"weight\":\"1.000000000000000000\"") + }, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + + genesisFile := testutil.WriteToNewTempFile(s.T(), tc.genesis) + jsonOutput, err := clitestutil.ExecTestCLICmd(s.clientCtx, cli.MigrateGenesisCmd(), []string{tc.target, genesisFile.Name()}) + if tc.expErr { + s.Require().Contains(err.Error(), tc.expErrMsg) + } else { + s.Require().NoError(err) + tc.check(jsonOutput.String()) + } + }) + } +} diff --git a/x/genutil/client/cli/validate_genesis_test.go b/x/genutil/client/cli/validate_genesis_test.go new file mode 100644 index 0000000000..73e1aab3a3 --- /dev/null +++ b/x/genutil/client/cli/validate_genesis_test.go @@ -0,0 +1,103 @@ +package cli_test + +import ( + "github.com/cosmos/cosmos-sdk/testutil" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" +) + +// An example exported genesis file from a 0.37 chain. Note that evidence +// parameters only contains `max_age`. +var v037Exported = `{ + "app_hash": "", + "app_state": {}, + "chain_id": "test", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1", + "time_iota_ms": "1000" + }, + "evidence": { "max_age": "100000" }, + "validator": { "pub_key_types": ["ed25519"] } + }, + "genesis_time": "2020-09-29T20:16:29.172362037Z", + "validators": [] +}` + +// An example exported genesis file that's 0.40 compatible. +// We added the following app_state: +// +// - x/gov: added votes to test ADR-037 split votes migration. +var v040Valid = `{ + "app_hash": "", + "app_state": { + "gov": { + "starting_proposal_id": "0", + "deposits": [], + "votes": [ + { + "proposal_id": "5", + "voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", + "option": "VOTE_OPTION_YES" + } + ], + "proposals": [], + "deposit_params": { "min_deposit": [], "max_deposit_period": "0s" }, + "voting_params": { "voting_period": "0s" }, + "tally_params": { "quorum": "0", "threshold": "0", "veto_threshold": "0" } + } + }, + "chain_id": "test", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1", + "time_iota_ms": "1000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000", + "max_bytes": "0" + }, + "validator": { "pub_key_types": ["ed25519"] } + }, + "genesis_time": "2020-09-29T20:16:29.172362037Z", + "validators": [] +}` + +func (s *CLITestSuite) TestValidateGenesis() { + // accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) + // val0 := accounts[0] + + testCases := []struct { + name string + genesis string + expErr bool + }{ + { + "exported 0.37 genesis file", + v037Exported, + true, + }, + { + "valid 0.40 genesis file", + v040Valid, + false, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + + genesisFile := testutil.WriteToNewTempFile(s.T(), tc.genesis) + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cli.ValidateGenesisCmd(nil), []string{genesisFile.Name()}) + if tc.expErr { + s.Require().Contains(err.Error(), "Make sure that you have correctly migrated all Tendermint consensus params") + } else { + s.Require().NoError(err) + } + }) + } +}