diff options
| author | Russ Cox <rsc@golang.org> | 2016-11-02 21:40:47 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2016-11-03 18:19:49 +0000 |
| commit | 43f954e09858449cc5f3650720e81b7e879ab349 (patch) | |
| tree | b90e4449cb80a45e9ab3b95a69fe2efe54bc6a90 /src/testing/testing.go | |
| parent | f3862742b67a84edf939f41276360ada4e7197a6 (diff) | |
| download | go-43f954e09858449cc5f3650720e81b7e879ab349.tar.xz | |
testing: mark tests and benchmarks failed if a race occurs during execution
Before:
$ go test -race -v -run TestRace
=== RUN TestRace
==================
WARNING: DATA RACE
Write at 0x00c420076420 by goroutine 7:
_/Users/rsc/go/src/cmd/go/testdata/src/testrace.TestRace.func1()
/Users/rsc/go/src/cmd/go/testdata/src/testrace/race_test.go:10 +0x3b
Previous write at 0x00c420076420 by goroutine 6:
_/Users/rsc/go/src/cmd/go/testdata/src/testrace.TestRace()
/Users/rsc/go/src/cmd/go/testdata/src/testrace/race_test.go:13 +0xcc
testing.tRunner()
/Users/rsc/go/src/testing/testing.go:656 +0x104
Goroutine 7 (running) created at:
_/Users/rsc/go/src/cmd/go/testdata/src/testrace.TestRace()
/Users/rsc/go/src/cmd/go/testdata/src/testrace/race_test.go:12 +0xbb
testing.tRunner()
/Users/rsc/go/src/testing/testing.go:656 +0x104
Goroutine 6 (running) created at:
testing.(*T).Run()
/Users/rsc/go/src/testing/testing.go:693 +0x536
testing.runTests.func1()
/Users/rsc/go/src/testing/testing.go:877 +0xaa
testing.tRunner()
/Users/rsc/go/src/testing/testing.go:656 +0x104
testing.runTests()
/Users/rsc/go/src/testing/testing.go:883 +0x4ac
testing.(*M).Run()
/Users/rsc/go/src/testing/testing.go:818 +0x1c3
main.main()
_/Users/rsc/go/src/cmd/go/testdata/src/testrace/_test/_testmain.go:42 +0x20f
==================
--- PASS: TestRace (0.00s)
PASS
Found 1 data race(s)
FAIL _/Users/rsc/go/src/cmd/go/testdata/src/testrace 1.026s
$
After:
$ go test -race -v -run TestRace
=== RUN TestRace
==================
WARNING: DATA RACE
Write at 0x00c420076420 by goroutine 7:
_/Users/rsc/go/src/cmd/go/testdata/src/testrace.TestRace.func1()
/Users/rsc/go/src/cmd/go/testdata/src/testrace/race_test.go:10 +0x3b
Previous write at 0x00c420076420 by goroutine 6:
_/Users/rsc/go/src/cmd/go/testdata/src/testrace.TestRace()
/Users/rsc/go/src/cmd/go/testdata/src/testrace/race_test.go:13 +0xcc
testing.tRunner()
/Users/rsc/go/src/testing/testing.go:656 +0x104
Goroutine 7 (running) created at:
_/Users/rsc/go/src/cmd/go/testdata/src/testrace.TestRace()
/Users/rsc/go/src/cmd/go/testdata/src/testrace/race_test.go:12 +0xbb
testing.tRunner()
/Users/rsc/go/src/testing/testing.go:656 +0x104
Goroutine 6 (running) created at:
testing.(*T).Run()
/Users/rsc/go/src/testing/testing.go:693 +0x536
testing.runTests.func1()
/Users/rsc/go/src/testing/testing.go:877 +0xaa
testing.tRunner()
/Users/rsc/go/src/testing/testing.go:656 +0x104
testing.runTests()
/Users/rsc/go/src/testing/testing.go:883 +0x4ac
testing.(*M).Run()
/Users/rsc/go/src/testing/testing.go:818 +0x1c3
main.main()
_/Users/rsc/go/src/cmd/go/testdata/src/testrace/_test/_testmain.go:42 +0x20f
==================
--- FAIL: TestRace (0.00s)
testing.go:609: race detected during execution of test
FAIL
FAIL _/Users/rsc/go/src/cmd/go/testdata/src/testrace 0.022s
$
Fixes #15972.
Change-Id: Idb15b8ab81d65637bb535c7e275595ca4a6e450e
Reviewed-on: https://go-review.googlesource.com/32615
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/testing/testing.go')
| -rw-r--r-- | src/testing/testing.go | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/testing/testing.go b/src/testing/testing.go index 1dae90873a..31290aaec0 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -207,6 +207,7 @@ import ( "errors" "flag" "fmt" + "internal/race" "io" "os" "runtime" @@ -257,16 +258,17 @@ var ( // common holds the elements common between T and B and // captures common methods such as Errorf. type common struct { - mu sync.RWMutex // guards output, failed, and done. - output []byte // Output generated by test or benchmark. - w io.Writer // For flushToParent. - chatty bool // A copy of the chatty flag. - ran bool // Test or benchmark (or one of its subtests) was executed. - failed bool // Test or benchmark has failed. - skipped bool // Test of benchmark has been skipped. - finished bool // Test function has completed. - done bool // Test is finished and all subtests have completed. - hasSub bool + mu sync.RWMutex // guards output, failed, and done. + output []byte // Output generated by test or benchmark. + w io.Writer // For flushToParent. + chatty bool // A copy of the chatty flag. + ran bool // Test or benchmark (or one of its subtests) was executed. + failed bool // Test or benchmark has failed. + skipped bool // Test of benchmark has been skipped. + finished bool // Test function has completed. + done bool // Test is finished and all subtests have completed. + hasSub bool + raceErrors int // number of races detected during test parent *common level int // Nesting depth of test or benchmark. @@ -580,11 +582,13 @@ func (t *T) Parallel() { // Add to the list of tests to be released by the parent. t.parent.sub = append(t.parent.sub, t) + t.raceErrors += race.Errors() t.signal <- true // Release calling test. <-t.parent.barrier // Wait for the parent test to complete. t.context.waitParallel() t.start = time.Now() + t.raceErrors += -race.Errors() } // An internal type but exported because it is cross-package; part of the implementation @@ -600,6 +604,11 @@ func tRunner(t *T, fn func(t *T)) { // a call to runtime.Goexit, record the duration and send // a signal saying that the test is done. defer func() { + t.raceErrors += race.Errors() + if t.raceErrors > 0 { + t.Errorf("race detected during execution of test") + } + t.duration += time.Now().Sub(t.start) // If the test panicked, print any test output before dying. err := recover() @@ -643,6 +652,7 @@ func tRunner(t *T, fn func(t *T)) { }() t.start = time.Now() + t.raceErrors = -race.Errors() fn(t) t.finished = true } @@ -810,7 +820,7 @@ func (m *M) Run() int { if !testRan && !exampleRan && *matchBenchmarks == "" { fmt.Fprintln(os.Stderr, "testing: warning: no tests to run") } - if !testOk || !exampleOk || !runBenchmarks(m.deps.MatchString, m.benchmarks) { + if !testOk || !exampleOk || !runBenchmarks(m.deps.MatchString, m.benchmarks) || race.Errors() > 0 { fmt.Println("FAIL") m.after() return 1 |
