]> Cypherpunks repositories - gostls13.git/commitdiff
testing/quick: generate all possible int64, uint64 values
authorRuss Cox <rsc@golang.org>
Fri, 31 Mar 2017 16:46:35 +0000 (12:46 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 3 Apr 2017 14:01:25 +0000 (14:01 +0000)
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>
src/go/build/deps_test.go
src/testing/quick/quick.go
src/time/format_test.go

index 043f9f283270477c8acf9aa9ac0c46dcdf30de9d..53d129c23fae9b4fb40785c79cc26e21028ec976 100644 (file)
@@ -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
index 95860fda0fb32ed0d9050a0c4ab51e68f6a79560..6415e50d652d28863c2d353e9600ed96be17eeec 100644 (file)
@@ -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")
@@ -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.
@@ -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
 }
index d0013bc3e34c03d8ac3e0d492e7cf7140bf4ce3b..710de594a0106a6bfdfc6c9fc646a34cad80220c 100644 (file)
@@ -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
                }