Skip to content

Commit

Permalink
Add cli test for query Account (#6973)
Browse files Browse the repository at this point in the history
Closes: #7007

Ref: #6571

Co-authored-by: Aaron Craelius <aaron@regen.network>
Co-authored-by: Alessio Treglia <alessio@tendermint.com>
  • Loading branch information
3 people committed Aug 17, 2020
1 parent 23cabc0 commit 77124da
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 296 deletions.
24 changes: 23 additions & 1 deletion baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/gogo/protobuf/proto"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/telemetry"
Expand Down Expand Up @@ -358,14 +360,34 @@ func (app *BaseApp) handleQueryGRPC(handler GRPCQueryHandler, req abci.RequestQu

res, err := handler(ctx, req)
if err != nil {
res = sdkerrors.QueryResult(err)
res = sdkerrors.QueryResult(gRPCErrorToSDKError(err))
res.Height = req.Height
return res
}

return res
}

func gRPCErrorToSDKError(err error) error {
status, ok := grpcstatus.FromError(err)
if !ok {
return err
}

switch status.Code() {
case codes.NotFound:
return sdkerrors.Wrap(sdkerrors.ErrKeyNotFound, err.Error())
case codes.InvalidArgument:
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
case codes.FailedPrecondition:
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
case codes.Unauthenticated:
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, err.Error())
default:
return sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, err.Error())
}
}

// createQueryContext creates a new sdk.Context for a query, taking as args
// the block height and whether the query needs a proof or not.
func (app *BaseApp) createQueryContext(height int64, prove bool) (sdk.Context, error) {
Expand Down
39 changes: 20 additions & 19 deletions testutil/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,24 @@ type Config struct {
Codec codec.Marshaler
LegacyAmino *codec.LegacyAmino // TODO: Remove!
InterfaceRegistry codectypes.InterfaceRegistry
TxConfig client.TxConfig
AccountRetriever client.AccountRetriever
AppConstructor AppConstructor // the ABCI application constructor
GenesisState map[string]json.RawMessage // custom gensis state to provide
TimeoutCommit time.Duration // the consensus commitment timeout
ChainID string // the network chain-id
NumValidators int // the total number of validators to create and bond
BondDenom string // the staking bond denomination
MinGasPrices string // the minimum gas prices each validator will accept
AccountTokens sdk.Int // the amount of unique validator tokens (e.g. 1000node0)
StakingTokens sdk.Int // the amount of tokens each validator has available to stake
BondedTokens sdk.Int // the amount of tokens each validator stakes
PruningStrategy string // the pruning strategy each validator will have
EnableLogging bool // enable Tendermint logging to STDOUT
CleanupDir bool // remove base temporary directory during cleanup
SigningAlgo string // signing algorithm for keys
KeyringOptions []keyring.Option

TxConfig client.TxConfig
AccountRetriever client.AccountRetriever
AppConstructor AppConstructor // the ABCI application constructor
GenesisState map[string]json.RawMessage // custom gensis state to provide
TimeoutCommit time.Duration // the consensus commitment timeout
ChainID string // the network chain-id
NumValidators int // the total number of validators to create and bond
BondDenom string // the staking bond denomination
MinGasPrices string // the minimum gas prices each validator will accept
AccountTokens sdk.Int // the amount of unique validator tokens (e.g. 1000node0)
StakingTokens sdk.Int // the amount of tokens each validator has available to stake
BondedTokens sdk.Int // the amount of tokens each validator stakes
PruningStrategy string // the pruning strategy each validator will have
EnableLogging bool // enable Tendermint logging to STDOUT
CleanupDir bool // remove base temporary directory during cleanup
SigningAlgo string // signing algorithm for keys
KeyringOptions []keyring.Option
}

// DefaultConfig returns a sane default configuration suitable for nearly all
Expand Down Expand Up @@ -324,11 +325,11 @@ func New(t *testing.T, cfg Config) *Network {
WithKeyring(kb).
WithHomeDir(tmCfg.RootDir).
WithChainID(cfg.ChainID).
WithInterfaceRegistry(cfg.InterfaceRegistry).
WithJSONMarshaler(cfg.Codec).
WithLegacyAmino(cfg.LegacyAmino).
WithTxConfig(cfg.TxConfig).
WithAccountRetriever(cfg.AccountRetriever).
WithInterfaceRegistry(cfg.InterfaceRegistry)
WithAccountRetriever(cfg.AccountRetriever)

network.Validators[i] = &Validator{
AppConfig: appCfg,
Expand Down
64 changes: 57 additions & 7 deletions x/auth/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import (
"strings"
"testing"

"github.com/cosmos/cosmos-sdk/codec/types"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
tmcrypto "github.com/tendermint/tendermint/crypto"
tmcli "github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
Expand All @@ -20,10 +23,13 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
Expand Down Expand Up @@ -211,7 +217,7 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() {
s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1)
s.Require().Equal(0, len(txBuilder.GetTx().GetSignatures()))

resp, err := bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), val1.Address)
resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address)
s.Require().NoError(err)

var balRes banktypes.QueryAllBalancesResponse
Expand Down Expand Up @@ -281,7 +287,7 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() {
s.Require().True(strings.Contains(res.String(), "[OK]"))

// Ensure foo has right amount of funds
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), val1.Address)
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address)
s.Require().NoError(err)

err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &balRes)
Expand All @@ -304,15 +310,15 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() {
s.Require().NoError(s.network.WaitForNextBlock())

// Ensure destiny account state
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), account.GetAddress())
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, account.GetAddress())
s.Require().NoError(err)

err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &balRes)
s.Require().NoError(err)
s.Require().Equal(sendTokens.Amount, balRes.Balances.AmountOf(s.cfg.BondDenom))

// Ensure origin account state
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), val1.Address)
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address)
s.Require().NoError(err)

err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &balRes)
Expand Down Expand Up @@ -448,7 +454,7 @@ func (s *IntegrationTestSuite) TestCLIMultisignSortSignatures() {
multisigInfo, err := val1.ClientCtx.Keyring.Key("multi")
s.Require().NoError(err)

resp, err := bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), multisigInfo.GetAddress())
resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, multisigInfo.GetAddress())
s.Require().NoError(err)

var balRes banktypes.QueryAllBalancesResponse
Expand All @@ -472,7 +478,7 @@ func (s *IntegrationTestSuite) TestCLIMultisignSortSignatures() {

s.Require().NoError(s.network.WaitForNextBlock())

resp, err = bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), multisigInfo.GetAddress())
resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, multisigInfo.GetAddress())
s.Require().NoError(err)

err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &balRes)
Expand Down Expand Up @@ -564,7 +570,7 @@ func (s *IntegrationTestSuite) TestCLIMultisign() {

s.Require().NoError(s.network.WaitForNextBlock())

resp, err := bankcli.QueryBalancesExec(val1.ClientCtx.WithOutputFormat("json"), multisigInfo.GetAddress())
resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, multisigInfo.GetAddress())
s.Require().NoError(err)

var balRes banktypes.QueryAllBalancesResponse
Expand Down Expand Up @@ -628,6 +634,50 @@ func (s *IntegrationTestSuite) TestCLIMultisign() {
s.Require().NoError(s.network.WaitForNextBlock())
}

func (s *IntegrationTestSuite) TestGetAccountCmd() {
val := s.network.Validators[0]
_, _, addr1 := testdata.KeyTestPubAddr()

testCases := []struct {
name string
args []string
expectErr bool
}{
{
"invalid address",
[]string{addr1.String(),
fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
true,
},
{
"valid address",
[]string{val.Address.String(),
fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
false,
},
}

for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := authcli.GetAccountCmd()
clientCtx := val.ClientCtx

out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
s.Require().NotEqual("internal", err.Error())
} else {
var any types.Any
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &any))
var acc authtypes.AccountI
s.Require().NoError(val.ClientCtx.InterfaceRegistry.UnpackAny(&any, &acc))
s.Require().Equal(val.Address, acc.GetAddress())
}
})
}
}

func TestGetBroadcastCommand_OfflineFlag(t *testing.T) {
clientCtx := client.Context{}.WithOffline(true)
clientCtx = clientCtx.WithTxConfig(simapp.MakeEncodingConfig().TxConfig)
Expand Down
22 changes: 2 additions & 20 deletions x/auth/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package keeper

import (
"context"
"fmt"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

proto "github.com/gogo/protobuf/proto"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/types"
Expand All @@ -32,12 +29,12 @@ func (ak AccountKeeper) Account(c context.Context, req *types.QueryAccountReques
return nil, status.Errorf(codes.NotFound, "account %s not found", req.Address)
}

acc, err := ConvertAccount(account)
any, err := codectypes.NewAnyWithValue(account)
if err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}

return &types.QueryAccountResponse{Account: acc}, nil
return &types.QueryAccountResponse{Account: any}, nil
}

// Params returns parameters of auth module
Expand All @@ -50,18 +47,3 @@ func (ak AccountKeeper) Params(c context.Context, req *types.QueryParamsRequest)

return &types.QueryParamsResponse{Params: params}, nil
}

// ConvertAccount converts AccountI to Any type
func ConvertAccount(account types.AccountI) (*codectypes.Any, error) {
msg, ok := account.(proto.Message)
if !ok {
return nil, fmt.Errorf("can't protomarshal %T", msg)
}

any, err := codectypes.NewAnyWithValue(msg)
if err != nil {
return nil, err
}

return any, nil
}
4 changes: 4 additions & 0 deletions x/auth/types/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"fmt"
"strings"

"github.com/gogo/protobuf/proto"

"github.com/tendermint/tendermint/crypto"
yaml "gopkg.in/yaml.v2"

Expand Down Expand Up @@ -292,6 +294,8 @@ func (ma *ModuleAccount) UnmarshalJSON(bz []byte) error {
//
// Many complex conditions can be used in the concrete struct which implements AccountI.
type AccountI interface {
proto.Message

GetAddress() sdk.AccAddress
SetAddress(sdk.AccAddress) error // errors if already set.

Expand Down
10 changes: 10 additions & 0 deletions x/auth/types/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package types

import codectypes "github.com/cosmos/cosmos-sdk/codec/types"

func (m *QueryAccountResponse) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
var account AccountI
return unpacker.UnpackAny(m.Account, &account)
}

var _ codectypes.UnpackInterfacesMessage = &QueryAccountResponse{}
33 changes: 7 additions & 26 deletions x/bank/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"fmt"
"testing"

"github.com/cosmos/cosmos-sdk/client"

"github.com/gogo/protobuf/proto"

"github.com/stretchr/testify/suite"
tmcli "github.com/tendermint/tendermint/libs/cli"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -101,22 +102,13 @@ func (s *IntegrationTestSuite) TestGetBalancesCmd() {

s.Run(tc.name, func() {
cmd := cli.GetBalancesCmd()
_, out := testutil.ApplyMockIO(cmd)

clientCtx := val.ClientCtx.WithOutput(out)

ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)

out.Reset()
cmd.SetArgs(tc.args)
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, tc.args)

err := cmd.ExecuteContext(ctx)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType))
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), tc.respType))
s.Require().Equal(tc.expected.String(), tc.respType.String())
}
})
Expand Down Expand Up @@ -173,17 +165,9 @@ func (s *IntegrationTestSuite) TestGetCmdQueryTotalSupply() {

s.Run(tc.name, func() {
cmd := cli.GetCmdQueryTotalSupply()
_, out := testutil.ApplyMockIO(cmd)

clientCtx := val.ClientCtx.WithOutput(out)

ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)

out.Reset()
cmd.SetArgs(tc.args)
clientCtx := val.ClientCtx

err := cmd.ExecuteContext(ctx)
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
Expand Down Expand Up @@ -295,9 +279,6 @@ func (s *IntegrationTestSuite) TestNewSendTxCmd() {
s.Run(tc.name, func() {
clientCtx := val.ClientCtx

ctx := context.Background()
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)

bz, err := banktestutil.MsgSendExec(clientCtx, tc.from, tc.to, tc.amount, tc.args...)
if tc.expectErr {
s.Require().Error(err)
Expand Down

0 comments on commit 77124da

Please sign in to comment.