From 589edc15c8efe4543395455a5db9cbfc492fb0a6 Mon Sep 17 00:00:00 2001 From: yihuang Date: Mon, 21 Dec 2020 10:46:28 +0800 Subject: [PATCH] cherry-pick 8dd8bfd2ed9f1b31614829124910cd13e53f083c Problem: test_min_self_delegate don't work in recent version (#299) Solution: - use a separate cluster config for this test case - make it more stable by not depend on order of validators response - stablise other integration tests - use builtin `Execute`, which add new log_level flag - register tmservice grpc gateway --- app/app.go | 2 ++ cmd/chain-maind/app/app.go | 20 ----------- cmd/chain-maind/main.go | 8 +++-- cmd/chain-maind/main_test.go | 8 +++-- integration_tests/configs/staking.yaml | 36 +++++++++++++++++++ integration_tests/test_gov.py | 4 ++- integration_tests/test_slashing.py | 9 ++++- integration_tests/test_staking.py | 49 +++++++++++++++++++------- pystarport/pystarport/cluster.py | 2 -- x/chainmain/client/cli/genaccounts.go | 1 + 10 files changed, 97 insertions(+), 42 deletions(-) create mode 100644 integration_tests/configs/staking.yaml diff --git a/app/app.go b/app/app.go index a8e63bfe5..2f1dac48c 100644 --- a/app/app.go +++ b/app/app.go @@ -544,6 +544,8 @@ func (app *ChainApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIC authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register new tendermint queries routes from grpc-gateway. + tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register legacy and grpc-gateway routes for all modules. ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router) diff --git a/cmd/chain-maind/app/app.go b/cmd/chain-maind/app/app.go index 8a139aab6..1447a9a90 100644 --- a/cmd/chain-maind/app/app.go +++ b/cmd/chain-maind/app/app.go @@ -1,7 +1,6 @@ package app import ( - "context" "encoding/json" "fmt" "io" @@ -73,25 +72,6 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { return rootCmd, encodingConfig } -// Execute executes the root command. -func Execute(rootCmd *cobra.Command) error { - // Create and set a client.Context on the command's Context. During the pre-run - // of the root command, a default initialized client.Context is provided to - // seed child command execution with values such as AccountRetriver, Keyring, - // and a Tendermint RPC. This requires the use of a pointer reference when - // getting and setting the client.Context. Ideally, we utilize - // https://github.com/spf13/cobra/pull/1118. - srvCtx := server.NewDefaultContext() - ctx := context.Background() - ctx = context.WithValue(ctx, client.ClientContextKey, &client.Context{}) - ctx = context.WithValue(ctx, server.ServerContextKey, srvCtx) - - rootCmd.PersistentFlags().String("log-level", srvCtx.Config.LogLevel, "The logging level in the format of trace|debug|info|warn|error|fatal|panic") - - executor := tmcli.PrepareBaseCmd(rootCmd, "", app.DefaultNodeHome) - return executor.ExecuteContext(ctx) -} - func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { authclient.Codec = encodingConfig.Marshaler diff --git a/cmd/chain-maind/main.go b/cmd/chain-maind/main.go index 47548f1d4..8479090b6 100644 --- a/cmd/chain-maind/main.go +++ b/cmd/chain-maind/main.go @@ -4,12 +4,14 @@ import ( "os" "github.com/cosmos/cosmos-sdk/server" - "github.com/crypto-com/chain-main/cmd/chain-maind/app" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + "github.com/crypto-com/chain-main/app" + cmd "github.com/crypto-com/chain-main/cmd/chain-maind/app" ) func main() { - rootCmd, _ := app.NewRootCmd() - if err := app.Execute(rootCmd); err != nil { + rootCmd, _ := cmd.NewRootCmd() + if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: os.Exit(e.Code) diff --git a/cmd/chain-maind/main_test.go b/cmd/chain-maind/main_test.go index a5aac5de3..ac7fef415 100644 --- a/cmd/chain-maind/main_test.go +++ b/cmd/chain-maind/main_test.go @@ -7,12 +7,14 @@ import ( "github.com/confluentinc/bincover" "github.com/cosmos/cosmos-sdk/server" - "github.com/crypto-com/chain-main/cmd/chain-maind/app" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + "github.com/crypto-com/chain-main/app" + cmd "github.com/crypto-com/chain-main/cmd/chain-maind/app" ) func test_main() { - rootCmd, _ := app.NewRootCmd() - if err := app.Execute(rootCmd); err != nil { + rootCmd, _ := cmd.NewRootCmd() + if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: bincover.ExitCode = e.Code diff --git a/integration_tests/configs/staking.yaml b/integration_tests/configs/staking.yaml new file mode 100644 index 000000000..d3c30fd10 --- /dev/null +++ b/integration_tests/configs/staking.yaml @@ -0,0 +1,36 @@ +stakingtest: + validators: + - coins: 10cro + staked: 10cro + - coins: 10cro + staked: 10cro + - coins: 1cro + staked: 1cro + min_self_delegation: 10000000 # 0.1cro + accounts: + - name: community + coins: 100cro + - name: ecosystem + coins: 200cro + - name: reserve + coins: 200cro + vesting: "60s" + - name: launch + coins: 100cro + - name: signer1 + coins: 10000cro + - name: signer2 + coins: 2000cro + genesis: + app_state: + staking: + params: + unbonding_time: "10s" + gov: + voting_params: + voting_period: "10s" + deposit_params: + max_deposit_period: "10s" + min_deposit: + - denom: "basecro" + amount: "10000000" diff --git a/integration_tests/test_gov.py b/integration_tests/test_gov.py index 466da72ed..75149bb2c 100644 --- a/integration_tests/test_gov.py +++ b/integration_tests/test_gov.py @@ -200,7 +200,9 @@ def test_community_pool_spend_proposal(cluster): # wait for voting period end proposal = cluster.query_proposal(proposal_id) assert proposal["status"] == "PROPOSAL_STATUS_VOTING_PERIOD", proposal - wait_for_block_time(cluster, isoparse(proposal["voting_end_time"])) + wait_for_block_time( + cluster, isoparse(proposal["voting_end_time"]) + timedelta(seconds=1) + ) proposal = cluster.query_proposal(proposal_id) assert proposal["status"] == "PROPOSAL_STATUS_PASSED", proposal diff --git a/integration_tests/test_slashing.py b/integration_tests/test_slashing.py index 4275d362e..31826ae9e 100644 --- a/integration_tests/test_slashing.py +++ b/integration_tests/test_slashing.py @@ -3,8 +3,14 @@ import pytest from dateutil.parser import isoparse +from pystarport.ports import rpc_port -from .utils import cluster_fixture, wait_for_block_time, wait_for_new_blocks +from .utils import ( + cluster_fixture, + wait_for_block_time, + wait_for_new_blocks, + wait_for_port, +) """ slashing testing @@ -35,6 +41,7 @@ def test_slashing(cluster): cluster.supervisor.stopProcess(f"{cluster.chain_id}-node2") wait_for_new_blocks(cluster, 10) cluster.supervisor.startProcess(f"{cluster.chain_id}-node2") + wait_for_port(rpc_port(cluster.base_port(2))) val = cluster.validator(val_addr) tokens2 = int(val["tokens"]) diff --git a/integration_tests/test_staking.py b/integration_tests/test_staking.py index 51c873da9..3867e3b38 100644 --- a/integration_tests/test_staking.py +++ b/integration_tests/test_staking.py @@ -1,10 +1,17 @@ from datetime import timedelta +from pathlib import Path import pytest from dateutil.parser import isoparse from pystarport.ports import rpc_port -from .utils import parse_events, wait_for_block, wait_for_block_time, wait_for_port +from .utils import ( + cluster_fixture, + parse_events, + wait_for_block, + wait_for_block_time, + wait_for_port, +) def test_staking_delegate(cluster): @@ -118,29 +125,47 @@ def test_join_validator(cluster): assert cluster.validator(val_addr)["description"]["moniker"] == "awesome node" -@pytest.mark.skip(reason="FIXME: not sure if this test worked in the first place?") -def test_min_self_delegation(cluster): +@pytest.fixture(scope="module") +def staking_cluster(pytestconfig, tmp_path_factory): + "override cluster fixture for this test module" + yield from cluster_fixture( + Path(__file__).parent / "configs/staking.yaml", + 27000, + tmp_path_factory, + quiet=pytestconfig.getoption("supervisord-quiet"), + ) + + +def test_min_self_delegation(staking_cluster): """ - validator unbond min_self_delegation - check not in validator set anymore """ - wait_for_block(cluster, 3) + cluster = staking_cluster + wait_for_block(cluster, 2) - valset = cluster.validators() - oper_addr = valset[2]["operator_address"] - acct_addr = cluster.address("validator", i=2) + assert len(cluster.validators()) == 3, "wrong validator set" - print(oper_addr, acct_addr) - # fails AssertionError: failed to execute message; - # message index: 0: no delegation for (address, validator) tuple + oper_addr = cluster.address("validator", i=2, bech="val") + acct_addr = cluster.address("validator", i=2) rsp = cluster.unbond_amount(oper_addr, "90000000basecro", acct_addr, i=2) assert rsp["code"] == 0, rsp["raw_log"] + + def find_validator(): + return next( + iter( + val + for val in cluster.validators() + if val["operator_address"] == oper_addr + ) + ) + assert ( - cluster.validators()[2]["status"] == "BOND_STATUS_BONDED" + find_validator()["status"] == "BOND_STATUS_BONDED" ), "validator set not changed yet" rsp = cluster.unbond_amount(oper_addr, "1basecro", acct_addr, i=2) assert rsp["code"] == 0, rsp["raw_log"] assert ( - cluster.validators()[2]["status"] == "BOND_STATUS_UNBONDING" + find_validator()["status"] == "BOND_STATUS_UNBONDING" ), "validator get removed" diff --git a/pystarport/pystarport/cluster.py b/pystarport/pystarport/cluster.py index 3cfeaad45..256e7ec4b 100644 --- a/pystarport/pystarport/cluster.py +++ b/pystarport/pystarport/cluster.py @@ -1103,7 +1103,6 @@ def create_account(cli, account, use_ledger=False): ChainCommand(cmd)( "init", val["moniker"], - log_level="info", chain_id=config["chain_id"], home=home_dir(data_dir, i), ) @@ -1356,7 +1355,6 @@ def edit_tm_cfg(path, base_port, peers, *, custom_edit=None): doc = tomlkit.parse(open(path).read()) # tendermint is start in process, not needed # doc['proxy_app'] = 'tcp://127.0.0.1:%d' % abci_port(base_port) - doc["log_level"] = "info" doc["rpc"]["laddr"] = "tcp://0.0.0.0:%d" % ports.rpc_port(base_port) doc["rpc"]["pprof_laddr"] = "localhost:%d" % ports.pprof_port(base_port) doc["rpc"]["grpc_laddr"] = "tcp://0.0.0.0:%d" % ports.grpc_port_tx_only(base_port) diff --git a/x/chainmain/client/cli/genaccounts.go b/x/chainmain/client/cli/genaccounts.go index 8cd65e0bd..8278de3c1 100644 --- a/x/chainmain/client/cli/genaccounts.go +++ b/x/chainmain/client/cli/genaccounts.go @@ -205,6 +205,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa } cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") + cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts") cmd.Flags().String(flagVestingStart, "0", "schedule start time (RFC-3339 format or unix timestamp) for vesting accounts") cmd.Flags().String(flagVestingEnd, "0", "schedule end time (RFC-3339 format or unix timestamp) for vesting accounts")