-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: testing: t.Cleanup should run on panic #41355
Comments
Cleanup definitely should run on panic. That was always part of the design (and the original code at least tested for that AFAIR) and if it doesn't, it should be considered a bug IMHO. Furthermore, even if one Cleanup function panics, the others should still run. |
Pinging @ianlancetaylor and @bradfitz too, who have worked on Cleanup or reviewed CLs for it. I imagine this issue is straightforward enough to not need a proposal. |
Okay, I'm sorry, probably I misunderstood something. t.Cleanup do run on panic, the issue is somewhere else. Probably execution environment inside t.Cleanup somehow differ from usual defer: package main_test
import (
"testing"
"github.com/golang/mock/gomock"
)
//go:generate mockgen -package=$GOPACKAGE -source=$GOFILE -destination=mock.$GOFILE T
type T interface{ F() }
func TestCleanupOnPanic(t *testing.T) {
ctrl := gomock.NewController(t)
cleanup := func() {
println("enter cleanup")
ctrl.Finish()
println("leave cleanup")
}
mockT := NewMockT(ctrl)
mockT.EXPECT().F()
t.Cleanup(cleanup) // (1)
// defer cleanup() // (2)
t.Run("", func(t *testing.T) {
panic("boom")
})
// cleanup() // (3)
} Running
But if we uncomment (2) or (3) and comment out (1) it'll work better (don't swallow panic and hang at least, but it still won't output error from gomock about missing call):
And only if we'll remove t.Run we'll get error from gomock about missing call to F(). TBH I'm unsure now is this issue actually about Go itself or it's related only to gomock. Feel free to close if you believe it's only about gomock. |
It looks like in case of It is actually really weird |
package main_test
import "testing"
func TestDeferOnPanicInsideRun(t *testing.T) {
defer println("never here")
t.Run("", func(t *testing.T) {
panic("boom")
})
} Output:
|
Change https://golang.org/cl/254637 mentions this issue: |
The hang happens if
@powerman In your example, In a panicking test, all cleanups are running in the panicking goroutine. Line 1092 in 66e66e7
The Line 1106 in 66e66e7
Since it failed to call panic and the goroutine is early exited, and the test signal that supposes to send to a parent goroutine is not performed. Therefore it hangs. I've sent a CL254637 for this. Let's see if the fix is worthwhile. /cc @mvdan |
There was a discussion about gomock hang on panic because it's
ctrl.Finish()
was called insidet.Cleanup
instead ofdefer
(golang/mock#428). It helped me to realizet.Cleanup
won't be called in case ofpanic
, as I (and probably others too) was expected.At a glance it looks feasible to change testing package to add few internal
defer
to ensuret.Cleanup
will be called onpanic
/t.FailNow
. And as current documentation doesn't mention is this will happens or not we can consider this change compatible.In case this proposal will be rejected I think it's worth to update the doc and make explicit that t.Cleanup won't be called on panic, because this limits it usability a lot and probably contradict user's expectations.
The text was updated successfully, but these errors were encountered: