aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/testing
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-07-17 12:30:51 -0700
committerIan Lance Taylor <iant@golang.org>2020-07-17 14:28:28 -0700
commitd5dfd4793febee6526e9ca84e06b5e207e0fbcee (patch)
tree67ee8ec7e6ad1697dfa1546524756140af9c8664 /libgo/go/testing
parentf1b6e46c417224887c2f21baa6d4c538a25fe9fb (diff)
downloadgcc-d5dfd4793febee6526e9ca84e06b5e207e0fbcee.zip
gcc-d5dfd4793febee6526e9ca84e06b5e207e0fbcee.tar.gz
gcc-d5dfd4793febee6526e9ca84e06b5e207e0fbcee.tar.bz2
libgo: update to Go 1.14.6 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/243317
Diffstat (limited to 'libgo/go/testing')
-rw-r--r--libgo/go/testing/benchmark.go3
-rw-r--r--libgo/go/testing/sub_test.go126
-rw-r--r--libgo/go/testing/testing.go80
3 files changed, 132 insertions, 77 deletions
diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go
index 88ba0f0..5276600 100644
--- a/libgo/go/testing/benchmark.go
+++ b/libgo/go/testing/benchmark.go
@@ -526,6 +526,7 @@ func runBenchmarks(importPath string, matchString func(pat, str string) (bool, e
name: "Main",
w: os.Stdout,
chatty: *chatty,
+ bench: true,
},
importPath: importPath,
benchFunc: func(b *B) {
@@ -559,6 +560,7 @@ func (ctx *benchContext) processBench(b *B) {
name: b.name,
w: b.w,
chatty: b.chatty,
+ bench: true,
},
benchFunc: b.benchFunc,
benchTime: b.benchTime,
@@ -624,6 +626,7 @@ func (b *B) Run(name string, f func(b *B)) bool {
creator: pc[:n],
w: b.w,
chatty: b.chatty,
+ bench: true,
},
importPath: b.importPath,
benchFunc: f,
diff --git a/libgo/go/testing/sub_test.go b/libgo/go/testing/sub_test.go
index 95f8220..8eb0084 100644
--- a/libgo/go/testing/sub_test.go
+++ b/libgo/go/testing/sub_test.go
@@ -438,8 +438,6 @@ func TestTRun(t *T) {
}, {
// A chatty test should always log with fmt.Print, even if the
// parent test has completed.
- // TODO(deklerk) Capture the log of fmt.Print and assert that the
- // subtest message is not lost.
desc: "log in finished sub test with chatty",
ok: false,
chatty: true,
@@ -477,35 +475,37 @@ func TestTRun(t *T) {
},
}}
for _, tc := range testCases {
- ctx := newTestContext(tc.maxPar, newMatcher(regexp.MatchString, "", ""))
- buf := &bytes.Buffer{}
- root := &T{
- common: common{
- signal: make(chan bool),
- name: "Test",
- w: buf,
- chatty: tc.chatty,
- },
- context: ctx,
- }
- ok := root.Run(tc.desc, tc.f)
- ctx.release()
+ t.Run(tc.desc, func(t *T) {
+ ctx := newTestContext(tc.maxPar, newMatcher(regexp.MatchString, "", ""))
+ buf := &bytes.Buffer{}
+ root := &T{
+ common: common{
+ signal: make(chan bool),
+ name: "Test",
+ w: buf,
+ chatty: tc.chatty,
+ },
+ context: ctx,
+ }
+ ok := root.Run(tc.desc, tc.f)
+ ctx.release()
- if ok != tc.ok {
- t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, tc.ok)
- }
- if ok != !root.Failed() {
- t.Errorf("%s:root failed: got %v; want %v", tc.desc, !ok, root.Failed())
- }
- if ctx.running != 0 || ctx.numWaiting != 0 {
- t.Errorf("%s:running and waiting non-zero: got %d and %d", tc.desc, ctx.running, ctx.numWaiting)
- }
- got := strings.TrimSpace(buf.String())
- want := strings.TrimSpace(tc.output)
- re := makeRegexp(want)
- if ok, err := regexp.MatchString(re, got); !ok || err != nil {
- t.Errorf("%s:output:\ngot:\n%s\nwant:\n%s", tc.desc, got, want)
- }
+ if ok != tc.ok {
+ t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, tc.ok)
+ }
+ if ok != !root.Failed() {
+ t.Errorf("%s:root failed: got %v; want %v", tc.desc, !ok, root.Failed())
+ }
+ if ctx.running != 0 || ctx.numWaiting != 0 {
+ t.Errorf("%s:running and waiting non-zero: got %d and %d", tc.desc, ctx.running, ctx.numWaiting)
+ }
+ got := strings.TrimSpace(buf.String())
+ want := strings.TrimSpace(tc.output)
+ re := makeRegexp(want)
+ if ok, err := regexp.MatchString(re, got); !ok || err != nil {
+ t.Errorf("%s:output:\ngot:\n%s\nwant:\n%s", tc.desc, got, want)
+ }
+ })
}
}
@@ -655,43 +655,45 @@ func TestBRun(t *T) {
},
}}
for _, tc := range testCases {
- var ok bool
- buf := &bytes.Buffer{}
- // This is almost like the Benchmark function, except that we override
- // the benchtime and catch the failure result of the subbenchmark.
- root := &B{
- common: common{
- signal: make(chan bool),
- name: "root",
- w: buf,
- chatty: tc.chatty,
- },
- benchFunc: func(b *B) { ok = b.Run("test", tc.f) }, // Use Run to catch failure.
- benchTime: benchTimeFlag{d: 1 * time.Microsecond},
- }
- root.runN(1)
- if ok != !tc.failed {
- t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, !tc.failed)
- }
- if !ok != root.Failed() {
- t.Errorf("%s:root failed: got %v; want %v", tc.desc, !ok, root.Failed())
- }
- // All tests are run as subtests
- if root.result.N != 1 {
- t.Errorf("%s: N for parent benchmark was %d; want 1", tc.desc, root.result.N)
- }
- got := strings.TrimSpace(buf.String())
- want := strings.TrimSpace(tc.output)
- re := makeRegexp(want)
- if ok, err := regexp.MatchString(re, got); !ok || err != nil {
- t.Errorf("%s:output:\ngot:\n%s\nwant:\n%s", tc.desc, got, want)
- }
+ t.Run(tc.desc, func(t *T) {
+ var ok bool
+ buf := &bytes.Buffer{}
+ // This is almost like the Benchmark function, except that we override
+ // the benchtime and catch the failure result of the subbenchmark.
+ root := &B{
+ common: common{
+ signal: make(chan bool),
+ name: "root",
+ w: buf,
+ chatty: tc.chatty,
+ },
+ benchFunc: func(b *B) { ok = b.Run("test", tc.f) }, // Use Run to catch failure.
+ benchTime: benchTimeFlag{d: 1 * time.Microsecond},
+ }
+ root.runN(1)
+ if ok != !tc.failed {
+ t.Errorf("%s:ok: got %v; want %v", tc.desc, ok, !tc.failed)
+ }
+ if !ok != root.Failed() {
+ t.Errorf("%s:root failed: got %v; want %v", tc.desc, !ok, root.Failed())
+ }
+ // All tests are run as subtests
+ if root.result.N != 1 {
+ t.Errorf("%s: N for parent benchmark was %d; want 1", tc.desc, root.result.N)
+ }
+ got := strings.TrimSpace(buf.String())
+ want := strings.TrimSpace(tc.output)
+ re := makeRegexp(want)
+ if ok, err := regexp.MatchString(re, got); !ok || err != nil {
+ t.Errorf("%s:output:\ngot:\n%s\nwant:\n%s", tc.desc, got, want)
+ }
+ })
}
}
func makeRegexp(s string) string {
s = regexp.QuoteMeta(s)
- s = strings.ReplaceAll(s, ":NNN:", `:\d\d\d:`)
+ s = strings.ReplaceAll(s, ":NNN:", `:\d\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 758af74..9f47eb8 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -320,6 +320,7 @@ var (
cpuListStr *string
parallel *int
testlog *string
+ printer *testPrinter
haveExamples bool // are there examples?
@@ -329,6 +330,48 @@ var (
numFailed uint32 // number of test failures
)
+type testPrinter struct {
+ chatty bool
+
+ lastNameMu sync.Mutex // guards lastName
+ lastName string // last printed test name in chatty mode
+}
+
+func newTestPrinter(chatty bool) *testPrinter {
+ return &testPrinter{
+ chatty: chatty,
+ }
+}
+
+func (p *testPrinter) Print(testName, out string) {
+ p.Fprint(os.Stdout, testName, out)
+}
+
+func (p *testPrinter) Fprint(w io.Writer, testName, out string) {
+ p.lastNameMu.Lock()
+ defer p.lastNameMu.Unlock()
+
+ if !p.chatty ||
+ strings.HasPrefix(out, "--- PASS") ||
+ strings.HasPrefix(out, "--- FAIL") ||
+ strings.HasPrefix(out, "=== CONT") ||
+ strings.HasPrefix(out, "=== RUN") {
+ p.lastName = testName
+ fmt.Fprint(w, out)
+ return
+ }
+
+ if p.lastName == "" {
+ p.lastName = testName
+ } else if p.lastName != testName {
+ // Always printed as-is, with 0 decoration or indentation. So, we skip
+ // printing to w.
+ fmt.Printf("=== CONT %s\n", testName)
+ p.lastName = testName
+ }
+ fmt.Fprint(w, out)
+}
+
// The maximum number of stack frames to go through when skipping helper functions for
// the purpose of decorating log messages.
const maxStackLen = 50
@@ -347,10 +390,11 @@ type common struct {
cleanup func() // optional function to be called at the end of the test
chatty bool // A copy of the chatty flag.
+ bench bool // Whether the current test is a benchmark.
finished bool // Test function has completed.
- hasSub int32 // written atomically
- raceErrors int // number of races detected during test
- runner string // function name of tRunner running the test
+ hasSub int32 // Written atomically.
+ raceErrors int // Number of races detected during test.
+ runner string // Function name of tRunner running the test.
parent *common
level int // Nesting depth of test or benchmark.
@@ -480,9 +524,6 @@ func (c *common) decorate(s string, skip int) string {
buf := new(strings.Builder)
// Every line is indented at least 4 spaces.
buf.WriteString(" ")
- if c.chatty {
- fmt.Fprintf(buf, "%s: ", c.name)
- }
fmt.Fprintf(buf, "%s:%d: ", file, line)
lines := strings.Split(s, "\n")
if l := len(lines); l > 1 && lines[l-1] == "" {
@@ -501,12 +542,12 @@ func (c *common) decorate(s string, skip int) string {
// flushToParent writes c.output to the parent after first writing the header
// with the given format and arguments.
-func (c *common) flushToParent(format string, args ...interface{}) {
+func (c *common) flushToParent(testName, format string, args ...interface{}) {
p := c.parent
p.mu.Lock()
defer p.mu.Unlock()
- fmt.Fprintf(p.w, format, args...)
+ printer.Fprint(p.w, testName, fmt.Sprintf(format, args...))
c.mu.Lock()
defer c.mu.Unlock()
@@ -680,7 +721,14 @@ func (c *common) logDepth(s string, depth int) {
panic("Log in goroutine after " + c.name + " has completed")
} else {
if c.chatty {
- fmt.Print(c.decorate(s, depth+1))
+ if c.bench {
+ // Benchmarks don't print === CONT, so we should skip the test
+ // printer and just print straight to stdout.
+ fmt.Print(c.decorate(s, depth+1))
+ } else {
+ printer.Print(c.name, c.decorate(s, depth+1))
+ }
+
return
}
c.output = append(c.output, c.decorate(s, depth+1)...)
@@ -909,7 +957,7 @@ func (t *T) Parallel() {
for ; root.parent != nil; root = root.parent {
}
root.mu.Lock()
- fmt.Fprintf(root.w, "=== CONT %s\n", t.name)
+ printer.Fprint(root.w, t.name, fmt.Sprintf("=== CONT %s\n", t.name))
root.mu.Unlock()
}
@@ -968,7 +1016,7 @@ func tRunner(t *T, fn func(t *T)) {
root.duration += time.Since(root.start)
d := root.duration
root.mu.Unlock()
- root.flushToParent("--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
+ root.flushToParent(root.name, "--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
if r := root.parent.runCleanup(recoverAndReturnPanic); r != nil {
fmt.Fprintf(root.parent.w, "cleanup panicked with %v", r)
}
@@ -1067,7 +1115,7 @@ func (t *T) Run(name string, f func(t *T)) bool {
for ; root.parent != nil; root = root.parent {
}
root.mu.Lock()
- fmt.Fprintf(root.w, "=== RUN %s\n", t.name)
+ printer.Fprint(root.w, t.name, fmt.Sprintf("=== RUN %s\n", t.name))
root.mu.Unlock()
}
// Instead of reducing the running count of this test before calling the
@@ -1215,6 +1263,8 @@ func (m *M) Run() int {
flag.Parse()
}
+ printer = newTestPrinter(Verbose())
+
if *parallel < 1 {
fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
flag.Usage()
@@ -1254,12 +1304,12 @@ func (t *T) report() {
dstr := fmtDuration(t.duration)
format := "--- %s: %s (%s)\n"
if t.Failed() {
- t.flushToParent(format, "FAIL", t.name, dstr)
+ t.flushToParent(t.name, format, "FAIL", t.name, dstr)
} else if t.chatty {
if t.Skipped() {
- t.flushToParent(format, "SKIP", t.name, dstr)
+ t.flushToParent(t.name, format, "SKIP", t.name, dstr)
} else {
- t.flushToParent(format, "PASS", t.name, dstr)
+ t.flushToParent(t.name, format, "PASS", t.name, dstr)
}
}
}