From 40544307556b5385b8c5ce7bd6fefbfb9c726517 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Thu, 20 Feb 2025 18:14:44 +0100 Subject: [PATCH] test: fix ica compatibility tests (#7976) * test: fix ica compatibility tests * lint * fix event search * lint (cherry picked from commit 22efa6c014bc6a7b502cb1284606d90f2a91c802) --- .github/workflows/e2e-compatibility.yaml | 18 ---- e2e/tests/interchain_accounts/params_test.go | 7 +- e2e/tests/interchain_accounts/query_test.go | 16 ++-- e2e/testsuite/query/grpc_query.go | 94 +++++++++++--------- e2e/testsuite/testsuite.go | 5 ++ e2e/testsuite/tx.go | 36 +++----- 6 files changed, 75 insertions(+), 101 deletions(-) diff --git a/.github/workflows/e2e-compatibility.yaml b/.github/workflows/e2e-compatibility.yaml index f93c57f8254..0df9efd471d 100644 --- a/.github/workflows/e2e-compatibility.yaml +++ b/.github/workflows/e2e-compatibility.yaml @@ -236,24 +236,6 @@ jobs: test-file: "e2e/tests/transfer/send_receive_test.go" release-version: "${{ needs.determine-image-tag.outputs.release-version }}" - transfer-upgrades-v1-test: - needs: - - build-release-images - - determine-image-tag - uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml - with: - test-file: "e2e/tests/transfer/upgradesv1_test.go" - release-version: "${{ needs.determine-image-tag.outputs.release-version }}" - - transfer-upgrades-v2-test: - needs: - - build-release-images - - determine-image-tag - uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml - with: - test-file: "e2e/tests/transfer/upgradesv2_test.go" - release-version: "${{ needs.determine-image-tag.outputs.release-version }}" - upgrade-genesis-test: needs: - build-release-images diff --git a/e2e/tests/interchain_accounts/params_test.go b/e2e/tests/interchain_accounts/params_test.go index 2477f146661..7ff388b09d1 100644 --- a/e2e/tests/interchain_accounts/params_test.go +++ b/e2e/tests/interchain_accounts/params_test.go @@ -252,16 +252,13 @@ func (s *InterchainAccountsParamsTestSuite) TestHostEnabledParam() { }) t.Run("verify acknowledgement error in ack transaction", func(t *testing.T) { - cmd := "message.action=/ibc.core.channel.v1.MsgRecvPacket" - if testvalues.TransactionEventQueryFeatureReleases.IsSupported(chainBVersion) { - cmd = "message.action='/ibc.core.channel.v1.MsgRecvPacket'" - } + cmd := "message.action='/ibc.core.channel.v1.MsgRecvPacket'" txSearchRes, err := s.QueryTxsByEvents(ctx, chainB, 1, 1, cmd, "") s.Require().NoError(err) s.Require().Len(txSearchRes.Txs, 1) errorMessage, isFound := s.ExtractValueFromEvents( - txSearchRes.Txs[0].Events, + txSearchRes.TxResponses[0].Events, coretypes.ErrorAttributeKeyPrefix+icatypes.EventTypePacket, coretypes.ErrorAttributeKeyPrefix+icatypes.AttributeKeyAckError, ) diff --git a/e2e/tests/interchain_accounts/query_test.go b/e2e/tests/interchain_accounts/query_test.go index 7839bfeff7b..0a748f7000c 100644 --- a/e2e/tests/interchain_accounts/query_test.go +++ b/e2e/tests/interchain_accounts/query_test.go @@ -35,7 +35,7 @@ type InterchainAccountsQueryTestSuite struct { testsuite.E2ETestSuite } -// compatibility:InterchainAccountsQueryTestSuite:from_versions: v7.5.0,v7.6.0,v7.7.0,v7.8.0,v8.4.0,v8.5.0,v10.0.0 +// compatibility:TestInterchainAccountsQuery:from_versions: v7.5.0,v7.6.0,v7.7.0,v7.8.0,v8.4.0,v8.5.0,v10.0.0 func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { t := s.T() ctx := context.TODO() @@ -44,7 +44,6 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { relayer := s.CreateDefaultPaths(testName) chainA, chainB := s.GetChains() - chainBVersion := chainB.Config().Images[0].Version // setup 2 accounts: controller account on chain A, a second chain B account. // host account will be created when the ICA is registered @@ -106,7 +105,7 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { txResp := s.BroadcastMessages(ctx, chainA, controllerAccount, icaQueryMsg) s.AssertTxSuccess(txResp) - s.Require().NoError(testutil.WaitForBlocks(ctx, 10, chainA, chainB)) + s.Require().NoError(testutil.WaitForBlocks(ctx, 20, chainA, chainB)) }) t.Run("verify query response", func(t *testing.T) { @@ -114,18 +113,15 @@ func (s *InterchainAccountsQueryTestSuite) TestInterchainAccountsQuery() { ack := &channeltypes.Acknowledgement_Result{} t.Run("retrieve acknowledgement", func(t *testing.T) { - cmd := "message.action=/ibc.core.channel.v1.MsgRecvPacket" - if testvalues.TransactionEventQueryFeatureReleases.IsSupported(chainBVersion) { - cmd = "message.action='/ibc.core.channel.v1.MsgRecvPacket'" - } + cmd := "message.action='/ibc.core.channel.v1.MsgRecvPacket'" txSearchRes, err := s.QueryTxsByEvents(ctx, chainB, 1, 1, cmd, "") s.Require().NoError(err) - s.Require().Len(txSearchRes.Txs, 1) + s.Require().Len(txSearchRes.TxResponses, 1) - expQueryHeight = uint64(txSearchRes.Txs[0].Height) + expQueryHeight = uint64(txSearchRes.TxResponses[0].Height) ackHexValue, isFound := s.ExtractValueFromEvents( - txSearchRes.Txs[0].Events, + txSearchRes.TxResponses[0].Events, channeltypes.EventTypeWriteAck, channeltypes.AttributeKeyAckHex, ) diff --git a/e2e/testsuite/query/grpc_query.go b/e2e/testsuite/query/grpc_query.go index 4e64c206fff..46164a7286c 100644 --- a/e2e/testsuite/query/grpc_query.go +++ b/e2e/testsuite/query/grpc_query.go @@ -3,19 +3,49 @@ package query import ( "context" "fmt" - "strings" "github.com/cosmos/gogoproto/proto" "github.com/strangelove-ventures/interchaintest/v8/ibc" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + pb "google.golang.org/protobuf/proto" + + msgv1 "cosmossdk.io/api/cosmos/msg/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" ) +var queryReqToPath = make(map[string]string) + +func PopulateQueryReqToPath(ctx context.Context, chain ibc.Chain) error { + resp, err := queryFileDescriptors(ctx, chain) + if err != nil { + return err + } + + for _, fileDescriptor := range resp.Files { + for _, service := range fileDescriptor.GetService() { + // Skip services that are annotated with the "cosmos.msg.v1.service" option. + if ext := pb.GetExtension(service.GetOptions(), msgv1.E_Service); ext != nil { + if ok, extBool := ext.(bool); ok && extBool { + continue + } + } + + for _, method := range service.GetMethod() { + // trim the first character from input which is a dot + queryReqToPath[method.GetInputType()[1:]] = fileDescriptor.GetPackage() + "." + service.GetName() + "/" + method.GetName() + } + } + } + + return nil +} + // GRPCQuery queries the chain with a query request and deserializes the response to T func GRPCQuery[T any](ctx context.Context, chain ibc.Chain, req proto.Message, opts ...grpc.CallOption) (*T, error) { - path, err := getProtoPath(req) - if err != nil { - return nil, err + path, ok := queryReqToPath[proto.MessageName(req)] + if !ok { + return nil, fmt.Errorf("no path found for %s", proto.MessageName(req)) } return grpcQueryWithMethod[T](ctx, chain, req, path, opts...) @@ -43,48 +73,26 @@ func grpcQueryWithMethod[T any](ctx context.Context, chain ibc.Chain, req proto. return resp, nil } -func getProtoPath(req proto.Message) (string, error) { - typeURL := "/" + proto.MessageName(req) - - switch { - case strings.Contains(typeURL, "Query"): - return getQueryProtoPath(typeURL) - case strings.Contains(typeURL, "cosmos.base.tendermint"): - return getCmtProtoPath(typeURL) - default: - return "", fmt.Errorf("unsupported typeURL: %s", typeURL) - } -} - -func getQueryProtoPath(queryTypeURL string) (string, error) { - queryIndex := strings.Index(queryTypeURL, "Query") - if queryIndex == -1 { - return "", fmt.Errorf("invalid typeURL: %s", queryTypeURL) - } - - // Add to the index to account for the length of "Query" - queryIndex += len("Query") - - // Add a slash before the query - urlWithSlash := queryTypeURL[:queryIndex] + "/" + queryTypeURL[queryIndex:] - if !strings.HasSuffix(urlWithSlash, "Request") { - return "", fmt.Errorf("invalid typeURL: %s", queryTypeURL) +func queryFileDescriptors(ctx context.Context, chain ibc.Chain) (*reflectionv1.FileDescriptorsResponse, error) { + // Create a connection to the gRPC server. + grpcConn, err := grpc.Dial( + chain.GetHostGRPCAddress(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + return nil, err } - return strings.TrimSuffix(urlWithSlash, "Request"), nil -} - -func getCmtProtoPath(cmtTypeURL string) (string, error) { - cmtIndex := strings.Index(cmtTypeURL, "Get") - if cmtIndex == -1 { - return "", fmt.Errorf("invalid typeURL: %s", cmtTypeURL) - } + defer grpcConn.Close() - // Add a slash before the commitment - urlWithSlash := cmtTypeURL[:cmtIndex] + "Service/" + cmtTypeURL[cmtIndex:] - if !strings.HasSuffix(urlWithSlash, "Request") { - return "", fmt.Errorf("invalid typeURL: %s", cmtTypeURL) + resp := new(reflectionv1.FileDescriptorsResponse) + err = grpcConn.Invoke( + ctx, reflectionv1.ReflectionService_FileDescriptors_FullMethodName, + &reflectionv1.FileDescriptorsRequest{}, resp, + ) + if err != nil { + return nil, err } - return strings.TrimSuffix(urlWithSlash, "Request"), nil + return resp, nil } diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index c24c96f3ed9..4d58fc883ec 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -192,6 +192,11 @@ func (s *E2ETestSuite) SetupChains(ctx context.Context, channelOptionsModifier C } s.Require().NoError(ic.Build(ctx, s.GetRelayerExecReporter(), buildOpts)) + + // setup query paths for GRPC queries: + for _, chain := range s.chains { + s.Require().NoError(query.PopulateQueryReqToPath(ctx, chain)) + } } // CreateDefaultPaths creates a path between the chains using the default client and channel options. diff --git a/e2e/testsuite/tx.go b/e2e/testsuite/tx.go index 2493728b1ad..f03e97bb89e 100644 --- a/e2e/testsuite/tx.go +++ b/e2e/testsuite/tx.go @@ -17,9 +17,9 @@ import ( sdkmath "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" @@ -309,43 +309,29 @@ func (s *E2ETestSuite) PruneAcknowledgements( func (*E2ETestSuite) QueryTxsByEvents( ctx context.Context, chain ibc.Chain, page, limit int, queryReq, orderBy string, -) (*sdk.SearchTxsResult, error) { +) (*txtypes.GetTxsEventResponse, error) { cosmosChain, ok := chain.(*cosmos.CosmosChain) if !ok { return nil, errors.New("QueryTxsByEvents must be passed a cosmos.CosmosChain") } - cmd := []string{"txs"} - - chainVersion := chain.Config().Images[0].Version - if testvalues.TransactionEventQueryFeatureReleases.IsSupported(chainVersion) { - cmd = append(cmd, "--query", queryReq) - } else { - cmd = append(cmd, "--events", queryReq) - } - - if orderBy != "" { - cmd = append(cmd, "--order_by", orderBy) - } - if page != 0 { - cmd = append(cmd, "--"+flags.FlagPage, strconv.Itoa(page)) - } - if limit != 0 { - cmd = append(cmd, "--"+flags.FlagLimit, strconv.Itoa(limit)) + req := &txtypes.GetTxsEventRequest{ + Page: uint64(page), + Limit: uint64(limit), + Query: queryReq, } - stdout, _, err := cosmosChain.GetNode().ExecQuery(ctx, cmd...) - if err != nil { - return nil, err + if !testvalues.TransactionEventQueryFeatureReleases.IsSupported(chain.Config().Images[0].Version) { + req.Events = []string{queryReq} + req.Query = "" } - result := &sdk.SearchTxsResult{} - err = Codec().UnmarshalJSON(stdout, result) + res, err := query.GRPCQuery[txtypes.GetTxsEventResponse](ctx, cosmosChain, req) if err != nil { return nil, err } - return result, nil + return res, nil } // ExtractValueFromEvents extracts the value of an attribute from a list of events.