diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-01-18 19:04:36 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-18 19:04:36 +0000 |
commit | 4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch) | |
tree | f12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/go/testing | |
parent | 225220d668dafb8262db7012bced688acbe63b33 (diff) | |
download | gcc-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.go | 77 | ||||
-rw-r--r-- | libgo/go/testing/sub_test.go | 31 | ||||
-rw-r--r-- | libgo/go/testing/testing.go | 53 |
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, |