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  }