Initial release.

Closes: cosmos/cosmos-sdk#4103
This commit is contained in:
Alessio Treglia
2019-05-16 22:10:14 +02:00
parent d69d9ff32c
commit c05e6c9c05
63 changed files with 9026 additions and 0 deletions

51
cli_test/README.md Normal file
View File

@@ -0,0 +1,51 @@
# Gaia CLI Integration tests
The gaia cli integration tests live in this folder. You can run the full suite by running:
```bash
$ go test -mod=readonly -p 4 `go list ./cmd/gaia/cli_test/...` -tags=cli_test
# OR!
$ make test_cli
```
> NOTE: While the full suite runs in parallel, some of the tests can take up to a minute to complete
### Test Structure
This integration suite [uses a thin wrapper](https://godoc.org/github.com/cosmos/cosmos-sdk/tests) over the [`os/exec`](https://golang.org/pkg/os/exec/) package. This allows the integration test to run against built binaries (both `gaiad` and `gaiacli` are used) while being written in golang. This allows tests to take advantage of the various golang code we have for operations like marshal/unmarshal, crypto, etc...
> NOTE: The tests will use whatever `gaiad` or `gaiacli` binaries are available in your `$PATH`. You can check which binary will be run by the suite by running `which gaiad` or `which gaiacli`. If you have your `$GOPATH` properly setup they should be in `$GOPATH/bin/gaia*`. This will ensure that your test uses the latest binary you have built
Tests generally follow this structure:
```go
func TestMyNewCommand(t *testing.T) {
t.Parallel()
f := InitFixtures(t)
// start gaiad server
proc := f.GDStart()
defer proc.Stop(false)
// Your test code goes here...
f.Cleanup()
}
```
This boilerplate above:
- Ensures the tests run in parallel. Because the tests are calling out to `os/exec` for many operations these tests can take a long time to run.
- Creates `.gaiad` and `.gaiacli` folders in a new temp folder.
- Uses `gaiacli` to create 2 accounts for use in testing: `foo` and `bar`
- Creates a genesis file with coins (`1000footoken,1000feetoken,150stake`) controlled by the `foo` key
- Generates an initial bonding transaction (`gentx`) to make the `foo` key a validator at genesis
- Starts `gaiad` and stops it once the test exits
- Cleans up test state on a successful run
### Notes when adding/running tests
- Because the tests run against a built binary, you should make sure you build every time the code changes and you want to test again, otherwise you will be testing against an older version. If you are adding new tests this can easily lead to confusing test results.
- The [`test_helpers.go`](./test_helpers.go) file is organized according to the format of `gaiacli` and `gaiad` commands. There are comments with section headers describing the different areas. Helper functions to call CLI functionality are generally named after the command (e.g. `gaiacli query staking validator` would be `QueryStakingValidator`). Try to keep functions grouped by their position in the command tree.
- Test state that is needed by `tx` and `query` commands (`home`, `chain_id`, etc...) is stored on the `Fixtures` object. This makes constructing your new tests almost trivial.
- Sometimes if you exit a test early there can be still running `gaiad` and `gaiacli` processes that will interrupt subsequent runs. Still running `gaiacli` processes will block access to the keybase while still running `gaiad` processes will block ports and prevent new tests from spinning up. You can ensure new tests spin up clean by running `pkill -9 gaiad && pkill -9 gaiacli` before each test run.
- Most `query` and `tx` commands take a variadic `flags` argument. This pattern allows for the creation of a general function which is easily modified by adding flags. See the `TxSend` function and its use for a good example.
- `Tx*` functions follow a general pattern and return `(success bool, stdout string, stderr string)`. This allows for easy testing of multiple different flag configurations. See `TestGaiaCLICreateValidator` or `TestGaiaCLISubmitProposal` for a good example of the pattern.

1251
cli_test/cli_test.go Normal file

File diff suppressed because it is too large Load Diff

3
cli_test/doc.go Normal file
View File

@@ -0,0 +1,3 @@
package clitest
// package clitest runs integration tests which make use of CLI commands.

731
cli_test/test_helpers.go Normal file
View File

@@ -0,0 +1,731 @@
package clitest
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/cosmos/cosmos-sdk/client"
"github.com/stretchr/testify/require"
cmn "github.com/tendermint/tendermint/libs/common"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/gaia/app"
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
"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/distribution"
"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 {
BuildDir string
RootDir string
GaiadBinary string
GaiacliBinary string
ChainID string
RPCAddr string
Port string
GaiadHome string
GaiacliHome 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)
buildDir := os.Getenv("BUILDDIR")
if buildDir == "" {
buildDir, err = filepath.Abs("../../../build/")
require.NoError(t, err)
}
return &Fixtures{
T: t,
BuildDir: buildDir,
RootDir: tmpDir,
GaiadBinary: filepath.Join(buildDir, "gaiad"),
GaiacliBinary: filepath.Join(buildDir, "gaiacli"),
GaiadHome: filepath.Join(tmpDir, ".gaiad"),
GaiacliHome: 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.GaiadHome, "config", "genesis.json")
}
// GenesisFile returns the application's genesis state
func (f Fixtures) GenesisState() app.GenesisState {
cdc := codec.New()
genDoc, err := tmtypes.GenesisDocFromFile(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.RootDir)
for _, d := range clean {
require.NoError(f.T, os.RemoveAll(d))
}
}
// Flags returns the flags necessary for making most CLI calls
func (f *Fixtures) Flags() string {
return fmt.Sprintf("--home=%s --node=%s", f.GaiacliHome, f.RPCAddr)
}
//___________________________________________________________________________________
// gaiad
// UnsafeResetAll is gaiad unsafe-reset-all
func (f *Fixtures) UnsafeResetAll(flags ...string) {
cmd := fmt.Sprintf("%s --home=%s unsafe-reset-all", f.GaiadBinary, f.GaiadHome)
executeWrite(f.T, addFlags(cmd, flags))
err := os.RemoveAll(filepath.Join(f.GaiadHome, "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("%s init -o --home=%s %s", f.GaiadBinary, f.GaiadHome, moniker)
_, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), client.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("%s add-genesis-account %s %s --home=%s", f.GaiadBinary, address, coins, f.GaiadHome)
executeWriteCheckErr(f.T, addFlags(cmd, flags))
}
// GenTx is gaiad gentx
func (f *Fixtures) GenTx(name string, flags ...string) {
cmd := fmt.Sprintf("%s gentx --name=%s --home=%s --home-client=%s", f.GaiadBinary, name, f.GaiadHome, f.GaiacliHome)
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// CollectGenTxs is gaiad collect-gentxs
func (f *Fixtures) CollectGenTxs(flags ...string) {
cmd := fmt.Sprintf("%s collect-gentxs --home=%s", f.GaiadBinary, f.GaiadHome)
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// GDStart runs gaiad start with the appropriate flags and returns a process
func (f *Fixtures) GDStart(flags ...string) *tests.Process {
cmd := fmt.Sprintf("%s start --home=%s --rpc.laddr=%v --p2p.laddr=%v", f.GaiadBinary, f.GaiadHome, 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("%s tendermint %s --home=%s", f.GaiadBinary, query, f.GaiadHome)
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("%s validate-genesis --home=%s", f.GaiadBinary, f.GaiadHome)
executeWriteCheckErr(f.T, cmd)
}
//___________________________________________________________________________________
// gaiacli keys
// KeysDelete is gaiacli keys delete
func (f *Fixtures) KeysDelete(name string, flags ...string) {
cmd := fmt.Sprintf("%s keys delete --home=%s %s", f.GaiacliBinary, f.GaiacliHome, 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("%s keys add --home=%s %s", f.GaiacliBinary, f.GaiacliHome, name)
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// KeysAddRecover prepares gaiacli keys add --recover
func (f *Fixtures) KeysAddRecover(name, mnemonic string, flags ...string) (exitSuccess bool, stdout, stderr string) {
cmd := fmt.Sprintf("%s keys add --home=%s --recover %s", f.GaiacliBinary, f.GaiacliHome, name)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.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("%s keys add --home=%s --recover %s --account %d --index %d", f.GaiacliBinary, f.GaiacliHome, name, account, index)
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass, mnemonic)
}
// KeysShow is gaiacli keys show
func (f *Fixtures) KeysShow(name string, flags ...string) keys.KeyOutput {
cmd := fmt.Sprintf("%s keys show --home=%s %s", f.GaiacliBinary, f.GaiacliHome, 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("%s config --home=%s %s %s", f.GaiacliBinary, f.GaiacliHome, 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("%s tx send %s %s %s %v", f.GaiacliBinary, from, to, amount, f.Flags())
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
func (f *Fixtures) txSendWithConfirm(
from string, to sdk.AccAddress, amount sdk.Coin, confirm string, flags ...string,
) (bool, string, string) {
cmd := fmt.Sprintf("%s tx send %s %s %s %v", f.GaiacliBinary, from, to, amount, f.Flags())
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), confirm, client.DefaultKeyPass)
}
// TxSign is gaiacli tx sign
func (f *Fixtures) TxSign(signer, fileName string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx sign %v --from=%s %v", f.GaiacliBinary, f.Flags(), signer, fileName)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// TxBroadcast is gaiacli tx broadcast
func (f *Fixtures) TxBroadcast(fileName string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx broadcast %v %v", f.GaiacliBinary, f.Flags(), fileName)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// TxEncode is gaiacli tx encode
func (f *Fixtures) TxEncode(fileName string, flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx encode %v %v", f.GaiacliBinary, f.Flags(), fileName)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// TxMultisign is gaiacli tx multisign
func (f *Fixtures) TxMultisign(fileName, name string, signaturesFiles []string,
flags ...string) (bool, string, string) {
cmd := fmt.Sprintf("%s tx multisign %v %s %s %s", f.GaiacliBinary, 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("%s tx staking create-validator %v --from=%s --pubkey=%s", f.GaiacliBinary, 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), client.DefaultKeyPass)
}
// TxStakingUnbond is gaiacli tx staking unbond
func (f *Fixtures) TxStakingUnbond(from, shares string, validator sdk.ValAddress, flags ...string) bool {
cmd := fmt.Sprintf("%s tx staking unbond %s %v --from=%s %v", f.GaiacliBinary, validator, shares, from, f.Flags())
return executeWrite(f.T, addFlags(cmd, flags), client.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("%s tx gov submit-proposal %v --from=%s --type=%s", f.GaiacliBinary, f.Flags(), from, typ)
cmd += fmt.Sprintf(" --title=%s --description=%s --deposit=%s", title, description, deposit)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.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("%s tx gov deposit %d %s --from=%s %v", f.GaiacliBinary, proposalID, amount, from, f.Flags())
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.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("%s tx gov vote %d %s --from=%s %v", f.GaiacliBinary, proposalID, option, from, f.Flags())
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
// TxGovSubmitParamChangeProposal executes a CLI parameter change proposal
// submission.
func (f *Fixtures) TxGovSubmitParamChangeProposal(
from, proposalPath string, deposit sdk.Coin, flags ...string,
) (bool, string, string) {
cmd := fmt.Sprintf(
"%s tx gov submit-proposal param-change %s --from=%s %v",
f.GaiacliBinary, proposalPath, from, f.Flags(),
)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
//___________________________________________________________________________________
// gaiacli query account
// QueryAccount is gaiacli query account
func (f *Fixtures) QueryAccount(address sdk.AccAddress, flags ...string) auth.BaseAccount {
cmd := fmt.Sprintf("%s query account %s %v", f.GaiacliBinary, 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.SearchTxsResult {
cmd := fmt.Sprintf("%s query txs --page=%d --limit=%d --tags='%s' %v", f.GaiacliBinary, page, limit, queryTags(tags), f.Flags())
out, _ := tests.ExecuteT(f.T, cmd, "")
var result sdk.SearchTxsResult
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &result)
require.NoError(f.T, err, "out %v\n, err %v", out, err)
return &result
}
// QueryTxsInvalid query txs with wrong parameters and compare expected error
func (f *Fixtures) QueryTxsInvalid(expectedErr error, page, limit int, tags ...string) {
cmd := fmt.Sprintf("%s query txs --page=%d --limit=%d --tags='%s' %v", f.GaiacliBinary, 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("%s query staking validator %s %v", f.GaiacliBinary, 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("%s query staking unbonding-delegations-from %s %v", f.GaiacliBinary, 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("%s query staking delegations-to %s %v", f.GaiacliBinary, 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("%s query staking pool %v", f.GaiacliBinary, 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("%s query staking params %v", f.GaiacliBinary, f.Flags())
out, _ := tests.ExecuteT(f.T, addFlags(cmd, flags), "")
var params staking.Params
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &params)
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("%s query gov param deposit %s", f.GaiacliBinary, 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("%s query gov param voting %s", f.GaiacliBinary, 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("%s query gov param tallying %s", f.GaiacliBinary, 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("%s query gov proposals %v", f.GaiacliBinary, 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("%s query gov proposal %d %v", f.GaiacliBinary, 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("%s query gov vote %d %s %v", f.GaiacliBinary, 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("%s query gov votes %d %v", f.GaiacliBinary, 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("%s query gov deposit %d %s %v", f.GaiacliBinary, 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("%s query gov deposits %d %v", f.GaiacliBinary, 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("%s query slashing signing-info %s %s", f.GaiacliBinary, 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("%s query slashing params %s", f.GaiacliBinary, 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), &params)
require.NoError(f.T, err)
return params
}
//___________________________________________________________________________________
// query distribution
// QuerySigningInfo returns the signing info for a validator
func (f *Fixtures) QueryRewards(delAddr sdk.AccAddress, flags ...string) distribution.QueryDelegatorTotalRewardsResponse {
cmd := fmt.Sprintf("%s query distr rewards %s %s", f.GaiacliBinary, delAddr, f.Flags())
res, errStr := tests.ExecuteT(f.T, cmd, "")
require.Empty(f.T, errStr)
cdc := app.MakeCodec()
var rewards distribution.QueryDelegatorTotalRewardsResponse
err := cdc.UnmarshalJSON([]byte(res), &rewards)
require.NoError(f.T, err)
return rewards
}
//___________________________________________________________________________________
// 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
}