diff options
Diffstat (limited to 'libgo/go/testing')
-rw-r--r-- | libgo/go/testing/allocs_test.go | 29 | ||||
-rw-r--r-- | libgo/go/testing/benchmark.go | 16 | ||||
-rw-r--r-- | libgo/go/testing/benchmark_test.go | 2 | ||||
-rw-r--r-- | libgo/go/testing/cover.go | 28 | ||||
-rw-r--r-- | libgo/go/testing/example.go | 6 | ||||
-rw-r--r-- | libgo/go/testing/quick/quick.go | 6 | ||||
-rw-r--r-- | libgo/go/testing/testing.go | 18 | ||||
-rw-r--r-- | libgo/go/testing/testing_test.go | 18 |
8 files changed, 103 insertions, 20 deletions
diff --git a/libgo/go/testing/allocs_test.go b/libgo/go/testing/allocs_test.go new file mode 100644 index 00000000000..ec17daa2b1d --- /dev/null +++ b/libgo/go/testing/allocs_test.go @@ -0,0 +1,29 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testing_test + +import "testing" + +var global interface{} + +var allocsPerRunTests = []struct { + name string + fn func() + allocs float64 +}{ + {"alloc *byte", func() { global = new(*byte) }, 1}, + {"alloc complex128", func() { global = new(complex128) }, 1}, + {"alloc float64", func() { global = new(float64) }, 1}, + {"alloc int32", func() { global = new(int32) }, 1}, + {"alloc byte", func() { global = new(byte) }, 1}, +} + +func TestAllocsPerRun(t *testing.T) { + for _, tt := range allocsPerRunTests { + if allocs := testing.AllocsPerRun(100, tt.fn); allocs != tt.allocs { + t.Errorf("AllocsPerRun(100, %s) = %v, want %v", tt.name, allocs, tt.allocs) + } + } +} diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go index 1fbf5c8615f..ffd5376844a 100644 --- a/libgo/go/testing/benchmark.go +++ b/libgo/go/testing/benchmark.go @@ -157,7 +157,7 @@ func roundDown10(n int) int { return result } -// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX]. +// roundUp rounds x up to a number of the form [1eX, 2eX, 3eX, 5eX]. func roundUp(n int) int { base := roundDown10(n) switch { @@ -165,6 +165,8 @@ func roundUp(n int) int { return base case n <= (2 * base): return 2 * base + case n <= (3 * base): + return 3 * base case n <= (5 * base): return 5 * base default: @@ -180,10 +182,10 @@ func (b *B) run() BenchmarkResult { } // launch launches the benchmark function. It gradually increases the number -// of benchmark iterations until the benchmark runs for a second in order -// to get a reasonable measurement. It prints timing information in this form +// of benchmark iterations until the benchmark runs for the requested benchtime. +// It prints timing information in this form // testing.BenchmarkHello 100000 19 ns/op -// launch is run by the fun function as a separate goroutine. +// launch is run by the run function as a separate goroutine. func (b *B) launch() { // Run the benchmark for a single iteration in case it's expensive. n := 1 @@ -199,16 +201,16 @@ func (b *B) launch() { d := *benchTime for !b.failed && b.duration < d && n < 1e9 { last := n - // Predict iterations/sec. + // Predict required iterations. if b.nsPerOp() == 0 { n = 1e9 } else { n = int(d.Nanoseconds() / b.nsPerOp()) } - // Run more iterations than we think we'll need for a second (1.5x). + // Run more iterations than we think we'll need (1.2x). // Don't grow too fast in case we had timing errors previously. // Be sure to run at least one more than last time. - n = max(min(n+n/2, 100*last), last+1) + n = max(min(n+n/5, 100*last), last+1) // Round up to something easy to read. n = roundUp(n) b.runN(n) diff --git a/libgo/go/testing/benchmark_test.go b/libgo/go/testing/benchmark_test.go index f7ea64e7f1c..431bb537bd5 100644 --- a/libgo/go/testing/benchmark_test.go +++ b/libgo/go/testing/benchmark_test.go @@ -41,12 +41,14 @@ var roundUpTests = []struct { {0, 1}, {1, 1}, {2, 2}, + {3, 3}, {5, 5}, {9, 10}, {999, 1000}, {1000, 1000}, {1400, 2000}, {1700, 2000}, + {2700, 3000}, {4999, 5000}, {5000, 5000}, {5001, 10000}, diff --git a/libgo/go/testing/cover.go b/libgo/go/testing/cover.go index dd29364d87e..a4ce37f7c2d 100644 --- a/libgo/go/testing/cover.go +++ b/libgo/go/testing/cover.go @@ -9,6 +9,7 @@ package testing import ( "fmt" "os" + "sync/atomic" ) // CoverBlock records the coverage data for a single basic block. @@ -34,6 +35,29 @@ type Cover struct { CoveredPackages string } +// Coverage reports the current code coverage as a fraction in the range [0, 1]. +// If coverage is not enabled, Coverage returns 0. +// +// When running a large set of sequential test cases, checking Coverage after each one +// can be useful for identifying which test cases exercise new code paths. +// It is not a replacement for the reports generated by 'go test -cover' and +// 'go tool cover'. +func Coverage() float64 { + var n, d int64 + for _, counters := range cover.Counters { + for i := range counters { + if atomic.LoadUint32(&counters[i]) > 0 { + n++ + } + d++ + } + } + if d == 0 { + return 0 + } + return float64(n) / float64(d) +} + // RegisterCover records the coverage data accumulators for the tests. // NOTE: This function is internal to the testing infrastructure and may change. // It is not covered (yet) by the Go 1 compatibility guidelines. @@ -61,11 +85,13 @@ func coverReport() { } var active, total int64 + var count uint32 for name, counts := range cover.Counters { blocks := cover.Blocks[name] - for i, count := range counts { + for i := range counts { stmts := int64(blocks[i].Stmts) total += stmts + count = atomic.LoadUint32(&counts[i]) // For -mode=atomic. if count > 0 { active += stmts } diff --git a/libgo/go/testing/example.go b/libgo/go/testing/example.go index 828c2d3eda8..f5762e4db4a 100644 --- a/libgo/go/testing/example.go +++ b/libgo/go/testing/example.go @@ -71,7 +71,7 @@ func runExample(eg InternalExample) (ok bool) { // Clean up in a deferred call so we can recover if the example panics. defer func() { - d := time.Now().Sub(start) + dstr := fmtDuration(time.Now().Sub(start)) // Close pipe, restore stdout, get output. w.Close() @@ -84,10 +84,10 @@ func runExample(eg InternalExample) (ok bool) { fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", g, e) } if fail != "" || err != nil { - fmt.Printf("--- FAIL: %s (%v)\n%s", eg.Name, d, fail) + fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail) ok = false } else if *chatty { - fmt.Printf("--- PASS: %s (%v)\n", eg.Name, d) + fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr) } if err != nil { panic(err) diff --git a/libgo/go/testing/quick/quick.go b/libgo/go/testing/quick/quick.go index bc79cc32922..909c65f788b 100644 --- a/libgo/go/testing/quick/quick.go +++ b/libgo/go/testing/quick/quick.go @@ -225,12 +225,12 @@ func (s *CheckEqualError) Error() string { // t.Error(err) // } // } -func Check(function interface{}, config *Config) (err error) { +func Check(f interface{}, config *Config) (err error) { if config == nil { config = &defaultConfig } - f, fType, ok := functionAndType(function) + fVal, fType, ok := functionAndType(f) if !ok { err = SetupError("argument is not a function") return @@ -255,7 +255,7 @@ func Check(function interface{}, config *Config) (err error) { return } - if !f.Call(arguments)[0].Bool() { + if !fVal.Call(arguments)[0].Bool() { err = &CheckError{i + 1, toInterfaces(arguments)} return } diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index 1b7360a177e..e54a3b8ce4d 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -44,7 +44,7 @@ // } // // The benchmark function must run the target code b.N times. -// The benchmark package will vary b.N until the benchmark function lasts +// During benchark execution, b.N is adjusted until the benchmark function lasts // long enough to be timed reliably. The output // BenchmarkHello 10000000 282 ns/op // means that the loop ran 10000000 times at a speed of 282 ns per loop. @@ -243,6 +243,11 @@ func decorate(s string) string { return buf.String() } +// fmtDuration returns a string representing d in the form "87.00s". +func fmtDuration(d time.Duration) string { + return fmt.Sprintf("%.2fs", d.Seconds()) +} + // TB is the interface common to T and B. type TB interface { Error(args ...interface{}) @@ -492,15 +497,15 @@ func (m *M) Run() int { } func (t *T) report() { - tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds()) - format := "--- %s: %s %s\n%s" + dstr := fmtDuration(t.duration) + format := "--- %s: %s (%s)\n%s" if t.Failed() { - fmt.Printf(format, "FAIL", t.name, tstr, t.output) + fmt.Printf(format, "FAIL", t.name, dstr, t.output) } else if *chatty { if t.Skipped() { - fmt.Printf(format, "SKIP", t.name, tstr, t.output) + fmt.Printf(format, "SKIP", t.name, dstr, t.output) } else { - fmt.Printf(format, "PASS", t.name, tstr, t.output) + fmt.Printf(format, "PASS", t.name, dstr, t.output) } } } @@ -615,6 +620,7 @@ func after() { fmt.Fprintf(os.Stderr, "testing: %s\n", err) os.Exit(2) } + runtime.GC() // materialize all statistics if err = pprof.WriteHeapProfile(f); err != nil { fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *memProfile, err) os.Exit(2) diff --git a/libgo/go/testing/testing_test.go b/libgo/go/testing/testing_test.go new file mode 100644 index 00000000000..87a5c16d6ed --- /dev/null +++ b/libgo/go/testing/testing_test.go @@ -0,0 +1,18 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testing_test + +import ( + "os" + "testing" +) + +// This is exactly what a test would do without a TestMain. +// It's here only so that there is at least one package in the +// standard library with a TestMain, so that code is executed. + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} |