]> Cypherpunks repositories - gostls13.git/commitdiff
testing: send t.signal only if there is no panic
authorChangkun Ou <hi@changkun.us>
Sat, 19 Sep 2020 21:32:12 +0000 (23:32 +0200)
committerEmmanuel Odeke <emm.odeke@gmail.com>
Thu, 24 Sep 2020 19:32:05 +0000 (19:32 +0000)
If a signal is sent to t.signal before the panic is triggered,
a panicking test may end up with "warning: no tests to run" because
the tRunner that invokes the test in t.Run calls runtime.Goexit on
panic, which causes the panicking test not be recorded in runTests.

Send the signal if and only if there is no panic.

Fixes #41479

Change-Id: I812f1303bfe02c443a1902732e68d21620d6672e
Reviewed-on: https://go-review.googlesource.com/c/go/+/256098
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Trust: Emmanuel Odeke <emm.odeke@gmail.com>
Trust: Bryan C. Mills <bcmills@google.com>

src/cmd/go/testdata/script/test_cleanup_failnow.txt
src/testing/testing.go

index 5ad4185fc10d4ff202e546ad74174caa202169ce..0737a93db21443b10ea1ba7bd29bba27b11fa3a7 100644 (file)
@@ -1,11 +1,25 @@
 # For issue 41355
 [short] skip
 
+# This test could fail if the testing package does not wait until
+# a panicking test does the panic. Turn off multithreading, GC, and
+# async preemption to increase the probability of such a failure.
+env GOMAXPROCS=1
+env GOGC=off
+env GODEBUG=asyncpreempt=off
+
+# If the test exits with 'no tests to run', it means the testing package
+# implementation is incorrect and does not wait until a test panic.
+# If the test exits with '(?s)panic: die.*panic: die', it means
+# the testing package did an extra panic for a panicking test.
+
 ! go test -v cleanup_failnow/panic_nocleanup_test.go
+! stdout 'no tests to run'
 stdout '(?s)panic: die \[recovered\].*panic: die'
 ! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die'
 
 ! go test -v cleanup_failnow/panic_withcleanup_test.go
+! stdout 'no tests to run'
 stdout '(?s)panic: die \[recovered\].*panic: die'
 ! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die'
 
index d86354093a4f5da30dafebc6df80d81031df175f..a44c0a07497cce78084c0e5ee6da601ae47c5696 100644 (file)
@@ -1091,10 +1091,16 @@ func tRunner(t *T, fn func(t *T)) {
                // complete even if a cleanup function calls t.FailNow. See issue 41355.
                didPanic := false
                defer func() {
-                       t.signal <- signal
-                       if err != nil && !didPanic {
+                       if didPanic {
+                               return
+                       }
+                       if err != nil {
                                panic(err)
                        }
+                       // Only report that the test is complete if it doesn't panic,
+                       // as otherwise the test binary can exit before the panic is
+                       // reported to the user. See issue 41479.
+                       t.signal <- signal
                }()
 
                doPanic := func(err interface{}) {