Skip to content

Commit 93a9561

Browse files
changkunianlancetaylor
authored andcommitted
testing: fix data race between parallel subtests
This CL fixes a race condition if there are two subtests, and one finishing but the other is panicking. Fixes #37551 Change-Id: Ic33963eb338aec228964b95f7c34a0d207b91e00 Reviewed-on: https://go-review.googlesource.com/c/go/+/221322 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent a4c48d6 commit 93a9561

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[short] skip
2+
[!race] skip
3+
4+
! go test -v -race main_panic/testmain_parallel_sub_panic_test.go
5+
! stdout 'DATA RACE'
6+
-- main_panic/testmain_parallel_sub_panic_test.go --
7+
package testmain_parallel_sub_panic_test
8+
9+
import "testing"
10+
11+
func setup() { println("setup()") }
12+
func teardown() { println("teardown()") }
13+
func TestA(t *testing.T) {
14+
t.Run("1", func(t *testing.T) {
15+
t.Run("1", func(t *testing.T) {
16+
t.Parallel()
17+
panic("A/1/1 panics")
18+
})
19+
t.Run("2", func(t *testing.T) {
20+
t.Parallel()
21+
println("A/1/2 is ok")
22+
})
23+
})
24+
}
25+
26+
func TestMain(m *testing.M) {
27+
setup()
28+
defer teardown()
29+
m.Run()
30+
}

src/testing/testing.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -928,16 +928,15 @@ func tRunner(t *T, fn func(t *T)) {
928928
t.Logf("cleanup panicked with %v", r)
929929
}
930930
// Flush the output log up to the root before dying.
931-
t.mu.Lock()
932-
root := &t.common
933-
for ; root.parent != nil; root = root.parent {
931+
for root := &t.common; root.parent != nil; root = root.parent {
932+
root.mu.Lock()
934933
root.duration += time.Since(root.start)
935-
fmt.Fprintf(root.parent.w, "--- FAIL: %s (%s)\n", root.name, fmtDuration(root.duration))
934+
d := root.duration
935+
root.mu.Unlock()
936+
root.flushToParent("--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
936937
if r := root.parent.runCleanup(recoverAndReturnPanic); r != nil {
937938
fmt.Fprintf(root.parent.w, "cleanup panicked with %v", r)
938939
}
939-
root.parent.mu.Lock()
940-
io.Copy(root.parent.w, bytes.NewReader(root.output))
941940
}
942941
panic(err)
943942
}

0 commit comments

Comments
 (0)