Closed weltkante closed 3 months ago
/cc @hughbe in case this is of interest, /cc @RussKie FYI
I'm not starting a PR since I only know how to fix the trivial cases (marked above) - though if you want a partial PR for this issue I can do that.
While looking at #3391 I noticed ErrorProviderAccessibleObjectTests
test class constructor creates controls which are apparently not disposed. Fix is to implement IDisposable on the test class.
I'm surprised this doesn't appear in my list above, seems the GC never ran during my experimenting, maybe the test executed late and process terminated before GC collected these.
We're stress testing the runtime and the tests we've (đź‘€ @ @hughbe) written. Whilst it is somewhat frustrating, I think, overall it has been a very good learning for all of us. I expect to find more bugs, but I think we're getting better at it :) To top it off we found few genuine bugs too.
if you want a partial PR for this issue I can do that.
I'm happy with partial fixes, less to worry about :)
PR for the simple cases is up.
Also found a control leak outside unit tests, ColorDialog caches its ColorUI popup but never disposes it, and the class is not disposable either.
Currently this is a liability for unit testing, disposing of the dialog is only possible via reflection. I doubt it'll cause issues in the field unless someone builds a multithreaded designer for some reason which shows popups on a seperate UI thread.
@LeafShi1 - please verify if this issue is still applicable, we were fixing test data as we were editing the tests
please verify if this issue is still applicable, we were fixing test data as we were editing the tests
@Tanya-Solyanik Look like it is still applicable. But I don't know how to verify whether these objects are disposed successfully. Also, do objects in TestData
need to be disposed as well? How should this be done?
But I don't know how to verify whether these objects are disposed successfully.
See last paragraph in original post, when I originally debugged this issue there was no infrastructure and you had to set breakpoints or modify the code to verify this. By now #3348 has added some infrastructure but I'm not familiar with how it works.
What you want to ensure is that the finalizer isn't used at all to dispose/cleanup controls, because by the time it runs the thread it needs for disposal may already be gone, causing unstable tests that occasionally hang or fail (at least that was what happened back then when I looked into it).
Also, do objects in TestData need to be disposed as well?
Objects implementing IDisposable in the test data are disposed, but in the quoted example the control is just created and never put into the test data, so no automatic disposal happening.
.NET Core Version: github master
Have you experienced this same bug with .NET Framework?: n/a
Problem description: Disposing controls in unit tests is required because the usage of multiple UI threads. If the control has not been GC'ed by the time the UI thread terminates this can lead to hangs.
Related to #3348 but this is short-term bugfixing while the other issue is long-term reliability to detect regressions in unit test quality.
Following call sites do not dispose their controls:
Checked entries look like they are straightforward to fix, unchecked ones require refactoring of the tests or deeper investigation.
Further entries discovered independently (see issue discussion below)
ErrorProviderAccessibleObjectTests
constructor, test class needs to be disposableExpected behavior: All unit tests dispose their controls.
Minimal repro: In the absence of #3348 you can set a conditional breakpoint (or write logging code) in
NativeWindow.ForceExitMessageLoop
and check forhandle != IntPtr.Zero && ownedHandle
to detect problematic cases. To identify who created the control capture a stack trace in the NativeWindow constructor (callnew StackTrace()
and store it as a member).