aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChangkun Ou <hi@changkun.us>2020-02-28 21:53:38 +0100
committerIan Lance Taylor <iant@golang.org>2020-03-20 19:05:17 +0000
commitab9d037401dba9cd82e7eba87f04ae896709ef62 (patch)
treea7c1c7eae95d0fef559819be8a61fbc1648f8178
parent564c76a268b75f56d6f465b82fba7f6fb929fd70 (diff)
downloadgo-ab9d037401dba9cd82e7eba87f04ae896709ef62.tar.gz
go-ab9d037401dba9cd82e7eba87f04ae896709ef62.zip
[release-branch.go1.14] 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. 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>
-rw-r--r--src/cmd/go/testdata/script/test_main_panic.txt30
-rw-r--r--src/testing/testing.go11
2 files changed, 35 insertions, 6 deletions
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
index 0000000000..45887c5c73
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_main_panic.txt
@@ -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
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 8a0c7b3021..966cafbd3a 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -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)
}