2020-09-15 02:43:46 -07:00
|
|
|
// +build norace
|
|
|
|
|
2020-07-27 10:57:15 -07:00
|
|
|
package grpc_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
2020-11-03 10:35:22 -08:00
|
|
|
"github.com/stretchr/testify/require"
|
2020-07-27 10:57:15 -07:00
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/metadata"
|
2020-07-28 02:20:17 -07:00
|
|
|
rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
|
|
|
|
|
2020-07-27 10:57:15 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/testutil/network"
|
|
|
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2020-08-12 07:42:10 -07:00
|
|
|
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
2020-11-30 08:59:35 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/types/tx"
|
|
|
|
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
2021-02-18 10:00:19 -08:00
|
|
|
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
2020-07-27 10:57:15 -07:00
|
|
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type IntegrationTestSuite struct {
|
|
|
|
suite.Suite
|
|
|
|
|
2020-12-02 09:50:40 -08:00
|
|
|
cfg network.Config
|
2020-07-27 10:57:15 -07:00
|
|
|
network *network.Network
|
2020-12-02 09:50:40 -08:00
|
|
|
conn *grpc.ClientConn
|
2020-07-27 10:57:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *IntegrationTestSuite) SetupSuite() {
|
|
|
|
s.T().Log("setting up integration test suite")
|
|
|
|
|
2020-12-02 09:50:40 -08:00
|
|
|
s.cfg = network.DefaultConfig()
|
2021-02-18 10:00:19 -08:00
|
|
|
s.cfg.NumValidators = 1
|
2020-12-02 09:50:40 -08:00
|
|
|
s.network = network.New(s.T(), s.cfg)
|
2020-07-27 10:57:15 -07:00
|
|
|
s.Require().NotNil(s.network)
|
|
|
|
|
|
|
|
_, err := s.network.WaitForHeight(2)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
val0 := s.network.Validators[0]
|
2020-12-02 09:50:40 -08:00
|
|
|
s.conn, err = grpc.Dial(
|
2020-07-27 10:57:15 -07:00
|
|
|
val0.AppConfig.GRPC.Address,
|
|
|
|
grpc.WithInsecure(), // Or else we get "no transport security set"
|
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
2020-12-02 09:50:40 -08:00
|
|
|
}
|
2020-07-27 10:57:15 -07:00
|
|
|
|
2020-12-02 09:50:40 -08:00
|
|
|
func (s *IntegrationTestSuite) TearDownSuite() {
|
|
|
|
s.T().Log("tearing down integration test suite")
|
|
|
|
s.conn.Close()
|
|
|
|
s.network.Cleanup()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *IntegrationTestSuite) TestGRPCServer_TestService() {
|
2020-07-27 10:57:15 -07:00
|
|
|
// gRPC query to test service should work
|
2020-12-02 09:50:40 -08:00
|
|
|
testClient := testdata.NewQueryClient(s.conn)
|
2020-07-27 10:57:15 -07:00
|
|
|
testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal("hello", testRes.Message)
|
2020-12-02 09:50:40 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *IntegrationTestSuite) TestGRPCServer_BankBalance() {
|
|
|
|
val0 := s.network.Validators[0]
|
2020-07-27 10:57:15 -07:00
|
|
|
|
|
|
|
// gRPC query to bank service should work
|
|
|
|
denom := fmt.Sprintf("%stoken", val0.Moniker)
|
2020-12-02 09:50:40 -08:00
|
|
|
bankClient := banktypes.NewQueryClient(s.conn)
|
2020-07-27 10:57:15 -07:00
|
|
|
var header metadata.MD
|
|
|
|
bankRes, err := bankClient.Balance(
|
|
|
|
context.Background(),
|
2020-09-25 03:25:37 -07:00
|
|
|
&banktypes.QueryBalanceRequest{Address: val0.Address.String(), Denom: denom},
|
2020-07-27 10:57:15 -07:00
|
|
|
grpc.Header(&header), // Also fetch grpc header
|
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(
|
|
|
|
sdk.NewCoin(denom, s.network.Config.AccountTokens),
|
|
|
|
*bankRes.GetBalance(),
|
|
|
|
)
|
2020-08-12 07:42:10 -07:00
|
|
|
blockHeight := header.Get(grpctypes.GRPCBlockHeightHeader)
|
2020-08-05 08:45:22 -07:00
|
|
|
s.Require().NotEmpty(blockHeight[0]) // Should contain the block height
|
2020-07-27 10:57:15 -07:00
|
|
|
|
|
|
|
// Request metadata should work
|
|
|
|
bankRes, err = bankClient.Balance(
|
2020-08-12 07:42:10 -07:00
|
|
|
metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, "1"), // Add metadata to request
|
2020-09-25 03:25:37 -07:00
|
|
|
&banktypes.QueryBalanceRequest{Address: val0.Address.String(), Denom: denom},
|
2020-07-27 10:57:15 -07:00
|
|
|
grpc.Header(&header),
|
|
|
|
)
|
2020-08-12 07:42:10 -07:00
|
|
|
blockHeight = header.Get(grpctypes.GRPCBlockHeightHeader)
|
2021-02-15 02:01:44 -08:00
|
|
|
s.Require().NotEmpty(blockHeight[0]) // blockHeight is []string, first element is block height.
|
2020-12-02 09:50:40 -08:00
|
|
|
}
|
2020-07-27 10:57:15 -07:00
|
|
|
|
2020-12-02 09:50:40 -08:00
|
|
|
func (s *IntegrationTestSuite) TestGRPCServer_Reflection() {
|
2020-07-27 10:57:15 -07:00
|
|
|
// Test server reflection
|
2020-12-02 09:50:40 -08:00
|
|
|
reflectClient := rpb.NewServerReflectionClient(s.conn)
|
2020-07-27 10:57:15 -07:00
|
|
|
stream, err := reflectClient.ServerReflectionInfo(context.Background(), grpc.WaitForReady(true))
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().NoError(stream.Send(&rpb.ServerReflectionRequest{
|
|
|
|
MessageRequest: &rpb.ServerReflectionRequest_ListServices{},
|
|
|
|
}))
|
|
|
|
res, err := stream.Recv()
|
|
|
|
s.Require().NoError(err)
|
|
|
|
services := res.GetListServicesResponse().Service
|
|
|
|
servicesMap := make(map[string]bool)
|
|
|
|
for _, s := range services {
|
|
|
|
servicesMap[s.Name] = true
|
|
|
|
}
|
|
|
|
// Make sure the following services are present
|
2020-08-11 04:49:45 -07:00
|
|
|
s.Require().True(servicesMap["cosmos.bank.v1beta1.Query"])
|
2020-12-02 09:50:40 -08:00
|
|
|
}
|
2020-11-30 08:59:35 -08:00
|
|
|
|
2020-12-02 09:50:40 -08:00
|
|
|
func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() {
|
2020-11-30 08:59:35 -08:00
|
|
|
// Query the tx via gRPC without pagination. This used to panic, see
|
|
|
|
// https://github.com/cosmos/cosmos-sdk/issues/8038.
|
2020-12-02 09:50:40 -08:00
|
|
|
txServiceClient := txtypes.NewServiceClient(s.conn)
|
|
|
|
_, err := txServiceClient.GetTxsEvent(
|
2020-11-30 08:59:35 -08:00
|
|
|
context.Background(),
|
|
|
|
&tx.GetTxsEventRequest{
|
2021-03-01 07:57:28 -08:00
|
|
|
Events: []string{"message.action='send'"},
|
2020-11-30 08:59:35 -08:00
|
|
|
},
|
|
|
|
)
|
2020-11-30 20:18:35 -08:00
|
|
|
s.Require().NoError(err)
|
2020-07-27 10:57:15 -07:00
|
|
|
}
|
|
|
|
|
2020-12-02 09:50:40 -08:00
|
|
|
func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() {
|
|
|
|
val0 := s.network.Validators[0]
|
|
|
|
|
2021-02-18 10:00:19 -08:00
|
|
|
grpcRes, err := banktestutil.LegacyGRPCProtoMsgSend(val0.ClientCtx,
|
|
|
|
val0.Moniker, val0.Address, val0.Address,
|
|
|
|
sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}, sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)},
|
2020-12-02 09:50:40 -08:00
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(uint32(0), grpcRes.TxResponse.Code)
|
|
|
|
}
|
|
|
|
|
2020-11-03 10:35:22 -08:00
|
|
|
// Test and enforce that we upfront reject any connections to baseapp containing
|
|
|
|
// invalid initial x-cosmos-block-height that aren't positive and in the range [0, max(int64)]
|
|
|
|
// See issue https://github.com/cosmos/cosmos-sdk/issues/7662.
|
|
|
|
func (s *IntegrationTestSuite) TestGRPCServerInvalidHeaderHeights() {
|
|
|
|
t := s.T()
|
|
|
|
val0 := s.network.Validators[0]
|
|
|
|
|
|
|
|
// We should reject connections with invalid block heights off the bat.
|
|
|
|
invalidHeightStrs := []struct {
|
|
|
|
value string
|
|
|
|
wantErr string
|
|
|
|
}{
|
2021-02-15 02:01:44 -08:00
|
|
|
{"-1", "\"x-cosmos-block-height\" must be >= 0"},
|
2020-11-03 10:35:22 -08:00
|
|
|
{"9223372036854775808", "value out of range"}, // > max(int64) by 1
|
2021-02-15 02:01:44 -08:00
|
|
|
{"-10", "\"x-cosmos-block-height\" must be >= 0"},
|
2020-11-03 10:35:22 -08:00
|
|
|
{"18446744073709551615", "value out of range"}, // max uint64, which is > max(int64)
|
|
|
|
{"-9223372036854775809", "value out of range"}, // Out of the range of for negative int64
|
|
|
|
}
|
|
|
|
for _, tt := range invalidHeightStrs {
|
|
|
|
t.Run(tt.value, func(t *testing.T) {
|
|
|
|
conn, err := grpc.Dial(
|
|
|
|
val0.AppConfig.GRPC.Address,
|
|
|
|
grpc.WithInsecure(), // Or else we get "no transport security set"
|
|
|
|
)
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
testClient := testdata.NewQueryClient(conn)
|
|
|
|
ctx := metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, tt.value)
|
|
|
|
testRes, err := testClient.Echo(ctx, &testdata.EchoRequest{Message: "hello"})
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Nil(t, testRes)
|
|
|
|
require.Contains(t, err.Error(), tt.wantErr)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-27 10:57:15 -07:00
|
|
|
func TestIntegrationTestSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(IntegrationTestSuite))
|
|
|
|
}
|