Skip to content

Commit

Permalink
[tests] verify trimmer warnings where appropriate (#9076)
Browse files Browse the repository at this point in the history
One change we need in the Android workload is to make sure that
trimmer warnings are displayed if a project sets `$(IsAotCompatible)`.
Customers would likely want this set for all platforms if they are
using NativeAOT on iOS or MacCatalyst.

I also wrote a test with somewhat complicated parameters to verify
we get warnings.

First, I can create a warning for both `IL2055` and `IL3050`:

    // Member field
    Type type = typeof (List<>);
    // ...
    // Later in OnCreate
    Console.WriteLine (type.MakeGenericType (typeof (object)));

The combinations of tests are:

| Configuration | Property                           | Warning(s)        |
| ------------- | ---------------------------------- | ----------------- |
| Debug         | (defaults)                         | None              |
| Release       | (defaults)                         | None              |
| Debug         | TrimMode=full                      | None              |
| Release       | TrimMode=full                      | IL2055(2)         |
| Release       | SuppressTrimAnalysisWarnings=false | IL2055(2)         |
| Debug         | IsAotCompatible=true               | IL2055, IL3050    |
| Release       | IsAotCompatible=false              | IL2055(2), IL3050 |

Some of the cases receive duplicate warnings, but this is expected as
the same behavior occurs in the simplest case:

* `dotnet new console`
* Add the above code to `Program.cs`
* `dotnet publish -c Release -r win-x64 -p:PublishAot=true`
* Receive warnings from both the Roslyn analyzer and ILC (NativeAOT compiler)

In a future PR, I might try to "fix" the duplicate warnings.
  • Loading branch information
jonathanpeppers authored Jul 4, 2024
1 parent 54a9c8c commit 6b665dc
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
<!-- For compat with user code not marked trimmable, only trim opt-in by default. -->
<TrimMode Condition=" '$(TrimMode)' == '' and '$(AndroidLinkMode)' == 'Full' ">full</TrimMode>
<TrimMode Condition="'$(TrimMode)' == ''">partial</TrimMode>
<SuppressTrimAnalysisWarnings Condition=" '$(SuppressTrimAnalysisWarnings)' == '' and '$(TrimMode)' == 'full' ">false</SuppressTrimAnalysisWarnings>
<SuppressTrimAnalysisWarnings Condition=" '$(SuppressTrimAnalysisWarnings)' == '' and ('$(TrimMode)' == 'full' or '$(IsAotCompatible)' == 'true') ">false</SuppressTrimAnalysisWarnings>
<SuppressTrimAnalysisWarnings Condition=" '$(SuppressTrimAnalysisWarnings)' == '' ">true</SuppressTrimAnalysisWarnings>
<!-- Prefer $(RuntimeIdentifiers) plural -->
<RuntimeIdentifiers Condition=" '$(RuntimeIdentifier)' == '' And '$(RuntimeIdentifiers)' == '' ">android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,48 @@ public void BuildHasNoWarnings (bool isRelease, bool xamarinForms, bool multidex
}
}

[Test]
[TestCase ("", new string [0], false)]
[TestCase ("", new string [0], true)]
[TestCase ("SuppressTrimAnalysisWarnings=false", new string [] { "IL2055" }, true, 2)]
[TestCase ("TrimMode=full", new string [0], false)]
[TestCase ("TrimMode=full", new string [] { "IL2055" }, true, 2)]
[TestCase ("IsAotCompatible=true", new string [] { "IL2055", "IL3050" }, false)]
[TestCase ("IsAotCompatible=true", new string [] { "IL2055", "IL3050" }, true, 3)]
public void BuildHasTrimmerWarnings (string properties, string [] codes, bool isRelease, int? totalWarnings = null)
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = isRelease,
};
proj.SetRuntimeIdentifier ("arm64-v8a");
proj.MainActivity = proj.DefaultMainActivity
.Replace ("//${FIELDS}", "Type type = typeof (List<>);")
.Replace ("//${AFTER_ONCREATE}", "Console.WriteLine (type.MakeGenericType (typeof (object)));");
proj.SetProperty ("TrimmerSingleWarn", "false");

if (!string.IsNullOrEmpty (properties)) {
foreach (var property in properties.Split (';')) {
int index = property.IndexOf ('=');
if (index != -1) {
proj.SetProperty (property [..index], property [(index + 1)..]);
}
}
}

using var b = CreateApkBuilder (Path.Combine ("temp", TestName));
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

if (codes.Length == 0) {
b.AssertHasNoWarnings ();
} else {
totalWarnings ??= codes.Length;
Assert.True (StringAssertEx.ContainsText (b.LastBuildOutput, $"{totalWarnings} Warning(s)"), $"Should receive {totalWarnings} warnings");
foreach (var code in codes) {
Assert.True (StringAssertEx.ContainsText (b.LastBuildOutput, code), $"Should receive {code} warning");
}
}
}

[Test]
[TestCase ("AndroidFastDeploymentType", "Assemblies", true, false)]
[TestCase ("AndroidFastDeploymentType", "Assemblies", false, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace ${ROOT_NAMESPACE}
[Register ("${JAVA_PACKAGENAME}.MainActivity"), Activity (Label = "${PROJECT_NAME}", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
//${FIELDS}
int count = 1;

protected override void OnCreate (Bundle bundle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace ${ROOT_NAMESPACE}
[Android.Runtime.Register ("${JAVA_PACKAGENAME}.MainActivity"), Activity (Label = "${PROJECT_NAME}", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
//${FIELDS}
int count = 1;

protected override void OnCreate (Bundle? bundle)
Expand Down

0 comments on commit 6b665dc

Please sign in to comment.