1
2
3
4
5 package uuid
6
7
8
9
10 import (
11 "bytes"
12 "fmt"
13 "os"
14 "strings"
15 "testing"
16 )
17
18 type test struct {
19 in string
20 version Version
21 variant Variant
22 isuuid bool
23 }
24
25 var tests = []test{
26 {"f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, RFC4122, true},
27 {"f47ac10b-58cc-1372-8567-0e02b2c3d479", 1, RFC4122, true},
28 {"f47ac10b-58cc-2372-8567-0e02b2c3d479", 2, RFC4122, true},
29 {"f47ac10b-58cc-3372-8567-0e02b2c3d479", 3, RFC4122, true},
30 {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true},
31 {"f47ac10b-58cc-5372-8567-0e02b2c3d479", 5, RFC4122, true},
32 {"f47ac10b-58cc-6372-8567-0e02b2c3d479", 6, RFC4122, true},
33 {"f47ac10b-58cc-7372-8567-0e02b2c3d479", 7, RFC4122, true},
34 {"f47ac10b-58cc-8372-8567-0e02b2c3d479", 8, RFC4122, true},
35 {"f47ac10b-58cc-9372-8567-0e02b2c3d479", 9, RFC4122, true},
36 {"f47ac10b-58cc-a372-8567-0e02b2c3d479", 10, RFC4122, true},
37 {"f47ac10b-58cc-b372-8567-0e02b2c3d479", 11, RFC4122, true},
38 {"f47ac10b-58cc-c372-8567-0e02b2c3d479", 12, RFC4122, true},
39 {"f47ac10b-58cc-d372-8567-0e02b2c3d479", 13, RFC4122, true},
40 {"f47ac10b-58cc-e372-8567-0e02b2c3d479", 14, RFC4122, true},
41 {"f47ac10b-58cc-f372-8567-0e02b2c3d479", 15, RFC4122, true},
42
43 {"urn:uuid:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
44 {"URN:UUID:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
45 {"f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
46 {"f47ac10b-58cc-4372-1567-0e02b2c3d479", 4, Reserved, true},
47 {"f47ac10b-58cc-4372-2567-0e02b2c3d479", 4, Reserved, true},
48 {"f47ac10b-58cc-4372-3567-0e02b2c3d479", 4, Reserved, true},
49 {"f47ac10b-58cc-4372-4567-0e02b2c3d479", 4, Reserved, true},
50 {"f47ac10b-58cc-4372-5567-0e02b2c3d479", 4, Reserved, true},
51 {"f47ac10b-58cc-4372-6567-0e02b2c3d479", 4, Reserved, true},
52 {"f47ac10b-58cc-4372-7567-0e02b2c3d479", 4, Reserved, true},
53 {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true},
54 {"f47ac10b-58cc-4372-9567-0e02b2c3d479", 4, RFC4122, true},
55 {"f47ac10b-58cc-4372-a567-0e02b2c3d479", 4, RFC4122, true},
56 {"f47ac10b-58cc-4372-b567-0e02b2c3d479", 4, RFC4122, true},
57 {"f47ac10b-58cc-4372-c567-0e02b2c3d479", 4, Microsoft, true},
58 {"f47ac10b-58cc-4372-d567-0e02b2c3d479", 4, Microsoft, true},
59 {"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true},
60 {"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true},
61
62 {"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false},
63 {"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false},
64 {"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false},
65 {"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false},
66 {"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false},
67 {"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false},
68 }
69
70 var constants = []struct {
71 c interface{}
72 name string
73 }{
74 {Person, "Person"},
75 {Group, "Group"},
76 {Org, "Org"},
77 {Invalid, "Invalid"},
78 {RFC4122, "RFC4122"},
79 {Reserved, "Reserved"},
80 {Microsoft, "Microsoft"},
81 {Future, "Future"},
82 {Domain(17), "Domain17"},
83 {Variant(42), "BadVariant42"},
84 }
85
86 func testTest(t *testing.T, in string, tt test) {
87 uuid := Parse(in)
88 if ok := (uuid != nil); ok != tt.isuuid {
89 t.Errorf("Parse(%s) got %v expected %v\b", in, ok, tt.isuuid)
90 }
91 if uuid == nil {
92 return
93 }
94
95 if v := uuid.Variant(); v != tt.variant {
96 t.Errorf("Variant(%s) got %d expected %d\b", in, v, tt.variant)
97 }
98 if v, _ := uuid.Version(); v != tt.version {
99 t.Errorf("Version(%s) got %d expected %d\b", in, v, tt.version)
100 }
101 }
102
103 func TestUUID(t *testing.T) {
104 for _, tt := range tests {
105 testTest(t, tt.in, tt)
106 testTest(t, strings.ToUpper(tt.in), tt)
107 }
108 }
109
110 func TestConstants(t *testing.T) {
111 for x, tt := range constants {
112 v, ok := tt.c.(fmt.Stringer)
113 if !ok {
114 t.Errorf("%x: %v: not a stringer", x, v)
115 } else if s := v.String(); s != tt.name {
116 v, _ := tt.c.(int)
117 t.Errorf("%x: Constant %T:%d gives %q, expected %q", x, tt.c, v, s, tt.name)
118 }
119 }
120 }
121
122 func TestRandomUUID(t *testing.T) {
123 m := make(map[string]bool)
124 for x := 1; x < 32; x++ {
125 uuid := NewRandom()
126 s := uuid.String()
127 if m[s] {
128 t.Errorf("NewRandom returned duplicated UUID %s", s)
129 }
130 m[s] = true
131 if v, _ := uuid.Version(); v != 4 {
132 t.Errorf("Random UUID of version %s", v)
133 }
134 if uuid.Variant() != RFC4122 {
135 t.Errorf("Random UUID is variant %d", uuid.Variant())
136 }
137 }
138 }
139
140 func TestNew(t *testing.T) {
141 m := make(map[string]bool)
142 for x := 1; x < 32; x++ {
143 s := New()
144 if m[s] {
145 t.Errorf("New returned duplicated UUID %s", s)
146 }
147 m[s] = true
148 uuid := Parse(s)
149 if uuid == nil {
150 t.Errorf("New returned %q which does not decode", s)
151 continue
152 }
153 if v, _ := uuid.Version(); v != 4 {
154 t.Errorf("Random UUID of version %s", v)
155 }
156 if uuid.Variant() != RFC4122 {
157 t.Errorf("Random UUID is variant %d", uuid.Variant())
158 }
159 }
160 }
161
162 func TestCoding(t *testing.T) {
163 text := "7d444840-9dc0-11d1-b245-5ffdce74fad2"
164 urn := "urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2"
165 data := UUID{
166 0x7d, 0x44, 0x48, 0x40,
167 0x9d, 0xc0,
168 0x11, 0xd1,
169 0xb2, 0x45,
170 0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2,
171 }
172 if v := data.String(); v != text {
173 t.Errorf("%x: encoded to %s, expected %s", data, v, text)
174 }
175 if v := data.URN(); v != urn {
176 t.Errorf("%x: urn is %s, expected %s", data, v, urn)
177 }
178
179 uuid := Parse(text)
180 if !Equal(uuid, data) {
181 t.Errorf("%s: decoded to %s, expected %s", text, uuid, data)
182 }
183 }
184
185 func TestVersion1(t *testing.T) {
186 uuid1 := NewUUID()
187 uuid2 := NewUUID()
188
189 if Equal(uuid1, uuid2) {
190 t.Errorf("%s:duplicate uuid", uuid1)
191 }
192 if v, _ := uuid1.Version(); v != 1 {
193 t.Errorf("%s: version %s expected 1", uuid1, v)
194 }
195 if v, _ := uuid2.Version(); v != 1 {
196 t.Errorf("%s: version %s expected 1", uuid2, v)
197 }
198 n1 := uuid1.NodeID()
199 n2 := uuid2.NodeID()
200 if !bytes.Equal(n1, n2) {
201 t.Errorf("Different nodes %x != %x", n1, n2)
202 }
203 t1, ok := uuid1.Time()
204 if !ok {
205 t.Errorf("%s: invalid time", uuid1)
206 }
207 t2, ok := uuid2.Time()
208 if !ok {
209 t.Errorf("%s: invalid time", uuid2)
210 }
211 q1, ok := uuid1.ClockSequence()
212 if !ok {
213 t.Errorf("%s: invalid clock sequence", uuid1)
214 }
215 q2, ok := uuid2.ClockSequence()
216 if !ok {
217 t.Errorf("%s: invalid clock sequence", uuid2)
218 }
219
220 switch {
221 case t1 == t2 && q1 == q2:
222 t.Error("time stopped")
223 case t1 > t2 && q1 == q2:
224 t.Error("time reversed")
225 case t1 < t2 && q1 != q2:
226 t.Error("clock sequence chaned unexpectedly")
227 }
228 }
229
230 func TestMD5(t *testing.T) {
231 uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String()
232 want := "6fa459ea-ee8a-3ca4-894e-db77e160355e"
233 if uuid != want {
234 t.Errorf("MD5: got %q expected %q", uuid, want)
235 }
236 }
237
238 func TestSHA1(t *testing.T) {
239 uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String()
240 want := "886313e1-3b8a-5372-9b90-0c9aee199e5d"
241 if uuid != want {
242 t.Errorf("SHA1: got %q expected %q", uuid, want)
243 }
244 }
245
246 func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) {
247 if uuid == nil {
248 t.Errorf("%s failed", name)
249 return
250 }
251 if v, _ := uuid.Version(); v != 2 {
252 t.Errorf("%s: %s: expected version 2, got %s", name, uuid, v)
253 return
254 }
255 if v, ok := uuid.Domain(); !ok || v != domain {
256 if !ok {
257 t.Errorf("%s: %d: Domain failed", name, uuid)
258 } else {
259 t.Errorf("%s: %s: expected domain %d, got %d", name, uuid, domain, v)
260 }
261 }
262 if v, ok := uuid.Id(); !ok || v != id {
263 if !ok {
264 t.Errorf("%s: %d: ID failed", name, uuid)
265 } else {
266 t.Errorf("%s: %s: expected id %d, got %d", name, uuid, id, v)
267 }
268 }
269 }
270
271 func TestDCE(t *testing.T) {
272 testDCE(t, "NewDCESecurity", NewDCESecurity(42, 12345678), 42, 12345678)
273 testDCE(t, "NewDCEPerson", NewDCEPerson(), Person, uint32(os.Getuid()))
274 testDCE(t, "NewDCEGroup", NewDCEGroup(), Group, uint32(os.Getgid()))
275 }
276
277 type badRand struct{}
278
279 func (r badRand) Read(buf []byte) (int, error) {
280 for i := range buf {
281 buf[i] = byte(i)
282 }
283 return len(buf), nil
284 }
285
286 func TestBadRand(t *testing.T) {
287 SetRand(badRand{})
288 uuid1 := New()
289 uuid2 := New()
290 if uuid1 != uuid2 {
291 t.Errorf("expected duplicates, got %q and %q", uuid1, uuid2)
292 }
293 SetRand(nil)
294 uuid1 = New()
295 uuid2 = New()
296 if uuid1 == uuid2 {
297 t.Errorf("unexpected duplicates, got %q", uuid1)
298 }
299 }
300
301 func TestUUID_Array(t *testing.T) {
302 expect := Array{
303 0xf4, 0x7a, 0xc1, 0x0b,
304 0x58, 0xcc,
305 0x03, 0x72,
306 0x85, 0x67,
307 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
308 }
309 uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
310 if uuid == nil {
311 t.Fatal("invalid uuid")
312 }
313 if uuid.Array() != expect {
314 t.Fatal("invalid array")
315 }
316 }
317
318 func TestArray_UUID(t *testing.T) {
319 array := Array{
320 0xf4, 0x7a, 0xc1, 0x0b,
321 0x58, 0xcc,
322 0x03, 0x72,
323 0x85, 0x67,
324 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
325 }
326 expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
327 if expect == nil {
328 t.Fatal("invalid uuid")
329 }
330 if !bytes.Equal(array.UUID(), expect) {
331 t.Fatal("invalid uuid")
332 }
333 }
334
335 func BenchmarkParse(b *testing.B) {
336 for i := 0; i < b.N; i++ {
337 uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
338 if uuid == nil {
339 b.Fatal("invalid uuid")
340 }
341 }
342 }
343
344 func BenchmarkNew(b *testing.B) {
345 for i := 0; i < b.N; i++ {
346 New()
347 }
348 }
349
350 func BenchmarkUUID_String(b *testing.B) {
351 uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
352 if uuid == nil {
353 b.Fatal("invalid uuid")
354 }
355 for i := 0; i < b.N; i++ {
356 if uuid.String() == "" {
357 b.Fatal("invalid uuid")
358 }
359 }
360 }
361
362 func BenchmarkUUID_URN(b *testing.B) {
363 uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
364 if uuid == nil {
365 b.Fatal("invalid uuid")
366 }
367 for i := 0; i < b.N; i++ {
368 if uuid.URN() == "" {
369 b.Fatal("invalid uuid")
370 }
371 }
372 }
373
374 func BenchmarkUUID_Array(b *testing.B) {
375 expect := Array{
376 0xf4, 0x7a, 0xc1, 0x0b,
377 0x58, 0xcc,
378 0x03, 0x72,
379 0x85, 0x67,
380 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
381 }
382 uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
383 if uuid == nil {
384 b.Fatal("invalid uuid")
385 }
386 for i := 0; i < b.N; i++ {
387 if uuid.Array() != expect {
388 b.Fatal("invalid array")
389 }
390 }
391 }
392
393 func BenchmarkArray_UUID(b *testing.B) {
394 array := Array{
395 0xf4, 0x7a, 0xc1, 0x0b,
396 0x58, 0xcc,
397 0x03, 0x72,
398 0x85, 0x67,
399 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
400 }
401 expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
402 if expect == nil {
403 b.Fatal("invalid uuid")
404 }
405 for i := 0; i < b.N; i++ {
406 if !bytes.Equal(array.UUID(), expect) {
407 b.Fatal("invalid uuid")
408 }
409 }
410 }
411
View as plain text