Commit 719c7b03 authored by Russ Cox's avatar Russ Cox

testing/quick: generate all possible int64, uint64 values

When generating a random int8, uint8, int16, uint16, int32, uint32,
quick.Value chooses among all possible values.

But when generating a random int64 or uint64, it only chooses
values in the range [-2⁶², 2⁶²) (even for uint64).
It should, like for all the other integers, use the full range.

If it had, this would have caught #19807 earlier.
Instead it let us discover the presence of #19809.

While we are here, also make the default source of
randomness not completely deterministic.

Fixes #19808.

Change-Id: I070f852531c92b3670bd76523326c9132bfc9416
Reviewed-on: https://go-review.googlesource.com/39152
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRob Pike <r@golang.org>
parent 65c17a05
...@@ -183,7 +183,7 @@ var pkgDeps = map[string][]string{ ...@@ -183,7 +183,7 @@ var pkgDeps = map[string][]string{
"testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"}, "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
"testing/iotest": {"L2", "log"}, "testing/iotest": {"L2", "log"},
"testing/quick": {"L2", "flag", "fmt", "reflect"}, "testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
"internal/testenv": {"L2", "OS", "flag", "testing", "syscall"}, "internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
// L4 is defined as L3+fmt+log+time, because in general once // L4 is defined as L3+fmt+log+time, because in general once
......
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"math/rand" "math/rand"
"reflect" "reflect"
"strings" "strings"
"time"
) )
var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check") var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
...@@ -43,8 +44,14 @@ func randFloat64(rand *rand.Rand) float64 { ...@@ -43,8 +44,14 @@ func randFloat64(rand *rand.Rand) float64 {
return f return f
} }
// randInt64 returns a random integer taking half the range of an int64. // randInt64 returns a random int64.
func randInt64(rand *rand.Rand) int64 { return rand.Int63() - 1<<62 } func randInt64(rand *rand.Rand) int64 {
x := rand.Int63() - 1<<62
// x in [-2⁶²,2⁶²), so top two bits are 00 or 11, never 10 or 01.
// Mix in some bits from the middle.
x ^= x<<29 ^ x<<43
return x
}
// complexSize is the maximum length of arbitrary values that contain other // complexSize is the maximum length of arbitrary values that contain other
// values. // values.
...@@ -193,7 +200,7 @@ var defaultConfig Config ...@@ -193,7 +200,7 @@ var defaultConfig Config
// getRand returns the *rand.Rand to use for a given Config. // getRand returns the *rand.Rand to use for a given Config.
func (c *Config) getRand() *rand.Rand { func (c *Config) getRand() *rand.Rand {
if c.Rand == nil { if c.Rand == nil {
return rand.New(rand.NewSource(0)) return rand.New(rand.NewSource(time.Now().UnixNano()))
} }
return c.Rand return c.Rand
} }
......
...@@ -378,8 +378,8 @@ func checkTime(time Time, test *ParseTest, t *testing.T) { ...@@ -378,8 +378,8 @@ func checkTime(time Time, test *ParseTest, t *testing.T) {
func TestFormatAndParse(t *testing.T) { func TestFormatAndParse(t *testing.T) {
const fmt = "Mon MST " + RFC3339 // all fields const fmt = "Mon MST " + RFC3339 // all fields
f := func(sec int64) bool { f := func(sec int64) bool {
t1 := Unix(sec, 0) t1 := Unix(sec/2, 0)
if t1.Year() < 1000 || t1.Year() > 9999 { if t1.Year() < 1000 || t1.Year() > 9999 || t1.Unix() != sec {
// not required to work // not required to work
return true return true
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment