Join GitHub today
Add testing ByteBufAllocator for leak unit testing (almson version) #8431
Currently the only way to detect leaks during testing is log scanning which is
Added ResourceLeakDetector.assertAllResourcesDisposed which can be used in unit tests to ensure that all resources have been disposed. However, invoking assertAllResourcesDisposed directly can be problematic due to the fact that the leak detector is usually a static singleton and/or private in the classes that use it.
To that end, added TestingPooledByteBufAllocator which maintains a non-static leak detector and is useful for concurrent tests. It implements AutoCloseable (for use with try-with-resources) and invokes assertAllResourcesDisposed in the close method. To implement this, AbstractByteBufAllocator.toLeakAwareBuffer was made non-static to allow sub classes to use their own leak detector.
ResourceLeakDetector.clearRefQueue was removed because it created a danger that assertAllResourcesDisposed would not detect all leaks. This method is a useless optimization which saves a few cycles in the unlikely event that error logging is off, leaks are happening, and the leak detector is enabled.
Developers using Netty can now easily verify that all buffers have been released in unit tests.
referenced this pull request
Oct 26, 2018
I'm pretty sure that is version will not throw an assertion error for any leak that is "reported" as part of the normal garbage collection cycle (via the
WeakReference processing in
reportLeak()). The prior version catches these by adding hooks for when a leak is detected and stores the records, so that when
close is called, all leaks are reported.
@almson, I see it now. All reported leaks are already stored in
BTW, I didn't make any suggested changes, and I'm not sure why Github said that. That is a brand new feature, so maybe it was a bug.
Generally LGTM... Just a few suggestions. Thanks!
@normanmaurer, actually, after further review, I believe this PR also requires a subclass of
ResourceLeakDetector to override the
shouldTrack method. @almson, I believe the main difference is the addition of the single method
ResourceLeakDectector.assertAllResourcesDisposed() to dispose all references and assert no leaks, whereas the other PR #8423 adds a method to "disposes" all references, and assert leaks in a separate "subclass" method.
I don't have a strong preference for either approach.
@almson, I set "request changes" for the comment about overriding
What do you think about building a plugin for testing framework or a JVM agent to make this functionality available without making any user code change? A user has to add some code to take advantage of this, but it's not always doable especially for integration tests that involve a lot of components. A user would find it is tedious to add try-with-resources or assertion for all test cases.
I agree though that this still may be useful if a user needs to find a leak in a very specific scope, but I guess the problem we are trying to solve here in general is to fail the build reliably when there is a leak regardless of where it really is? Given the nature of how leak detector works, the point of leak detection may be much later than when a buffer actually leaked.
I agree that that might be interesting to those trying to catch general leaks. In my case, I am interested in failing the specific test that created the leak, and I run tests in parallel, so a global tracker would not work for me.
@normanmaurer or @trustin, can we get a call on which direction you want to go for this feature? As I mentioned above, I believe the main difference is the addition of the new method