1
2
3
4
5 package gob
6
7 import (
8 "bytes"
9 "reflect"
10 "sync"
11 "testing"
12 )
13
14 type typeT struct {
15 id typeId
16 str string
17 }
18
19 var basicTypes = []typeT{
20 {tBool, "bool"},
21 {tInt, "int"},
22 {tUint, "uint"},
23 {tFloat, "float"},
24 {tBytes, "bytes"},
25 {tString, "string"},
26 }
27
28 func getTypeUnlocked(name string, rt reflect.Type) gobType {
29 typeLock.Lock()
30 defer typeLock.Unlock()
31 t, err := getBaseType(name, rt)
32 if err != nil {
33 panic("getTypeUnlocked: " + err.Error())
34 }
35 return t
36 }
37
38
39 func TestBasic(t *testing.T) {
40 for _, tt := range basicTypes {
41 if tt.id.string() != tt.str {
42 t.Errorf("checkType: expected %q got %s", tt.str, tt.id.string())
43 }
44 if tt.id == 0 {
45 t.Errorf("id for %q is zero", tt.str)
46 }
47 }
48 }
49
50
51 func TestReregistration(t *testing.T) {
52 newtyp := getTypeUnlocked("int", reflect.TypeOf(int(0)))
53 if newtyp != tInt.gobType() {
54 t.Errorf("reregistration of %s got new type", newtyp.string())
55 }
56 newtyp = getTypeUnlocked("uint", reflect.TypeOf(uint(0)))
57 if newtyp != tUint.gobType() {
58 t.Errorf("reregistration of %s got new type", newtyp.string())
59 }
60 newtyp = getTypeUnlocked("string", reflect.TypeOf("hello"))
61 if newtyp != tString.gobType() {
62 t.Errorf("reregistration of %s got new type", newtyp.string())
63 }
64 }
65
66 func TestArrayType(t *testing.T) {
67 var a3 [3]int
68 a3int := getTypeUnlocked("foo", reflect.TypeOf(a3))
69 newa3int := getTypeUnlocked("bar", reflect.TypeOf(a3))
70 if a3int != newa3int {
71 t.Errorf("second registration of [3]int creates new type")
72 }
73 var a4 [4]int
74 a4int := getTypeUnlocked("goo", reflect.TypeOf(a4))
75 if a3int == a4int {
76 t.Errorf("registration of [3]int creates same type as [4]int")
77 }
78 var b3 [3]bool
79 a3bool := getTypeUnlocked("", reflect.TypeOf(b3))
80 if a3int == a3bool {
81 t.Errorf("registration of [3]bool creates same type as [3]int")
82 }
83 str := a3bool.string()
84 expected := "[3]bool"
85 if str != expected {
86 t.Errorf("array printed as %q; expected %q", str, expected)
87 }
88 }
89
90 func TestSliceType(t *testing.T) {
91 var s []int
92 sint := getTypeUnlocked("slice", reflect.TypeOf(s))
93 var news []int
94 newsint := getTypeUnlocked("slice1", reflect.TypeOf(news))
95 if sint != newsint {
96 t.Errorf("second registration of []int creates new type")
97 }
98 var b []bool
99 sbool := getTypeUnlocked("", reflect.TypeOf(b))
100 if sbool == sint {
101 t.Errorf("registration of []bool creates same type as []int")
102 }
103 str := sbool.string()
104 expected := "[]bool"
105 if str != expected {
106 t.Errorf("slice printed as %q; expected %q", str, expected)
107 }
108 }
109
110 func TestMapType(t *testing.T) {
111 var m map[string]int
112 mapStringInt := getTypeUnlocked("map", reflect.TypeOf(m))
113 var newm map[string]int
114 newMapStringInt := getTypeUnlocked("map1", reflect.TypeOf(newm))
115 if mapStringInt != newMapStringInt {
116 t.Errorf("second registration of map[string]int creates new type")
117 }
118 var b map[string]bool
119 mapStringBool := getTypeUnlocked("", reflect.TypeOf(b))
120 if mapStringBool == mapStringInt {
121 t.Errorf("registration of map[string]bool creates same type as map[string]int")
122 }
123 str := mapStringBool.string()
124 expected := "map[string]bool"
125 if str != expected {
126 t.Errorf("map printed as %q; expected %q", str, expected)
127 }
128 }
129
130 type Bar struct {
131 X string
132 }
133
134
135 type Foo struct {
136 A int
137 B int32
138 C string
139 D []byte
140 E *float64
141 F ****float64
142 G *Bar
143 H *Bar
144 I *Foo
145 }
146
147 func TestStructType(t *testing.T) {
148 sstruct := getTypeUnlocked("Foo", reflect.TypeOf(Foo{}))
149 str := sstruct.string()
150
151 expected := "Foo = struct { A int; B int; C string; D bytes; E float; F float; G Bar = struct { X string; }; H Bar; I Foo; }"
152 if str != expected {
153 t.Errorf("struct printed as %q; expected %q", str, expected)
154 }
155 }
156
157
158
159 func TestRegistration(t *testing.T) {
160 type T struct{ a int }
161 Register(new(T))
162 Register(new(T))
163 }
164
165 type N1 struct{}
166 type N2 struct{}
167
168
169 func TestRegistrationNaming(t *testing.T) {
170 testCases := []struct {
171 t interface{}
172 name string
173 }{
174 {&N1{}, "*gob.N1"},
175 {N2{}, "encoding/gob.N2"},
176 }
177
178 for _, tc := range testCases {
179 Register(tc.t)
180
181 tct := reflect.TypeOf(tc.t)
182 ct, _ := nameToConcreteType.Load(tc.name)
183 if ct != tct {
184 t.Errorf("nameToConcreteType[%q] = %v, want %v", tc.name, ct, tct)
185 }
186
187 if tct.Kind() == reflect.Ptr {
188 tct = tct.Elem()
189 }
190 if n, _ := concreteTypeToName.Load(tct); n != tc.name {
191 t.Errorf("concreteTypeToName[%v] got %v, want %v", tct, n, tc.name)
192 }
193 }
194 }
195
196 func TestStressParallel(t *testing.T) {
197 type T2 struct{ A int }
198 c := make(chan bool)
199 const N = 10
200 for i := 0; i < N; i++ {
201 go func() {
202 p := new(T2)
203 Register(p)
204 b := new(bytes.Buffer)
205 enc := NewEncoder(b)
206 err := enc.Encode(p)
207 if err != nil {
208 t.Error("encoder fail:", err)
209 }
210 dec := NewDecoder(b)
211 err = dec.Decode(p)
212 if err != nil {
213 t.Error("decoder fail:", err)
214 }
215 c <- true
216 }()
217 }
218 for i := 0; i < N; i++ {
219 <-c
220 }
221 }
222
223
224 func TestTypeRace(t *testing.T) {
225 c := make(chan bool)
226 var wg sync.WaitGroup
227 for i := 0; i < 2; i++ {
228 wg.Add(1)
229 go func(i int) {
230 defer wg.Done()
231 var buf bytes.Buffer
232 enc := NewEncoder(&buf)
233 dec := NewDecoder(&buf)
234 var x interface{}
235 switch i {
236 case 0:
237 x = &N1{}
238 case 1:
239 x = &N2{}
240 default:
241 t.Errorf("bad i %d", i)
242 return
243 }
244 m := make(map[string]string)
245 <-c
246 if err := enc.Encode(x); err != nil {
247 t.Error(err)
248 return
249 }
250 if err := enc.Encode(x); err != nil {
251 t.Error(err)
252 return
253 }
254 if err := dec.Decode(&m); err == nil {
255 t.Error("decode unexpectedly succeeded")
256 return
257 }
258 }(i)
259 }
260 close(c)
261 wg.Wait()
262 }
263
View as plain text