diff options
author | Ian Lance Taylor <iant@google.com> | 2016-02-03 21:58:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-02-03 21:58:02 +0000 |
commit | f98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch) | |
tree | 2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/testing | |
parent | b081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff) | |
download | gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2 |
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200
From-SVN: r233110
Diffstat (limited to 'libgo/go/testing')
-rw-r--r-- | libgo/go/testing/benchmark.go | 11 | ||||
-rw-r--r-- | libgo/go/testing/quick/quick.go | 38 | ||||
-rw-r--r-- | libgo/go/testing/quick/quick_test.go | 53 | ||||
-rw-r--r-- | libgo/go/testing/testing.go | 32 |
4 files changed, 109 insertions, 25 deletions
diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go index 62e696d..85178c2 100644 --- a/libgo/go/testing/benchmark.go +++ b/libgo/go/testing/benchmark.go @@ -33,6 +33,17 @@ type InternalBenchmark struct { // B is a type passed to Benchmark functions to manage benchmark // timing and to specify the number of iterations to run. +// +// A benchmark ends when its Benchmark function returns or calls any of the methods +// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods must be called +// only from the goroutine running the Benchmark function. +// The other reporting methods, such as the variations of Log and Error, +// may be called simultaneously from multiple goroutines. +// +// Like in tests, benchmark logs are accumulated during execution +// and dumped to standard error when done. Unlike in tests, benchmark logs +// are always printed, so as not to hide output whose existence may be +// affecting benchmark results. type B struct { common N int diff --git a/libgo/go/testing/quick/quick.go b/libgo/go/testing/quick/quick.go index 13c56cd..187195c 100644 --- a/libgo/go/testing/quick/quick.go +++ b/libgo/go/testing/quick/quick.go @@ -52,8 +52,15 @@ const complexSize = 50 // If the type implements the Generator interface, that will be used. // Note: To create arbitrary values for structs, all the fields must be exported. func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { + return sizedValue(t, rand, complexSize) +} + +// sizedValue returns an arbitrary value of the given type. The size +// hint is used for shrinking as a function of indirection level so +// that recursive data structures will terminate. +func sizedValue(t reflect.Type, rand *rand.Rand, size int) (value reflect.Value, ok bool) { if m, ok := reflect.Zero(t).Interface().(Generator); ok { - return m.Generate(rand, complexSize), true + return m.Generate(rand, size), true } v := reflect.New(t).Elem() @@ -91,21 +98,21 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { case reflect.Uintptr: v.SetUint(uint64(randInt64(rand))) case reflect.Map: - numElems := rand.Intn(complexSize) + numElems := rand.Intn(size) v.Set(reflect.MakeMap(concrete)) for i := 0; i < numElems; i++ { - key, ok1 := Value(concrete.Key(), rand) - value, ok2 := Value(concrete.Elem(), rand) + key, ok1 := sizedValue(concrete.Key(), rand, size) + value, ok2 := sizedValue(concrete.Elem(), rand, size) if !ok1 || !ok2 { return reflect.Value{}, false } v.SetMapIndex(key, value) } case reflect.Ptr: - if rand.Intn(complexSize) == 0 { + if rand.Intn(size) == 0 { v.Set(reflect.Zero(concrete)) // Generate nil pointer. } else { - elem, ok := Value(concrete.Elem(), rand) + elem, ok := sizedValue(concrete.Elem(), rand, size) if !ok { return reflect.Value{}, false } @@ -113,10 +120,11 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { v.Elem().Set(elem) } case reflect.Slice: - numElems := rand.Intn(complexSize) + numElems := rand.Intn(size) + sizeLeft := size - numElems v.Set(reflect.MakeSlice(concrete, numElems, numElems)) for i := 0; i < numElems; i++ { - elem, ok := Value(concrete.Elem(), rand) + elem, ok := sizedValue(concrete.Elem(), rand, sizeLeft) if !ok { return reflect.Value{}, false } @@ -124,7 +132,7 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { } case reflect.Array: for i := 0; i < v.Len(); i++ { - elem, ok := Value(concrete.Elem(), rand) + elem, ok := sizedValue(concrete.Elem(), rand, size) if !ok { return reflect.Value{}, false } @@ -138,8 +146,16 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { } v.SetString(string(codePoints)) case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - elem, ok := Value(concrete.Field(i).Type, rand) + n := v.NumField() + // Divide sizeLeft evenly among the struct fields. + sizeLeft := size + if n > sizeLeft { + sizeLeft = 1 + } else if n > 0 { + sizeLeft /= n + } + for i := 0; i < n; i++ { + elem, ok := sizedValue(concrete.Field(i).Type, rand, sizeLeft) if !ok { return reflect.Value{}, false } diff --git a/libgo/go/testing/quick/quick_test.go b/libgo/go/testing/quick/quick_test.go index c79f30e..fe44359 100644 --- a/libgo/go/testing/quick/quick_test.go +++ b/libgo/go/testing/quick/quick_test.go @@ -259,16 +259,51 @@ func TestFailure(t *testing.T) { } } -// The following test didn't terminate because nil pointers were not -// generated. -// Issue 8818. -func TestNilPointers(t *testing.T) { - type Recursive struct { - Next *Recursive +// Recursive data structures didn't terminate. +// Issues 8818 and 11148. +func TestRecursive(t *testing.T) { + type R struct { + Ptr *R + SliceP []*R + Slice []R + Map map[int]R + MapP map[int]*R + MapR map[*R]*R + SliceMap []map[int]R } - f := func(rec Recursive) bool { - return true - } + f := func(r R) bool { return true } + Check(f, nil) +} + +func TestEmptyStruct(t *testing.T) { + f := func(struct{}) bool { return true } + Check(f, nil) +} + +type ( + A struct{ B *B } + B struct{ A *A } +) + +func TestMutuallyRecursive(t *testing.T) { + f := func(a A) bool { return true } Check(f, nil) } + +// Some serialization formats (e.g. encoding/pem) cannot distinguish +// between a nil and an empty map or slice, so avoid generating the +// zero value for these. +func TestNonZeroSliceAndMap(t *testing.T) { + type Q struct { + M map[int]int + S []int + } + f := func(q Q) bool { + return q.M != nil && q.S != nil + } + err := Check(f, nil) + if err != nil { + t.Fatal(err) + } +} diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index 9ec3869..bcbe8f1 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -149,6 +149,7 @@ import ( "fmt" "os" "runtime" + "runtime/debug" "runtime/pprof" "strconv" "strings" @@ -281,9 +282,18 @@ var _ TB = (*B)(nil) // T is a type passed to Test functions to manage test state and support formatted test logs. // Logs are accumulated during execution and dumped to standard error when done. +// +// A test ends when its Test function returns or calls any of the methods +// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as +// the Parallel method, must be called only from the goroutine running the +// Test function. +// +// The other reporting methods, such as the variations of Log and Error, +// may be called simultaneously from multiple goroutines. type T struct { common - name string // Name of test. + name string // Name of test. + isParallel bool startParallel chan bool // Parallel tests will wait on this. } @@ -417,10 +427,17 @@ func (c *common) Skipped() bool { // Parallel signals that this test is to be run in parallel with (and only with) // other parallel tests. func (t *T) Parallel() { + if t.isParallel { + panic("testing: t.Parallel called multiple times") + } + t.isParallel = true + + // We don't want to include the time we spend waiting for serial tests + // in the test duration. Record the elapsed time thus far and reset the + // timer afterwards. + t.duration += time.Since(t.start) t.signal <- (*T)(nil) // Release main testing loop <-t.startParallel // Wait for serial tests to finish - // Assuming Parallel is the first thing a test does, which is reasonable, - // reinitialize the test's start time because it's actually starting now. t.start = time.Now() } @@ -437,7 +454,7 @@ func tRunner(t *T, test *InternalTest) { // a call to runtime.Goexit, record the duration and send // a signal saying that the test is done. defer func() { - t.duration = time.Now().Sub(t.start) + t.duration += time.Now().Sub(t.start) // If the test panicked, print any test output before dying. err := recover() if !t.finished && err == nil { @@ -484,7 +501,11 @@ func MainStart(matchString func(pat, str string) (bool, error), tests []Internal // Run runs the tests. It returns an exit code to pass to os.Exit. func (m *M) Run() int { - flag.Parse() + // TestMain may have already called flag.Parse. + if !flag.Parsed() { + flag.Parse() + } + parseCpuList() before() @@ -704,6 +725,7 @@ var timer *time.Timer func startAlarm() { if *timeout > 0 { timer = time.AfterFunc(*timeout, func() { + debug.SetTraceback("all") panic(fmt.Sprintf("test timed out after %v", *timeout)) }) } |