1// Copyright (C) 2013, 2015 by Maxim Bublis <b@codemonkey.ru> 2// 3// Permission is hereby granted, free of charge, to any person obtaining 4// a copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to 8// permit persons to whom the Software is furnished to do so, subject to 9// the following conditions: 10// 11// The above copyright notice and this permission notice shall be 12// included in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22package uuid 23 24import ( 25 "bytes" 26 "testing" 27) 28 29func TestBytes(t *testing.T) { 30 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 31 32 bytes1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 33 34 if !bytes.Equal(u.Bytes(), bytes1) { 35 t.Errorf("Incorrect bytes representation for UUID: %s", u) 36 } 37} 38 39func TestString(t *testing.T) { 40 if NamespaceDNS.String() != "6ba7b810-9dad-11d1-80b4-00c04fd430c8" { 41 t.Errorf("Incorrect string representation for UUID: %s", NamespaceDNS.String()) 42 } 43} 44 45func TestEqual(t *testing.T) { 46 if !Equal(NamespaceDNS, NamespaceDNS) { 47 t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceDNS) 48 } 49 50 if Equal(NamespaceDNS, NamespaceURL) { 51 t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceURL) 52 } 53} 54 55func TestOr(t *testing.T) { 56 u1 := UUID{0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff} 57 u2 := UUID{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00} 58 59 u := UUID{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 60 61 if !Equal(u, Or(u1, u2)) { 62 t.Errorf("Incorrect bitwise OR result %s", Or(u1, u2)) 63 } 64} 65 66func TestAnd(t *testing.T) { 67 u1 := UUID{0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff} 68 u2 := UUID{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00} 69 70 u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 71 72 if !Equal(u, And(u1, u2)) { 73 t.Errorf("Incorrect bitwise AND result %s", And(u1, u2)) 74 } 75} 76 77func TestVersion(t *testing.T) { 78 u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 79 80 if u.Version() != 1 { 81 t.Errorf("Incorrect version for UUID: %d", u.Version()) 82 } 83} 84 85func TestSetVersion(t *testing.T) { 86 u := UUID{} 87 u.SetVersion(4) 88 89 if u.Version() != 4 { 90 t.Errorf("Incorrect version for UUID after u.setVersion(4): %d", u.Version()) 91 } 92} 93 94func TestVariant(t *testing.T) { 95 u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 96 97 if u1.Variant() != VariantNCS { 98 t.Errorf("Incorrect variant for UUID variant %d: %d", VariantNCS, u1.Variant()) 99 } 100 101 u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 102 103 if u2.Variant() != VariantRFC4122 { 104 t.Errorf("Incorrect variant for UUID variant %d: %d", VariantRFC4122, u2.Variant()) 105 } 106 107 u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 108 109 if u3.Variant() != VariantMicrosoft { 110 t.Errorf("Incorrect variant for UUID variant %d: %d", VariantMicrosoft, u3.Variant()) 111 } 112 113 u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 114 115 if u4.Variant() != VariantFuture { 116 t.Errorf("Incorrect variant for UUID variant %d: %d", VariantFuture, u4.Variant()) 117 } 118} 119 120func TestSetVariant(t *testing.T) { 121 u := new(UUID) 122 u.SetVariant() 123 124 if u.Variant() != VariantRFC4122 { 125 t.Errorf("Incorrect variant for UUID after u.setVariant(): %d", u.Variant()) 126 } 127} 128 129func TestFromBytes(t *testing.T) { 130 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 131 b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 132 133 u1, err := FromBytes(b1) 134 if err != nil { 135 t.Errorf("Error parsing UUID from bytes: %s", err) 136 } 137 138 if !Equal(u, u1) { 139 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 140 } 141 142 b2 := []byte{} 143 144 _, err = FromBytes(b2) 145 if err == nil { 146 t.Errorf("Should return error parsing from empty byte slice, got %s", err) 147 } 148} 149 150func TestMarshalBinary(t *testing.T) { 151 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 152 b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 153 154 b2, err := u.MarshalBinary() 155 if err != nil { 156 t.Errorf("Error marshaling UUID: %s", err) 157 } 158 159 if !bytes.Equal(b1, b2) { 160 t.Errorf("Marshaled UUID should be %s, got %s", b1, b2) 161 } 162} 163 164func TestUnmarshalBinary(t *testing.T) { 165 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 166 b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 167 168 u1 := UUID{} 169 err := u1.UnmarshalBinary(b1) 170 if err != nil { 171 t.Errorf("Error unmarshaling UUID: %s", err) 172 } 173 174 if !Equal(u, u1) { 175 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 176 } 177 178 b2 := []byte{} 179 u2 := UUID{} 180 181 err = u2.UnmarshalBinary(b2) 182 if err == nil { 183 t.Errorf("Should return error unmarshalling from empty byte slice, got %s", err) 184 } 185} 186 187func TestFromString(t *testing.T) { 188 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 189 190 s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 191 s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" 192 s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 193 194 _, err := FromString("") 195 if err == nil { 196 t.Errorf("Should return error trying to parse empty string, got %s", err) 197 } 198 199 u1, err := FromString(s1) 200 if err != nil { 201 t.Errorf("Error parsing UUID from string: %s", err) 202 } 203 204 if !Equal(u, u1) { 205 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 206 } 207 208 u2, err := FromString(s2) 209 if err != nil { 210 t.Errorf("Error parsing UUID from string: %s", err) 211 } 212 213 if !Equal(u, u2) { 214 t.Errorf("UUIDs should be equal: %s and %s", u, u2) 215 } 216 217 u3, err := FromString(s3) 218 if err != nil { 219 t.Errorf("Error parsing UUID from string: %s", err) 220 } 221 222 if !Equal(u, u3) { 223 t.Errorf("UUIDs should be equal: %s and %s", u, u3) 224 } 225} 226 227func TestFromStringOrNil(t *testing.T) { 228 u := FromStringOrNil("") 229 if u != Nil { 230 t.Errorf("Should return Nil UUID on parse failure, got %s", u) 231 } 232} 233 234func TestFromBytesOrNil(t *testing.T) { 235 b := []byte{} 236 u := FromBytesOrNil(b) 237 if u != Nil { 238 t.Errorf("Should return Nil UUID on parse failure, got %s", u) 239 } 240} 241 242func TestMarshalText(t *testing.T) { 243 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 244 b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 245 246 b2, err := u.MarshalText() 247 if err != nil { 248 t.Errorf("Error marshaling UUID: %s", err) 249 } 250 251 if !bytes.Equal(b1, b2) { 252 t.Errorf("Marshaled UUID should be %s, got %s", b1, b2) 253 } 254} 255 256func TestUnmarshalText(t *testing.T) { 257 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 258 b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 259 260 u1 := UUID{} 261 err := u1.UnmarshalText(b1) 262 if err != nil { 263 t.Errorf("Error unmarshaling UUID: %s", err) 264 } 265 266 if !Equal(u, u1) { 267 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 268 } 269 270 b2 := []byte("") 271 u2 := UUID{} 272 273 err = u2.UnmarshalText(b2) 274 if err == nil { 275 t.Errorf("Should return error trying to unmarshal from empty string") 276 } 277} 278 279func TestValue(t *testing.T) { 280 u, err := FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 281 if err != nil { 282 t.Errorf("Error parsing UUID from string: %s", err) 283 } 284 285 val, err := u.Value() 286 if err != nil { 287 t.Errorf("Error getting UUID value: %s", err) 288 } 289 290 if val != u.String() { 291 t.Errorf("Wrong value returned, should be equal: %s and %s", val, u) 292 } 293} 294 295func TestScanBinary(t *testing.T) { 296 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 297 b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 298 299 u1 := UUID{} 300 err := u1.Scan(b1) 301 if err != nil { 302 t.Errorf("Error unmarshaling UUID: %s", err) 303 } 304 305 if !Equal(u, u1) { 306 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 307 } 308 309 b2 := []byte{} 310 u2 := UUID{} 311 312 err = u2.Scan(b2) 313 if err == nil { 314 t.Errorf("Should return error unmarshalling from empty byte slice, got %s", err) 315 } 316} 317 318func TestScanString(t *testing.T) { 319 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 320 s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 321 322 u1 := UUID{} 323 err := u1.Scan(s1) 324 if err != nil { 325 t.Errorf("Error unmarshaling UUID: %s", err) 326 } 327 328 if !Equal(u, u1) { 329 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 330 } 331 332 s2 := "" 333 u2 := UUID{} 334 335 err = u2.Scan(s2) 336 if err == nil { 337 t.Errorf("Should return error trying to unmarshal from empty string") 338 } 339} 340 341func TestScanText(t *testing.T) { 342 u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 343 b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 344 345 u1 := UUID{} 346 err := u1.Scan(b1) 347 if err != nil { 348 t.Errorf("Error unmarshaling UUID: %s", err) 349 } 350 351 if !Equal(u, u1) { 352 t.Errorf("UUIDs should be equal: %s and %s", u, u1) 353 } 354 355 b2 := []byte("") 356 u2 := UUID{} 357 358 err = u2.Scan(b2) 359 if err == nil { 360 t.Errorf("Should return error trying to unmarshal from empty string") 361 } 362} 363 364func TestScanUnsupported(t *testing.T) { 365 u := UUID{} 366 367 err := u.Scan(true) 368 if err == nil { 369 t.Errorf("Should return error trying to unmarshal from bool") 370 } 371} 372 373func TestNewV1(t *testing.T) { 374 u := NewV1() 375 376 if u.Version() != 1 { 377 t.Errorf("UUIDv1 generated with incorrect version: %d", u.Version()) 378 } 379 380 if u.Variant() != VariantRFC4122 { 381 t.Errorf("UUIDv1 generated with incorrect variant: %d", u.Variant()) 382 } 383 384 u1 := NewV1() 385 u2 := NewV1() 386 387 if Equal(u1, u2) { 388 t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u1, u2) 389 } 390 391 oldFunc := epochFunc 392 epochFunc = func() uint64 { return 0 } 393 394 u3 := NewV1() 395 u4 := NewV1() 396 397 if Equal(u3, u4) { 398 t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u3, u4) 399 } 400 401 epochFunc = oldFunc 402} 403 404func TestNewV2(t *testing.T) { 405 u1 := NewV2(DomainPerson) 406 407 if u1.Version() != 2 { 408 t.Errorf("UUIDv2 generated with incorrect version: %d", u1.Version()) 409 } 410 411 if u1.Variant() != VariantRFC4122 { 412 t.Errorf("UUIDv2 generated with incorrect variant: %d", u1.Variant()) 413 } 414 415 u2 := NewV2(DomainGroup) 416 417 if u2.Version() != 2 { 418 t.Errorf("UUIDv2 generated with incorrect version: %d", u2.Version()) 419 } 420 421 if u2.Variant() != VariantRFC4122 { 422 t.Errorf("UUIDv2 generated with incorrect variant: %d", u2.Variant()) 423 } 424} 425 426func TestNewV3(t *testing.T) { 427 u := NewV3(NamespaceDNS, "www.example.com") 428 429 if u.Version() != 3 { 430 t.Errorf("UUIDv3 generated with incorrect version: %d", u.Version()) 431 } 432 433 if u.Variant() != VariantRFC4122 { 434 t.Errorf("UUIDv3 generated with incorrect variant: %d", u.Variant()) 435 } 436 437 if u.String() != "5df41881-3aed-3515-88a7-2f4a814cf09e" { 438 t.Errorf("UUIDv3 generated incorrectly: %s", u.String()) 439 } 440 441 u = NewV3(NamespaceDNS, "python.org") 442 443 if u.String() != "6fa459ea-ee8a-3ca4-894e-db77e160355e" { 444 t.Errorf("UUIDv3 generated incorrectly: %s", u.String()) 445 } 446 447 u1 := NewV3(NamespaceDNS, "golang.org") 448 u2 := NewV3(NamespaceDNS, "golang.org") 449 if !Equal(u1, u2) { 450 t.Errorf("UUIDv3 generated different UUIDs for same namespace and name: %s and %s", u1, u2) 451 } 452 453 u3 := NewV3(NamespaceDNS, "example.com") 454 if Equal(u1, u3) { 455 t.Errorf("UUIDv3 generated same UUIDs for different names in same namespace: %s and %s", u1, u2) 456 } 457 458 u4 := NewV3(NamespaceURL, "golang.org") 459 if Equal(u1, u4) { 460 t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4) 461 } 462} 463 464func TestNewV4(t *testing.T) { 465 u := NewV4() 466 467 if u.Version() != 4 { 468 t.Errorf("UUIDv4 generated with incorrect version: %d", u.Version()) 469 } 470 471 if u.Variant() != VariantRFC4122 { 472 t.Errorf("UUIDv4 generated with incorrect variant: %d", u.Variant()) 473 } 474} 475 476func TestNewV5(t *testing.T) { 477 u := NewV5(NamespaceDNS, "www.example.com") 478 479 if u.Version() != 5 { 480 t.Errorf("UUIDv5 generated with incorrect version: %d", u.Version()) 481 } 482 483 if u.Variant() != VariantRFC4122 { 484 t.Errorf("UUIDv5 generated with incorrect variant: %d", u.Variant()) 485 } 486 487 u = NewV5(NamespaceDNS, "python.org") 488 489 if u.String() != "886313e1-3b8a-5372-9b90-0c9aee199e5d" { 490 t.Errorf("UUIDv5 generated incorrectly: %s", u.String()) 491 } 492 493 u1 := NewV5(NamespaceDNS, "golang.org") 494 u2 := NewV5(NamespaceDNS, "golang.org") 495 if !Equal(u1, u2) { 496 t.Errorf("UUIDv5 generated different UUIDs for same namespace and name: %s and %s", u1, u2) 497 } 498 499 u3 := NewV5(NamespaceDNS, "example.com") 500 if Equal(u1, u3) { 501 t.Errorf("UUIDv5 generated same UUIDs for different names in same namespace: %s and %s", u1, u2) 502 } 503 504 u4 := NewV5(NamespaceURL, "golang.org") 505 if Equal(u1, u4) { 506 t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4) 507 } 508} 509