package clitest import ( "encoding/json" "fmt" "io/ioutil" "os" "path/filepath" "strings" "testing" "time" "github.com/stretchr/testify/require" cmn "github.com/tendermint/tendermint/libs/common" clientkeys "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" appInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/staking" ) const ( denom = "stake" keyFoo = "foo" keyBar = "bar" fooDenom = "footoken" feeDenom = "feetoken" fee2Denom = "fee2token" keyBaz = "baz" keyVesting = "vesting" keyFooBarBaz = "foobarbaz" ) var ( startCoins = sdk.Coins{ sdk.NewCoin(feeDenom, sdk.TokensFromTendermintPower(1000000)), sdk.NewCoin(fee2Denom, sdk.TokensFromTendermintPower(1000000)), sdk.NewCoin(fooDenom, sdk.TokensFromTendermintPower(1000)), sdk.NewCoin(denom, sdk.TokensFromTendermintPower(150)), } vestingCoins = sdk.Coins{ sdk.NewCoin(feeDenom, sdk.TokensFromTendermintPower(500000)), } ) //___________________________________________________________________________________ // Fixtures // Fixtures is used to setup the testing environment type Fixtures struct { ChainID string RPCAddr string Port string GDHome string GCLIHome string P2PAddr string T *testing.T } // NewFixtures creates a new instance of Fixtures with many vars set func NewFixtures(t *testing.T) *Fixtures { tmpDir, err := ioutil.TempDir("", "gaia_integration_"+t.Name()+"_") require.NoError(t, err) servAddr, port, err := server.FreeTCPAddr() require.NoError(t, err) p2pAddr, _, err := server.FreeTCPAddr() require.NoError(t, err) return &Fixtures{ T: t, GDHome: filepath.Join(tmpDir, ".gaiad"), GCLIHome: filepath.Join(tmpDir, ".gaiacli"), RPCAddr: servAddr, P2PAddr: p2pAddr, Port: port, } } // GenesisFile returns the path of the genesis file func (f Fixtures) GenesisFile() string { return filepath.Join(f.GDHome, "config", "genesis.json") } // GenesisFile returns the application's genesis state func (f Fixtures) GenesisState() app.GenesisState { cdc := codec.New() genDoc, err := appInit.LoadGenesisDoc(cdc, f.GenesisFile()) require.NoError(f.T, err) var appState app.GenesisState require.NoError(f.T, cdc.UnmarshalJSON(genDoc.AppState, &appState)) return appState } // InitFixtures is called at the beginning of a test and initializes a chain // with 1 validator. func InitFixtures(t *testing.T) (f *Fixtures) { f = NewFixtures(t) // reset test state f.UnsafeResetAll() // ensure keystore has foo and bar keys f.KeysDelete(keyFoo) f.KeysDelete(keyBar) f.KeysDelete(keyBar) f.KeysDelete(keyFooBarBaz) f.KeysAdd(keyFoo) f.KeysAdd(keyBar) f.KeysAdd(keyBaz) f.KeysAdd(keyVesting) f.KeysAdd(keyFooBarBaz, "--multisig-threshold=2", fmt.Sprintf( "--multisig=%s,%s,%s", keyFoo, keyBar, keyBaz)) // ensure that CLI output is in JSON format f.CLIConfig("output", "json") // NOTE: GDInit sets the ChainID f.GDInit(keyFoo) f.CLIConfig("chain-id", f.ChainID) f.CLIConfig("broadcast-mode", "block") // start an account with tokens f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins) f.AddGenesisAccount( f.KeyAddress(keyVesting), startCoins, fmt.Sprintf("--vesting-amount=%s", vestingCoins), fmt.Sprintf("--vesting-start-time=%d", time.Now().UTC().UnixNano()), fmt.Sprintf("--vesting-end-time=%d", time.Now().Add(60*time.Second).UTC().UnixNano()), ) f.GenTx(keyFoo) f.CollectGenTxs() return } // Cleanup is meant to be run at the end of a test to clean up an remaining test state func (f *Fixtures) Cleanup(dirs ...string) { clean := append(dirs, f.GDHome, f.GCLIHome) for _, d := range clean { err := os.RemoveAll(d) require.NoError(f.T, err) } } // Flags returns the flags necessary for making most CLI calls func (f *Fixtures) Flags() string { return fmt.Sprintf("--home=%s --node=%s", f.GCLIHome, f.RPCAddr) } //___________________________________________________________________________________ // gaiad // UnsafeResetAll is gaiad unsafe-reset-all func (f *Fixtures) UnsafeResetAll(flags ...string) { cmd := fmt.Sprintf("../../../build/gaiad --home=%s unsafe-reset-all", f.GDHome) executeWrite(f.T, addFlags(cmd, flags)) err := os.RemoveAll(filepath.Join(f.GDHome, "config", "gentx")) require.NoError(f.T, err) } // GDInit is gaiad init // NOTE: GDInit sets the ChainID for the Fixtures instance func (f *Fixtures) GDInit(moniker string, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiad init -o --home=%s %s", f.GDHome, moniker) _, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), app.DefaultKeyPass) var chainID string var initRes map[string]json.RawMessage err := json.Unmarshal([]byte(stderr), &initRes) require.NoError(f.T, err) err = json.Unmarshal(initRes["chain_id"], &chainID) require.NoError(f.T, err) f.ChainID = chainID } // AddGenesisAccount is gaiad add-genesis-account func (f *Fixtures) AddGenesisAccount(address sdk.AccAddress, coins sdk.Coins, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiad add-genesis-account %s %s --home=%s", address, coins, f.GDHome) executeWriteCheckErr(f.T, addFlags(cmd, flags)) } // GenTx is gaiad gentx func (f *Fixtures) GenTx(name string, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiad gentx --name=%s --home=%s --home-client=%s", name, f.GDHome, f.GCLIHome) executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // CollectGenTxs is gaiad collect-gentxs func (f *Fixtures) CollectGenTxs(flags ...string) { cmd := fmt.Sprintf("../../../build/gaiad collect-gentxs --home=%s", f.GDHome) executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // GDStart runs gaiad start with the appropriate flags and returns a process func (f *Fixtures) GDStart(flags ...string) *tests.Process { cmd := fmt.Sprintf("../../../build/gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", f.GDHome, f.RPCAddr, f.P2PAddr) proc := tests.GoExecuteTWithStdout(f.T, addFlags(cmd, flags)) tests.WaitForTMStart(f.Port) tests.WaitForNextNBlocksTM(1, f.Port) return proc } // GDTendermint returns the results of gaiad tendermint [query] func (f *Fixtures) GDTendermint(query string) string { cmd := fmt.Sprintf("../../../build/gaiad tendermint %s --home=%s", query, f.GDHome) success, stdout, stderr := executeWriteRetStdStreams(f.T, cmd) require.Empty(f.T, stderr) require.True(f.T, success) return strings.TrimSpace(stdout) } // ValidateGenesis runs gaiad validate-genesis func (f *Fixtures) ValidateGenesis() { cmd := fmt.Sprintf("../../../build/gaiad validate-genesis --home=%s", f.GDHome) executeWriteCheckErr(f.T, cmd) } //___________________________________________________________________________________ // gaiacli keys // KeysDelete is gaiacli keys delete func (f *Fixtures) KeysDelete(name string, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiacli keys delete --home=%s %s", f.GCLIHome, name) executeWrite(f.T, addFlags(cmd, append(append(flags, "-y"), "-f"))) } // KeysAdd is gaiacli keys add func (f *Fixtures) KeysAdd(name string, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s %s", f.GCLIHome, name) executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // KeysAddRecover prepares gaiacli keys add --recover func (f *Fixtures) KeysAddRecover(name, mnemonic string, flags ...string) (exitSuccess bool, stdout, stderr string) { cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s --recover %s", f.GCLIHome, name) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass, mnemonic) } // KeysAddRecoverHDPath prepares gaiacli keys add --recover --account --index func (f *Fixtures) KeysAddRecoverHDPath(name, mnemonic string, account uint32, index uint32, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s --recover %s --account %d --index %d", f.GCLIHome, name, account, index) executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass, mnemonic) } // KeysShow is gaiacli keys show func (f *Fixtures) KeysShow(name string, flags ...string) keys.KeyOutput { cmd := fmt.Sprintf("../../../build/gaiacli keys show --home=%s %s", f.GCLIHome, name) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var ko keys.KeyOutput err := clientkeys.UnmarshalJSON([]byte(out), &ko) require.NoError(f.T, err) return ko } // KeyAddress returns the SDK account address from the key func (f *Fixtures) KeyAddress(name string) sdk.AccAddress { ko := f.KeysShow(name) accAddr, err := sdk.AccAddressFromBech32(ko.Address) require.NoError(f.T, err) return accAddr } //___________________________________________________________________________________ // gaiacli config // CLIConfig is gaiacli config func (f *Fixtures) CLIConfig(key, value string, flags ...string) { cmd := fmt.Sprintf("../../../build/gaiacli config --home=%s %s %s", f.GCLIHome, key, value) executeWriteCheckErr(f.T, addFlags(cmd, flags)) } //___________________________________________________________________________________ // gaiacli tx send/sign/broadcast // TxSend is gaiacli tx send func (f *Fixtures) TxSend(from string, to sdk.AccAddress, amount sdk.Coin, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx send %s %s %v --from=%s", to, amount, f.Flags(), from) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } func (f *Fixtures) txSendWithConfirm( from string, to sdk.AccAddress, amount sdk.Coin, confirm string, flags ...string, ) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx send %s %s %v --from=%s", to, amount, f.Flags(), from) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), confirm, app.DefaultKeyPass) } // TxSign is gaiacli tx sign func (f *Fixtures) TxSign(signer, fileName string, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx sign %v --from=%s %v", f.Flags(), signer, fileName) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // TxBroadcast is gaiacli tx broadcast func (f *Fixtures) TxBroadcast(fileName string, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx broadcast %v %v", f.Flags(), fileName) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // TxEncode is gaiacli tx encode func (f *Fixtures) TxEncode(fileName string, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx encode %v %v", f.Flags(), fileName) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // TxMultisign is gaiacli tx multisign func (f *Fixtures) TxMultisign(fileName, name string, signaturesFiles []string, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx multisign %v %s %s %s", f.Flags(), fileName, name, strings.Join(signaturesFiles, " "), ) return executeWriteRetStdStreams(f.T, cmd) } //___________________________________________________________________________________ // gaiacli tx staking // TxStakingCreateValidator is gaiacli tx staking create-validator func (f *Fixtures) TxStakingCreateValidator(from, consPubKey string, amount sdk.Coin, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx staking create-validator %v --from=%s --pubkey=%s", f.Flags(), from, consPubKey) cmd += fmt.Sprintf(" --amount=%v --moniker=%v --commission-rate=%v", amount, from, "0.05") cmd += fmt.Sprintf(" --commission-max-rate=%v --commission-max-change-rate=%v", "0.20", "0.10") cmd += fmt.Sprintf(" --min-self-delegation=%v", "1") return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // TxStakingUnbond is gaiacli tx staking unbond func (f *Fixtures) TxStakingUnbond(from, shares string, validator sdk.ValAddress, flags ...string) bool { cmd := fmt.Sprintf("../../../build/gaiacli tx staking unbond %s %v --from=%s %v", validator, shares, from, f.Flags()) return executeWrite(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } //___________________________________________________________________________________ // gaiacli tx gov // TxGovSubmitProposal is gaiacli tx gov submit-proposal func (f *Fixtures) TxGovSubmitProposal(from, typ, title, description string, deposit sdk.Coin, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx gov submit-proposal %v --from=%s --type=%s", f.Flags(), from, typ) cmd += fmt.Sprintf(" --title=%s --description=%s --deposit=%s", title, description, deposit) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // TxGovDeposit is gaiacli tx gov deposit func (f *Fixtures) TxGovDeposit(proposalID int, from string, amount sdk.Coin, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx gov deposit %d %s --from=%s %v", proposalID, amount, from, f.Flags()) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } // TxGovVote is gaiacli tx gov vote func (f *Fixtures) TxGovVote(proposalID int, option gov.VoteOption, from string, flags ...string) (bool, string, string) { cmd := fmt.Sprintf("../../../build/gaiacli tx gov vote %d %s --from=%s %v", proposalID, option, from, f.Flags()) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass) } //___________________________________________________________________________________ // gaiacli query account // QueryAccount is gaiacli query account func (f *Fixtures) QueryAccount(address sdk.AccAddress, flags ...string) auth.BaseAccount { cmd := fmt.Sprintf("../../../build/gaiacli query account %s %v", address, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var initRes map[string]json.RawMessage err := json.Unmarshal([]byte(out), &initRes) require.NoError(f.T, err, "out %v, err %v", out, err) value := initRes["value"] var acc auth.BaseAccount cdc := codec.New() codec.RegisterCrypto(cdc) err = cdc.UnmarshalJSON(value, &acc) require.NoError(f.T, err, "value %v, err %v", string(value), err) return acc } //___________________________________________________________________________________ // gaiacli query txs // QueryTxs is gaiacli query txs func (f *Fixtures) QueryTxs(page, limit int, tags ...string) []sdk.TxResponse { cmd := fmt.Sprintf("../../../build/gaiacli query txs --page=%d --limit=%d --tags='%s' %v", page, limit, queryTags(tags), f.Flags()) out, _ := tests.ExecuteT(f.T, cmd, "") var txs []sdk.TxResponse cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &txs) require.NoError(f.T, err, "out %v\n, err %v", out, err) return txs } // QueryTxsInvalid query txs with wrong parameters and compare expected error func (f *Fixtures) QueryTxsInvalid(expectedErr error, page, limit int, tags ...string) { cmd := fmt.Sprintf("../../../build/gaiacli query txs --page=%d --limit=%d --tags='%s' %v", page, limit, queryTags(tags), f.Flags()) _, err := tests.ExecuteT(f.T, cmd, "") require.EqualError(f.T, expectedErr, err) } //___________________________________________________________________________________ // gaiacli query staking // QueryStakingValidator is gaiacli query staking validator func (f *Fixtures) QueryStakingValidator(valAddr sdk.ValAddress, flags ...string) staking.Validator { cmd := fmt.Sprintf("../../../build/gaiacli query staking validator %s %v", valAddr, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var validator staking.Validator cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &validator) require.NoError(f.T, err, "out %v\n, err %v", out, err) return validator } // QueryStakingUnbondingDelegationsFrom is gaiacli query staking unbonding-delegations-from func (f *Fixtures) QueryStakingUnbondingDelegationsFrom(valAddr sdk.ValAddress, flags ...string) []staking.UnbondingDelegation { cmd := fmt.Sprintf("../../../build/gaiacli query staking unbonding-delegations-from %s %v", valAddr, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var ubds []staking.UnbondingDelegation cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &ubds) require.NoError(f.T, err, "out %v\n, err %v", out, err) return ubds } // QueryStakingDelegationsTo is gaiacli query staking delegations-to func (f *Fixtures) QueryStakingDelegationsTo(valAddr sdk.ValAddress, flags ...string) []staking.Delegation { cmd := fmt.Sprintf("../../../build/gaiacli query staking delegations-to %s %v", valAddr, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var delegations []staking.Delegation cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &delegations) require.NoError(f.T, err, "out %v\n, err %v", out, err) return delegations } // QueryStakingPool is gaiacli query staking pool func (f *Fixtures) QueryStakingPool(flags ...string) staking.Pool { cmd := fmt.Sprintf("../../../build/gaiacli query staking pool %v", f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var pool staking.Pool cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &pool) require.NoError(f.T, err, "out %v\n, err %v", out, err) return pool } // QueryStakingParameters is gaiacli query staking parameters func (f *Fixtures) QueryStakingParameters(flags ...string) staking.Params { cmd := fmt.Sprintf("../../../build/gaiacli query staking params %v", f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var params staking.Params cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), ¶ms) require.NoError(f.T, err, "out %v\n, err %v", out, err) return params } //___________________________________________________________________________________ // gaiacli query gov // QueryGovParamDeposit is gaiacli query gov param deposit func (f *Fixtures) QueryGovParamDeposit() gov.DepositParams { cmd := fmt.Sprintf("../../../build/gaiacli query gov param deposit %s", f.Flags()) out, _ := tests.ExecuteT(f.T, cmd, "") var depositParam gov.DepositParams cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &depositParam) require.NoError(f.T, err, "out %v\n, err %v", out, err) return depositParam } // QueryGovParamVoting is gaiacli query gov param voting func (f *Fixtures) QueryGovParamVoting() gov.VotingParams { cmd := fmt.Sprintf("../../../build/gaiacli query gov param voting %s", f.Flags()) out, _ := tests.ExecuteT(f.T, cmd, "") var votingParam gov.VotingParams cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &votingParam) require.NoError(f.T, err, "out %v\n, err %v", out, err) return votingParam } // QueryGovParamTallying is gaiacli query gov param tallying func (f *Fixtures) QueryGovParamTallying() gov.TallyParams { cmd := fmt.Sprintf("../../../build/gaiacli query gov param tallying %s", f.Flags()) out, _ := tests.ExecuteT(f.T, cmd, "") var tallyingParam gov.TallyParams cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &tallyingParam) require.NoError(f.T, err, "out %v\n, err %v", out, err) return tallyingParam } // QueryGovProposals is gaiacli query gov proposals func (f *Fixtures) QueryGovProposals(flags ...string) gov.Proposals { cmd := fmt.Sprintf("../../../build/gaiacli query gov proposals %v", f.Flags()) stdout, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), "") if strings.Contains(stderr, "No matching proposals found") { return gov.Proposals{} } require.Empty(f.T, stderr) var out gov.Proposals cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(stdout), &out) require.NoError(f.T, err) return out } // QueryGovProposal is gaiacli query gov proposal func (f *Fixtures) QueryGovProposal(proposalID int, flags ...string) gov.Proposal { cmd := fmt.Sprintf("../../../build/gaiacli query gov proposal %d %v", proposalID, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var proposal gov.Proposal cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &proposal) require.NoError(f.T, err, "out %v\n, err %v", out, err) return proposal } // QueryGovVote is gaiacli query gov vote func (f *Fixtures) QueryGovVote(proposalID int, voter sdk.AccAddress, flags ...string) gov.Vote { cmd := fmt.Sprintf("../../../build/gaiacli query gov vote %d %s %v", proposalID, voter, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var vote gov.Vote cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &vote) require.NoError(f.T, err, "out %v\n, err %v", out, err) return vote } // QueryGovVotes is gaiacli query gov votes func (f *Fixtures) QueryGovVotes(proposalID int, flags ...string) []gov.Vote { cmd := fmt.Sprintf("../../../build/gaiacli query gov votes %d %v", proposalID, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var votes []gov.Vote cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &votes) require.NoError(f.T, err, "out %v\n, err %v", out, err) return votes } // QueryGovDeposit is gaiacli query gov deposit func (f *Fixtures) QueryGovDeposit(proposalID int, depositor sdk.AccAddress, flags ...string) gov.Deposit { cmd := fmt.Sprintf("../../../build/gaiacli query gov deposit %d %s %v", proposalID, depositor, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var deposit gov.Deposit cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &deposit) require.NoError(f.T, err, "out %v\n, err %v", out, err) return deposit } // QueryGovDeposits is gaiacli query gov deposits func (f *Fixtures) QueryGovDeposits(propsalID int, flags ...string) []gov.Deposit { cmd := fmt.Sprintf("../../../build/gaiacli query gov deposits %d %v", propsalID, f.Flags()) out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "") var deposits []gov.Deposit cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &deposits) require.NoError(f.T, err, "out %v\n, err %v", out, err) return deposits } //___________________________________________________________________________________ // query slashing // QuerySigningInfo returns the signing info for a validator func (f *Fixtures) QuerySigningInfo(val string) slashing.ValidatorSigningInfo { cmd := fmt.Sprintf("../../../build/gaiacli query slashing signing-info %s %s", val, f.Flags()) res, errStr := tests.ExecuteT(f.T, cmd, "") require.Empty(f.T, errStr) cdc := app.MakeCodec() var sinfo slashing.ValidatorSigningInfo err := cdc.UnmarshalJSON([]byte(res), &sinfo) require.NoError(f.T, err) return sinfo } // QuerySlashingParams is gaiacli query slashing params func (f *Fixtures) QuerySlashingParams() slashing.Params { cmd := fmt.Sprintf("../../../build/gaiacli query slashing params %s", f.Flags()) res, errStr := tests.ExecuteT(f.T, cmd, "") require.Empty(f.T, errStr) cdc := app.MakeCodec() var params slashing.Params err := cdc.UnmarshalJSON([]byte(res), ¶ms) require.NoError(f.T, err) return params } //___________________________________________________________________________________ // executors func executeWriteCheckErr(t *testing.T, cmdStr string, writes ...string) { require.True(t, executeWrite(t, cmdStr, writes...)) } func executeWrite(t *testing.T, cmdStr string, writes ...string) (exitSuccess bool) { exitSuccess, _, _ = executeWriteRetStdStreams(t, cmdStr, writes...) return } func executeWriteRetStdStreams(t *testing.T, cmdStr string, writes ...string) (bool, string, string) { proc := tests.GoExecuteT(t, cmdStr) // Enables use of interactive commands for _, write := range writes { _, err := proc.StdinPipe.Write([]byte(write + "\n")) require.NoError(t, err) } // Read both stdout and stderr from the process stdout, stderr, err := proc.ReadAll() if err != nil { fmt.Println("Err on proc.ReadAll()", err, cmdStr) } // Log output. if len(stdout) > 0 { t.Log("Stdout:", cmn.Green(string(stdout))) } if len(stderr) > 0 { t.Log("Stderr:", cmn.Red(string(stderr))) } // Wait for process to exit proc.Wait() // Return succes, stdout, stderr return proc.ExitState.Success(), string(stdout), string(stderr) } //___________________________________________________________________________________ // utils func addFlags(cmd string, flags []string) string { for _, f := range flags { cmd += " " + f } return strings.TrimSpace(cmd) } func queryTags(tags []string) (out string) { for _, tag := range tags { out += tag + "&" } return strings.TrimSuffix(out, "&") } // Write the given string to a new temporary file func WriteToNewTempFile(t *testing.T, s string) *os.File { fp, err := ioutil.TempFile(os.TempDir(), "cosmos_cli_test_") require.Nil(t, err) _, err = fp.WriteString(s) require.Nil(t, err) return fp } func marshalStdTx(t *testing.T, stdTx auth.StdTx) []byte { cdc := app.MakeCodec() bz, err := cdc.MarshalBinaryBare(stdTx) require.NoError(t, err) return bz } func unmarshalStdTx(t *testing.T, s string) (stdTx auth.StdTx) { cdc := app.MakeCodec() require.Nil(t, cdc.UnmarshalJSON([]byte(s), &stdTx)) return }