github.com/cloudwego/kitex@v0.9.0/pkg/remote/trans/nphttp2/client_handler_test.go (about) 1 /* 2 * Copyright 2022 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package nphttp2 18 19 import ( 20 "context" 21 "net" 22 "testing" 23 "time" 24 25 "github.com/cloudwego/kitex/internal/test" 26 "github.com/cloudwego/kitex/pkg/kerrors" 27 "github.com/cloudwego/kitex/pkg/remote" 28 "github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/metadata" 29 "github.com/cloudwego/kitex/pkg/rpcinfo" 30 "github.com/cloudwego/kitex/pkg/serviceinfo" 31 "github.com/cloudwego/kitex/transport" 32 ) 33 34 func TestClientHandler(t *testing.T) { 35 // init 36 opt := newMockClientOption() 37 ctx := newMockCtxWithRPCInfo() 38 msg := newMockNewMessage() 39 msg.ProtocolInfoFunc = func() remote.ProtocolInfo { 40 return remote.NewProtocolInfo(transport.PurePayload, serviceinfo.Protobuf) 41 } 42 msg.RPCInfoFunc = func() rpcinfo.RPCInfo { 43 return newMockRPCInfo() 44 } 45 conn, err := opt.ConnPool.Get(ctx, "tcp", mockAddr0, remote.ConnOption{Dialer: opt.Dialer, ConnectTimeout: time.Second}) 46 test.Assert(t, err == nil, err) 47 48 // test NewTransHandler() 49 cliTransHandler, err := NewCliTransHandlerFactory().NewTransHandler(opt) 50 test.Assert(t, err == nil, err) 51 52 // test Read(): comment now since Read will block until header has been received, which is not suitable for ut. 53 // newMockStreamRecvHelloRequest(conn.(*clientConn).s) 54 // ctx, err = cliTransHandler.Read(ctx, conn, msg) 55 // test.Assert(t, err == nil, err) 56 57 // test write() 58 ctx, err = cliTransHandler.Write(ctx, conn, msg) 59 test.Assert(t, ctx != nil, ctx) 60 test.Assert(t, err == nil, err) 61 } 62 63 type mockCodec struct { 64 remote.Codec 65 encode func(ctx context.Context, msg remote.Message, out remote.ByteBuffer) error 66 decode func(ctx context.Context, msg remote.Message, in remote.ByteBuffer) error 67 } 68 69 func (c *mockCodec) Encode(ctx context.Context, msg remote.Message, out remote.ByteBuffer) error { 70 return c.encode(ctx, msg, out) 71 } 72 73 func (c *mockCodec) Decode(ctx context.Context, msg remote.Message, in remote.ByteBuffer) error { 74 return c.decode(ctx, msg, in) 75 } 76 77 var ( 78 _ hasTrailer = (*mockConnForRead)(nil) 79 _ hasHeader = (*mockConnForRead)(nil) 80 _ hasGetRecvCompress = (*mockConnForRead)(nil) 81 _ GRPCConn = (*mockConnForRead)(nil) 82 ) 83 84 type mockConnForRead struct { 85 net.Conn 86 } 87 88 func (m *mockConnForRead) WriteFrame(hdr, data []byte) (n int, err error) { 89 return 0, nil 90 } 91 92 func (m *mockConnForRead) ReadFrame() (hdr, data []byte, err error) { 93 return nil, nil, nil 94 } 95 96 func (m *mockConnForRead) GetRecvCompress() string { 97 return "" 98 } 99 100 func (m *mockConnForRead) Header() (metadata.MD, error) { 101 return nil, nil 102 } 103 104 func (m *mockConnForRead) Trailer() metadata.MD { 105 return nil 106 } 107 108 func Test_cliTransHandler_Read(t *testing.T) { 109 t.Run("no error", func(t *testing.T) { 110 h := &cliTransHandler{ 111 codec: &mockCodec{ 112 decode: func(ctx context.Context, msg remote.Message, out remote.ByteBuffer) error { 113 return nil 114 }, 115 }, 116 } 117 msg := newMockNewMessage() 118 ivk := rpcinfo.NewInvocation("service", "method") 119 ri := rpcinfo.NewRPCInfo(nil, nil, ivk, nil, nil) 120 msg.RPCInfoFunc = func() rpcinfo.RPCInfo { 121 return ri 122 } 123 _, err := h.Read(context.Background(), &mockConnForRead{}, msg) 124 test.Assert(t, err == nil, err) 125 test.Assert(t, ivk.BizStatusErr() == nil) 126 }) 127 128 t.Run("biz error", func(t *testing.T) { 129 h := &cliTransHandler{ 130 codec: &mockCodec{ 131 decode: func(ctx context.Context, msg remote.Message, out remote.ByteBuffer) error { 132 return kerrors.NewBizStatusError(100, "biz error") 133 }, 134 }, 135 } 136 msg := newMockNewMessage() 137 ivk := rpcinfo.NewInvocation("service", "method") 138 ri := rpcinfo.NewRPCInfo(nil, nil, ivk, nil, nil) 139 msg.RPCInfoFunc = func() rpcinfo.RPCInfo { 140 return ri 141 } 142 _, err := h.Read(context.Background(), &mockConnForRead{}, msg) 143 test.Assert(t, err == nil, err) 144 test.Assert(t, ivk.BizStatusErr().BizStatusCode() == 100) 145 }) 146 }