uuid_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // Copyright 2011 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package uuid
  5. import (
  6. "bytes"
  7. "fmt"
  8. "os"
  9. "strings"
  10. "testing"
  11. "time"
  12. )
  13. type test struct {
  14. in string
  15. version Version
  16. variant Variant
  17. isuuid bool
  18. }
  19. var tests = []test{
  20. {"f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, RFC4122, true},
  21. {"f47ac10b-58cc-1372-8567-0e02b2c3d479", 1, RFC4122, true},
  22. {"f47ac10b-58cc-2372-8567-0e02b2c3d479", 2, RFC4122, true},
  23. {"f47ac10b-58cc-3372-8567-0e02b2c3d479", 3, RFC4122, true},
  24. {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true},
  25. {"f47ac10b-58cc-5372-8567-0e02b2c3d479", 5, RFC4122, true},
  26. {"f47ac10b-58cc-6372-8567-0e02b2c3d479", 6, RFC4122, true},
  27. {"f47ac10b-58cc-7372-8567-0e02b2c3d479", 7, RFC4122, true},
  28. {"f47ac10b-58cc-8372-8567-0e02b2c3d479", 8, RFC4122, true},
  29. {"f47ac10b-58cc-9372-8567-0e02b2c3d479", 9, RFC4122, true},
  30. {"f47ac10b-58cc-a372-8567-0e02b2c3d479", 10, RFC4122, true},
  31. {"f47ac10b-58cc-b372-8567-0e02b2c3d479", 11, RFC4122, true},
  32. {"f47ac10b-58cc-c372-8567-0e02b2c3d479", 12, RFC4122, true},
  33. {"f47ac10b-58cc-d372-8567-0e02b2c3d479", 13, RFC4122, true},
  34. {"f47ac10b-58cc-e372-8567-0e02b2c3d479", 14, RFC4122, true},
  35. {"f47ac10b-58cc-f372-8567-0e02b2c3d479", 15, RFC4122, true},
  36. {"urn:uuid:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
  37. {"URN:UUID:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
  38. {"f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
  39. {"f47ac10b-58cc-4372-1567-0e02b2c3d479", 4, Reserved, true},
  40. {"f47ac10b-58cc-4372-2567-0e02b2c3d479", 4, Reserved, true},
  41. {"f47ac10b-58cc-4372-3567-0e02b2c3d479", 4, Reserved, true},
  42. {"f47ac10b-58cc-4372-4567-0e02b2c3d479", 4, Reserved, true},
  43. {"f47ac10b-58cc-4372-5567-0e02b2c3d479", 4, Reserved, true},
  44. {"f47ac10b-58cc-4372-6567-0e02b2c3d479", 4, Reserved, true},
  45. {"f47ac10b-58cc-4372-7567-0e02b2c3d479", 4, Reserved, true},
  46. {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true},
  47. {"f47ac10b-58cc-4372-9567-0e02b2c3d479", 4, RFC4122, true},
  48. {"f47ac10b-58cc-4372-a567-0e02b2c3d479", 4, RFC4122, true},
  49. {"f47ac10b-58cc-4372-b567-0e02b2c3d479", 4, RFC4122, true},
  50. {"f47ac10b-58cc-4372-c567-0e02b2c3d479", 4, Microsoft, true},
  51. {"f47ac10b-58cc-4372-d567-0e02b2c3d479", 4, Microsoft, true},
  52. {"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true},
  53. {"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true},
  54. {"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false},
  55. {"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false},
  56. {"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false},
  57. {"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false},
  58. {"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false},
  59. {"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false},
  60. }
  61. var constants = []struct {
  62. c interface{}
  63. name string
  64. }{
  65. {Person, "Person"},
  66. {Group, "Group"},
  67. {Org, "Org"},
  68. {Invalid, "Invalid"},
  69. {RFC4122, "RFC4122"},
  70. {Reserved, "Reserved"},
  71. {Microsoft, "Microsoft"},
  72. {Future, "Future"},
  73. {Domain(17), "Domain17"},
  74. {Variant(42), "BadVariant42"},
  75. }
  76. func testTest(t *testing.T, in string, tt test) {
  77. uuid := Parse(in)
  78. if ok := (uuid != nil); ok != tt.isuuid {
  79. t.Errorf("Parse(%s) got %v expected %v\b", in, ok, tt.isuuid)
  80. }
  81. if uuid == nil {
  82. return
  83. }
  84. if v := uuid.Variant(); v != tt.variant {
  85. t.Errorf("Variant(%s) got %d expected %d\b", in, v, tt.variant)
  86. }
  87. if v, _ := uuid.Version(); v != tt.version {
  88. t.Errorf("Version(%s) got %d expected %d\b", in, v, tt.version)
  89. }
  90. }
  91. func TestUUID(t *testing.T) {
  92. for _, tt := range tests {
  93. testTest(t, tt.in, tt)
  94. testTest(t, strings.ToUpper(tt.in), tt)
  95. }
  96. }
  97. func TestConstants(t *testing.T) {
  98. for x, tt := range constants {
  99. v, ok := tt.c.(fmt.Stringer)
  100. if !ok {
  101. t.Errorf("%x: %v: not a stringer", x, v)
  102. } else if s := v.String(); s != tt.name {
  103. v, _ := tt.c.(int)
  104. t.Errorf("%x: Constant %T:%d gives %q, expected %q", x, tt.c, v, s, tt.name)
  105. }
  106. }
  107. }
  108. func TestRandomUUID(t *testing.T) {
  109. m := make(map[string]bool)
  110. for x := 1; x < 32; x++ {
  111. uuid := NewRandom()
  112. s := uuid.String()
  113. if m[s] {
  114. t.Errorf("NewRandom returned duplicated UUID %s", s)
  115. }
  116. m[s] = true
  117. if v, _ := uuid.Version(); v != 4 {
  118. t.Errorf("Random UUID of version %s", v)
  119. }
  120. if uuid.Variant() != RFC4122 {
  121. t.Errorf("Random UUID is variant %d", uuid.Variant())
  122. }
  123. }
  124. }
  125. func TestNew(t *testing.T) {
  126. m := make(map[string]bool)
  127. for x := 1; x < 32; x++ {
  128. s := New()
  129. if m[s] {
  130. t.Errorf("New returned duplicated UUID %s", s)
  131. }
  132. m[s] = true
  133. uuid := Parse(s)
  134. if uuid == nil {
  135. t.Errorf("New returned %q which does not decode", s)
  136. continue
  137. }
  138. if v, _ := uuid.Version(); v != 4 {
  139. t.Errorf("Random UUID of version %s", v)
  140. }
  141. if uuid.Variant() != RFC4122 {
  142. t.Errorf("Random UUID is variant %d", uuid.Variant())
  143. }
  144. }
  145. }
  146. func clockSeq(t *testing.T, uuid UUID) int {
  147. seq, ok := uuid.ClockSequence()
  148. if !ok {
  149. t.Fatalf("%s: invalid clock sequence", uuid)
  150. }
  151. return seq
  152. }
  153. func TestClockSeq(t *testing.T) {
  154. // Fake time.Now for this test to return a monotonically advancing time; restore it at end.
  155. defer func(orig func() time.Time) { timeNow = orig }(timeNow)
  156. monTime := time.Now()
  157. timeNow = func() time.Time {
  158. monTime = monTime.Add(1 * time.Second)
  159. return monTime
  160. }
  161. SetClockSequence(-1)
  162. uuid1 := NewUUID()
  163. uuid2 := NewUUID()
  164. if clockSeq(t, uuid1) != clockSeq(t, uuid2) {
  165. t.Errorf("clock sequence %d != %d", clockSeq(t, uuid1), clockSeq(t, uuid2))
  166. }
  167. SetClockSequence(-1)
  168. uuid2 = NewUUID()
  169. // Just on the very off chance we generated the same sequence
  170. // two times we try again.
  171. if clockSeq(t, uuid1) == clockSeq(t, uuid2) {
  172. SetClockSequence(-1)
  173. uuid2 = NewUUID()
  174. }
  175. if clockSeq(t, uuid1) == clockSeq(t, uuid2) {
  176. t.Errorf("Duplicate clock sequence %d", clockSeq(t, uuid1))
  177. }
  178. SetClockSequence(0x1234)
  179. uuid1 = NewUUID()
  180. if seq := clockSeq(t, uuid1); seq != 0x1234 {
  181. t.Errorf("%s: expected seq 0x1234 got 0x%04x", uuid1, seq)
  182. }
  183. }
  184. func TestCoding(t *testing.T) {
  185. text := "7d444840-9dc0-11d1-b245-5ffdce74fad2"
  186. urn := "urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2"
  187. data := UUID{
  188. 0x7d, 0x44, 0x48, 0x40,
  189. 0x9d, 0xc0,
  190. 0x11, 0xd1,
  191. 0xb2, 0x45,
  192. 0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2,
  193. }
  194. if v := data.String(); v != text {
  195. t.Errorf("%x: encoded to %s, expected %s", data, v, text)
  196. }
  197. if v := data.URN(); v != urn {
  198. t.Errorf("%x: urn is %s, expected %s", data, v, urn)
  199. }
  200. uuid := Parse(text)
  201. if !Equal(uuid, data) {
  202. t.Errorf("%s: decoded to %s, expected %s", text, uuid, data)
  203. }
  204. }
  205. func TestVersion1(t *testing.T) {
  206. uuid1 := NewUUID()
  207. uuid2 := NewUUID()
  208. if Equal(uuid1, uuid2) {
  209. t.Errorf("%s:duplicate uuid", uuid1)
  210. }
  211. if v, _ := uuid1.Version(); v != 1 {
  212. t.Errorf("%s: version %s expected 1", uuid1, v)
  213. }
  214. if v, _ := uuid2.Version(); v != 1 {
  215. t.Errorf("%s: version %s expected 1", uuid2, v)
  216. }
  217. n1 := uuid1.NodeID()
  218. n2 := uuid2.NodeID()
  219. if !bytes.Equal(n1, n2) {
  220. t.Errorf("Different nodes %x != %x", n1, n2)
  221. }
  222. t1, ok := uuid1.Time()
  223. if !ok {
  224. t.Errorf("%s: invalid time", uuid1)
  225. }
  226. t2, ok := uuid2.Time()
  227. if !ok {
  228. t.Errorf("%s: invalid time", uuid2)
  229. }
  230. q1, ok := uuid1.ClockSequence()
  231. if !ok {
  232. t.Errorf("%s: invalid clock sequence", uuid1)
  233. }
  234. q2, ok := uuid2.ClockSequence()
  235. if !ok {
  236. t.Errorf("%s: invalid clock sequence", uuid2)
  237. }
  238. switch {
  239. case t1 == t2 && q1 == q2:
  240. t.Error("time stopped")
  241. case t1 > t2 && q1 == q2:
  242. t.Error("time reversed")
  243. case t1 < t2 && q1 != q2:
  244. t.Error("clock sequence chaned unexpectedly")
  245. }
  246. }
  247. func TestNode(t *testing.T) {
  248. // This test is mostly to make sure we don't leave nodeMu locked.
  249. ifname = ""
  250. if ni := NodeInterface(); ni != "" {
  251. t.Errorf("NodeInterface got %q, want %q", ni, "")
  252. }
  253. if SetNodeInterface("xyzzy") {
  254. t.Error("SetNodeInterface succeeded on a bad interface name")
  255. }
  256. if !SetNodeInterface("") {
  257. t.Error("SetNodeInterface failed")
  258. }
  259. if ni := NodeInterface(); ni == "" {
  260. t.Error("NodeInterface returned an empty string")
  261. }
  262. ni := NodeID()
  263. if len(ni) != 6 {
  264. t.Errorf("ni got %d bytes, want 6", len(ni))
  265. }
  266. hasData := false
  267. for _, b := range ni {
  268. if b != 0 {
  269. hasData = true
  270. }
  271. }
  272. if !hasData {
  273. t.Error("nodeid is all zeros")
  274. }
  275. id := []byte{1, 2, 3, 4, 5, 6, 7, 8}
  276. SetNodeID(id)
  277. ni = NodeID()
  278. if !bytes.Equal(ni, id[:6]) {
  279. t.Errorf("got nodeid %v, want %v", ni, id[:6])
  280. }
  281. if ni := NodeInterface(); ni != "user" {
  282. t.Errorf("got inteface %q, want %q", ni, "user")
  283. }
  284. }
  285. func TestNodeAndTime(t *testing.T) {
  286. // Time is February 5, 1998 12:30:23.136364800 AM GMT
  287. uuid := Parse("7d444840-9dc0-11d1-b245-5ffdce74fad2")
  288. node := []byte{0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2}
  289. ts, ok := uuid.Time()
  290. if ok {
  291. c := time.Unix(ts.UnixTime())
  292. want := time.Date(1998, 2, 5, 0, 30, 23, 136364800, time.UTC)
  293. if !c.Equal(want) {
  294. t.Errorf("Got time %v, want %v", c, want)
  295. }
  296. } else {
  297. t.Errorf("%s: bad time", uuid)
  298. }
  299. if !bytes.Equal(node, uuid.NodeID()) {
  300. t.Errorf("Expected node %v got %v", node, uuid.NodeID())
  301. }
  302. }
  303. func TestMD5(t *testing.T) {
  304. uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String()
  305. want := "6fa459ea-ee8a-3ca4-894e-db77e160355e"
  306. if uuid != want {
  307. t.Errorf("MD5: got %q expected %q", uuid, want)
  308. }
  309. }
  310. func TestSHA1(t *testing.T) {
  311. uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String()
  312. want := "886313e1-3b8a-5372-9b90-0c9aee199e5d"
  313. if uuid != want {
  314. t.Errorf("SHA1: got %q expected %q", uuid, want)
  315. }
  316. }
  317. func TestNodeID(t *testing.T) {
  318. nid := []byte{1, 2, 3, 4, 5, 6}
  319. SetNodeInterface("")
  320. s := NodeInterface()
  321. if s == "" || s == "user" {
  322. t.Errorf("NodeInterface %q after SetInteface", s)
  323. }
  324. node1 := NodeID()
  325. if node1 == nil {
  326. t.Error("NodeID nil after SetNodeInterface", s)
  327. }
  328. SetNodeID(nid)
  329. s = NodeInterface()
  330. if s != "user" {
  331. t.Errorf("Expected NodeInterface %q got %q", "user", s)
  332. }
  333. node2 := NodeID()
  334. if node2 == nil {
  335. t.Error("NodeID nil after SetNodeID", s)
  336. }
  337. if bytes.Equal(node1, node2) {
  338. t.Error("NodeID not changed after SetNodeID", s)
  339. } else if !bytes.Equal(nid, node2) {
  340. t.Errorf("NodeID is %x, expected %x", node2, nid)
  341. }
  342. }
  343. func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) {
  344. if uuid == nil {
  345. t.Errorf("%s failed", name)
  346. return
  347. }
  348. if v, _ := uuid.Version(); v != 2 {
  349. t.Errorf("%s: %s: expected version 2, got %s", name, uuid, v)
  350. return
  351. }
  352. if v, ok := uuid.Domain(); !ok || v != domain {
  353. if !ok {
  354. t.Errorf("%s: %d: Domain failed", name, uuid)
  355. } else {
  356. t.Errorf("%s: %s: expected domain %d, got %d", name, uuid, domain, v)
  357. }
  358. }
  359. if v, ok := uuid.Id(); !ok || v != id {
  360. if !ok {
  361. t.Errorf("%s: %d: Id failed", name, uuid)
  362. } else {
  363. t.Errorf("%s: %s: expected id %d, got %d", name, uuid, id, v)
  364. }
  365. }
  366. }
  367. func TestDCE(t *testing.T) {
  368. testDCE(t, "NewDCESecurity", NewDCESecurity(42, 12345678), 42, 12345678)
  369. testDCE(t, "NewDCEPerson", NewDCEPerson(), Person, uint32(os.Getuid()))
  370. testDCE(t, "NewDCEGroup", NewDCEGroup(), Group, uint32(os.Getgid()))
  371. }
  372. type badRand struct{}
  373. func (r badRand) Read(buf []byte) (int, error) {
  374. for i, _ := range buf {
  375. buf[i] = byte(i)
  376. }
  377. return len(buf), nil
  378. }
  379. func TestBadRand(t *testing.T) {
  380. SetRand(badRand{})
  381. uuid1 := New()
  382. uuid2 := New()
  383. if uuid1 != uuid2 {
  384. t.Errorf("execpted duplicates, got %q and %q", uuid1, uuid2)
  385. }
  386. SetRand(nil)
  387. uuid1 = New()
  388. uuid2 = New()
  389. if uuid1 == uuid2 {
  390. t.Errorf("unexecpted duplicates, got %q", uuid1)
  391. }
  392. }
  393. func TestUUID_Array(t *testing.T) {
  394. expect := Array{
  395. 0xf4, 0x7a, 0xc1, 0x0b,
  396. 0x58, 0xcc,
  397. 0x03, 0x72,
  398. 0x85, 0x67,
  399. 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
  400. }
  401. uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  402. if uuid == nil {
  403. t.Fatal("invalid uuid")
  404. }
  405. if uuid.Array() != expect {
  406. t.Fatal("invalid array")
  407. }
  408. }
  409. func TestArray_UUID(t *testing.T) {
  410. array := Array{
  411. 0xf4, 0x7a, 0xc1, 0x0b,
  412. 0x58, 0xcc,
  413. 0x03, 0x72,
  414. 0x85, 0x67,
  415. 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
  416. }
  417. expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  418. if expect == nil {
  419. t.Fatal("invalid uuid")
  420. }
  421. if !bytes.Equal(array.UUID(), expect) {
  422. t.Fatal("invalid uuid")
  423. }
  424. }
  425. func BenchmarkParse(b *testing.B) {
  426. for i := 0; i < b.N; i++ {
  427. uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  428. if uuid == nil {
  429. b.Fatal("invalid uuid")
  430. }
  431. }
  432. }
  433. func BenchmarkNew(b *testing.B) {
  434. for i := 0; i < b.N; i++ {
  435. New()
  436. }
  437. }
  438. func BenchmarkUUID_String(b *testing.B) {
  439. uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  440. if uuid == nil {
  441. b.Fatal("invalid uuid")
  442. }
  443. for i := 0; i < b.N; i++ {
  444. if uuid.String() == "" {
  445. b.Fatal("invalid uuid")
  446. }
  447. }
  448. }
  449. func BenchmarkUUID_URN(b *testing.B) {
  450. uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  451. if uuid == nil {
  452. b.Fatal("invalid uuid")
  453. }
  454. for i := 0; i < b.N; i++ {
  455. if uuid.URN() == "" {
  456. b.Fatal("invalid uuid")
  457. }
  458. }
  459. }
  460. func BenchmarkUUID_Array(b *testing.B) {
  461. expect := Array{
  462. 0xf4, 0x7a, 0xc1, 0x0b,
  463. 0x58, 0xcc,
  464. 0x03, 0x72,
  465. 0x85, 0x67,
  466. 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
  467. }
  468. uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  469. if uuid == nil {
  470. b.Fatal("invalid uuid")
  471. }
  472. for i := 0; i < b.N; i++ {
  473. if uuid.Array() != expect {
  474. b.Fatal("invalid array")
  475. }
  476. }
  477. }
  478. func BenchmarkArray_UUID(b *testing.B) {
  479. array := Array{
  480. 0xf4, 0x7a, 0xc1, 0x0b,
  481. 0x58, 0xcc,
  482. 0x03, 0x72,
  483. 0x85, 0x67,
  484. 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79,
  485. }
  486. expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
  487. if expect == nil {
  488. b.Fatal("invalid uuid")
  489. }
  490. for i := 0; i < b.N; i++ {
  491. if !bytes.Equal(array.UUID(), expect) {
  492. b.Fatal("invalid uuid")
  493. }
  494. }
  495. }