[tests] Fix CA1416 root cause in test projects instead of suppressing it#11761
[tests] Fix CA1416 root cause in test projects instead of suppressing it#11761simonrozsival wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a tests/Directory.Build.props to suppress CA1416 (platform compatibility analyzer) warnings across all projects under tests/, reducing build log noise while preserving the repository-root build settings via an explicit import chain.
Changes:
- Add
tests/Directory.Build.propsthat explicitly imports the repo-rootDirectory.Build.props(since MSBuild only auto-imports the nearest one). - Append
CA1416to$(NoWarn)for all test projects undertests/.
Show a summary per file
| File | Description |
|---|---|
| tests/Directory.Build.props | Chains to repo-root Directory.Build.props and suppresses CA1416 for all projects under tests/. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 1
| // This test assembly only ever runs on Android (minimum API level 24). Without this | ||
| // attribute the platform-compatibility analyzer treats the assembly as platform-neutral | ||
| // (because GenerateAssemblyInfo is disabled) and emits spurious CA1416 warnings for every | ||
| // call to an [SupportedOSPlatform("android24.0")] API. | ||
| [assembly: SupportedOSPlatform ("android24.0")] |
There was a problem hiding this comment.
Can you set the SupportedOSPlatformVersion MSBuild property instead?
There was a problem hiding this comment.
SupportedOSPlatformVersion is actually already set on this project (<SupportedOSPlatformVersion>$(AndroidMinimumDotNetApiLevel)</SupportedOSPlatformVersion>, currently 24) — but it doesn't produce the attribute here.
The .NET SDK only turns SupportedOSPlatformVersion into [assembly: SupportedOSPlatform] inside the GenerateAssemblyInfo target, which is gated on GenerateAssemblyInfo == true (Microsoft.NET.GenerateAssemblyInfo.targets). These test projects set <GenerateAssemblyInfo>false</GenerateAssemblyInfo> to avoid clashing with the hand-written Properties/AssemblyInfo.cs, so the property is inert and no attribute is emitted. The Android SDK consumes SupportedOSPlatformVersion only for typemap/runtime generation, not for the assembly attribute.
So to drive it from the property we'd have to either:
- stop setting
GenerateAssemblyInfo=falseand move everything inProperties/AssemblyInfo.cs(including[assembly: UsesPermission]inTestRunner.Core) into MSBuild, or - add a small target that emits the attribute from
$(SupportedOSPlatformVersion)viaWriteCodeFragment.
Do you prefer one of those over the explicit [assembly: SupportedOSPlatform]? Happy to wire up (2) if you'd like to keep it property-driven.
There was a problem hiding this comment.
Ok, yeah we can remove GenerateAssemblyInfo=false, I remember this problem.
We'd have to migrate attributes to the relevant MSBuild properties -- or you get duplicates.
The MSBuild properties seem better, in general.
Android-targeted test projects emitted ~1300 CA1416 warnings per build (e.g.
in Mono.Android.NET-Tests) because they set <GenerateAssemblyInfo>false</> to
avoid clashing with hand-written Properties/AssemblyInfo.cs. With assembly-info
generation disabled, the .NET SDK never emits the
[assembly: SupportedOSPlatform("android24.0")] attribute that it normally
derives from <SupportedOSPlatformVersion>, so the platform-compatibility
analyzer treats these assemblies as platform-neutral and flags every call to a
Mono.Android API.
Remove <GenerateAssemblyInfo>false</> so the SDK emits the platform attribute
from the existing <SupportedOSPlatformVersion> property (default android24.0),
and delete the hand-written Properties/AssemblyInfo.cs files to avoid duplicate
attribute errors. The cosmetic assembly metadata they declared is not needed on
test assemblies and is dropped; the only functional attribute, TestRunner.Core's
[assembly: UsesPermission(...READ_PHONE_STATE)], is preserved as an
<AssemblyAttribute> item.
This fixes the warnings at their root rather than suppressing CA1416.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
3a7cfd3 to
1e6bd9e
Compare
Summary
Our Android-targeted test projects emit a large volume of
CA1416warnings — roughly 1300 per build in theMono.Android.NET-Testsbuild alone. Rather than suppress the rule, this PR fixes the root cause by declaring each affected assembly's supported platform.Root cause
The telltale wording is "This call site is reachable on all platforms. 'X' is only supported on: 'Android' 24.0 and later." — the platform-compatibility analyzer thinks the assembly is platform-neutral, not Android-only.
Normally the .NET SDK auto-emits an assembly-level attribute that tells the analyzer the assembly only runs on Android:
But these test projects set
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>(to avoid clashing with their hand-writtenProperties/AssemblyInfo.cs). In the .NET SDK, theSupportedOSPlatformAttributeis only emitted insideCoreGenerateAssemblyInfo, which is gated entirely byGenerateAssemblyInfo == true. With it disabled, the attribute is never produced, the analyzer has no Android floor, and every call to aMono.AndroidAPI (with minimum API level 24, essentially the entire API surface is annotatedandroid24.0) raisesCA1416.Fix
Add
[assembly: SupportedOSPlatform("android24.0")]to the affected assemblies. This states the literal truth — these test apps only ever run on Android 24+ — so the analyzer stops warning, without hiding genuine portability diagnostics the way a blanketNoWarnwould.Projects changed
Only Android-targeted test projects that both set
GenerateAssemblyInfo=falseand callMono.AndroidAPIs need this:Mono.Android.NET-TestsTestRunner.CoreCodeBehind/BuildTestsProjects intentionally left alone
StartupHook— also setsGenerateAssemblyInfo=false, but calls noMono.AndroidAPIs, so it never trips CA1416.MSBuildDeviceIntegration,Xamarin.Android.McwGen-Tests,Xamarin.Android.JcwGen-Tests— use the defaultGenerateAssemblyInfo=true, so the SDK already emits the platform attribute.Verification
Verified against the real
Mono.Androidreference assembly (Microsoft.Android.Ref.37) with a minimalnet*-androidproject mirroring the test projects' settings (GenerateAssemblyInfo=false,SupportedOSPlatformVersion=24) and the same kinds of API calls (Object.Handle,JavaSystem.IdentityHashCode,JNIEnv.GetMethodID,Activity.OnCreate,Instrumentation,Log.Error,TextView/Button, …):CA1416warnings ("reachable on all platforms", android 24.0)