github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/twinj/uuid/uuids_test.go (about) 1 package uuid 2 3 /**************** 4 * Date: 3/02/14 5 * Time: 10:59 PM 6 ***************/ 7 8 import ( 9 "crypto/md5" 10 "crypto/sha1" 11 "fmt" 12 "regexp" 13 "strings" 14 "testing" 15 ) 16 17 const ( 18 secondsPerHour = 60 * 60 19 secondsPerDay = 24 * secondsPerHour 20 unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay 21 internalToUnix int64 = -unixToInternal 22 ) 23 24 var ( 25 uuid_goLang Name = "https://google.com/golang.org?q=golang" 26 printer bool = false 27 uuid_bytes = []byte{ 28 0xAA, 0xCF, 0xEE, 0x12, 29 0xD4, 0x00, 30 0x27, 0x23, 31 0x00, 32 0xD3, 33 0x23, 0x12, 0x4A, 0x11, 0x89, 0xFF, 34 } 35 uuid_variants = []byte{ 36 ReservedNCS, ReservedRFC4122, ReservedMicrosoft, ReservedFuture, 37 } 38 namespaceUuids = []UUID{ 39 NamespaceDNS, NamespaceURL, NamespaceOID, NamespaceX500, 40 } 41 invalidHexStrings = [...]string{ 42 "foo", 43 "6ba7b814-9dad-11d1-80b4-", 44 "6ba7b814--9dad-11d1-80b4--00c04fd430c8", 45 "6ba7b814-9dad7-11d1-80b4-00c04fd430c8999", 46 "{6ba7b814-9dad-1180b4-00c04fd430c8", 47 "{6ba7b814--11d1-80b4-00c04fd430c8}", 48 "urn:uuid:6ba7b814-9dad-1666666680b4-00c04fd430c8", 49 } 50 validHexStrings = [...]string{ 51 "6ba7b8149dad-11d1-80b4-00c04fd430c8}", 52 "{6ba7b8149dad-11d1-80b400c04fd430c8}", 53 "{6ba7b814-9dad11d180b400c04fd430c8}", 54 "6ba7b8149dad-11d1-80b4-00c04fd430c8", 55 "6ba7b814-9dad11d1-80b4-00c04fd430c8", 56 "6ba7b814-9dad-11d180b4-00c04fd430c8", 57 "6ba7b814-9dad-11d1-80b400c04fd430c8", 58 "6ba7b8149dad11d180b400c04fd430c8", 59 "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 60 "{6ba7b814-9dad-11d1-80b4-00c04fd430c8}", 61 "{6ba7b814-9dad-11d1-80b4-00c04fd430c8", 62 "6ba7b814-9dad-11d1-80b4-00c04fd430c8}", 63 "(6ba7b814-9dad-11d1-80b4-00c04fd430c8)", 64 "urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8", 65 } 66 ) 67 68 func TestUUID_Simple(t *testing.T) { 69 u := NewV1() 70 outputLn(u) 71 72 u, _ = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 73 u = NewV3(u, Name("test")) 74 outputLn(u) 75 if !strings.EqualFold("45a113ac-c7f2-30b0-90a5-a399ab912716", u.String()) { 76 t.Errorf("Expected string representation to be %s, but got: %s", "45a113ac-c7f2-30b0-90a5-a399ab912716", u.String()) 77 } 78 79 u = NewV4() 80 outputLn(u) 81 82 u = NewV5(u, Name("test")) 83 outputLn(u) 84 } 85 86 func TestUUID_New(t *testing.T) { 87 u := New(uuid_bytes) 88 if u == nil { 89 t.Error("Expected a valid UUID") 90 } 91 if u.Version() != 2 { 92 t.Errorf("Expected correct version %d, but got %d", 2, u.Version()) 93 } 94 if u.Variant() != ReservedNCS { 95 t.Errorf("Expected ReservedNCS variant %x, but got %x", ReservedNCS, u.Variant()) 96 } 97 if !parseUUIDRegex.MatchString(u.String()) { 98 t.Errorf("Expected string representation to be valid, given: %s", u.String()) 99 } 100 } 101 102 func TestUUID_NewBulk(t *testing.T) { 103 for i := 0; i < 1000000; i++ { 104 New(uuid_bytes) 105 } 106 } 107 108 109 const ( 110 clean = `[A-Fa-f0-9]{8}[A-Fa-f0-9]{4}[1-5fF][A-Fa-f0-9]{3}[A-Fa-f0-9]{4}[A-Fa-f0-9]{12}` 111 cleanHexPattern = `^` + clean + `$` 112 curlyHexPattern = `^\{` + clean + `\}$` 113 bracketHexPattern = `^\(` + clean + `\)$` 114 hyphen = `[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[1-5fF][A-Fa-f0-9]{3}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}` 115 cleanHyphenHexPattern = `^` + hyphen + `$` 116 curlyHyphenHexPattern = `^\{` + hyphen + `\}$` 117 bracketHyphenHexPattern = `^\(` + hyphen + `\)$` 118 goIdHexPattern = `^\[[A-F0-9]{8}-[A-F0-9]{4}-[1-5fF][a-f0-9]{3}-[A-F0-9]{4}-[a-f0-9]{12}\]$` 119 ) 120 121 func TestUUID_Formats_String(t *testing.T) { 122 ids := []UUID{NewV4(), NewV1()} 123 124 // Reset default 125 SwitchFormat(CleanHyphen) 126 127 for _, u := range ids { 128 129 SwitchFormatUpperCase(CurlyHyphen) 130 if !regexp.MustCompile(curlyHyphenHexPattern).MatchString(u.String()) { 131 t.Error("Curly hyphen UUID string output got", u, u.Version()) 132 } 133 outputLn(u) 134 135 // Clean 136 SwitchFormat(Clean) 137 if !regexp.MustCompile(cleanHexPattern).MatchString(u.String()) { 138 t.Error("Clean UUID string output got", u, u.Version()) 139 } 140 outputLn(u) 141 142 // Curly 143 SwitchFormat(Curly) 144 if !regexp.MustCompile(curlyHexPattern).MatchString(u.String()) { 145 t.Error("Curly clean UUID string output got", u, u.Version()) 146 } 147 outputLn(u) 148 149 // Bracket 150 SwitchFormat(Bracket) 151 if !regexp.MustCompile(bracketHexPattern).MatchString(u.String()) { 152 t.Error("Bracket clean UUID string output got", u, u.Version()) 153 } 154 outputLn(u) 155 156 // Clean Hyphen 157 SwitchFormat(CleanHyphen) 158 if !regexp.MustCompile(cleanHyphenHexPattern).MatchString(u.String()) { 159 t.Error("Clean hyphen UUID string output got", u, u.Version()) 160 } 161 outputLn(u) 162 163 // Bracket Hyphen 164 SwitchFormat(BracketHyphen) 165 if !regexp.MustCompile(bracketHyphenHexPattern).MatchString(u.String()) { 166 t.Error("Bracket hyphen UUID string output got", u, u.Version()) 167 } 168 outputLn(u) 169 170 // Bracket Hyphen 171 SwitchFormat(GoIdFormat) 172 if !regexp.MustCompile(goIdHexPattern).MatchString(u.String()) { 173 t.Error("GoId UUID string output expected", u, u.Version()) 174 } 175 outputLn(u) 176 177 // Reset default 178 SwitchFormat(CleanHyphen) 179 } 180 } 181 182 func TestUUID_Formatter(t *testing.T) { 183 ids := []UUID{NewV4(), NewV1()} 184 185 for _, u := range ids { 186 // CurlyHyphen - default 187 if !regexp.MustCompile(curlyHyphenHexPattern).MatchString(Formatter(u, CurlyHyphen)) { 188 t.Error("Curly hyphen UUID string output got", Formatter(u, CurlyHyphen)) 189 } 190 outputLn(Formatter(u, CurlyHyphen)) 191 192 // Clean 193 if !regexp.MustCompile(cleanHexPattern).MatchString(Formatter(u, Clean)) { 194 t.Error("Clean UUID string output got", Formatter(u, Clean)) 195 } 196 outputLn(Formatter(u, Clean)) 197 198 // Curly 199 if !regexp.MustCompile(curlyHexPattern).MatchString(Formatter(u, Curly)) { 200 t.Error("Curly clean UUID string output", Formatter(u, Curly)) 201 } 202 outputLn(Formatter(u, Curly)) 203 204 // Bracket 205 if !regexp.MustCompile(bracketHexPattern).MatchString(Formatter(u, Bracket)) { 206 t.Error("Bracket clean UUID string output", Formatter(u, Bracket)) 207 } 208 outputLn(Formatter(u, Bracket)) 209 210 // Clean Hyphen 211 if !regexp.MustCompile(cleanHyphenHexPattern).MatchString(Formatter(u, CleanHyphen)) { 212 t.Error("Clean hyphen UUID string output", Formatter(u, CleanHyphen)) 213 } 214 outputLn(Formatter(u, CleanHyphen)) 215 216 // Bracket Hyphen 217 if !regexp.MustCompile(bracketHyphenHexPattern).MatchString(Formatter(u, BracketHyphen)) { 218 t.Error("Bracket hyphen UUID string output", Formatter(u, BracketHyphen)) 219 } 220 outputLn(Formatter(u, BracketHyphen)) 221 222 // GoId Format 223 if !regexp.MustCompile(goIdHexPattern).MatchString(Formatter(u, GoIdFormat)) { 224 t.Error("GoId UUID string output expected", Formatter(u, GoIdFormat)) 225 } 226 outputLn(Formatter(u, GoIdFormat)) 227 } 228 } 229 230 func TestUUID_NewHex(t *testing.T) { 231 s := "f3593cffee9240df408687825b523f13" 232 u := NewHex(s) 233 if u == nil { 234 t.Error("Expected a valid UUID") 235 } 236 if u.Version() != 4 { 237 t.Errorf("Expected correct version %d, but got %d", 4, u.Version()) 238 } 239 if u.Variant() != ReservedNCS { 240 t.Errorf("Expected ReservedNCS variant %x, but got %x", ReservedNCS, u.Variant()) 241 } 242 if !parseUUIDRegex.MatchString(u.String()) { 243 t.Errorf("Expected string representation to be valid, given: %s", u.String()) 244 } 245 } 246 247 func TestUUID_NewHexBulk(t *testing.T) { 248 for i := 0; i < 1000000; i++ { 249 s := "f3593cffee9240df408687825b523f13" 250 NewHex(s) 251 } 252 } 253 254 func TestUUID_Parse(t *testing.T) { 255 for _, v := range invalidHexStrings { 256 _, err := Parse(v) 257 if err == nil { 258 t.Error("Expected error due to invalid UUID string:", v) 259 } 260 } 261 for _, v := range validHexStrings { 262 _, err := Parse(v) 263 if err != nil { 264 t.Error("Expected valid UUID string but got error:", v) 265 } 266 } 267 for _, id := range namespaceUuids { 268 _, err := Parse(id.String()) 269 if err != nil { 270 t.Error("Expected valid UUID string but got error:", err) 271 } 272 } 273 } 274 275 func TestUUID_Sum(t *testing.T) { 276 u := new(Array) 277 Digest(u, NamespaceDNS, uuid_goLang, md5.New()) 278 if u.Bytes() == nil { 279 t.Error("Expected new data in bytes") 280 } 281 output(u.Bytes()) 282 u = new(Array) 283 Digest(u, NamespaceDNS, uuid_goLang, sha1.New()) 284 if u.Bytes() == nil { 285 t.Error("Expected new data in bytes") 286 } 287 output(u.Bytes()) 288 } 289 290 // Tests all possible version numbers and that 291 // each number returned is the same 292 func TestUUID_Struct_VersionBits(t *testing.T) { 293 uStruct := new(Struct) 294 uStruct.size = length 295 for v := 0; v < 16; v++ { 296 for i := 0; i <= 255; i++ { 297 uuid_bytes[versionIndex] = byte(i) 298 uStruct.Unmarshal(uuid_bytes) 299 uStruct.setVersion(v) 300 output(uStruct) 301 if uStruct.Version() != v { 302 t.Errorf("%x does not resolve to %x", byte(uStruct.Version()), v) 303 } 304 output("\n") 305 } 306 } 307 } 308 309 // Tests all possible variants with their respective bits set 310 // Tests whether the expected output comes out on each byte case 311 func TestUUID_Struct_VariantBits(t *testing.T) { 312 for _, v := range uuid_variants { 313 for i := 0; i <= 255; i++ { 314 uuid_bytes[variantIndex] = byte(i) 315 316 uStruct := createStruct(uuid_bytes, 4, v) 317 b := uStruct.sequenceHiAndVariant >> 4 318 tVariantConstraint(v, b, uStruct, t) 319 320 if uStruct.Variant() != v { 321 t.Errorf("%d does not resolve to %x: get %x", i, v, uStruct.Variant()) 322 } 323 } 324 } 325 } 326 327 // Tests all possible variants with their respective bits set 328 // Tests whether the expected output comes out on each byte case 329 func TestUUID_Array_VariantBits(t *testing.T) { 330 for _, v := range uuid_variants { 331 for i := 0; i <= 255; i++ { 332 uuid_bytes[variantIndex] = byte(i) 333 334 uArray := createArray(uuid_bytes, 4, v) 335 b := uArray[variantIndex] >> 4 336 tVariantConstraint(v, b, uArray, t) 337 338 if uArray.Variant() != v { 339 t.Errorf("%d does not resolve to %x", i, v) 340 } 341 } 342 } 343 } 344 345 // Tests all possible version numbers and that 346 // each number returned is the same 347 func TestUUID_Array_VersionBits(t *testing.T) { 348 uArray := new(Array) 349 for v := 0; v < 16; v++ { 350 for i := 0; i <= 255; i++ { 351 uuid_bytes[versionIndex] = byte(i) 352 uArray.Unmarshal(uuid_bytes) 353 uArray.setVersion(v) 354 output(uArray) 355 if uArray.Version() != v { 356 t.Errorf("%x does not resolve to %x", byte(uArray.Version()), v) 357 } 358 output("\n") 359 } 360 } 361 } 362 363 func BenchmarkUUID_Parse(b *testing.B) { 364 s := "f3593cff-ee92-40df-4086-87825b523f13" 365 for i := 0; i < b.N; i++ { 366 _, err := Parse(s) 367 if err != nil { 368 b.Fatal(err) 369 } 370 } 371 b.StopTimer() 372 b.ReportAllocs() 373 } 374 375 // ******************************************************* 376 377 func createStruct(pData []byte, pVersion int, pVariant byte) *Struct { 378 o := new(Struct) 379 o.size = length 380 o.Unmarshal(pData) 381 o.setVersion(pVersion) 382 o.setVariant(pVariant) 383 return o 384 } 385 386 func createArray(pData []byte, pVersion int, pVariant byte) *Array { 387 o := new(Array) 388 o.Unmarshal(pData) 389 o.setVersion(pVersion) 390 o.setVariant(pVariant) 391 return o 392 } 393 394 func tVariantConstraint(v byte, b byte, o UUID, t *testing.T) { 395 output(o) 396 switch v { 397 case ReservedNCS: 398 switch b { 399 case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07: 400 outputF(": %X ", b) 401 break 402 default: 403 t.Errorf("%X most high bits do not resolve to 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07", b) 404 } 405 case ReservedRFC4122: 406 switch b { 407 case 0x08, 0x09, 0x0A, 0x0B: 408 outputF(": %X ", b) 409 break 410 default: 411 t.Errorf("%X most high bits do not resolve to 0x08, 0x09, 0x0A, 0x0B", b) 412 } 413 case ReservedMicrosoft: 414 switch b { 415 case 0x0C, 0x0D: 416 outputF(": %X ", b) 417 break 418 default: 419 t.Errorf("%X most high bits do not resolve to 0x0C, 0x0D", b) 420 } 421 case ReservedFuture: 422 switch b { 423 case 0x0E, 0x0F: 424 outputF(": %X ", b) 425 break 426 default: 427 t.Errorf("%X most high bits do not resolve to 0x0E, 0x0F", b) 428 } 429 } 430 output("\n") 431 } 432 433 func output(a ...interface{}) { 434 if printer { 435 fmt.Print(a...) 436 } 437 } 438 439 func outputLn(a ...interface{}) { 440 if printer { 441 fmt.Println(a...) 442 } 443 } 444 445 func outputF(format string, a ...interface{}) { 446 if printer { 447 fmt.Printf(format, a) 448 } 449 }