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 }