github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/binary_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 "fmt" 22 "io/ioutil" 23 "os" 24 "runtime" 25 "runtime/debug" 26 "strings" 27 "testing" 28 "time" 29 30 "github.com/stretchr/testify/require" 31 ) 32 33 var ( 34 debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == "" 35 ) 36 37 func TestMain(m *testing.M) { 38 go func() { 39 if !debugAsyncGC { 40 return 41 } 42 println("Begin GC looping...") 43 for { 44 runtime.GC() 45 debug.FreeOSMemory() 46 } 47 }() 48 time.Sleep(time.Millisecond) 49 m.Run() 50 } 51 52 func getExampleDesc() *TypeDescriptor { 53 svc, err := NewDescritorFromPath(context.Background(), "../testdata/idl/example.thrift") 54 if err != nil { 55 panic(err) 56 } 57 return svc.Functions()["ExampleMethod"].Request().Struct().FieldByKey("req").Type() 58 } 59 60 func getExampleData() []byte { 61 out, err := ioutil.ReadFile("../testdata/data/example.bin") 62 if err != nil { 63 panic(err) 64 } 65 return out 66 } 67 68 func TestBinaryProtocol_ReadAnyWithDesc(t *testing.T) { 69 p1, err := NewDescritorFromPath(context.Background(), "../testdata/idl/example3.thrift") 70 if err != nil { 71 panic(err) 72 } 73 exp3partial := p1.Functions()["PartialMethod"].Response().Struct().FieldById(0).Type() 74 data, err := ioutil.ReadFile("../testdata/data/example3.bin") 75 if err != nil { 76 panic(err) 77 } 78 79 p := NewBinaryProtocol(data) 80 v, err := p.ReadAnyWithDesc(exp3partial, false, false, false, true) 81 if err != nil { 82 panic(err) 83 } 84 fmt.Printf("%#v", v) 85 p = NewBinaryProtocolBuffer() 86 err = p.WriteAnyWithDesc(exp3partial, v, true, true, true) 87 if err != nil { 88 panic(err) 89 } 90 fmt.Printf("%x", p.RawBuf()) 91 v, err = p.ReadAnyWithDesc(exp3partial, false, false, false, true) 92 if err != nil { 93 panic(err) 94 } 95 fmt.Printf("%#v", v) 96 } 97 98 func TestBinaryProtocol_WriteAny_ReadAny(t *testing.T) { 99 type args struct { 100 val interface{} 101 sliceAsSet bool 102 strAsBinary bool 103 byteAsInt8 bool 104 } 105 tests := []struct { 106 name string 107 args args 108 wantErr bool 109 want interface{} 110 }{ 111 {"bool", args{true, false, false, false}, false, true}, 112 {"byte", args{byte(1), false, false, false}, false, byte(1)}, 113 {"byte", args{byte(1), false, false, true}, false, int8(1)}, 114 {"i16", args{int16(1), false, false, false}, false, int16(1)}, 115 {"i32", args{int32(1), false, false, false}, false, int32(1)}, 116 {"i64", args{int64(1), false, false, false}, false, int64(1)}, 117 {"int", args{1, false, false, false}, false, int64(1)}, 118 {"f32", args{float32(1.0), false, false, false}, false, float64(1.0)}, 119 {"f64", args{1.0, false, false, false}, false, float64(1.0)}, 120 {"string", args{"1", false, false, false}, false, "1"}, 121 {"string2binary", args{"1", false, true, false}, false, []byte{'1'}}, 122 {"binary2string", args{[]byte{1}, false, false, false}, false, string("\x01")}, 123 {"binary2binary", args{[]byte{1}, false, true, false}, false, []byte{1}}, 124 {"list", args{[]interface{}{int32(1)}, false, false, false}, false, []interface{}{int32(1)}}, 125 {"set", args{[]interface{}{int64(1)}, true, false, false}, false, []interface{}{int64(1)}}, 126 {"int map", args{map[int]interface{}{1: byte(1)}, false, false, false}, false, map[int]interface{}{1: byte(1)}}, 127 {"int map error", args{map[int64]interface{}{1: byte(1)}, false, false, true}, false, map[int]interface{}{1: int8(1)}}, 128 {"int map empty", args{map[int64]interface{}{}, false, false, false}, true, nil}, 129 {"string map", args{map[string]interface{}{"1": "1"}, false, false, true}, false, map[string]interface{}{"1": "1"}}, 130 {"string map error", args{map[string]interface{}{"1": []int{1}}, false, false, true}, true, nil}, 131 {"string map empty", args{map[string]interface{}{}, false, false, true}, true, nil}, 132 {"any map", args{map[interface{}]interface{}{1.1: "1"}, false, false, false}, false, map[interface{}]interface{}{1.1: "1"}}, 133 {"any map + key list", args{map[interface{}]interface{}{&[]interface{}{1}: "1"}, false, false, false}, false, map[interface{}]interface{}{&[]interface{}{int64(1)}: "1"}}, 134 {"any map + val list", args{map[interface{}]interface{}{1.1: []interface{}{"1"}}, false, true, false}, false, map[interface{}]interface{}{1.1: []interface{}{[]byte{'1'}}}}, 135 {"any map empty", args{map[interface{}]interface{}{}, false, false, false}, true, nil}, 136 {"struct", args{map[FieldID]interface{}{FieldID(1): 1.1}, false, false, false}, false, map[FieldID]interface{}{FieldID(1): 1.1}}, 137 } 138 for _, tt := range tests { 139 t.Run(tt.name, func(t *testing.T) { 140 println("case:", tt.name) 141 p := &BinaryProtocol{} 142 typ, err := p.WriteAny(tt.args.val, tt.args.sliceAsSet) 143 if (err != nil) != tt.wantErr { 144 t.Fatalf("BinaryProtocol.WriteAny() error = %v, wantErr %v", err, tt.wantErr) 145 } 146 fmt.Printf("buf:%+v\n", p.RawBuf()) 147 got, err := p.ReadAny(typ, tt.args.strAsBinary, tt.args.byteAsInt8) 148 if (err != nil) != tt.wantErr { 149 t.Fatalf("BinaryProtocol.ReadAny() error = %v, wantErr %v", err, tt.wantErr) 150 } 151 fmt.Printf("got:%#v\n", got) 152 if strings.Contains(tt.name, "any map + key") { 153 em := tt.want.(map[interface{}]interface{}) 154 gm := got.(map[interface{}]interface{}) 155 require.Equal(t, len(em), len(gm)) 156 var firstK, firstV interface{} 157 for k, v := range em { 158 firstK, firstV = k, v 159 break 160 } 161 var firstKgot, firstVgot interface{} 162 for k, v := range gm { 163 firstKgot, firstVgot = k, v 164 break 165 } 166 require.Equal(t, firstK, firstKgot) 167 require.Equal(t, firstV, firstVgot) 168 } else { 169 require.Equal(t, tt.want, got) 170 } 171 }) 172 } 173 }