summaryrefslogtreecommitdiff
path: root/libgo/go/testing/testing.go
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2013-01-18 12:34:11 -0800
committerH.J. Lu <hjl.tools@gmail.com>2013-01-18 12:34:11 -0800
commit43269d882367dc4f0e4c2651d6625e1b7de78764 (patch)
tree6aaf525a6fb8a4fb63a71c9ca56be58bc1d6655b /libgo/go/testing/testing.go
parentce97ec0e268b7b50b9f801dd12ffc67042c47193 (diff)
parent48dc1117de124a2265129a36bfbbc211522c2c02 (diff)
downloadgcc-43269d882367dc4f0e4c2651d6625e1b7de78764.tar.gz
Merge remote-tracking branch 'origin/gcc-4_7-branch' into hjl/tsx/gcc-4_7-branchhjl/tsx/gcc-4_7-branch
Conflicts: gcc/config/i386/driver-i386.c gcc/config/i386/i386.c gcc/config/i386/sync.md
Diffstat (limited to 'libgo/go/testing/testing.go')
-rw-r--r--libgo/go/testing/testing.go87
1 files changed, 53 insertions, 34 deletions
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index 1cb8a078c6d..2d2f45e4df1 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -80,6 +80,7 @@ package testing
import (
_ "debug/elf"
+ "bytes"
"flag"
"fmt"
"os"
@@ -87,6 +88,7 @@ import (
"runtime/pprof"
"strconv"
"strings"
+ "sync"
"time"
)
@@ -116,8 +118,10 @@ var (
// common holds the elements common between T and B and
// captures common methods such as Errorf.
type common struct {
- output []byte // Output generated by test or benchmark.
- failed bool // Test or benchmark has failed.
+ mu sync.RWMutex // guards output and failed
+ output []byte // Output generated by test or benchmark.
+ failed bool // Test or benchmark has failed.
+
start time.Time // Time test or benchmark started
duration time.Duration
self interface{} // To be sent on signal channel when done.
@@ -129,37 +133,42 @@ func Short() bool {
return *short
}
-// decorate inserts the final newline if needed and indentation tabs for formatting.
-// If addFileLine is true, it also prefixes the string with the file and line of the call site.
-func decorate(s string, addFileLine bool) string {
- if addFileLine {
- _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
- if ok {
- // Truncate file name at last file name separator.
- if index := strings.LastIndex(file, "/"); index >= 0 {
- file = file[index+1:]
- } else if index = strings.LastIndex(file, "\\"); index >= 0 {
- file = file[index+1:]
- }
- } else {
- file = "???"
- line = 1
+// decorate prefixes the string with the file and line of the call site
+// and inserts the final newline if needed and indentation tabs for formatting.
+func decorate(s string) string {
+ _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
+ if ok {
+ // Truncate file name at last file name separator.
+ if index := strings.LastIndex(file, "/"); index >= 0 {
+ file = file[index+1:]
+ } else if index = strings.LastIndex(file, "\\"); index >= 0 {
+ file = file[index+1:]
}
- s = fmt.Sprintf("%s:%d: %s", file, line, s)
- }
- s = "\t" + s // Every line is indented at least one tab.
- n := len(s)
- if n > 0 && s[n-1] != '\n' {
- s += "\n"
- n++
+ } else {
+ file = "???"
+ line = 1
}
- for i := 0; i < n-1; i++ { // -1 to avoid final newline
- if s[i] == '\n' {
+ buf := new(bytes.Buffer)
+ fmt.Fprintf(buf, "%s:%d: ", file, line)
+
+ lines := strings.Split(s, "\n")
+ for i, line := range lines {
+ if i > 0 {
+ buf.WriteByte('\n')
+ }
+ // Every line is indented at least one tab.
+ buf.WriteByte('\t')
+ if i > 0 {
// Second and subsequent lines are indented an extra tab.
- return s[0:i+1] + "\t" + decorate(s[i+1:n], false)
+ buf.WriteByte('\t')
}
+ buf.WriteString(line)
+ }
+ if l := len(s); l > 0 && s[len(s)-1] != '\n' {
+ // Add final new line if needed.
+ buf.WriteByte('\n')
}
- return s
+ return buf.String()
}
// T is a type passed to Test functions to manage test state and support formatted test logs.
@@ -171,10 +180,18 @@ type T struct {
}
// Fail marks the function as having failed but continues execution.
-func (c *common) Fail() { c.failed = true }
+func (c *common) Fail() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.failed = true
+}
// Failed returns whether the function has failed.
-func (c *common) Failed() bool { return c.failed }
+func (c *common) Failed() bool {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ return c.failed
+}
// FailNow marks the function as having failed and stops its execution.
// Execution will continue at the next test or benchmark.
@@ -205,7 +222,9 @@ func (c *common) FailNow() {
// log generates the output. It's always at the same stack depth.
func (c *common) log(s string) {
- c.output = append(c.output, decorate(s, true)...)
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.output = append(c.output, decorate(s)...)
}
// Log formats its arguments using default formatting, analogous to Println(),
@@ -298,7 +317,7 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest,
func (t *T) report() {
tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds())
format := "--- %s: %s %s\n%s"
- if t.failed {
+ if t.Failed() {
fmt.Printf(format, "FAIL", t.name, tstr, t.output)
} else if *chatty {
fmt.Printf(format, "PASS", t.name, tstr, t.output)
@@ -357,7 +376,7 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
continue
}
t.report()
- ok = ok && !out.failed
+ ok = ok && !out.Failed()
}
running := 0
@@ -370,7 +389,7 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
}
t := (<-collector).(*T)
t.report()
- ok = ok && !t.failed
+ ok = ok && !t.Failed()
running--
}
}