Source file
src/math/rand/default_test.go
1
2
3
4
5 package rand_test
6
7 import (
8 "fmt"
9 "internal/race"
10 "internal/testenv"
11 . "math/rand"
12 "os"
13 "runtime"
14 "strconv"
15 "sync"
16 "testing"
17 )
18
19
20 func TestDefaultRace(t *testing.T) {
21
22
23
24 if testing.Short() && !race.Enabled {
25 t.Skip("skipping starting another executable in short mode")
26 }
27
28 const env = "GO_RAND_TEST_HELPER_CODE"
29 if v := os.Getenv(env); v != "" {
30 doDefaultTest(t, v)
31 return
32 }
33
34 t.Parallel()
35
36 for i := 0; i < 6; i++ {
37 t.Run(strconv.Itoa(i), func(t *testing.T) {
38 t.Parallel()
39 cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestDefaultRace$")
40 cmd = testenv.CleanCmdEnv(cmd)
41 cmd.Env = append(cmd.Env, fmt.Sprintf("GO_RAND_TEST_HELPER_CODE=%d", i/2))
42 if i%2 != 0 {
43 cmd.Env = append(cmd.Env, "GODEBUG=randautoseed=0")
44 }
45 out, err := cmd.CombinedOutput()
46 if len(out) > 0 {
47 t.Logf("%s", out)
48 }
49 if err != nil {
50 t.Error(err)
51 }
52 })
53 }
54 }
55
56
57
58
59
60 func doDefaultTest(t *testing.T, v string) {
61 code, err := strconv.Atoi(v)
62 if err != nil {
63 t.Fatalf("internal error: unrecognized code %q", v)
64 }
65
66 goroutines := runtime.GOMAXPROCS(0)
67 if goroutines < 4 {
68 goroutines = 4
69 }
70
71 ch := make(chan uint64, goroutines*3)
72 var wg sync.WaitGroup
73
74
75
76
77
78
79
80
81
82
83 switch code {
84 case 0:
85
86 wg.Add(goroutines)
87 for i := 0; i < goroutines; i++ {
88 go func(s int64) {
89 defer wg.Done()
90 Seed(s)
91 }(int64(i) + 100)
92 }
93 wg.Add(goroutines)
94 for i := 0; i < goroutines; i++ {
95 go func() {
96 defer wg.Done()
97 ch <- Uint64()
98 }()
99 }
100 case 1:
101
102 wg.Add(goroutines)
103 for i := 0; i < goroutines; i++ {
104 go func() {
105 defer wg.Done()
106 ch <- Uint64()
107 }()
108 }
109 case 2:
110
111
112 ch <- Uint64()
113 wg.Add(goroutines)
114 for i := 0; i < goroutines; i++ {
115 go func(s int64) {
116 defer wg.Done()
117 Seed(s)
118 }(int64(i) + 100)
119 }
120 wg.Add(goroutines)
121 for i := 0; i < goroutines; i++ {
122 go func() {
123 defer wg.Done()
124 ch <- Uint64()
125 }()
126 }
127 default:
128 t.Fatalf("internal error: unrecognized code %d", code)
129 }
130
131 go func() {
132 wg.Wait()
133 close(ch)
134 }()
135
136 m := make(map[uint64]bool)
137 for i := range ch {
138 if m[i] {
139 t.Errorf("saw %d twice", i)
140 }
141 m[i] = true
142 }
143 }
144
View as plain text