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