Commits

Anonymous committed 7a67d27 Draft

testing: allow concurrent use of T and B

Notably, allow concurrent logging and failing.

R=golang-dev, r
CC=golang-dev
http://codereview.appspot.com/6453045

Comments (0)

Files changed (1)

src/pkg/testing/testing.go

 	"runtime/pprof"
 	"strconv"
 	"strings"
+	"sync"
 	"time"
 )
 
 // 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.
 }
 
 // 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.
 
 // 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)...)
 }
 
 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)
 				continue
 			}
 			t.report()
-			ok = ok && !out.failed
+			ok = ok && !out.Failed()
 		}
 
 		running := 0
 			}
 			t := (<-collector).(*T)
 			t.report()
-			ok = ok && !t.failed
+			ok = ok && !t.Failed()
 			running--
 		}
 	}