Skip to content

Commit

Permalink
testing/quick: generate all possible int64, uint64 values
Browse files Browse the repository at this point in the history
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: Rob Pike <r@golang.org>
  • Loading branch information
rsc committed Apr 3, 2017
1 parent 65c17a0 commit 719c7b0
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/go/build/deps_test.go
Expand Up @@ -183,7 +183,7 @@ var pkgDeps = map[string][]string{

"testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
"testing/iotest": {"L2", "log"},
"testing/quick": {"L2", "flag", "fmt", "reflect"},
"testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
"internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},

// L4 is defined as L3+fmt+log+time, because in general once
Expand Down
13 changes: 10 additions & 3 deletions src/testing/quick/quick.go
Expand Up @@ -14,6 +14,7 @@ import (
"math/rand"
"reflect"
"strings"
"time"
)

var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
Expand Down Expand Up @@ -43,8 +44,14 @@ func randFloat64(rand *rand.Rand) float64 {
return f
}

// randInt64 returns a random integer taking half the range of an int64.
func randInt64(rand *rand.Rand) int64 { return rand.Int63() - 1<<62 }
// randInt64 returns a random int64.
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
// values.
Expand Down Expand Up @@ -193,7 +200,7 @@ var defaultConfig Config
// getRand returns the *rand.Rand to use for a given Config.
func (c *Config) getRand() *rand.Rand {
if c.Rand == nil {
return rand.New(rand.NewSource(0))
return rand.New(rand.NewSource(time.Now().UnixNano()))
}
return c.Rand
}
Expand Down
4 changes: 2 additions & 2 deletions src/time/format_test.go
Expand Up @@ -378,8 +378,8 @@ func checkTime(time Time, test *ParseTest, t *testing.T) {
func TestFormatAndParse(t *testing.T) {
const fmt = "Mon MST " + RFC3339 // all fields
f := func(sec int64) bool {
t1 := Unix(sec, 0)
if t1.Year() < 1000 || t1.Year() > 9999 {
t1 := Unix(sec/2, 0)
if t1.Year() < 1000 || t1.Year() > 9999 || t1.Unix() != sec {
// not required to work
return true
}
Expand Down

0 comments on commit 719c7b0

Please sign in to comment.