]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.14] testing: fix data race between parallel subtests
authorChangkun Ou <hi@changkun.us>
Fri, 28 Feb 2020 20:53:38 +0000 (21:53 +0100)
committerIan Lance Taylor <iant@golang.org>
Fri, 20 Mar 2020 19:05:17 +0000 (19:05 +0000)
This CL fixes a race condition if there are two subtests, and
one finishing but the other is panicking.

For #37551
Fixes #37959

Change-Id: Ic33963eb338aec228964b95f7c34a0d207b91e00
Reviewed-on: https://go-review.googlesource.com/c/go/+/221322
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 93a9561b23b782244a7c5d77efe71f57dee8c4a5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/224257
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Changkun Ou <euryugasaki@gmail.com>
src/cmd/go/testdata/script/test_main_panic.txt [new file with mode: 0644]
src/testing/testing.go

diff --git a/src/cmd/go/testdata/script/test_main_panic.txt b/src/cmd/go/testdata/script/test_main_panic.txt
new file mode 100644 (file)
index 0000000..45887c5
--- /dev/null
@@ -0,0 +1,30 @@
+[short] skip
+[!race] skip
+
+! go test -v -race main_panic/testmain_parallel_sub_panic_test.go
+! stdout 'DATA RACE'
+-- main_panic/testmain_parallel_sub_panic_test.go --
+package testmain_parallel_sub_panic_test
+
+import "testing"
+
+func setup()    { println("setup()") }
+func teardown() { println("teardown()") }
+func TestA(t *testing.T) {
+       t.Run("1", func(t *testing.T) {
+               t.Run("1", func(t *testing.T) {
+                       t.Parallel()
+                       panic("A/1/1 panics")
+               })
+               t.Run("2", func(t *testing.T) {
+                       t.Parallel()
+                       println("A/1/2 is ok")
+               })
+       })
+}
+
+func TestMain(m *testing.M) {
+       setup()
+       defer teardown()
+       m.Run()
+}
\ No newline at end of file
index 8a0c7b3021ab2711122c9891d15e03a57454082f..966cafbd3a6b1a4760a89d646314d96370d338e2 100644 (file)
@@ -927,16 +927,15 @@ func tRunner(t *T, fn func(t *T)) {
                                t.Logf("cleanup panicked with %v", r)
                        }
                        // Flush the output log up to the root before dying.
-                       t.mu.Lock()
-                       root := &t.common
-                       for ; root.parent != nil; root = root.parent {
+                       for root := &t.common; root.parent != nil; root = root.parent {
+                               root.mu.Lock()
                                root.duration += time.Since(root.start)
-                               fmt.Fprintf(root.parent.w, "--- FAIL: %s (%s)\n", root.name, fmtDuration(root.duration))
+                               d := root.duration
+                               root.mu.Unlock()
+                               root.flushToParent("--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
                                if r := root.parent.runCleanup(recoverAndReturnPanic); r != nil {
                                        fmt.Fprintf(root.parent.w, "cleanup panicked with %v", r)
                                }
-                               root.parent.mu.Lock()
-                               io.Copy(root.parent.w, bytes.NewReader(root.output))
                        }
                        panic(err)
                }