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