summaryrefslogtreecommitdiff
path: root/libgo/go/testing
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/testing')
-rw-r--r--libgo/go/testing/allocs_test.go29
-rw-r--r--libgo/go/testing/benchmark.go16
-rw-r--r--libgo/go/testing/benchmark_test.go2
-rw-r--r--libgo/go/testing/cover.go28
-rw-r--r--libgo/go/testing/example.go6
-rw-r--r--libgo/go/testing/quick/quick.go6
-rw-r--r--libgo/go/testing/testing.go18
-rw-r--r--libgo/go/testing/testing_test.go18
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())
+}