github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/binary/binary_test.go (about) 1 package binary 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 "testing" 8 9 "github.com/cloudwego/dynamicgo/proto" 10 "github.com/cloudwego/dynamicgo/testdata/kitex_gen/pb/example" 11 goproto "google.golang.org/protobuf/proto" 12 "google.golang.org/protobuf/reflect/protoreflect" 13 ) 14 15 type TestMode int8 16 17 const ( 18 PartialTest TestMode = iota 19 ScalarsTest 20 MessageTest 21 NestedTest 22 ListTest 23 MapTest 24 OneofTest 25 ) 26 27 type testCase struct { 28 file string 29 service string 30 isInput bool 31 fieldNumber int 32 mode TestMode 33 } 34 35 var testGroup = map[string]testCase{ 36 "Partial test": testCase{ 37 file: "../../testdata/idl/example.proto", 38 service: "PartialMethodTest", 39 isInput: false, 40 fieldNumber: 3, 41 mode: PartialTest, 42 }, 43 "Scalars test": testCase{ 44 file: "../../testdata/idl/example.proto", 45 service: "ScalarsMethodTest", 46 isInput: false, 47 fieldNumber: 7, 48 mode: ScalarsTest, 49 }, 50 "Message test": testCase{ 51 file: "../../testdata/idl/example.proto", 52 service: "MessageMethodTest", 53 isInput: false, 54 fieldNumber: 1, 55 mode: MessageTest, 56 }, 57 "NestedMessage test": testCase{ 58 file: "../../testdata/idl/example.proto", 59 service: "NestedMethodTest", 60 isInput: false, 61 fieldNumber: 1, 62 mode: NestedTest, 63 }, 64 "List test": testCase{ 65 file: "../../testdata/idl/example.proto", 66 service: "ListMethodTest", 67 isInput: false, 68 fieldNumber: 1, 69 mode: ListTest, 70 }, 71 "Map test": testCase{ 72 file: "../../testdata/idl/example.proto", 73 service: "MapMethodTest", 74 isInput: false, 75 fieldNumber: 1, 76 mode: MapTest, 77 }, 78 "Oneof test": testCase{ 79 file: "../../testdata/idl/example.proto", 80 service: "OneofMethodTest", 81 isInput: false, 82 fieldNumber: 1, 83 mode: OneofTest, 84 }, 85 } 86 87 func binaryDataBuild(mode TestMode) []byte { 88 var req protoreflect.ProtoMessage 89 switch mode { 90 case PartialTest: 91 data := &example.ExamplePartialResp{} 92 // data.ShortEnglishMsg = "first" 93 // data.ChineseMsg = "哈哈哈哈但是" 94 data.LongEnglishMsg = "noboiubibipbpsdakonobnuondfap123141adfasdf" 95 req = data 96 case MessageTest: 97 data := &example.ExampleMessageResp{} 98 data.Base = &example.InnerBase{} 99 data.Base.SBool = true 100 data.Base.SInt32 = 12 101 data.Base.SInt64 = 52 102 data.Base.SUint32 = uint32(22) 103 data.Base.SUint64 = uint64(62) 104 data.Base.SFixed32 = uint32(120) 105 data.Base.SFixed64 = uint64(240) 106 data.Base.SSfixed32 = int32(120) 107 data.Base.SSfixed64 = int64(240) 108 data.Base.SFloat = 26.4 109 data.Base.SDouble = 55.2 110 data.Base.SBytes = []byte{1, 2, 7, 12, 64} 111 data.Base.SString = "npdabigdbas dsaf@232#~32adgna;sbf;" 112 req = data 113 case NestedTest: 114 data := &example.ExampleNestedResp{} 115 data.TestNested = &example.Nested{} 116 data.TestNested.SString = "aaaa" 117 data.TestNested.Base = &example.InnerBase{} 118 data.TestNested.Base.SBool = true 119 data.TestNested.Base.SInt32 = 12 120 data.TestNested.Base.SInt64 = 52 121 data.TestNested.Base.SUint32 = uint32(22) 122 data.TestNested.Base.SUint64 = uint64(62) 123 data.TestNested.Base.SFixed32 = uint32(120) 124 data.TestNested.Base.SFixed64 = uint64(240) 125 data.TestNested.Base.SSfixed32 = int32(120) 126 data.TestNested.Base.SSfixed64 = int64(240) 127 data.TestNested.Base.SFloat = 26.4 128 data.TestNested.Base.SDouble = 55.2 129 data.TestNested.Base.SBytes = []byte{1, 2, 7, 12, 64} 130 data.TestNested.Base.SString = "npdabigdbas dsaf@232#~32adgna;sbf;" 131 req = data 132 case ScalarsTest: 133 data := &example.ExampleScalarsResp{} 134 data.Scalars = &example.Scalars{} 135 data.Scalars.SBool = true 136 data.Scalars.SInt32 = 12 137 data.Scalars.SInt64 = 52 138 data.Scalars.SUint32 = uint32(22) 139 data.Scalars.SUint64 = uint64(62) 140 data.Scalars.SFixed32 = uint32(120) 141 data.Scalars.SFixed64 = uint64(240) 142 data.Scalars.SSfixed32 = int32(120) 143 data.Scalars.SSfixed64 = int64(240) 144 data.Scalars.SFloat = 26.4 145 data.Scalars.SDouble = 55.2 146 data.Scalars.SBytes = []byte{1, 2, 7, 12, 64} 147 data.Scalars.SString = "npdabigdbas dsaf@232#~32adgna;sbf;" 148 req = data 149 case ListTest: 150 data := &example.ExampleListResp{} 151 data.TestList = &example.Repeats{} 152 data.TestList.RptBool = []bool{true, false, true, true, false, true} 153 data.TestList.RptInt32 = []int32{int32(12), int32(52), int32(123), int32(205)} 154 data.TestList.RptInt64 = []int64{int64(21), int64(56), int64(210), int64(650)} 155 data.TestList.RptUint32 = []uint32{uint32(22), uint32(78), uint32(110), uint32(430)} 156 data.TestList.RptUint64 = []uint64{uint64(24), uint64(88), uint64(250), uint64(400)} 157 data.TestList.RptFloat = []float32{float32(33), float32(50), float32(88), float32(130)} 158 data.TestList.RptDouble = []float64{float64(33), float64(50), float64(88), float64(130)} 159 data.TestList.RptString = []string{string("aaaa"), string("12sdfa"), string("2165cxvznpnbhpbnda"), string("bpibpbpi2b3541341")} 160 data.TestList.RptBytes = [][]byte{[]byte{97, 98, 99, 100, 101, 102, 103}, []byte{104, 105, 106, 107, 108, 109, 110}, []byte{111, 112, 113, 114, 115, 116, 117}, []byte{118, 119, 120, 121, 122, 123, 124}} 161 req = data 162 case MapTest: 163 data := &example.ExampleMapResp{} 164 data.TestMap = &example.Maps{} 165 data.TestMap.Int32ToStr = make(map[int32]string) 166 data.TestMap.Int32ToStr[1] = "aaa" 167 data.TestMap.Int32ToStr[2] = "bbb" 168 data.TestMap.Int32ToStr[3] = "ccc" 169 170 data.TestMap.BoolToUint32 = make(map[bool]uint32) 171 data.TestMap.BoolToUint32[true] = uint32(10) 172 data.TestMap.BoolToUint32[false] = uint32(12) 173 data.TestMap.BoolToUint32[true] = uint32(14) 174 175 data.TestMap.Uint64ToEnum = make(map[uint64]example.Enum) 176 data.TestMap.Uint64ToEnum[uint64(1)] = example.Enum_ONE 177 data.TestMap.Uint64ToEnum[uint64(2)] = example.Enum_TWO 178 data.TestMap.Uint64ToEnum[uint64(3)] = example.Enum_TEN 179 180 data.TestMap.StrToNested = make(map[string]*example.Nested) 181 nestedObj1 := example.Nested{} 182 nestedObj1.SString = "111" 183 nestedObj1.Base = &example.InnerBase{} 184 nestedObj1.Base.SBool = true 185 nestedObj1.Base.SString = "nested111" 186 nestedObj2 := example.Nested{} 187 nestedObj2.SString = "222" 188 nestedObj2.Base = &example.InnerBase{} 189 nestedObj2.Base.SBool = false 190 nestedObj2.Base.SString = "nested222" 191 nestedObj3 := example.Nested{} 192 nestedObj3.SString = "333" 193 nestedObj3.Base = &example.InnerBase{} 194 nestedObj3.Base.SBool = true 195 nestedObj3.Base.SString = "nested333" 196 data.TestMap.StrToNested["aaa"] = &nestedObj1 197 data.TestMap.StrToNested["bbb"] = &nestedObj2 198 data.TestMap.StrToNested["ccc"] = &nestedObj3 199 200 data.TestMap.StrToOneofs = make(map[string]*example.Oneofs) 201 oneofObj1 := example.Oneofs{} 202 enumUnion := &example.Oneofs_OneofEnum{} 203 enumUnion.OneofEnum = example.Enum_ONE 204 oneofObj1.Union = enumUnion 205 data.TestMap.StrToOneofs["aaa"] = &oneofObj1 206 207 oneofObj2 := example.Oneofs{} 208 stringUnion := &example.Oneofs_OneofString{} 209 stringUnion.OneofString = "stringUnion" 210 oneofObj2.Union = stringUnion 211 data.TestMap.StrToOneofs["bbb"] = &oneofObj2 212 213 oneofObj3 := example.Oneofs{} 214 nestedUnion := &example.Oneofs_OneofNested{} 215 nestedUnion.OneofNested = &example.Nested{} 216 nestedUnion.OneofNested.SString = "nestedStringUnion" 217 nestedUnion.OneofNested.Base = &example.InnerBase{} 218 nestedUnion.OneofNested.Base.SBool = true 219 nestedUnion.OneofNested.Base.SString = "bbb" 220 oneofObj3.Union = nestedUnion 221 data.TestMap.StrToOneofs["ccc"] = &oneofObj3 222 req = data 223 case OneofTest: 224 data := &example.ExampleOneofResp{} 225 data.TestOneof = &example.Oneofs{} 226 // enum inner of union 227 // enumUnion := &example.Oneofs_OneofEnum{} 228 // enumUnion.OneofEnum = example.Enum_ONE 229 // data.TestOneof.Union = enumUnion 230 // string inner of union 231 // stringUnion := &example.Oneofs_OneofString{} 232 // stringUnion.OneofString = "aaaa" 233 // data.TestOneof.Union = stringUnion 234 // Nested inner of union 235 nestedUnion := example.Oneofs_OneofNested{} 236 nestedUnion.OneofNested = &example.Nested{} 237 nestedUnion.OneofNested.SString = "aaa" 238 nestedUnion.OneofNested.Base = &example.InnerBase{} 239 nestedUnion.OneofNested.Base.SBool = true 240 nestedUnion.OneofNested.Base.SString = "bbb" 241 data.TestOneof.Union = &nestedUnion 242 req = data 243 } 244 res, err := goproto.Marshal(req) 245 if err != nil { 246 panic("proto Marshal failed: PartialTest") 247 } 248 return res 249 } 250 251 func TestBinaryProtocol_ReadAnyWithDesc(t *testing.T) { 252 for name, test := range testGroup { 253 t.Run(name, func(t *testing.T) { 254 p1, err := proto.NewDescritorFromPath(context.Background(), test.file) 255 if err != nil { 256 panic(err) 257 } 258 // get Target FieldDescriptor 259 var fieldDescriptor *proto.FieldDescriptor 260 if test.isInput { 261 fieldDescriptor = p1.LookupMethodByName(test.service).Input().Message().ByNumber(proto.FieldNumber(test.fieldNumber)) 262 } else { 263 fieldDescriptor = p1.LookupMethodByName(test.service).Output().Message().ByNumber(proto.FieldNumber(test.fieldNumber)) 264 } 265 // protoc build pbData 266 pbData := binaryDataBuild(test.mode) 267 p := NewBinaryProtol(pbData) 268 // WriteAnyWithDesc write the data into BinaryProtocol 269 hasmessageLen := true 270 if !fieldDescriptor.IsMap() && !fieldDescriptor.IsList() { 271 if _, _, _, err := p.ConsumeTag(); err != nil { 272 panic(err) 273 } 274 } 275 v1, err := p.ReadAnyWithDesc(fieldDescriptor.Type(), hasmessageLen, true, false, true) 276 fmt.Printf("%#v\n", v1) 277 278 // wirte 279 p = NewBinaryProtocolBuffer() 280 if !fieldDescriptor.IsMap() && !fieldDescriptor.IsList() { 281 p.AppendTagByKind(fieldDescriptor.Number(), fieldDescriptor.Kind()) 282 } 283 needMessageLen := true 284 err = p.WriteAnyWithDesc(fieldDescriptor.Type(), v1, needMessageLen, true, false, true) 285 if err != nil { 286 panic(err) 287 } 288 fmt.Printf("%x\n", p.RawBuf()) 289 290 // Read again by ReadAnyWithDesc 291 p = NewBinaryProtol(p.RawBuf()) 292 hasmessageLen = true 293 if !fieldDescriptor.IsMap() && !fieldDescriptor.IsList() { 294 if _, _, _, err := p.ConsumeTag(); err != nil { 295 panic(err) 296 } 297 } 298 v2, err := p.ReadAnyWithDesc(fieldDescriptor.Type(), hasmessageLen, true, false, true) 299 if err != nil { 300 panic(err) 301 } 302 fmt.Printf("%#v\n", v2) 303 if !reflect.DeepEqual(v1, v2) { 304 panic("test ReadAnyWithDesc error") 305 } 306 }) 307 } 308 } 309 310 func TestTag(t *testing.T) { 311 src := make([]byte, 0, 1024) 312 p := NewBinaryProtol(src) 313 // using a for loop to check each case of appendtag and consumeTag 314 // the case is in the TestTag2 315 316 testCase := []struct { 317 number proto.FieldNumber 318 wtyp proto.WireType 319 err error 320 }{ 321 {0, proto.Fixed32Type, errInvalidTag}, 322 {1, proto.Fixed32Type, nil}, 323 {proto.FirstReservedNumber, proto.BytesType, nil}, 324 {proto.LastReservedNumber, proto.StartGroupType, nil}, 325 {proto.MaxValidNumber, proto.VarintType, nil}, 326 } 327 328 for _, c := range testCase { 329 p.AppendTag(c.number, c.wtyp) 330 num, _, _, err := p.ConsumeTag() 331 if err != nil && err != errInvalidTag { 332 t.Fatal(err) 333 } 334 if num != c.number { 335 t.Fatal("test failed") 336 } 337 } 338 339 _, _, _, err := p.ConsumeTag() 340 if err != errInvalidTag { 341 t.Fatal("test failed") 342 } 343 }