blob: 2f4dbbc21297fcae59c5726fde40f8da32108d03 [file] [log] [blame]
Joe Tsaib9365042019-03-19 14:14:29 -07001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package legacy
6
7import (
8 "sync"
9 "testing"
10
11 "github.com/golang/protobuf/v2/reflect/protoreflect"
12)
13
14type (
15 MessageA struct {
16 A1 *MessageA `protobuf:"bytes,1,req,name=a1"`
17 A2 *MessageB `protobuf:"bytes,2,req,name=a2"`
18 A3 Enum `protobuf:"varint,3,opt,name=a3,enum=legacy.Enum"`
19 }
20 MessageB struct {
21 B1 *MessageA `protobuf:"bytes,1,req,name=b1"`
22 B2 *MessageB `protobuf:"bytes,2,req,name=b2"`
23 B3 Enum `protobuf:"varint,3,opt,name=b3,enum=legacy.Enum"`
24 }
25 Enum int32
26)
27
28// TestConcurrentInit tests that concurrent wrapping of multiple legacy types
29// results in the exact same descriptor being created.
30func TestConcurrentInit(t *testing.T) {
31 const numParallel = 5
32 var messageATypes [numParallel]protoreflect.MessageType
33 var messageBTypes [numParallel]protoreflect.MessageType
34 var enumTypes [numParallel]protoreflect.EnumType
35
36 // Concurrently load message and enum types.
37 var wg sync.WaitGroup
38 for i := 0; i < numParallel; i++ {
39 i := i
40 wg.Add(3)
41 go func() {
42 defer wg.Done()
43 messageATypes[i] = Export{}.MessageTypeOf((*MessageA)(nil))
44 }()
45 go func() {
46 defer wg.Done()
47 messageBTypes[i] = Export{}.MessageTypeOf((*MessageB)(nil))
48 }()
49 go func() {
50 defer wg.Done()
51 enumTypes[i] = Export{}.EnumTypeOf(Enum(0))
52 }()
53 }
54 wg.Wait()
55
56 var (
57 wantMTA = messageATypes[0]
58 wantMDA = messageATypes[0].Fields().ByNumber(1).MessageType()
59 wantMTB = messageBTypes[0]
60 wantMDB = messageBTypes[0].Fields().ByNumber(2).MessageType()
61 wantET = enumTypes[0]
62 wantED = messageATypes[0].Fields().ByNumber(3).EnumType()
63 )
64
65 for _, gotMT := range messageATypes[1:] {
66 if gotMT != wantMTA {
67 t.Error("MessageType(MessageA) mismatch")
68 }
69 if gotMDA := gotMT.Fields().ByNumber(1).MessageType(); gotMDA != wantMDA {
70 t.Error("MessageDescriptor(MessageA) mismatch")
71 }
72 if gotMDB := gotMT.Fields().ByNumber(2).MessageType(); gotMDB != wantMDB {
73 t.Error("MessageDescriptor(MessageB) mismatch")
74 }
75 if gotED := gotMT.Fields().ByNumber(3).EnumType(); gotED != wantED {
76 t.Error("EnumDescriptor(Enum) mismatch")
77 }
78 }
79 for _, gotMT := range messageBTypes[1:] {
80 if gotMT != wantMTB {
81 t.Error("MessageType(MessageB) mismatch")
82 }
83 if gotMDA := gotMT.Fields().ByNumber(1).MessageType(); gotMDA != wantMDA {
84 t.Error("MessageDescriptor(MessageA) mismatch")
85 }
86 if gotMDB := gotMT.Fields().ByNumber(2).MessageType(); gotMDB != wantMDB {
87 t.Error("MessageDescriptor(MessageB) mismatch")
88 }
89 if gotED := gotMT.Fields().ByNumber(3).EnumType(); gotED != wantED {
90 t.Error("EnumDescriptor(Enum) mismatch")
91 }
92 }
93 for _, gotET := range enumTypes[1:] {
94 if gotET != wantET {
95 t.Error("EnumType(Enum) mismatch")
96 }
97 }
98}