-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
testing: detect t.FailNow() called from wrong goroutine #24678
Comments
Duplicate of #15758, which is closed. I support this feature, but it seems infeasible without runtime trickery. |
If it's any consolation, I've learned that concurrent use of func Test(t *testing.T) {
go func() { t.FailNow() }()
} Running with race detector reports:
|
Cannot |
@dsnet Can you please reopen this issue? I think the cited duplicate was closed for incorrect reasons and we should discuss the ways in which a solution can be implemented. |
@balshetzer well it is true that this issue is a duplicate, so if we were going to reopen one, it would be the first one. At this point, #24680 is the best place to make the case for improving the Fatal/FailNow behavior (as you and I both have). |
@cespare My thought was that the original issue has been locked due to age and this one had just been closed so I thought it would be easier to reopen this one. I'm concerned that discussion on #24680 will get sidetracked because it is trying to discuss options for Go 2 and I want changes in Go 1. I think I am going to put together a pull request and see if I can get it accepted. |
I can reopen #15758 if there is a way to implement it that does not involve any sort of goroutine ID. |
@ianlancetaylor What I would do is analyze the stack using the runtime package whenever testing.T.FailNow is called. If a specific function isn't in the stack then I would print a warning. This would also be a good way to catch when the wrong testing.T is called. I see it a lot when people use testing.T.Run they accidentally use the testing.T passed to the Test* function instead of the one passed to the testing.T.Run callback. e.g.
If we encode inside the testing.T which function it should look for then it can even detect this case. |
OK, reopened #15758. |
@ianlancetaylor why is it not okay for the testing package to use the goroutine ID to implement this as long as it's a private detail? |
The testing package is not the runtime package. Let's not change the testing package to rely on what should be internal runtime details. |
@ianlancetaylor we gave testing a hook to know about the environment variables and files that the os package touches in order to support test caching. That seems quite intrusive compared with knowing the goroutine ID. We can expose the current goroutine via an internal package so that we don't directly do the unsafe nastiness inside the testing package. Why is it better to rely on parsing the stacks? (Which, incidentally, contain the goroutine ID anyway...) |
The os package is also not the runtime package. And the internal/testlog package was unavoidable for test caching, which is not the case here. |
What version of Go are you using (
go version
)?1.10.1
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?N/A
What did you do?
t.FailNow()
has this godoc:It is a common mistake to call
t.FailNow()
from a goroutine spawned in a test, not the goroutine that is executing the test.What did you expect to see?
Perhaps it is possible to detect this and let the user know? Maybe a panic/failing test with an explanation what is not right.
What did you see instead?
Nothing, it "works".
The text was updated successfully, but these errors were encountered: