blob: 450400c9b605392be8a6803b47ce78c2713a7a5d [file] [log] [blame]
Yuxuan 'fishy' Wang19c13b42022-10-12 14:13:15 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20package thrift
21
22import (
23 "fmt"
24 "testing"
25 "testing/quick"
26)
27
28func TestHexToByte(t *testing.T) {
29 for _, c := range []struct {
30 s string
31 b byte
32 fail bool
33 }{
34 {
35 s: "ff",
36 b: 0xff,
37 },
38 {
39 s: "FF",
40 b: 0xff,
41 },
42 {
43 s: "00",
44 b: 0,
45 },
46 {
47 s: "77",
48 b: 0x77,
49 },
50 {
51 s: "aC",
52 b: 0xac,
53 },
54 {
55 s: "xx",
56 fail: true,
57 },
58 {
59 s: "x0",
60 fail: true,
61 },
62 {
63 s: "fx",
64 fail: true,
65 },
66 } {
67 t.Run(c.s, func(t *testing.T) {
68 b, ok := hexToByte(c.s[0], c.s[1])
69 if ok != !c.fail {
70 t.Errorf("Want failure, got %x, %v", b, ok)
71 }
72 if !c.fail && b != c.b {
73 t.Errorf("Want %x, got %x", c.b, b)
74 }
75 })
76 }
77}
78
79func TestUUIDString(t *testing.T) {
80 for _, c := range []struct {
81 uuid Tuuid
82 want string
83 }{
84 {
85 uuid: Tuuid{},
86 want: "00000000-0000-0000-0000-000000000000",
87 },
88 {
89 uuid: Tuuid{
90 0x6b, 0xa7, 0xb8, 0x10,
91 0x9d, 0xad,
92 0x11, 0xd1,
93 0x80, 0xb4,
94 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
95 },
96 want: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
97 },
98 {
99 uuid: Tuuid{
100 0x6b, 0xa7, 0xB8, 0x11,
101 0x9d, 0xAd,
102 0x11, 0xd1,
103 0x80, 0xb4,
104 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
105 },
106 want: "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
107 },
108 {
109 uuid: Tuuid{
110 0x6b, 0xa7, 0xb8, 0x12,
111 0x9d, 0xad,
112 0x11, 0xd1,
113 0x80, 0xb4,
114 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
115 },
116 want: "6ba7b812-9dad-11d1-80b4-00c04fd430c8",
117 },
118 {
119 uuid: Tuuid{
120 0x6b, 0xa7, 0xb8, 0x14,
121 0x9d, 0xad,
122 0x11, 0xd1,
123 0x80, 0xb4,
124 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
125 },
126 want: "6ba7b814-9dad-11d1-80b4-00c04fd430c8",
127 },
128 } {
129 t.Run(fmt.Sprintf("% 02x", c.uuid[:]), func(t *testing.T) {
130 got := c.uuid.String()
131 if got != c.want {
132 t.Errorf("got %q, want %q", got, c.want)
133 }
134 })
135 }
136}
137
138func TestUUIDParse(t *testing.T) {
139 for _, c := range []struct {
140 uuid string
141 want Tuuid
142 err bool
143 }{
144 {
145 uuid: "00000000-0000-0000-0000-000000000000",
146 want: Tuuid{
147 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00,
149 0x00, 0x00,
150 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 },
153 },
154 {
155 uuid: "6BA7B810-9DAD-11D1-80B4-00C04FD430C8",
156 want: Tuuid{
157 0x6B, 0xA7, 0xB8, 0x10,
158 0x9D, 0xAD,
159 0x11, 0xD1,
160 0x80, 0xB4,
161 0x00, 0xC0, 0x4F, 0xD4, 0x30, 0xC8,
162 },
163 },
164 {
165 uuid: "6ba7B811-9dAd-11d1-80b4-00c04fd430c8",
166 want: Tuuid{
167 0x6b, 0xa7, 0xB8, 0x11,
168 0x9d, 0xAd,
169 0x11, 0xd1,
170 0x80, 0xb4,
171 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
172 },
173 },
174 {
175 uuid: "6ba7b812-9dad-11d1-80b4-00c04fd430c8",
176 want: Tuuid{
177 0x6b, 0xa7, 0xb8, 0x12,
178 0x9d, 0xad,
179 0x11, 0xd1,
180 0x80, 0xb4,
181 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
182 },
183 },
184 {
185 uuid: "6ba7b814-9dad-11d1-80b4-00c04fd430c8",
186 want: Tuuid{
187 0x6b, 0xa7, 0xb8, 0x14,
188 0x9d, 0xad,
189 0x11, 0xd1,
190 0x80, 0xb4,
191 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
192 },
193 },
194 {
195 uuid: "00000000000000000000000000000000",
196 err: true, // not in canonical form
197 },
198 {
199 uuid: "6ba7b810-9d-ad11d1-80b4-00c04fd430c8",
200 err: true, // wrong position of hyphens
201 },
202 {
203 uuid: "urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8",
204 err: true, // urn form is not supported
205 },
206 {
207 uuid: "{6ba7b812-9dad-11d1-80b4-00c04fd430c8}",
208 err: true, // guid with braces form is not supported
209 },
210 {
211 uuid: "6xa7b814-9dad-11d1-80b4-00c04fd430c8",
212 err: true, // non-hex numbers
213 },
214 } {
215 t.Run(c.uuid, func(t *testing.T) {
216 uuid, err := ParseTuuid(c.uuid)
217 if c.err {
218 if err == nil {
219 t.Errorf("Got %v, want error", uuid)
220 }
221 } else {
222 if err != nil {
223 t.Errorf("Failed to parse: %v", err)
224 }
225 if uuid != c.want {
226 t.Errorf("Got %v, want %v", uuid, c.want)
227 }
228 }
229 })
230 }
231}
232
233func TestUUIDQuick(t *testing.T) {
234 f := func(u Tuuid) bool {
235 s := u.String()
236 parsed, err := ParseTuuid(s)
237 if err != nil {
238 t.Error(err)
239 }
240 if parsed != u {
241 t.Errorf("Parsed %v want %v", parsed, u)
242 }
243 return !t.Failed()
244 }
245 if err := quick.Check(f, nil); err != nil {
246 t.Error(err)
247 }
248}
249
250func BenchmarkUUIDParse(b *testing.B) {
251 for _, s := range []string{
252 "00000000-0000-0000-0000-000000000000",
253 "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
254 "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
255 "6ba7b812-9dad-11d1-80b4-00c04fd430c8",
256 "6ba7b814-9dad-11d1-80b4-00c04fd430c8",
257 } {
258 b.Run(s, func(b *testing.B) {
259 b.ReportAllocs()
260 if _, err := ParseTuuid(s); err != nil {
261 b.Fatalf("Unable to parse %q: %v", s, err)
262 }
263 b.ResetTimer()
264 b.RunParallel(func(pb *testing.PB) {
265 for pb.Next() {
266 ParseTuuid(s)
267 }
268 })
269 })
270 }
271}
272
273func BenchmarkUUIDString(b *testing.B) {
274 for _, u := range []Tuuid{
275 {},
276 Must(ParseTuuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8")),
277 Must(ParseTuuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8")),
278 Must(ParseTuuid("6ba7b812-9dad-11d1-80b4-00c04fd430c8")),
279 Must(ParseTuuid("6ba7b814-9dad-11d1-80b4-00c04fd430c8")),
280 } {
281 b.Run(u.String(), func(b *testing.B) {
282 b.ReportAllocs()
283 b.RunParallel(func(pb *testing.PB) {
284 for pb.Next() {
285 _ = u.String()
286 }
287 })
288 })
289 }
290}