-
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: add Testing constant #60737
Comments
There's this on tip https://pkg.go.dev/testing@master#Testing |
dup of #52600 ? |
Oh, I didn't notice, but unfortunately that API doesn't work for the performance optimizations I'm hoping to get: first, it's implemented as a link-time variable, so the compiler can't act based on it at all; second, as a function it requires inlining to happen before code elimination, and I haven't tested it but it's unlikely that will then inform the inliner weight of the caller. The first part can be fixed but the second might be a permanent problem if we commit to a function in Go 1.21. |
release blocker for new api? |
Note that the release-blocker label likely means little unless this is milestoned for 1.21. cc @golang/release |
I'm not sure it's worth changing at the last minute, but it might be worth making an explicit decision, yeah. To test I compiled this program
where
The results were mixed but mostly optimization-averse:
While if we made it
|
Making |
I initially had the same reaction as @ianlancetaylor - today, if I test Worth noting that many people write internal tests at |
Another concern I would have is that you would be leaving your code much more exposed (at risk) for compiler bugs, since the code you're testing isn't the same as the code you're shipping (from a compiler IR perspective). Here's some contrived Go code:
Let's imagine that there is a bug in the register allocator that has to do with values flowing around loops. If |
This #52600 (comment) also pointed out wanting to be able to do this. (CC @aclements.)
What proportion of packages import "testing" in non-test code? Are there cases where doing so is unavoidable? Is it viable for the |
It doesn't seem appropriate to tie that kind of checking to whether the program is being run as a test: if you can't easily enable it in a more realistic configuration, it isn't useful for debugging a realistic program, and that's exactly where the edge-cases that trigger a bug are likely to arise. The sort of use-case you describe seems like a better fit for build constraints. For example, we sometimes put additional checks that slow down the program or cause otherwise-unnecessary escapes behind |
I don't think this should be a release-blocker. I think the only open question is whether we should put in the effort to make the I think we should close this as a dup of #52600 and open a new issue specific to making |
I filed #60772 for the proposal and will close this as a duplicate of some combination of #52600 and #60772. It is worth noting, however, that this use is problematic:
If these extra checks cause performance problems, then they will affect not just tests of the crypto packages themselves but also any tests importing crypto to do their own work. If I have A imports B imports C imports D imports E imports crypto and I am testing A, it's not at all obvious why crypto should slow down A's tests. The performance problems are even worse when you consider benchmarking A. Everyone will observe that wow crypto is super slow, and they'll have benchmarks to prove it. |
In cryptographic packages, I would like to perform extra consistency checks that are unsuitable for production either for performance reasons (they might be slow or cause inliner or escape analysis issues) or because they are not safe (they might be non-constant time or expose undesirable attack surface). In other languages, this is usually done with debug mode asserts, but really they are mostly exercised during tests.
I propose we add a constant to
testing
that is alwaystrue
if building withgo test
andfalse
otherwise. I couldn't come up with a better name thantesting.Testing
.Then, I could gate all my testing assertions with
if testing.Testing
and (depending on the order of optimization passes), count on dead code removal to make the effects of that code disappear in production builds. This feels like a technique that would make sense beyond cryptography, too, although for other packages it might be less important for it to be a constant, so it can be emulated withinit()
in a_test.go
file setting a variable.The text was updated successfully, but these errors were encountered: