aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/testing
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-01-18 19:04:36 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-01-18 19:04:36 +0000
commit4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch)
treef12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/go/testing
parent225220d668dafb8262db7012bced688acbe63b33 (diff)
downloadgcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.zip
gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.gz
gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.bz2
libgo: update to Go1.12beta2
Reviewed-on: https://go-review.googlesource.com/c/158019 gotools/: * Makefile.am (go_cmd_vet_files): Update for Go1.12beta2 release. (GOTOOLS_TEST_TIMEOUT): Increase to 600. (check-runtime): Export LD_LIBRARY_PATH before computing GOARCH and GOOS. (check-vet): Copy golang.org/x/tools into check-vet-dir. * Makefile.in: Regenerate. gcc/testsuite/: * go.go-torture/execute/names-1.go: Stop using debug/xcoff, which is no longer externally visible. From-SVN: r268084
Diffstat (limited to 'libgo/go/testing')
-rw-r--r--libgo/go/testing/benchmark.go77
-rw-r--r--libgo/go/testing/sub_test.go31
-rw-r--r--libgo/go/testing/testing.go53
3 files changed, 129 insertions, 32 deletions
diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go
index 9c7b1be..8dd8cbc 100644
--- a/libgo/go/testing/benchmark.go
+++ b/libgo/go/testing/benchmark.go
@@ -10,15 +10,50 @@ import (
"internal/race"
"os"
"runtime"
+ "strconv"
+ "strings"
"sync"
"sync/atomic"
"time"
)
var matchBenchmarks = flag.String("test.bench", "", "run only benchmarks matching `regexp`")
-var benchTime = flag.Duration("test.benchtime", 1*time.Second, "run each benchmark for duration `d`")
+var benchTime = benchTimeFlag{d: 1 * time.Second}
var benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
+func init() {
+ flag.Var(&benchTime, "test.benchtime", "run each benchmark for duration `d`")
+}
+
+type benchTimeFlag struct {
+ d time.Duration
+ n int
+}
+
+func (f *benchTimeFlag) String() string {
+ if f.n > 0 {
+ return fmt.Sprintf("%dx", f.n)
+ }
+ return time.Duration(f.d).String()
+}
+
+func (f *benchTimeFlag) Set(s string) error {
+ if strings.HasSuffix(s, "x") {
+ n, err := strconv.ParseInt(s[:len(s)-1], 10, 0)
+ if err != nil || n <= 0 {
+ return fmt.Errorf("invalid count")
+ }
+ *f = benchTimeFlag{n: int(n)}
+ return nil
+ }
+ d, err := time.ParseDuration(s)
+ if err != nil || d <= 0 {
+ return fmt.Errorf("invalid duration")
+ }
+ *f = benchTimeFlag{d: d}
+ return nil
+}
+
// Global lock to ensure only one benchmark runs at a time.
var benchmarkLock sync.Mutex
@@ -53,7 +88,7 @@ type B struct {
previousN int // number of iterations in the previous run
previousDuration time.Duration // total duration of the previous run
benchFunc func(b *B)
- benchTime time.Duration
+ benchTime benchTimeFlag
bytes int64
missingBytes bool // one of the subbenchmarks does not have bytes set.
timerOn bool
@@ -195,7 +230,7 @@ func roundUp(n int) int {
}
}
-// run1 runs the first iteration of benchFunc. It returns whether more
+// run1 runs the first iteration of benchFunc. It reports whether more
// iterations of this benchmarks should be run.
func (b *B) run1() bool {
if ctx := b.context; ctx != nil {
@@ -273,21 +308,25 @@ func (b *B) launch() {
}()
// Run the benchmark for at least the specified amount of time.
- d := b.benchTime
- for n := 1; !b.failed && b.duration < d && n < 1e9; {
- last := n
- // Predict required iterations.
- n = int(d.Nanoseconds())
- if nsop := b.nsPerOp(); nsop != 0 {
- n /= int(nsop)
+ if b.benchTime.n > 0 {
+ b.runN(b.benchTime.n)
+ } else {
+ d := b.benchTime.d
+ for n := 1; !b.failed && b.duration < d && n < 1e9; {
+ last := n
+ // Predict required iterations.
+ n = int(d.Nanoseconds())
+ if nsop := b.nsPerOp(); nsop != 0 {
+ n /= int(nsop)
+ }
+ // 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/5, 100*last), last+1)
+ // Round up to something easy to read.
+ n = roundUp(n)
+ b.runN(n)
}
- // 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/5, 100*last), last+1)
- // Round up to something easy to read.
- n = roundUp(n)
- b.runN(n)
}
b.result = BenchmarkResult{b.N, b.duration, b.bytes, b.netAllocs, b.netBytes}
}
@@ -416,7 +455,7 @@ func runBenchmarks(importPath string, matchString func(pat, str string) (bool, e
b.Run(Benchmark.Name, Benchmark.F)
}
},
- benchTime: *benchTime,
+ benchTime: benchTime,
context: ctx,
}
main.runN(1)
@@ -653,7 +692,7 @@ func Benchmark(f func(b *B)) BenchmarkResult {
w: discard{},
},
benchFunc: f,
- benchTime: *benchTime,
+ benchTime: benchTime,
}
if b.run1() {
b.run()
diff --git a/libgo/go/testing/sub_test.go b/libgo/go/testing/sub_test.go
index 9af3909..8c98971 100644
--- a/libgo/go/testing/sub_test.go
+++ b/libgo/go/testing/sub_test.go
@@ -17,7 +17,7 @@ import (
func init() {
// Make benchmark tests run 10* faster.
- *benchTime = 100 * time.Millisecond
+ benchTime.d = 100 * time.Millisecond
}
func TestTestContext(t *T) {
@@ -411,6 +411,29 @@ func TestTRun(t *T) {
ch <- true
<-ch
},
+ }, {
+ desc: "log in finished sub test logs to parent",
+ ok: false,
+ output: `
+ --- FAIL: log in finished sub test logs to parent (N.NNs)
+ sub_test.go:NNN: message2
+ sub_test.go:NNN: message1
+ sub_test.go:NNN: error`,
+ maxPar: 1,
+ f: func(t *T) {
+ ch := make(chan bool)
+ t.Run("sub", func(t2 *T) {
+ go func() {
+ <-ch
+ t2.Log("message1")
+ ch <- true
+ }()
+ })
+ t.Log("message2")
+ ch <- true
+ <-ch
+ t.Errorf("error")
+ },
}}
for _, tc := range testCases {
ctx := newTestContext(tc.maxPar, newMatcher(regexp.MatchString, "", ""))
@@ -570,7 +593,7 @@ func TestBRun(t *T) {
chatty: tc.chatty,
},
benchFunc: func(b *B) { ok = b.Run("test", tc.f) }, // Use Run to catch failure.
- benchTime: time.Microsecond,
+ benchTime: benchTimeFlag{d: 1 * time.Microsecond},
}
root.runN(1)
if ok != !tc.failed {
@@ -594,8 +617,8 @@ func TestBRun(t *T) {
func makeRegexp(s string) string {
s = regexp.QuoteMeta(s)
- s = strings.Replace(s, ":NNN:", `:\d\d\d:`, -1)
- s = strings.Replace(s, "N\\.NNs", `\d*\.\d*s`, -1)
+ s = strings.ReplaceAll(s, ":NNN:", `:\d\d\d:`)
+ s = strings.ReplaceAll(s, "N\\.NNs", `\d*\.\d*s`)
return s
}
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index a552b36..0ac51b6 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -17,13 +17,13 @@
// package builds but will be included when the ``go test'' command is run.
// For more detail, run ``go help test'' and ``go help testflag''.
//
-// Tests and benchmarks may be skipped if not applicable with a call to
-// the Skip method of *T and *B:
-// func TestTimeConsuming(t *testing.T) {
-// if testing.Short() {
-// t.Skip("skipping test in short mode.")
+// A simple test function looks like this:
+//
+// func TestAbs(t *testing.T) {
+// got := Abs(-1)
+// if got != 1 {
+// t.Errorf("Abs(-1) = %d; want 1", got)
// }
-// ...
// }
//
// Benchmarks
@@ -132,6 +132,18 @@
// example function, at least one other function, type, variable, or constant
// declaration, and no test or benchmark functions.
//
+// Skipping
+//
+// Tests or benchmarks may be skipped at run time with a call to
+// the Skip method of *T or *B:
+//
+// func TestTimeConsuming(t *testing.T) {
+// if testing.Short() {
+// t.Skip("skipping test in short mode.")
+// }
+// ...
+// }
+//
// Subtests and Sub-benchmarks
//
// The Run methods of T and B allow defining subtests and sub-benchmarks,
@@ -316,6 +328,13 @@ type common struct {
// Short reports whether the -test.short flag is set.
func Short() bool {
+ // Catch code that calls this from TestMain without first
+ // calling flag.Parse. This shouldn't really be a panic
+ if !flag.Parsed() {
+ fmt.Fprintf(os.Stderr, "testing: testing.Short called before flag.Parse\n")
+ os.Exit(2)
+ }
+
return *short
}
@@ -396,8 +415,8 @@ func (c *common) frameSkip(skip int) runtime.Frame {
// decorate prefixes the string with the file and line of the call site
// and inserts the final newline if needed and indentation spaces for formatting.
// This function must be called with c.mu held.
-func (c *common) decorate(s string) string {
- frame := c.frameSkip(3) // decorate + log + public function.
+func (c *common) decorate(s string, skip int) string {
+ frame := c.frameSkip(skip)
file := frame.File
line := frame.Line
if file != "" {
@@ -592,9 +611,25 @@ func (c *common) FailNow() {
// log generates the output. It's always at the same stack depth.
func (c *common) log(s string) {
+ c.logDepth(s, 3) // logDepth + log + public function
+}
+
+// logDepth generates the output. At an arbitary stack depth
+func (c *common) logDepth(s string, depth int) {
c.mu.Lock()
defer c.mu.Unlock()
- c.output = append(c.output, c.decorate(s)...)
+ // If this test has already finished try and log this message with our parent
+ // with this test name tagged so we know where it came from.
+ // If we don't have a parent panic.
+ if c.done {
+ if c.parent != nil {
+ c.parent.logDepth(s, depth+1)
+ } else {
+ panic("Log in goroutine after " + c.name + " has completed")
+ }
+ } else {
+ c.output = append(c.output, c.decorate(s, depth+1)...)
+ }
}
// Log formats its arguments using default formatting, analogous to Println,