-
Notifications
You must be signed in to change notification settings - Fork 32
Add cocoa fact attribute and related unit tests #68
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
Add cocoa fact attribute and related unit tests #68
Conversation
This is a work-in-progress branch, we'll take it out of draft when it's ready for review. |
Directory.Build.props
Outdated
<ProduceReferenceAssembly>true</ProduceReferenceAssembly> | ||
<EnableWindowsTargeting>true</EnableWindowsTargeting> | ||
<TargetingWindows Condition=" '$(TargetFramework)' == 'net472' or $(TargetFramework.EndsWith('-windows')) ">true</TargetingWindows> | ||
<TargetingMacos Condition=" '$(TargetFramework)' == 'net6.0-macos10.15' or $(TargetFramework.EndsWith('-macos')) ">true</TargetingMacos> |
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.
There is a contains syntax that may be better to use here if you're liable to use -macos10.15
, so that the condition doesn't silently start failing when you later move to -macos12
.
I think it's roughly this:
$(TargetFramework.Contains('macos'))
global.json
Outdated
{ | ||
"sdk": { | ||
"version": "7.0.101", | ||
"version": "7.0.100", |
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 presume this is just to allow you to build locally on your box and not because 7.0.101 is broken somehow. We'll need to revert this before merging. You could do it now and upgrade your SDK to solve the problem if you want.
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.
Yup, this whole branch was just us getting far enough locally to have something we could mess with in the Mac editor project. It's definitely not cleaned up or complete yet. 😄
I don't know what the effect of |
Xunit.Sdk.CocoaFactDiscoverer | ||
Xunit.Sdk.CocoaFactDiscoverer.CocoaFactDiscoverer(Xunit.Abstractions.IMessageSink! diagnosticMessageSink) -> void |
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.
Should these cocoa attributes really be exposed to net472? I get that mono used to target this, but that's history right? Can we expose the new attribute exclusively to the macos target framework?
Actually, looking at your msbuild conditions, it doesn't look like they should be exposed to net472 after all, which makes me wonder if you're getting compilation warnings suggesting you remove them.
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.
You are right that we won't expose those to net472, I will clean them up.
<ItemGroup> | ||
<None Remove="Mac\" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Folder Include="Mac\" /> | ||
</ItemGroup> |
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.
Can we remove these items, please?
<PropertyGroup> | ||
<TargetFrameworks>net472;netstandard2.0;net6.0;net6.0-windows</TargetFrameworks> | ||
<TargetFrameworks>net472;netstandard2.0;net6.0;net6.0-windows;net6.0-macos10.15</TargetFrameworks> | ||
<SupportedOSPlatformVersion Condition="'$(TargetingMacos)'=='true'">10.15</SupportedOSPlatformVersion> |
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'm surprised this property isn't set by virtue of the TargetFramework mentioning the macos version. Are you sure this is necessary?
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.
In theory, setting this is supposed to allow us to target net6.0-macos
instead of net6.0-macos10.15
, and still get net6.0-macos10.15
in the nupkg, but it wasn't working and we need to investigate. If we don't specify 10.15 somewhere, it uses the OS version of whoever does the build.
But yeah, it's not needed if we explicitly target net6.0-macos10.15
.
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.
If we don't specify 10.15 somewhere, it uses the OS version of whoever does the build.
Are you sure? I can build net6.0-macos
from Windows, and that has no basis for a macos version.
Also, when I target net6.0-windows
, that targets Windows 7 -- not the version of Windows that I am using.
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.
It looks like each TFW can specify its own default OS version behavior: https://learn.microsoft.com/en-us/dotnet/standard/frameworks#os-version-in-tfms. So I would imagine the macOS workload targets are doing this. It could be that they pick macOS 13 by default not because that was the build host's OS version, but because that's the version associated with the Xcode SDK. Either way, we need to manually specify 10.15.
And I think I see my answer for SupportedOSPlatformVersion
here: https://learn.microsoft.com/en-us/dotnet/standard/frameworks#support-older-os-versions. Seems that SupportedOSPlatformVersion
indicates runtime version. So I should drop it anyway.
Need a full app bundle in order to start Cocoa mainloop.
This allows building on macOS 12 and easily consuming the nupkg from projects still using older workload versions.
</ItemGroup> | ||
|
||
<PropertyGroup Label="Globals"> | ||
<PartialTargetPath>$(RepoRootPath)\bin\Xunit.StaFact.Tests.Mac\$(Configuration)\$(TargetFramework)\osx-x64</PartialTargetPath> |
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.
The osx-x64
part here seems like it would fail on arm64.
If that's the case, you could do something like the following:
<HostArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)</HostArchitecture>
<HostArchitecture>$(HostArchitecture.ToLower())</HostArchitecture>
<PartialTargetPath>$(RepoRootPath)\bin\Xunit.StaFact.Tests.Mac\$(Configuration)\$(TargetFramework)\osx-$(HostArchitecture)</PartialTargetPath>
Other than the Mac architecture problem described above, this PR is ready for review. Thanks! P.S. Not sure if the problem I mentioned above has any influence, since the MacOS pipeline is using osx-x64 instead arm64, so all the tests are built and passed. |
Hi @AArnott, can I have a code review on this PR when you have time? |
} | ||
if ($IsMacOS) { | ||
$frameworks += '-f','net6.0-macos' | ||
} |
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 think the changes to this file can be undone now, right?
I can't build Xunit.StaFact.Tests.Mac on my Windows machine due to this error:
What component do I need to install to get this? |
This works if I run init.ps1, restore, build works and even VS works if launched from that window. But VS launched from the start menu does not, nor does the command prompt until init.ps1 is run in that particular window. It seems that |
I don't know. On Mac, we have a property we can add to a solution to tell us where it should look for the .NET SDK. I'm not aware of any way to do this on Windows. Should we add a solution filter that removes the Mac projects from the solution that would be used by default? |
It isn't just the mac project. It causes all the projects to fail. The error I quoted appears for both Xunit.StaFact and Xunit.StaFact.Tests.Mac. And the presence of that error apparently causes nuget restore to altogether fail, so 302 compile errors are reported in the Error List across all projects. I've finished reviewing the PR and pushed a few changes so that I'm happy with the result, except for the fact that the solution is unusable in VS except when launched from a command prompt after running init. That's a very big loss from this PR, so I'm holding out hope that we can resolve that before merging this. |
init.ps1
Outdated
# Install specific macOS workload version in order to support usage on older .NET and macOS | ||
$rollbackFile = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid()) | ||
@{ | ||
"microsoft.net.sdk.macos" = "12.3.2372/7.0.100" |
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.
Can you explain to me more about this requirement? Does this mean that dotnet workload restore
is not enough?
I wonder too if this is somehow related to msbuild's failing import error.
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.
The macOS workload is necessary in order to target net6.0-macos
. That target framework is not available without the workload being installed.
The .NET SDK makes it difficult to specify a preferred version of a given workload. You have to use a rollback file to achieve this. Without specifying the version, the SDK will pull the latest for the SDK version specified in global.json
(without taking target framework into account). So, even though this project is net6.0-macos
, it would be referencing a newer Microsoft.macOS.dll
that is not compatible with projects using the .NET 6 SDK and an older macos workload. To fix this, we specify an older workload version that is compatible with an older .NET/workload.
I wonder too if this is somehow related to msbuild's failing import error.
Yes. dotnet workload restore
appears to be broken, at least with the macOS workload. It's like it tries to load targets before they have been installed. Tomas filed a bug about it recently: dotnet/sdk#30230. It would be great if the .NET SDK team fixed that. We can't depend on dotnet restore
for CI, because it would pick up the wrong workload version as described earlier, but for local development it would be very convenient.
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.
Thanks. That's helpful, and I've upvoted that issue.
How do dotnet workloads work when the SDK to be installed into is in an elevated location like Program Files?
It's very odd to me that init.ps1 works, but running this command outside of init fails, where workloads.json
refers to the json file your init.ps1 creates:
> dotnet workload install macos --from-rollback-file workloads.json
Downloading Microsoft.macOS.Sdk.Msi.x64 (13.1.1024)
Workload installation failed. Rolling back installed packs...
Workload installation failed: One or more errors occurred. (microsoft.macos.sdk.msi.x64::13.1.1024 is not found in NuGet feeds https://api.nuget.org/v3/index.json;https://pkgs.dev.azure.com/dnceng/public/_packaging/test-tools/nuget/v3/index.json".)
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.
Notice it's picking 13.1.1024, which is a different version. It's newer, and I don't see it in nuget.
If you have multiple SDK versions installed, and you're running workload install
from outside of a context where a global.json
is specifying your SDK version, you can get different results based on whatever the default SDK is.
How do dotnet workloads work when the SDK to be installed into is in an elevated location like Program Files?
On Mac, when installing workloads to the machine-wide .NET SDK installation (/usr/local/share/dotnet
), you have to use sudo
to elevate. Presumably something similar is needed on Windows?
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 do have the 7.0.200 installed, as of this morning when a VS update installed it. But all my dotnet workload install attempts were within the directory containing global.json, so evidently my repo's 7.0.101 constraint wasn't effective at retaining behavior from that SDK in this regard.
Windows doesn't need sudo
to elevate. It prompts with interactive UI as needed.
The failures I'm seeing turn out to come from a collection of bugs in the SDK around this area. The do not show up when DOTNET_ROOT is set, which is why it works in non-elevated scenarios.
Yeah, that's really unfortunate. If we're lucky, the .NET SDK team will fix Perhaps we should disable the |
Add [CocoaFact] attribute to run unit tests on the Main UI threat. Before this PR, StaFact doesn't have a suitable test attribute to allow others to run their UI thread only unit tests on Mac.
What is included in this PR:
Implement new [CocoaFact] attribute. Add a MacOS app bundle which contains a Xunit built-in test runner to run new attribute unit tests on the UI Main thread.