-
Notifications
You must be signed in to change notification settings - Fork 990
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
Untangle test utils refs #3013
Untangle test utils refs #3013
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3013 +/- ##
====================================================
- Coverage 65.14233% 34.18821% -30.95413%
====================================================
Files 1324 890 -434
Lines 489393 253798 -235595
Branches 40028 36786 -3242
====================================================
- Hits 318802 86769 -232033
+ Misses 165176 162265 -2911
+ Partials 5415 4764 -651
|
3b544b2
to
eb46b7c
Compare
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
@JeremyKuhne what do you think of the structure? |
In general this looks good to me. I'm sure we'll iterate over time, but this is a good step in the right direction. |
0eed004
to
808380f
Compare
808380f
to
0151ba2
Compare
@hughbe @weltkante @vladimir-krestov FYI - I'm planning to merge this in the next 24hrs, unless there are objections. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that we are turning WinFormsFact back to StaFact, I don't have definitive proof it causes issues but during the xunit.stafact upgrade it felt like I had to turn many StaFact to WinFormsFact to get tests succeed reliably. I couldn't exactly pin down all the root causes so it may have been unrelated, but if not this change may introduce flakyness (also see #3271 where my current theory is that OLE initialization may have been related to the previously observed CI flakyness)
If you want to merge as-is to get the restructuring going we'll want to track if it causes issues, or perhaps create a follow-up issue to clean up annotations. Personally I'd prefer as little usage of StaFact as possible because it requires a lot of thought to reason about when you can use them safely. Using WinFormsFact is always the safer way because as soon as you are using WinForms API you want a test infrastructure compatible with it. Directly testing pure STA based COM interop (without WinForms or OLE) is kinda rare in this repo.
[WinFormsFact] | ||
[StaFact] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think thats good, I still suspect STA is not enough for OLE, but don't have definitive proof yet. WinFormsFact will call Application.OleRequired but StaFact will just set the thread to STA.
StaFact often may work because WinForms implicitly initializes OLE in a lot of call chains, but if you directly test OLE interop like here that may not happen. Also the StaFact thread becomes "poisoned" by having OLE initialized through tests, depending on order tests may run with or without OLE initialized and become flaky if they actually require OLE
IMHO WinForms almost never should want StaFact unless you are testing some STA-but-not-OLE COM interop, which is rare in the scope of WinForms, most things are OLE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have access to System.Windows.Forms so we can't use WinFormsFact or any of SWF types
[WinFormsFact] | ||
[StaFact] |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
[WinFormsFact] | ||
[StaFact] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is using OLE APIs due to the usage of IPicture for testing IDispatch, I would keep them on WinFormsFact
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also see #3271 where we wanted to track if this being WinFormsFact fixes flaky tests after the xunit.stafact update, so turning it back to stafact may interfere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Speculating here, but flakiness might come from a fact that we're creating multiple of AxHost
controls concurrently, that spin up the whole SWF infra, whereas for these tests we want to ensure our COM interop definition is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of the issues this restructure is aiming to address - to provide clarity on what we're testing - COM/pinvoke definitions or actual control implementations.
|
||
namespace System.Windows.Forms.Primitives.Tests.Interop.Ole32 | ||
{ | ||
public class IPictureTests : IClassFixture<ThreadExceptionFixture> | ||
[Collection("Sequential")] | ||
public class IPictureTests | ||
{ | ||
[Fact] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its not introduced by the PR, but this seems wrong, GetIPictureFromCursor calls OleCreatePictureIndirect so the test should be WinFormsFact (or at the very least StaFact). Even if this API is robust enough to be called from MTA it doesn't feel right to rely on it, normally all OLE API is required to have OLE initialized.
Also adding [Collection("Sequential")]
is probably not required here, its not testing some globally shared resource like clipboard or drag'n'drop, so I don't see why it should coordinate with other tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that there were a few tests which were intentionally testing for failure when called on the wrong COM apartment, these may need to remain Fact
and not turned to WinFormsFact
. I don't see any of these tests in this file though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This being Fact
is also tracked in #3271 so if you want you can defer it and not update it in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe any of IPictureTests
, IDispatchTests
or ITypeInfoTests
test x-thread access, or failures for that matter.
I copied [Collection("Sequential")]
from the other two types, I think it ensures that these tests aren't run in parallel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe any of IPictureTests, IDispatchTests or ITypeInfoTests test x-thread access, or failures for that matter.
There are unexplained E_FAIL returns from OleCreatePictureIndirect on the CI machine (#3271). The only theory I currently have is that OLE isn't initialized and for some reason the CI machine is less robust than running locally, otherwise I have no idea why the initial call already fails with E_FAIL.
I copied [Collection("Sequential")] from the other two types, I think it ensures that these tests aren't run in parallel.
It ensures that the tests are not run in parallel with other tests having that attribute, so it can protect process wide shared resources. xunit docs say that tests on the same class are never run in parallel, only multiple test classes are run in parallel (can look up the doc link if you need it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, this is what I meant (sorry for not being clearer).
Given that all of the tests from these test classes test more of less the same area we probably don't want them to run in parallel.
@weltkante the idea here a clear separation of layers. System.Windows.Forms.Primitives project contains "bare bone" implementations and imports. This project underpins System.Windows.Forms project which defines and implements higher level abstractions such as
|
We need to watch if these tests are still flaky then (#3271) and if they are we need explicit OleInitialize calls to test if unexpected E_FAIL return values go away when OleInitialize was called. Automatically initializing OLE is something that was only added to WinFormsFact because its not something STA threads usually need, unless they are also running WinForms or WPF. |
The tests seem to hold after two runs. |
Ok so some concerns are adressed by the fact that you don't have a reference to WinForms, so you can't accidently call its API and "poison" the STA thread with WinForms infrastructure that doesn't get cleaned up. That leaves the OLE initialization which we don't know if its an issue or not. Never was an issue locally for me and I don't know how rare the failures in #3271 were, but feel free to merge, it probably will be noticable over time if OleCreatePictureIndirect still returns E_FAIL occasionaly on the CI machines. |
Pre-req or addendum to #3010
Proposed changes
InternalUtilitiesForTests
projectSystem.Windows.Forms.Primitives.TestUtilities
project.System.Windows.Forms.Primitives.Tests
is made dependent on this project.System.Windows.Forms.TestUtilities
project, dependent onSystem.Windows.Forms.Primitives.TestUtilities
project. Update all main test projects to depend on this project.NB: some tests in
System.Windows.Forms.Primitives.Tests
have been commented out until necessary low-level abstractions (such as introduced in #3010) are added.Microsoft Reviewers: Open in CodeFlow