aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/testing/testing.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/testing/testing.go')
-rw-r--r--libgo/go/testing/testing.go80
1 files changed, 65 insertions, 15 deletions
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)
}
}
}