]> Cypherpunks.ru repositories - gostls13.git/blob - src/math/rand/v2/regress_test.go
math/rand/v2: clean up regression test
[gostls13.git] / src / math / rand / v2 / regress_test.go
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Test that random number sequences generated by a specific seed
6 // do not change from version to version.
7 //
8 // Do NOT make changes to the golden outputs. If bugs need to be fixed
9 // in the underlying code, find ways to fix them that do not affect the
10 // outputs.
11
12 package rand_test
13
14 import (
15         "bytes"
16         "flag"
17         "fmt"
18         "go/format"
19         "io"
20         . "math/rand/v2"
21         "os"
22         "reflect"
23         "strings"
24         "testing"
25 )
26
27 var update = flag.Bool("update", false, "update golden results for regression test")
28
29 func TestRegress(t *testing.T) {
30         var int32s = []int32{1, 10, 32, 1 << 20, 1<<20 + 1, 1000000000, 1 << 30, 1<<31 - 2, 1<<31 - 1}
31         var uint32s = []uint32{1, 10, 32, 1 << 20, 1<<20 + 1, 1000000000, 1 << 30, 1<<31 - 2, 1<<31 - 1, 1<<32 - 2, 1<<32 - 1}
32         var int64s = []int64{1, 10, 32, 1 << 20, 1<<20 + 1, 1000000000, 1 << 30, 1<<31 - 2, 1<<31 - 1, 1000000000000000000, 1 << 60, 1<<63 - 2, 1<<63 - 1}
33         var uint64s = []uint64{1, 10, 32, 1 << 20, 1<<20 + 1, 1000000000, 1 << 30, 1<<31 - 2, 1<<31 - 1, 1000000000000000000, 1 << 60, 1<<63 - 2, 1<<63 - 1, 1<<64 - 2, 1<<64 - 1}
34         var permSizes = []int{0, 1, 5, 8, 9, 10, 16}
35
36         n := reflect.TypeOf(New(NewSource(1))).NumMethod()
37         p := 0
38         var buf bytes.Buffer
39         if *update {
40                 fmt.Fprintf(&buf, "var regressGolden = []any{\n")
41         }
42         for i := 0; i < n; i++ {
43                 if *update && i > 0 {
44                         fmt.Fprintf(&buf, "\n")
45                 }
46                 r := New(NewSource(1))
47                 rv := reflect.ValueOf(r)
48                 m := rv.Type().Method(i)
49                 mv := rv.Method(i)
50                 mt := mv.Type()
51                 if mt.NumOut() == 0 {
52                         continue
53                 }
54                 for repeat := 0; repeat < 20; repeat++ {
55                         var args []reflect.Value
56                         var argstr string
57                         if mt.NumIn() == 1 {
58                                 var x any
59                                 switch mt.In(0).Kind() {
60                                 default:
61                                         t.Fatalf("unexpected argument type for r.%s", m.Name)
62
63                                 case reflect.Int:
64                                         if m.Name == "Perm" {
65                                                 x = permSizes[repeat%len(permSizes)]
66                                                 break
67                                         }
68                                         big := int64s[repeat%len(int64s)]
69                                         if int64(int(big)) != big {
70                                                 // On 32-bit machine.
71                                                 // Consume an Int64 like on a 64-bit machine,
72                                                 // to keep the golden data the same on different architectures.
73                                                 r.Int64N(big)
74                                                 if *update {
75                                                         t.Fatalf("must run -update on 64-bit machine")
76                                                 }
77                                                 p++
78                                                 continue
79                                         }
80                                         x = int(big)
81
82                                 case reflect.Int32:
83                                         x = int32s[repeat%len(int32s)]
84
85                                 case reflect.Int64:
86                                         x = int64s[repeat%len(int64s)]
87
88                                 case reflect.Uint32:
89                                         x = uint32s[repeat%len(uint32s)]
90
91                                 case reflect.Uint64:
92                                         x = uint64s[repeat%len(uint64s)]
93                                 }
94                                 argstr = fmt.Sprint(x)
95                                 args = append(args, reflect.ValueOf(x))
96                         }
97
98                         var out any
99                         out = mv.Call(args)[0].Interface()
100                         if m.Name == "Int" || m.Name == "IntN" {
101                                 out = int64(out.(int))
102                         }
103                         if m.Name == "Uint" || m.Name == "UintN" {
104                                 out = uint64(out.(uint))
105                         }
106                         if *update {
107                                 var val string
108                                 big := int64(1 << 60)
109                                 if int64(int(big)) != big && (m.Name == "Int" || m.Name == "IntN") {
110                                         // 32-bit machine cannot print 64-bit results
111                                         val = "truncated"
112                                 } else if reflect.TypeOf(out).Kind() == reflect.Slice {
113                                         val = fmt.Sprintf("%#v", out)
114                                 } else {
115                                         val = fmt.Sprintf("%T(%v)", out, out)
116                                 }
117                                 fmt.Fprintf(&buf, "\t%s, // %s(%s)\n", val, m.Name, argstr)
118                         } else if p >= len(regressGolden) {
119                                 t.Errorf("r.%s(%s) = %v, missing golden value", m.Name, argstr, out)
120                         } else {
121                                 want := regressGolden[p]
122                                 if m.Name == "Int" {
123                                         want = int64(int(uint(want.(int64)) << 1 >> 1))
124                                 }
125                                 if !reflect.DeepEqual(out, want) {
126                                         t.Errorf("r.%s(%s) = %v, want %v", m.Name, argstr, out, want)
127                                 }
128                         }
129                         p++
130                 }
131         }
132         if *update {
133                 replace(t, "regress_test.go", buf.Bytes())
134         }
135 }
136
137 func TestUpdateExample(t *testing.T) {
138         if !*update {
139                 t.Skip("-update not given")
140         }
141
142         oldStdout := os.Stdout
143         defer func() {
144                 os.Stdout = oldStdout
145         }()
146
147         r, w, err := os.Pipe()
148         if err != nil {
149                 t.Fatal(err)
150         }
151         defer r.Close()
152         defer w.Close()
153
154         go func() {
155                 os.Stdout = w
156                 Example_rand()
157                 os.Stdout = oldStdout
158                 w.Close()
159         }()
160         out, err := io.ReadAll(r)
161         if err != nil {
162                 t.Fatal(err)
163         }
164
165         var buf bytes.Buffer
166         fmt.Fprintf(&buf, "\t// Output:\n")
167         for _, line := range strings.Split(string(out), "\n") {
168                 if line != "" {
169                         fmt.Fprintf(&buf, "\t// %s\n", line)
170                 }
171         }
172
173         replace(t, "example_test.go", buf.Bytes())
174
175         // Exit so that Example_rand cannot fail.
176         fmt.Printf("UPDATED; ignore non-zero exit status\n")
177         os.Exit(1)
178 }
179
180 // replace substitutes the definition text from new into the content of file.
181 // The text in new is of the form
182 //
183 //      var whatever = T{
184 //              ...
185 //      }
186 //
187 // Replace searches file for an exact match for the text of the first line,
188 // finds the closing brace, and then substitutes new for what used to be in the file.
189 // This lets us update the regressGolden table during go test -update.
190 func replace(t *testing.T, file string, new []byte) {
191         first, _, _ := bytes.Cut(new, []byte("\n"))
192         first = append(append([]byte("\n"), first...), '\n')
193         data, err := os.ReadFile(file)
194         if err != nil {
195                 t.Fatal(err)
196         }
197         i := bytes.Index(data, first)
198         if i < 0 {
199                 t.Fatalf("cannot find %q in %s", first, file)
200         }
201         j := bytes.Index(data[i+1:], []byte("\n}\n"))
202         if j < 0 {
203                 t.Fatalf("cannot find end in %s", file)
204         }
205         data = append(append(data[:i+1:i+1], new...), data[i+1+j+1:]...)
206         data, err = format.Source(data)
207         if err != nil {
208                 t.Fatal(err)
209         }
210         if err := os.WriteFile(file, data, 0666); err != nil {
211                 t.Fatal(err)
212         }
213 }
214
215 var regressGolden = []any{
216         float64(0.5872982159059681),  // ExpFloat64()
217         float64(0.5372820936538049),  // ExpFloat64()
218         float64(1.2310533463860203),  // ExpFloat64()
219         float64(0.6776268958872181),  // ExpFloat64()
220         float64(0.04451836051028885), // ExpFloat64()
221         float64(0.2228940815087735),  // ExpFloat64()
222         float64(0.09850095778902446), // ExpFloat64()
223         float64(0.18902358546064923), // ExpFloat64()
224         float64(0.18227281316102673), // ExpFloat64()
225         float64(0.31155615099079936), // ExpFloat64()
226         float64(0.9474409467969883),  // ExpFloat64()
227         float64(1.0451058861587306),  // ExpFloat64()
228         float64(0.21497642445756152), // ExpFloat64()
229         float64(1.4215752287217205),  // ExpFloat64()
230         float64(0.755823964126038),   // ExpFloat64()
231         float64(0.38996764757787583), // ExpFloat64()
232         float64(0.13309377582841803), // ExpFloat64()
233         float64(0.2115638815656507),  // ExpFloat64()
234         float64(0.7176288428497417),  // ExpFloat64()
235         float64(0.6120456642749681),  // ExpFloat64()
236
237         float32(0.6046603),  // Float32()
238         float32(0.9405091),  // Float32()
239         float32(0.6645601),  // Float32()
240         float32(0.4377142),  // Float32()
241         float32(0.4246375),  // Float32()
242         float32(0.68682307), // Float32()
243         float32(0.06563702), // Float32()
244         float32(0.15651925), // Float32()
245         float32(0.09696952), // Float32()
246         float32(0.30091187), // Float32()
247         float32(0.51521266), // Float32()
248         float32(0.81363994), // Float32()
249         float32(0.21426387), // Float32()
250         float32(0.3806572),  // Float32()
251         float32(0.31805816), // Float32()
252         float32(0.46888983), // Float32()
253         float32(0.28303415), // Float32()
254         float32(0.29310185), // Float32()
255         float32(0.67908466), // Float32()
256         float32(0.21855305), // Float32()
257
258         float64(0.6046602879796196),  // Float64()
259         float64(0.9405090880450124),  // Float64()
260         float64(0.6645600532184904),  // Float64()
261         float64(0.4377141871869802),  // Float64()
262         float64(0.4246374970712657),  // Float64()
263         float64(0.6868230728671094),  // Float64()
264         float64(0.06563701921747622), // Float64()
265         float64(0.15651925473279124), // Float64()
266         float64(0.09696951891448456), // Float64()
267         float64(0.30091186058528707), // Float64()
268         float64(0.5152126285020654),  // Float64()
269         float64(0.8136399609900968),  // Float64()
270         float64(0.21426387258237492), // Float64()
271         float64(0.380657189299686),   // Float64()
272         float64(0.31805817433032985), // Float64()
273         float64(0.4688898449024232),  // Float64()
274         float64(0.28303415118044517), // Float64()
275         float64(0.29310185733681576), // Float64()
276         float64(0.6790846759202163),  // Float64()
277         float64(0.21855305259276428), // Float64()
278
279         int64(5577006791947779410), // Int()
280         int64(8674665223082153551), // Int()
281         int64(6129484611666145821), // Int()
282         int64(4037200794235010051), // Int()
283         int64(3916589616287113937), // Int()
284         int64(6334824724549167320), // Int()
285         int64(605394647632969758),  // Int()
286         int64(1443635317331776148), // Int()
287         int64(894385949183117216),  // Int()
288         int64(2775422040480279449), // Int()
289         int64(4751997750760398084), // Int()
290         int64(7504504064263669287), // Int()
291         int64(1976235410884491574), // Int()
292         int64(3510942875414458836), // Int()
293         int64(2933568871211445515), // Int()
294         int64(4324745483838182873), // Int()
295         int64(2610529275472644968), // Int()
296         int64(2703387474910584091), // Int()
297         int64(6263450610539110790), // Int()
298         int64(2015796113853353331), // Int()
299
300         int32(1298498081), // Int32()
301         int32(2019727887), // Int32()
302         int32(1427131847), // Int32()
303         int32(939984059),  // Int32()
304         int32(911902081),  // Int32()
305         int32(1474941318), // Int32()
306         int32(140954425),  // Int32()
307         int32(336122540),  // Int32()
308         int32(208240456),  // Int32()
309         int32(646203300),  // Int32()
310         int32(1106410694), // Int32()
311         int32(1747278511), // Int32()
312         int32(460128162),  // Int32()
313         int32(817455089),  // Int32()
314         int32(683024728),  // Int32()
315         int32(1006933274), // Int32()
316         int32(607811211),  // Int32()
317         int32(629431445),  // Int32()
318         int32(1458323237), // Int32()
319         int32(469339106),  // Int32()
320
321         int32(0),          // Int32N(1)
322         int32(7),          // Int32N(10)
323         int32(7),          // Int32N(32)
324         int32(459963),     // Int32N(1048576)
325         int32(688668),     // Int32N(1048577)
326         int32(474941318),  // Int32N(1000000000)
327         int32(140954425),  // Int32N(1073741824)
328         int32(336122540),  // Int32N(2147483646)
329         int32(208240456),  // Int32N(2147483647)
330         int32(0),          // Int32N(1)
331         int32(4),          // Int32N(10)
332         int32(15),         // Int32N(32)
333         int32(851874),     // Int32N(1048576)
334         int32(613606),     // Int32N(1048577)
335         int32(683024728),  // Int32N(1000000000)
336         int32(1006933274), // Int32N(1073741824)
337         int32(607811211),  // Int32N(2147483646)
338         int32(629431445),  // Int32N(2147483647)
339         int32(0),          // Int32N(1)
340         int32(6),          // Int32N(10)
341
342         int64(5577006791947779410), // Int64()
343         int64(8674665223082153551), // Int64()
344         int64(6129484611666145821), // Int64()
345         int64(4037200794235010051), // Int64()
346         int64(3916589616287113937), // Int64()
347         int64(6334824724549167320), // Int64()
348         int64(605394647632969758),  // Int64()
349         int64(1443635317331776148), // Int64()
350         int64(894385949183117216),  // Int64()
351         int64(2775422040480279449), // Int64()
352         int64(4751997750760398084), // Int64()
353         int64(7504504064263669287), // Int64()
354         int64(1976235410884491574), // Int64()
355         int64(3510942875414458836), // Int64()
356         int64(2933568871211445515), // Int64()
357         int64(4324745483838182873), // Int64()
358         int64(2610529275472644968), // Int64()
359         int64(2703387474910584091), // Int64()
360         int64(6263450610539110790), // Int64()
361         int64(2015796113853353331), // Int64()
362
363         int64(0),                   // Int64N(1)
364         int64(1),                   // Int64N(10)
365         int64(29),                  // Int64N(32)
366         int64(883715),              // Int64N(1048576)
367         int64(338103),              // Int64N(1048577)
368         int64(549167320),           // Int64N(1000000000)
369         int64(957743134),           // Int64N(1073741824)
370         int64(1927814468),          // Int64N(2147483646)
371         int64(1375471152),          // Int64N(2147483647)
372         int64(775422040480279449),  // Int64N(1000000000000000000)
373         int64(140311732333010180),  // Int64N(1152921504606846976)
374         int64(7504504064263669287), // Int64N(9223372036854775806)
375         int64(1976235410884491574), // Int64N(9223372036854775807)
376         int64(0),                   // Int64N(1)
377         int64(5),                   // Int64N(10)
378         int64(25),                  // Int64N(32)
379         int64(920424),              // Int64N(1048576)
380         int64(345137),              // Int64N(1048577)
381         int64(539110790),           // Int64N(1000000000)
382         int64(701992307),           // Int64N(1073741824)
383
384         int64(0),                   // IntN(1)
385         int64(7),                   // IntN(10)
386         int64(7),                   // IntN(32)
387         int64(459963),              // IntN(1048576)
388         int64(688668),              // IntN(1048577)
389         int64(474941318),           // IntN(1000000000)
390         int64(140954425),           // IntN(1073741824)
391         int64(336122540),           // IntN(2147483646)
392         int64(208240456),           // IntN(2147483647)
393         int64(775422040480279449),  // IntN(1000000000000000000)
394         int64(140311732333010180),  // IntN(1152921504606846976)
395         int64(7504504064263669287), // IntN(9223372036854775806)
396         int64(1976235410884491574), // IntN(9223372036854775807)
397         int64(0),                   // IntN(1)
398         int64(8),                   // IntN(10)
399         int64(26),                  // IntN(32)
400         int64(685707),              // IntN(1048576)
401         int64(285245),              // IntN(1048577)
402         int64(458323237),           // IntN(1000000000)
403         int64(469339106),           // IntN(1073741824)
404
405         float64(-1.233758177597947),   // NormFloat64()
406         float64(-0.12634751070237293), // NormFloat64()
407         float64(-0.5209945711531503),  // NormFloat64()
408         float64(2.28571911769958),     // NormFloat64()
409         float64(0.3228052526115799),   // NormFloat64()
410         float64(0.5900672875996937),   // NormFloat64()
411         float64(0.15880774017643562),  // NormFloat64()
412         float64(0.9892020842955818),   // NormFloat64()
413         float64(-0.731283016177479),   // NormFloat64()
414         float64(0.6863807850359727),   // NormFloat64()
415         float64(1.585403962280623),    // NormFloat64()
416         float64(0.8382059044208106),   // NormFloat64()
417         float64(1.2988408475174342),   // NormFloat64()
418         float64(0.5273583930598617),   // NormFloat64()
419         float64(0.7324419258045132),   // NormFloat64()
420         float64(-1.0731798210887524),  // NormFloat64()
421         float64(0.7001209024399848),   // NormFloat64()
422         float64(0.4315307186960532),   // NormFloat64()
423         float64(0.9996261210112625),   // NormFloat64()
424         float64(-1.5239676725278932),  // NormFloat64()
425
426         []int{},                             // Perm(0)
427         []int{0},                            // Perm(1)
428         []int{0, 3, 2, 4, 1},                // Perm(5)
429         []int{3, 7, 0, 1, 6, 2, 4, 5},       // Perm(8)
430         []int{2, 3, 7, 6, 1, 8, 0, 5, 4},    // Perm(9)
431         []int{5, 2, 6, 4, 3, 7, 8, 9, 1, 0}, // Perm(10)
432         []int{0, 11, 2, 5, 14, 7, 3, 1, 13, 8, 9, 4, 10, 6, 12, 15}, // Perm(16)
433         []int{},                             // Perm(0)
434         []int{0},                            // Perm(1)
435         []int{4, 1, 0, 3, 2},                // Perm(5)
436         []int{6, 0, 1, 3, 2, 7, 4, 5},       // Perm(8)
437         []int{8, 3, 6, 7, 2, 5, 4, 0, 1},    // Perm(9)
438         []int{2, 5, 4, 9, 7, 0, 8, 3, 6, 1}, // Perm(10)
439         []int{12, 6, 8, 15, 3, 5, 9, 11, 7, 10, 1, 13, 14, 2, 0, 4}, // Perm(16)
440         []int{},                             // Perm(0)
441         []int{0},                            // Perm(1)
442         []int{0, 2, 4, 3, 1},                // Perm(5)
443         []int{4, 7, 0, 2, 6, 1, 5, 3},       // Perm(8)
444         []int{6, 5, 8, 0, 1, 3, 7, 2, 4},    // Perm(9)
445         []int{8, 1, 9, 7, 6, 5, 2, 0, 4, 3}, // Perm(10)
446
447         uint32(2596996162), // Uint32()
448         uint32(4039455774), // Uint32()
449         uint32(2854263694), // Uint32()
450         uint32(1879968118), // Uint32()
451         uint32(1823804162), // Uint32()
452         uint32(2949882636), // Uint32()
453         uint32(281908850),  // Uint32()
454         uint32(672245080),  // Uint32()
455         uint32(416480912),  // Uint32()
456         uint32(1292406600), // Uint32()
457         uint32(2212821389), // Uint32()
458         uint32(3494557023), // Uint32()
459         uint32(920256325),  // Uint32()
460         uint32(1634910179), // Uint32()
461         uint32(1366049456), // Uint32()
462         uint32(2013866549), // Uint32()
463         uint32(1215622422), // Uint32()
464         uint32(1258862891), // Uint32()
465         uint32(2916646474), // Uint32()
466         uint32(938678213),  // Uint32()
467
468         uint64(5577006791947779410),  // Uint64()
469         uint64(8674665223082153551),  // Uint64()
470         uint64(15352856648520921629), // Uint64()
471         uint64(13260572831089785859), // Uint64()
472         uint64(3916589616287113937),  // Uint64()
473         uint64(6334824724549167320),  // Uint64()
474         uint64(9828766684487745566),  // Uint64()
475         uint64(10667007354186551956), // Uint64()
476         uint64(894385949183117216),   // Uint64()
477         uint64(11998794077335055257), // Uint64()
478         uint64(4751997750760398084),  // Uint64()
479         uint64(7504504064263669287),  // Uint64()
480         uint64(11199607447739267382), // Uint64()
481         uint64(3510942875414458836),  // Uint64()
482         uint64(12156940908066221323), // Uint64()
483         uint64(4324745483838182873),  // Uint64()
484         uint64(11833901312327420776), // Uint64()
485         uint64(11926759511765359899), // Uint64()
486         uint64(6263450610539110790),  // Uint64()
487         uint64(11239168150708129139), // Uint64()
488 }