seq_test.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright 2016 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. "flag"
  7. "runtime"
  8. "testing"
  9. "time"
  10. )
  11. // This test is only run when --regressions is passed on the go test line.
  12. var regressions = flag.Bool("regressions", false, "run uuid regression tests")
  13. // TestClockSeqRace tests for a particular race condition of returning two
  14. // identical Version1 UUIDs. The duration of 1 minute was chosen as the race
  15. // condition, before being fixed, nearly always occurred in under 30 seconds.
  16. func TestClockSeqRace(t *testing.T) {
  17. if !*regressions {
  18. t.Skip("skipping regression tests")
  19. }
  20. duration := time.Minute
  21. done := make(chan struct{})
  22. defer close(done)
  23. ch := make(chan UUID, 10000)
  24. ncpu := runtime.NumCPU()
  25. switch ncpu {
  26. case 0, 1:
  27. // We can't run the test effectively.
  28. t.Skip("skipping race test, only one CPU detected")
  29. return
  30. default:
  31. runtime.GOMAXPROCS(ncpu)
  32. }
  33. for i := 0; i < ncpu; i++ {
  34. go func() {
  35. for {
  36. select {
  37. case <-done:
  38. return
  39. case ch <- Must(NewUUID()):
  40. }
  41. }
  42. }()
  43. }
  44. uuids := make(map[string]bool)
  45. cnt := 0
  46. start := time.Now()
  47. for u := range ch {
  48. s := u.String()
  49. if uuids[s] {
  50. t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s)
  51. return
  52. }
  53. uuids[s] = true
  54. if time.Since(start) > duration {
  55. return
  56. }
  57. cnt++
  58. }
  59. }