github.com/cloudwego/kitex@v0.9.0/pkg/remote/codec/thrift/thrift_data_test.go (about) 1 /* 2 * Copyright 2023 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 thrift 18 19 import ( 20 "context" 21 "reflect" 22 "testing" 23 24 "github.com/apache/thrift/lib/go/thrift" 25 26 "github.com/cloudwego/kitex/internal/mocks/thrift/fast" 27 "github.com/cloudwego/kitex/internal/test" 28 "github.com/cloudwego/kitex/pkg/remote" 29 ) 30 31 var ( 32 mockReq = &fast.MockReq{ 33 Msg: "hello", 34 } 35 mockReqThrift = []byte{ 36 11 /* string */, 0, 1 /* id=1 */, 0, 0, 0, 5 /* length=5 */, 104, 101, 108, 108, 111, /* "hello" */ 37 13 /* map */, 0, 2 /* id=2 */, 11 /* key:string*/, 11 /* value:string */, 0, 0, 0, 0, /* map size=0 */ 38 15 /* list */, 0, 3 /* id=3 */, 11 /* item:string */, 0, 0, 0, 0, /* list size=0 */ 39 0, /* end of struct */ 40 } 41 ) 42 43 func TestMarshalBasicThriftData(t *testing.T) { 44 t.Run("invalid-data", func(t *testing.T) { 45 err := marshalBasicThriftData(context.Background(), nil, 0) 46 test.Assert(t, err == errEncodeMismatchMsgType, err) 47 }) 48 t.Run("valid-data", func(t *testing.T) { 49 transport := thrift.NewTMemoryBufferLen(1024) 50 tProt := thrift.NewTBinaryProtocol(transport, true, true) 51 err := marshalBasicThriftData(context.Background(), tProt, mockReq) 52 test.Assert(t, err == nil, err) 53 result := transport.Bytes() 54 test.Assert(t, reflect.DeepEqual(result, mockReqThrift), result) 55 }) 56 } 57 58 func TestMarshalThriftData(t *testing.T) { 59 t.Run("NoCodec(=FastCodec)", func(t *testing.T) { 60 buf, err := MarshalThriftData(context.Background(), nil, mockReq) 61 test.Assert(t, err == nil, err) 62 test.Assert(t, reflect.DeepEqual(buf, mockReqThrift), buf) 63 }) 64 t.Run("FastCodec", func(t *testing.T) { 65 buf, err := MarshalThriftData(context.Background(), NewThriftCodecWithConfig(FastRead|FastWrite), mockReq) 66 test.Assert(t, err == nil, err) 67 test.Assert(t, reflect.DeepEqual(buf, mockReqThrift), buf) 68 }) 69 t.Run("BasicCodec", func(t *testing.T) { 70 buf, err := MarshalThriftData(context.Background(), NewThriftCodecWithConfig(Basic), mockReq) 71 test.Assert(t, err == nil, err) 72 test.Assert(t, reflect.DeepEqual(buf, mockReqThrift), buf) 73 }) 74 // FrugalCodec: in thrift_frugal_amd64_test.go: TestMarshalThriftDataFrugal 75 } 76 77 func Test_decodeBasicThriftData(t *testing.T) { 78 t.Run("empty-input", func(t *testing.T) { 79 req := &fast.MockReq{} 80 tProt := NewBinaryProtocol(remote.NewReaderBuffer([]byte{})) 81 err := decodeBasicThriftData(context.Background(), tProt, "mock", req) 82 test.Assert(t, err != nil, err) 83 }) 84 t.Run("invalid-input", func(t *testing.T) { 85 req := &fast.MockReq{} 86 tProt := NewBinaryProtocol(remote.NewReaderBuffer([]byte{0xff})) 87 err := decodeBasicThriftData(context.Background(), tProt, "mock", req) 88 test.Assert(t, err != nil, err) 89 }) 90 t.Run("normal-input", func(t *testing.T) { 91 req := &fast.MockReq{} 92 tProt := NewBinaryProtocol(remote.NewReaderBuffer(mockReqThrift)) 93 err := decodeBasicThriftData(context.Background(), tProt, "mock", req) 94 checkDecodeResult(t, err, req) 95 }) 96 } 97 98 func checkDecodeResult(t *testing.T, err error, req *fast.MockReq) { 99 test.Assert(t, err == nil, err) 100 test.Assert(t, req.Msg == mockReq.Msg, req.Msg, mockReq.Msg) 101 test.Assert(t, len(req.StrMap) == 0, req.StrMap) 102 test.Assert(t, len(req.StrList) == 0, req.StrList) 103 } 104 105 func TestUnmarshalThriftData(t *testing.T) { 106 t.Run("NoCodec(=FastCodec)", func(t *testing.T) { 107 req := &fast.MockReq{} 108 err := UnmarshalThriftData(context.Background(), nil, "mock", mockReqThrift, req) 109 checkDecodeResult(t, err, req) 110 }) 111 t.Run("FastCodec", func(t *testing.T) { 112 req := &fast.MockReq{} 113 err := UnmarshalThriftData(context.Background(), NewThriftCodecWithConfig(FastRead|FastWrite), "mock", mockReqThrift, req) 114 checkDecodeResult(t, err, req) 115 }) 116 t.Run("BasicCodec", func(t *testing.T) { 117 req := &fast.MockReq{} 118 err := UnmarshalThriftData(context.Background(), NewThriftCodecWithConfig(Basic), "mock", mockReqThrift, req) 119 checkDecodeResult(t, err, req) 120 }) 121 // FrugalCodec: in thrift_frugal_amd64_test.go: TestUnmarshalThriftDataFrugal 122 } 123 124 func TestUnmarshalThriftException(t *testing.T) { 125 // prepare exception thrift binary 126 transport := thrift.NewTMemoryBufferLen(marshalThriftBufferSize) 127 tProt := thrift.NewTBinaryProtocol(transport, true, true) 128 errMessage := "test: invalid protocol" 129 exc := thrift.NewTApplicationException(thrift.INVALID_PROTOCOL, errMessage) 130 err := exc.Write(tProt) 131 test.Assert(t, err == nil, err) 132 133 // unmarshal 134 tProtRead := NewBinaryProtocol(remote.NewReaderBuffer(transport.Bytes())) 135 err = UnmarshalThriftException(tProtRead) 136 transErr, ok := err.(*remote.TransError) 137 test.Assert(t, ok, err) 138 test.Assert(t, transErr.TypeID() == thrift.INVALID_PROTOCOL, transErr) 139 test.Assert(t, transErr.Error() == errMessage, transErr) 140 } 141 142 func Test_verifyMarshalBasicThriftDataType(t *testing.T) { 143 err := verifyMarshalBasicThriftDataType(&mockWithContext{}) 144 test.Assert(t, err == nil, err) 145 // data that is not part of basic thrift: in thrift_frugal_amd64_test.go: Test_verifyMarshalThriftDataFrugal 146 } 147 148 func Test_verifyUnmarshalBasicThriftDataType(t *testing.T) { 149 err := verifyUnmarshalBasicThriftDataType(&mockWithContext{}) 150 test.Assert(t, err == nil, err) 151 // data that is not part of basic thrift: in thrift_frugal_amd64_test.go: Test_verifyUnmarshalThriftDataFrugal 152 }