You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.4 KiB
66 lines
1.4 KiB
// Copyright 2016 Google Inc. All rights reserved. |
|
// Use of this source code is governed by a BSD-style |
|
// license that can be found in the LICENSE file. |
|
|
|
package uuid |
|
|
|
import ( |
|
"flag" |
|
"runtime" |
|
"testing" |
|
"time" |
|
) |
|
|
|
// This test is only run when --regressions is passed on the go test line. |
|
var regressions = flag.Bool("regressions", false, "run uuid regression tests") |
|
|
|
// 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. |
|
func TestClockSeqRace(t *testing.T) { |
|
if !*regressions { |
|
t.Skip("skipping regression tests") |
|
} |
|
duration := time.Minute |
|
|
|
done := make(chan struct{}) |
|
defer close(done) |
|
|
|
ch := make(chan UUID, 10000) |
|
ncpu := runtime.NumCPU() |
|
switch ncpu { |
|
case 0, 1: |
|
// We can't run the test effectively. |
|
t.Skip("skipping race test, only one CPU detected") |
|
return |
|
default: |
|
runtime.GOMAXPROCS(ncpu) |
|
} |
|
for i := 0; i < ncpu; i++ { |
|
go func() { |
|
for { |
|
select { |
|
case <-done: |
|
return |
|
case ch <- Must(NewUUID()): |
|
} |
|
} |
|
}() |
|
} |
|
|
|
uuids := make(map[string]bool) |
|
cnt := 0 |
|
start := time.Now() |
|
for u := range ch { |
|
s := u.String() |
|
if uuids[s] { |
|
t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s) |
|
return |
|
} |
|
uuids[s] = true |
|
if time.Since(start) > duration { |
|
return |
|
} |
|
cnt++ |
|
} |
|
}
|
|
|