github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/conn/conn_test.go (about)

     1  package conn
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Discovery_V1"
    10  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Query_V1"
    11  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
    12  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Discovery"
    13  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Operations"
    14  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Query"
    15  	"go.uber.org/mock/gomock"
    16  	"google.golang.org/grpc"
    17  	grpcCodes "google.golang.org/grpc/codes"
    18  	grpcStatus "google.golang.org/grpc/status"
    19  
    20  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    21  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest"
    22  )
    23  
    24  //go:generate mockgen -destination grpc_client_conn_interface_mock_test.go --typed -package conn -write_package_comment=false google.golang.org/grpc ClientConnInterface
    25  
    26  var _ grpc.ClientConnInterface = (*connMock)(nil)
    27  
    28  type connMock struct {
    29  	cc grpc.ClientConnInterface
    30  }
    31  
    32  func (c connMock) Invoke(ctx context.Context, method string, args any, reply any, opts ...grpc.CallOption) error {
    33  	_, _, err := invoke(ctx, method, args, reply, c.cc, nil, "", 0, opts...)
    34  
    35  	return err
    36  }
    37  
    38  func (c connMock) NewStream(
    39  	ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption,
    40  ) (grpc.ClientStream, error) {
    41  	return c.cc.NewStream(ctx, desc, method, opts...)
    42  }
    43  
    44  func TestConn(t *testing.T) {
    45  	t.Run("Invoke", func(t *testing.T) {
    46  		t.Run("HappyWay", func(t *testing.T) {
    47  			ctx := xtest.Context(t)
    48  			ctrl := gomock.NewController(t)
    49  			cc := NewMockClientConnInterface(ctrl)
    50  			cc.EXPECT().Invoke(
    51  				gomock.Any(),
    52  				Ydb_Discovery_V1.DiscoveryService_WhoAmI_FullMethodName,
    53  				&Ydb_Discovery.WhoAmIRequest{},
    54  				&Ydb_Discovery.WhoAmIResponse{},
    55  			).DoAndReturn(func(ctx context.Context, method string, args any, reply any, opts ...grpc.CallOption) error {
    56  				res, ok := reply.(*Ydb_Discovery.WhoAmIResponse)
    57  				if !ok {
    58  					return fmt.Errorf("reply is not *Ydb_Discovery.WhoAmIResponse: %T", reply)
    59  				}
    60  
    61  				res.Operation = &Ydb_Operations.Operation{
    62  					Ready:  true,
    63  					Status: Ydb.StatusIds_SUCCESS,
    64  				}
    65  
    66  				return nil
    67  			})
    68  			client := Ydb_Discovery_V1.NewDiscoveryServiceClient(&connMock{
    69  				cc,
    70  			})
    71  			response, err := client.WhoAmI(ctx, &Ydb_Discovery.WhoAmIRequest{})
    72  			require.NoError(t, err)
    73  			require.NotNil(t, response)
    74  		})
    75  		t.Run("TransportError", func(t *testing.T) {
    76  			ctx := xtest.Context(t)
    77  			ctrl := gomock.NewController(t)
    78  			cc := NewMockClientConnInterface(ctrl)
    79  			expectedErr := grpcStatus.Error(grpcCodes.Unavailable, "")
    80  			cc.EXPECT().Invoke(
    81  				gomock.Any(),
    82  				Ydb_Discovery_V1.DiscoveryService_WhoAmI_FullMethodName,
    83  				&Ydb_Discovery.WhoAmIRequest{},
    84  				&Ydb_Discovery.WhoAmIResponse{},
    85  			).Return(expectedErr)
    86  			client := Ydb_Discovery_V1.NewDiscoveryServiceClient(&connMock{
    87  				cc,
    88  			})
    89  			response, err := client.WhoAmI(ctx, &Ydb_Discovery.WhoAmIRequest{})
    90  			require.Error(t, err)
    91  			require.True(t, xerrors.IsTransportError(err, grpcCodes.Unavailable))
    92  			require.Nil(t, response)
    93  		})
    94  		t.Run("OperationError", func(t *testing.T) {
    95  			ctx := xtest.Context(t)
    96  			ctrl := gomock.NewController(t)
    97  			t.Run("discovery.WhoAmI", func(t *testing.T) {
    98  				cc := NewMockClientConnInterface(ctrl)
    99  				cc.EXPECT().Invoke(
   100  					gomock.Any(),
   101  					Ydb_Discovery_V1.DiscoveryService_WhoAmI_FullMethodName,
   102  					&Ydb_Discovery.WhoAmIRequest{},
   103  					&Ydb_Discovery.WhoAmIResponse{},
   104  				).DoAndReturn(func(ctx context.Context, method string, args any, reply any, opts ...grpc.CallOption) error {
   105  					res, ok := reply.(*Ydb_Discovery.WhoAmIResponse)
   106  					if !ok {
   107  						return fmt.Errorf("reply is not *Ydb_Discovery.WhoAmIResponse: %T", reply)
   108  					}
   109  
   110  					res.Operation = &Ydb_Operations.Operation{
   111  						Ready:  true,
   112  						Status: Ydb.StatusIds_UNAVAILABLE,
   113  					}
   114  
   115  					return nil
   116  				})
   117  				client := Ydb_Discovery_V1.NewDiscoveryServiceClient(&connMock{
   118  					cc,
   119  				})
   120  				response, err := client.WhoAmI(ctx, &Ydb_Discovery.WhoAmIRequest{})
   121  				require.Error(t, err)
   122  				require.True(t, xerrors.IsOperationError(err, Ydb.StatusIds_UNAVAILABLE))
   123  				require.Nil(t, response)
   124  			})
   125  			t.Run("query.BeginTransaction", func(t *testing.T) {
   126  				cc := NewMockClientConnInterface(ctrl)
   127  				cc.EXPECT().Invoke(
   128  					gomock.Any(),
   129  					Ydb_Query_V1.QueryService_BeginTransaction_FullMethodName,
   130  					&Ydb_Query.BeginTransactionRequest{},
   131  					&Ydb_Query.BeginTransactionResponse{},
   132  				).DoAndReturn(func(ctx context.Context, method string, args any, reply any, opts ...grpc.CallOption) error {
   133  					res, ok := reply.(*Ydb_Query.BeginTransactionResponse)
   134  					if !ok {
   135  						return fmt.Errorf("reply is not *Ydb_Query.BeginTransactionResponse: %T", reply)
   136  					}
   137  
   138  					res.Status = Ydb.StatusIds_UNAVAILABLE
   139  
   140  					return nil
   141  				})
   142  				client := Ydb_Query_V1.NewQueryServiceClient(&connMock{
   143  					cc,
   144  				})
   145  				response, err := client.BeginTransaction(ctx, &Ydb_Query.BeginTransactionRequest{})
   146  				require.Error(t, err)
   147  				require.True(t, xerrors.IsOperationError(err, Ydb.StatusIds_UNAVAILABLE))
   148  				require.Nil(t, response)
   149  			})
   150  		})
   151  	})
   152  }