From 9b1412701fc5f265c478153b2032ca90755c38cf Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 25 Jul 2012 10:17:27 -0700 Subject: [PATCH] testing: allow concurrent use of T and B Notably, allow concurrent logging and failing. R=golang-dev, r CC=golang-dev https://golang.org/cl/6453045 --- src/pkg/testing/testing.go | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/pkg/testing/testing.go b/src/pkg/testing/testing.go index 6a25cb3105..e56b77c9c7 100644 --- a/src/pkg/testing/testing.go +++ b/src/pkg/testing/testing.go @@ -87,6 +87,7 @@ import ( "runtime/pprof" "strconv" "strings" + "sync" "time" ) @@ -116,8 +117,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. @@ -176,10 +179,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. @@ -210,6 +221,8 @@ func (c *common) FailNow() { // log generates the output. It's always at the same stack depth. func (c *common) log(s string) { + c.mu.Lock() + defer c.mu.Unlock() c.output = append(c.output, decorate(s)...) } @@ -303,7 +316,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) @@ -362,7 +375,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 @@ -375,7 +388,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-- } } -- 2.48.1