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 i := i
38 t.Run(strconv.Itoa(i), func(t *testing.T) {
39 t.Parallel()
40 cmd := testenv.Command(t, testenv.Executable(t), "-test.run=TestDefaultRace")
41 cmd = testenv.CleanCmdEnv(cmd)
42 cmd.Env = append(cmd.Env, fmt.Sprintf("GO_RAND_TEST_HELPER_CODE=%d", i/2))
43 if i%2 != 0 {
44 cmd.Env = append(cmd.Env, "GODEBUG=randautoseed=0")
45 }
46 out, err := cmd.CombinedOutput()
47 if len(out) > 0 {
48 t.Logf("%s", out)
49 }
50 if err != nil {
51 t.Error(err)
52 }
53 })
54 }
55 }
56
57
58
59
60
61 func doDefaultTest(t *testing.T, v string) {
62 code, err := strconv.Atoi(v)
63 if err != nil {
64 t.Fatalf("internal error: unrecognized code %q", v)
65 }
66
67 goroutines := runtime.GOMAXPROCS(0)
68 if goroutines < 4 {
69 goroutines = 4
70 }
71
72 ch := make(chan uint64, goroutines*3)
73 var wg sync.WaitGroup
74
75
76
77
78
79
80
81
82
83
84 switch code {
85 case 0:
86
87 wg.Add(goroutines)
88 for i := 0; i < goroutines; i++ {
89 go func(s int64) {
90 defer wg.Done()
91 Seed(s)
92 }(int64(i) + 100)
93 }
94 wg.Add(goroutines)
95 for i := 0; i < goroutines; i++ {
96 go func() {
97 defer wg.Done()
98 ch <- Uint64()
99 }()
100 }
101 case 1:
102
103 wg.Add(goroutines)
104 for i := 0; i < goroutines; i++ {
105 go func() {
106 defer wg.Done()
107 ch <- Uint64()
108 }()
109 }
110 case 2:
111
112
113 ch <- Uint64()
114 wg.Add(goroutines)
115 for i := 0; i < goroutines; i++ {
116 go func(s int64) {
117 defer wg.Done()
118 Seed(s)
119 }(int64(i) + 100)
120 }
121 wg.Add(goroutines)
122 for i := 0; i < goroutines; i++ {
123 go func() {
124 defer wg.Done()
125 ch <- Uint64()
126 }()
127 }
128 default:
129 t.Fatalf("internal error: unrecognized code %d", code)
130 }
131
132 go func() {
133 wg.Wait()
134 close(ch)
135 }()
136
137 m := make(map[uint64]bool)
138 for i := range ch {
139 if m[i] {
140 t.Errorf("saw %d twice", i)
141 }
142 m[i] = true
143 }
144 }
145
View as plain text