From d69a9df8ec41d3a9fc8e139e90196a1e7f9c60ee Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 10:46:48 +0100 Subject: [PATCH 01/16] AssetPackTests.BuildLibraryWithAssetPack works --- .../Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs index 9d815c33d1b..96071e037e3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs @@ -13,8 +13,11 @@ public class AssetPackTests : BaseTest { [Test] [Category ("SmokeTests")] - public void BuildLibraryWithAssetPack ([Values (true, false)] bool isRelease) + public void BuildLibraryWithAssetPack ([Values] bool isRelease, [Values] AndroidRuntime runtime) { + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var path = Path.Combine ("temp", TestName); var lib = new XamarinAndroidLibraryProject { IsRelease = isRelease, @@ -26,6 +29,7 @@ public void BuildLibraryWithAssetPack ([Values (true, false)] bool isRelease) }, } }; + lib.SetRuntime (runtime); using (var builder = CreateDllBuilder (Path.Combine (path, lib.ProjectName))) { builder.ThrowOnBuildFailure = false; Assert.IsFalse (builder.Build (lib), $"{lib.ProjectName} should fail."); From c607f72cf331b9c506b7c9273c7b60f0fc74c2d3 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 10:52:55 +0100 Subject: [PATCH 02/16] AssetPackTests.BuildApplicationWithAssetPackThatHasInvalidName updated --- .../Xamarin.Android.Build.Tests/AssetPackTests.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs index 96071e037e3..7489c7af3a4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs @@ -4,6 +4,7 @@ using System.Text; using Xamarin.Android.Tasks; using Xamarin.ProjectTools; +using System.Collections.Generic; namespace Xamarin.Android.Build.Tests { @@ -40,13 +41,11 @@ public void BuildLibraryWithAssetPack ([Values] bool isRelease, [Values] Android [Test] [Category ("SmokeTests")] - [TestCase (false, AndroidRuntime.MonoVM)] - [TestCase (true, AndroidRuntime.MonoVM)] - [TestCase (false, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.NativeAOT)] - public void BuildApplicationWithAssetPackThatHasInvalidName (bool isRelease, AndroidRuntime runtime) + public void BuildApplicationWithAssetPackThatHasInvalidName ([Values] bool isRelease, [Values] AndroidRuntime runtime) { + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var path = Path.Combine ("temp", TestName); var app = new XamarinAndroidApplicationProject { IsRelease = isRelease, From 05dfeefcfca82043cfc4aa7eceb83f66b6cb3be5 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 10:57:42 +0100 Subject: [PATCH 03/16] AssetPackTests.BuildApplicationWithAssetPackOutsideProjectDirectory updated --- .../Xamarin.Android.Build.Tests/AssetPackTests.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs index 7489c7af3a4..ed68c93598e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs @@ -69,13 +69,11 @@ public void BuildApplicationWithAssetPackThatHasInvalidName ([Values] bool isRel [Test] [Category ("SmokeTests")] - [TestCase (false, AndroidRuntime.MonoVM)] - [TestCase (true, AndroidRuntime.MonoVM)] - [TestCase (false, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.NativeAOT)] - public void BuildApplicationWithAssetPackOutsideProjectDirectory (bool isRelease, AndroidRuntime runtime) + public void BuildApplicationWithAssetPackOutsideProjectDirectory ([Values] bool isRelease, [Values] AndroidRuntime runtime) { + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var path = Path.Combine ("temp", TestName); var app = new XamarinAndroidApplicationProject { ProjectName = "MyApp", From 1172423327b163986bdd4402078ce42bdb1fabcb Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 11:01:29 +0100 Subject: [PATCH 04/16] AssetPackTests.BuildApplicationWithAssetPackOverrides updated --- .../Xamarin.Android.Build.Tests/AssetPackTests.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs index ed68c93598e..32703a78796 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs @@ -118,13 +118,11 @@ public void BuildApplicationWithAssetPackOutsideProjectDirectory ([Values] bool [Test] [Category ("SmokeTests")] - [TestCase (false, AndroidRuntime.MonoVM)] - [TestCase (true, AndroidRuntime.MonoVM)] - [TestCase (false, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.NativeAOT)] - public void BuildApplicationWithAssetPackOverrides (bool isRelease, AndroidRuntime runtime) + public void BuildApplicationWithAssetPackOverrides ([Values] bool isRelease, [Values] AndroidRuntime runtime) { + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var path = Path.Combine ("temp", TestName); var app = new XamarinAndroidApplicationProject { ProjectName = "MyApp", From 601b44854636b35d9416b2b07c70766b4cd322d8 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 11:05:00 +0100 Subject: [PATCH 05/16] AssetPackTests.BuildApplicationWithAssetPack updated --- .../Xamarin.Android.Build.Tests/AssetPackTests.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs index 32703a78796..5b1a3831c71 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AssetPackTests.cs @@ -160,13 +160,11 @@ public void BuildApplicationWithAssetPackOverrides ([Values] bool isRelease, [Va [Test] [Category ("SmokeTests")] - [TestCase (false, AndroidRuntime.MonoVM)] - [TestCase (true, AndroidRuntime.MonoVM)] - [TestCase (false, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.CoreCLR)] - [TestCase (true, AndroidRuntime.NativeAOT)] - public void BuildApplicationWithAssetPack (bool isRelease, AndroidRuntime runtime) + public void BuildApplicationWithAssetPack ([Values] bool isRelease, [Values] AndroidRuntime runtime) { + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var path = Path.Combine ("temp", TestName); var asset3 = new AndroidItem.AndroidAsset ("Assets\\asset3.txt") { TextContent = () => "Asset3", From 8496165430effac74175d5a35b19ae8d4ca46c8d Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 12:35:55 +0100 Subject: [PATCH 06/16] CodeBehind tests work across all 3 runtimes --- .../CodeBehindTests.cs | 106 +++++++++++------- .../CodeBehindBuildTests.NET.csproj | 4 + .../CommonSampleLibrary.NET.csproj | 3 + 3 files changed, 74 insertions(+), 39 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index da088199ffd..208c298e565 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -9,6 +9,8 @@ using NUnit.Framework; using Xamarin.ProjectTools; +using Xamarin.Android.Tasks; +using System.Text; namespace Xamarin.Android.Build.Tests { @@ -111,25 +113,29 @@ sealed class TestProjectInfo { public string RootDirectory { get; } public string OutputDirectory { get; } + public string TestRootDirectory { get; } public string ObjPath { get; } public string BinPath { get; } public string GeneratedPath { get; } public string ProjectPath { get; } public string ProjectName { get; } public string TestName { get; } + public AndroidRuntime Runtime { get; } - public TestProjectInfo (string projectName, string testName, string rootDirectory, string outputRootDir) + public TestProjectInfo (string projectName, string testName, string rootDirectory, string outputRootDir, AndroidRuntime runtime) { TestName = testName; RootDirectory = rootDirectory; ProjectName = projectName; + Runtime = runtime; ObjPath = Path.Combine (rootDirectory, "obj"); GeneratedPath = Path.Combine (ObjPath, XABuildPaths.Configuration, "codebehind"); BinPath = Path.Combine (rootDirectory, "bin", XABuildPaths.Configuration); ProjectPath = Path.Combine (rootDirectory, $"{projectName}.csproj"); - OutputDirectory = Path.Combine (outputRootDir, testName, XABuildPaths.Configuration); + TestRootDirectory = Path.Combine (outputRootDir, testName); + OutputDirectory = Path.Combine (TestRootDirectory, XABuildPaths.Configuration); } } @@ -267,37 +273,38 @@ static CodeBehindTests () }, }; + // TODO: for some reason the tests no longer produce both aab and apk packages, at least locally? Fine? Bug? produced_binaries = new List { $"{ProjectName}.dll", "CommonSampleLibrary.dll", - $"{PackageName}-Signed.apk", +// $"{PackageName}-Signed.apk", $"{PackageName}.aab", $"{PackageName}-Signed.aab", }; } [Test] - public void SuccessfulBuildFew () + public void SuccessfulBuildFew ([Values] AndroidRuntime runtime) { - RunTest ("SuccessfulBuildFew", many: false, dtb: false, runner: SuccessfulBuild_RunTest); + RunTest (TestName, many: false, dtb: false, runner: SuccessfulBuild_RunTest, runtime: runtime); } [Test] - public void SuccessfulBuildMany () + public void SuccessfulBuildMany ([Values] AndroidRuntime runtime) { - RunTest ("SuccessfulBuildMany", many: true, dtb: false, runner: SuccessfulBuild_RunTest); + RunTest (TestName, many: true, dtb: false, runner: SuccessfulBuild_RunTest, runtime: runtime); } [Test] - public void SuccessfulBuildFew_DTB () + public void SuccessfulBuildFew_DTB ([Values] AndroidRuntime runtime) { - RunTest ("SuccessfulBuildFew_DTB", many: false, dtb: true, runner: SuccessfulBuild_RunTest); + RunTest (TestName, many: false, dtb: true, runner: SuccessfulBuild_RunTest, runtime: runtime); } [Test] - public void SuccessfulBuildMany_DTB () + public void SuccessfulBuildMany_DTB ([Values] AndroidRuntime runtime) { - RunTest ("SuccessfulBuildMany_DTB", many: true, dtb: true, runner: SuccessfulBuild_RunTest); + RunTest (TestName, many: true, dtb: true, runner: SuccessfulBuild_RunTest, runtime: runtime); } void SuccessfulBuild_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -328,9 +335,9 @@ void SuccessfulBuild_RunTest (TestProjectInfo testInfo, bool many, bool dtb, Loc } [Test] - public void SuccessfulAndroidXApp () + public void SuccessfulAndroidXApp ([Values] AndroidRuntime runtime) { - RunTest ("SuccessfulAndroidXApp", many: true, dtb: false, runner: SuccessfulBuild_AndroidX); + RunTest (TestName, many: true, dtb: false, runner: SuccessfulBuild_AndroidX, runtime: runtime); } void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -340,7 +347,9 @@ void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, Lo CopyLogs (testInfo, true); Assert.That (success, Is.True, "Build should have succeeded"); - Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings."); + if (testInfo.Runtime != AndroidRuntime.NativeAOT) { // NativeAOT currently (Nov 2025) produces 9 ILC warnings + Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings."); + } CopyGeneratedFiles (testInfo); @@ -363,15 +372,15 @@ void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, Lo } [Test] - public void FailedBuildFew_ConflictingFragment () + public void FailedBuildFew_ConflictingFragment ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildFew_ConflictingFragment", many: false, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest); + RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest, runtime: runtime); } [Test] - public void FailedBuildMany_ConflictingFragment () + public void FailedBuildMany_ConflictingFragment ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildMany_ConflictingFragment", many: true, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest); + RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest, runtime: runtime); } void FailedBuild_ConflictingFragment_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -391,15 +400,15 @@ void FailedBuild_ConflictingFragment_RunTest (TestProjectInfo testInfo, bool man } [Test] - public void FailedBuildFew_ConflictingTextView () + public void FailedBuildFew_ConflictingTextView ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildFew_ConflictingTextView", many: false, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest); + RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest, runtime: runtime); } [Test] - public void FailedBuildMany_ConflictingTextView () + public void FailedBuildMany_ConflictingTextView ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildMany_ConflictingTextView", many: true, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest); + RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest, runtime: runtime); } void FailedBuild_ConflictingTextView_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -419,15 +428,15 @@ void FailedBuild_ConflictingTextView_RunTest (TestProjectInfo testInfo, bool man } [Test] - public void FailedBuildFew_ConflictingButton () + public void FailedBuildFew_ConflictingButton ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildFew_ConflictingButton", many: false, dtb: false, runner: FailedBuild_ConflictingButton_RunTest); + RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingButton_RunTest, runtime: runtime); } [Test] - public void FailedBuildMany_ConflictingButton () + public void FailedBuildMany_ConflictingButton ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildMany_ConflictingButton", many: true, dtb: false, runner: FailedBuild_ConflictingButton_RunTest); + RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingButton_RunTest, runtime: runtime); } void FailedBuild_ConflictingButton_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -447,15 +456,15 @@ void FailedBuild_ConflictingButton_RunTest (TestProjectInfo testInfo, bool many, } [Test] - public void FailedBuildFew_ConflictingLinearLayout () + public void FailedBuildFew_ConflictingLinearLayout ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildFew_ConflictingLinearLayout", many: false, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest); + RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest, runtime: runtime); } [Test] - public void FailedBuildMany_ConflictingLinearLayout () + public void FailedBuildMany_ConflictingLinearLayout ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildMany_ConflictingLinearLayout", many: true, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest); + RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest, runtime: runtime); } void FailedBuild_ConflictingLinearLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -475,15 +484,15 @@ void FailedBuild_ConflictingLinearLayout_RunTest (TestProjectInfo testInfo, bool } [Test] - public void FailedBuildFew_ConflictingRelativeLayout () + public void FailedBuildFew_ConflictingRelativeLayout ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildFew_ConflictingRelativeLayout", many: false, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest); + RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest, runtime: runtime); } [Test] - public void FailedBuildMany_ConflictingRelativeLayout () + public void FailedBuildMany_ConflictingRelativeLayout ([Values] AndroidRuntime runtime) { - RunTest ("FailedBuildMany_ConflictingRelativeLayout", many: true, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest); + RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest, runtime: runtime); } void FailedBuild_ConflictingRelativeLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) @@ -577,12 +586,17 @@ void AssertHaveCompilerError (bool haveError, string fileName, int line) /// Generate code in parallel if true, serially otherwise /// Test design-time build if true, regular build otherwise /// Action consituting the main body of the test. Passed parameters are described above in the remarks section. - void RunTest (string testName, bool many, bool dtb, Action runner) + void RunTest (string testName, bool many, bool dtb, Action runner, AndroidRuntime runtime) { - string temporaryProjectDir = PrepareProject (testName); + bool isRelease = runtime == AndroidRuntime.NativeAOT; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } + + string temporaryProjectDir = PrepareProject (testName, isRelease, runtime); LocalBuilder builder = GetBuilder ($"{ProjectName}.{testName}"); builder.BuildingInsideVisualStudio = dtb; - var testInfo = new TestProjectInfo (ProjectName, testName, temporaryProjectDir, TestOutputDir); + var testInfo = new TestProjectInfo (ProjectName, testName, temporaryProjectDir, TestOutputDir, runtime); try { runner (testInfo, many, dtb, builder); @@ -604,7 +618,7 @@ void RunTest (string testName, bool many, bool dtb, Action ignoreDirs) diff --git a/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj b/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj index 2175ae82a5d..de570bdf7e1 100644 --- a/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj +++ b/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj @@ -11,6 +11,10 @@ false false false + aab + @UseMonoRuntime@ + @PublishAot@ + @Configuration@ $(DefineConstants);$(ExtraConstants) diff --git a/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj b/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj index 3765f0d1a57..c053db4655b 100644 --- a/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj +++ b/tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj @@ -4,6 +4,9 @@ CommonSampleLibrary CommonSampleLibrary false + @UseMonoRuntime@ + @PublishAot@ + @Configuration@ $(DefineConstants);$(ExtraConstants) From ec3cb4e90d48597b2d8a1198bec026e5a5975558 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 12:44:53 +0100 Subject: [PATCH 07/16] DeferredBuildTest.SelectivelyRunUpdateAndroidResources works --- .../Xamarin.Android.Build.Tests/DeferredBuildTest.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs index 696cffe87b2..60d05efa1f1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs @@ -2,6 +2,7 @@ using System.IO; using Xamarin.ProjectTools; using Microsoft.Build.Framework; +using Xamarin.Android.Tasks; namespace Xamarin.Android.Build.Tests { @@ -9,13 +10,19 @@ namespace Xamarin.Android.Build.Tests public class DeferredBuildTest : BaseTest { [Test] - public void SelectivelyRunUpdateAndroidResources () + public void SelectivelyRunUpdateAndroidResources ([Values] AndroidRuntime runtime) { + bool isRelease = runtime == AndroidRuntime.NativeAOT; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var path = Path.Combine ("temp", TestName); var app = new XamarinAndroidApplicationProject { + IsRelease = isRelease, ProjectName = "MyApp", }; + app.SetRuntime (runtime); app.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", "True"); app.SetProperty ("AndroidUseIntermediateDesignerFile", "True"); From 2789ac01e33bb1094cea37bd4cae51f32d7dfd47 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 12:48:11 +0100 Subject: [PATCH 08/16] DeferredBuildTest.RunUpdateAndroidResourcesIfBackgroundBuildNotSupported works --- .../Xamarin.Android.Build.Tests/DeferredBuildTest.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs index 60d05efa1f1..07bd0676864 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DeferredBuildTest.cs @@ -61,13 +61,20 @@ public void SelectivelyRunUpdateAndroidResources ([Values] AndroidRuntime runtim } [Test] - public void RunUpdateAndroidResourcesIfBackgroundBuildNotSupported () + public void RunUpdateAndroidResourcesIfBackgroundBuildNotSupported ([Values] AndroidRuntime runtime) { + bool isRelease = runtime == AndroidRuntime.NativeAOT; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } + var path = Path.Combine ("temp", TestName); var app = new XamarinAndroidApplicationProject { + IsRelease = isRelease, ProjectName = "MyApp", }; + app.SetRuntime (runtime); app.SetProperty ("AndroidUseManagedDesignTimeResourceGenerator", "True"); app.SetProperty ("AndroidUseIntermediateDesignerFile", "True"); From ab20dd3ca2bb4186ec4c8e80d91ca415b16ceb39 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 13:55:18 +0100 Subject: [PATCH 09/16] EnvironmentContentTests.BuildApplicationWithMonoEnvironment updated (broken on NAOT) --- .../EnvironmentContentTests.cs | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs index 1427e30cf0b..6ab23bdf27d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs @@ -16,18 +16,29 @@ public class EnvironmentContentTests : BaseTest { [Test] [NonParallelizable] - public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline")] string sequencePointsMode, - [Values (AndroidRuntime.MonoVM, AndroidRuntime.CoreCLR)] AndroidRuntime runtime) + public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline")] string sequencePointsMode, [Values] AndroidRuntime runtime) { + const bool isRelease = true; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } + + // TODO: NativeAOT fails all the tests, `MONO_DEBUG` is not found in the environment. Question is - should we fix it for backward compatibility, + // even though NativeAOT won't use it (and CoreCLR passes the tests), or should we just ignore this test for NativeAOT? + if (runtime == AndroidRuntime.NativeAOT) { + Assert.Ignore ("NativeAOT doesn't currently export the MONO_DEBUG environment variable"); + } + string supportedAbis = runtime switch { AndroidRuntime.MonoVM => "armeabi-v7a;x86", AndroidRuntime.CoreCLR => "arm64-v8a;x86_64", + AndroidRuntime.NativeAOT => "arm64-v8a;x86_64", _ => throw new NotSupportedException ($"Unsupported runtime '{runtime}'") }; var lib = new XamarinAndroidLibraryProject { ProjectName = "Library1", - IsRelease = true, + IsRelease = isRelease, OtherBuildItems = { new AndroidItem.AndroidEnvironment ("Mono.env") { TextContent = () => "MONO_DEBUG=soft-breakpoints" }, @@ -35,7 +46,7 @@ public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline }; lib.SetRuntime (runtime); var app = new XamarinFormsAndroidApplicationProject () { - IsRelease = true, + IsRelease = isRelease, AndroidLinkModeRelease = AndroidLinkMode.Full, References = { new BuildItem ("ProjectReference","..\\Library1\\Library1.csproj"), @@ -53,7 +64,7 @@ public void BuildApplicationWithMonoEnvironment ([Values ("", "Normal", "Offline Assert.IsTrue (appb.Build (app), "App should have succeeded."); string intermediateOutputDir = Path.Combine (Root, appb.ProjectDirectory, app.IntermediateOutputPath); - List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, runtime); Assert.IsTrue (envvars.Count > 0, $"No environment variables defined"); @@ -99,7 +110,7 @@ public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline" Assert.IsTrue (b.Build (proj), "Build should have succeeded."); string intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath); - List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, AndroidRuntime.MonoVM); Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.MonoVM); Assert.IsTrue (envvars.Count > 0, $"No environment variables defined"); @@ -117,11 +128,16 @@ public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline" } [Test] - public void CheckConcurrentGC () + public void CheckConcurrentGC ([Values] AndroidRuntime runtime) { + const bool isRelease = true; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, + IsRelease = isRelease, }; + proj.SetRuntime (runtime); var gcVarName = "MONO_GC_PARAMS"; var expectedDefaultValue = "major=marksweep"; var expectedUpdatedValue = "major=marksweep-conc"; @@ -135,14 +151,14 @@ public void CheckConcurrentGC () Assert.IsTrue (b.Build (proj), "Build should have succeeded."); var intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath); // AndroidEnableSGenConcurrent=False by default - List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.MonoVM); Assert.IsTrue (envvars.ContainsKey (gcVarName), $"Environment should contain '{gcVarName}'."); Assert.AreEqual (expectedDefaultValue, envvars[gcVarName], $"'{gcVarName}' should have been '{expectedDefaultValue}' when concurrent GC is disabled."); proj.SetProperty ("AndroidEnableSGenConcurrent", "True"); Assert.IsTrue (b.Build (proj), "Second build should have succeeded."); - envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true); + envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.MonoVM); Assert.IsTrue (envvars.ContainsKey (gcVarName), $"Environment should contain '{gcVarName}'."); Assert.AreEqual (expectedUpdatedValue, envvars[gcVarName], $"'{gcVarName}' should have been '{expectedUpdatedValue}' when concurrent GC is enabled."); @@ -187,14 +203,14 @@ public void CheckHttpClientHandlerType ([Values (AndroidRuntime.MonoVM, AndroidR proj.SetProperty ("AndroidHttpClientHandlerType", expectedDefaultValue); Assert.IsTrue (b.Build (proj), "Build should have succeeded."); var intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath); - List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, runtime); Assert.IsTrue (envvars.ContainsKey (httpClientHandlerVarName), $"Environment should contain '{httpClientHandlerVarName}'."); Assert.AreEqual (expectedDefaultValue, envvars[httpClientHandlerVarName]); proj.SetProperty ("AndroidHttpClientHandlerType", expectedUpdatedValue); Assert.IsTrue (b.Build (proj), "Second build should have succeeded."); - envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true); + envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, runtime); Assert.IsTrue (envvars.ContainsKey (httpClientHandlerVarName), $"Environment should contain '{httpClientHandlerVarName}'."); Assert.AreEqual (expectedUpdatedValue, envvars[httpClientHandlerVarName]); From 67cb15e646ff5484cae56deace57dd6f73dca1e4 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 14:01:08 +0100 Subject: [PATCH 10/16] EnvironmentContentTests.CheckConcurrentGC updated --- .../EnvironmentContentTests.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs index 6ab23bdf27d..109422f442c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs @@ -128,16 +128,12 @@ public void CheckMonoDebugIsAddedToEnvironment ([Values ("", "Normal", "Offline" } [Test] - public void CheckConcurrentGC ([Values] AndroidRuntime runtime) + public void CheckConcurrentGC () { - const bool isRelease = true; - if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { - return; - } var proj = new XamarinAndroidApplicationProject () { - IsRelease = isRelease, + IsRelease = true, }; - proj.SetRuntime (runtime); + var gcVarName = "MONO_GC_PARAMS"; var expectedDefaultValue = "major=marksweep"; var expectedUpdatedValue = "major=marksweep-conc"; @@ -151,14 +147,14 @@ public void CheckConcurrentGC ([Values] AndroidRuntime runtime) Assert.IsTrue (b.Build (proj), "Build should have succeeded."); var intermediateOutputDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath); // AndroidEnableSGenConcurrent=False by default - List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); + List envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, AndroidRuntime.MonoVM); Dictionary envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.MonoVM); Assert.IsTrue (envvars.ContainsKey (gcVarName), $"Environment should contain '{gcVarName}'."); Assert.AreEqual (expectedDefaultValue, envvars[gcVarName], $"'{gcVarName}' should have been '{expectedDefaultValue}' when concurrent GC is disabled."); proj.SetProperty ("AndroidEnableSGenConcurrent", "True"); Assert.IsTrue (b.Build (proj), "Second build should have succeeded."); - envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, runtime); + envFiles = EnvironmentHelper.GatherEnvironmentFiles (intermediateOutputDir, supportedAbis, true, AndroidRuntime.MonoVM); envvars = EnvironmentHelper.ReadEnvironmentVariables (envFiles, AndroidRuntime.MonoVM); Assert.IsTrue (envvars.ContainsKey (gcVarName), $"Environment should contain '{gcVarName}'."); Assert.AreEqual (expectedUpdatedValue, envvars[gcVarName], $"'{gcVarName}' should have been '{expectedUpdatedValue}' when concurrent GC is enabled."); From 6603d64cff526aee4541062c39e03f5f5aa23658 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 14:12:18 +0100 Subject: [PATCH 11/16] EnvironmentContentTests.CheckForInvalidHttpClientHandlerType works --- .../EnvironmentContentTests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs index 109422f442c..770492f0895 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs @@ -162,11 +162,16 @@ public void CheckConcurrentGC () } [Test] - public void CheckForInvalidHttpClientHandlerType () + public void CheckForInvalidHttpClientHandlerType ([Values] AndroidRuntime runtime) { + const bool isRelease = true; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, + IsRelease = isRelease, }; + proj.SetRuntime (runtime); using (var b = CreateApkBuilder ()) { b.ThrowOnBuildFailure = false; proj.SetProperty ("AndroidHttpClientHandlerType", "Android.App.Application"); From f1b1e3303dc1f2f6817734584dbb3ba123e4e08f Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 20 Nov 2025 14:22:53 +0100 Subject: [PATCH 12/16] EnvironmentContentTests.CheckForInvalidHttpClientHandlerType works --- .../EnvironmentContentTests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs index 770492f0895..b0eb166863a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/EnvironmentContentTests.cs @@ -181,10 +181,14 @@ public void CheckForInvalidHttpClientHandlerType ([Values] AndroidRuntime runtim } [Test] - public void CheckHttpClientHandlerType ([Values (AndroidRuntime.MonoVM, AndroidRuntime.CoreCLR)] AndroidRuntime runtime) + public void CheckHttpClientHandlerType ([Values] AndroidRuntime runtime) { + bool isRelease = runtime == AndroidRuntime.NativeAOT; + if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { + return; + } var proj = new XamarinAndroidApplicationProject () { - IsRelease = true, + IsRelease = isRelease, }; var httpClientHandlerVarName = "XA_HTTP_CLIENT_HANDLER_TYPE"; var expectedDefaultValue = "System.Net.Http.SocketsHttpHandler, System.Net.Http"; @@ -193,6 +197,7 @@ public void CheckHttpClientHandlerType ([Values (AndroidRuntime.MonoVM, AndroidR string supportedAbis = runtime switch { AndroidRuntime.MonoVM => "armeabi-v7a;arm64-v8a", AndroidRuntime.CoreCLR => "arm64-v8a;x86_64", + AndroidRuntime.NativeAOT => "arm64-v8a;x86_64", _ => throw new NotSupportedException ($"Unsupported runtime '{runtime}'") }; proj.SetRuntime (runtime); From 775ed378bf27f7620689855798032c69969dd7f9 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 2 Dec 2025 11:46:31 +0100 Subject: [PATCH 13/16] Try disabling NativeAOT and ILC warnings on CI --- tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj b/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj index de570bdf7e1..25439f6fff7 100644 --- a/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj +++ b/tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj @@ -16,6 +16,12 @@ @PublishAot@ @Configuration@ + + + + XA1040;IL3053 + + $(DefineConstants);$(ExtraConstants) From e0e2d41927e8b944b91bdb9c268126e1be528aec Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 3 Dec 2025 09:23:18 +0100 Subject: [PATCH 14/16] Let's try this --- .../CodeBehindTests.cs | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 208c298e565..3879e6b0d14 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -307,9 +307,9 @@ public void SuccessfulBuildMany_DTB ([Values] AndroidRuntime runtime) RunTest (TestName, many: true, dtb: true, runner: SuccessfulBuild_RunTest, runtime: runtime); } - void SuccessfulBuild_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void SuccessfulBuild_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:false); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:false); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -340,9 +340,9 @@ public void SuccessfulAndroidXApp ([Values] AndroidRuntime runtime) RunTest (TestName, many: true, dtb: false, runner: SuccessfulBuild_AndroidX, runtime: runtime); } - void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:true, "__HAVE_ANDROIDX__"); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:true, "__HAVE_ANDROIDX__"); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -383,9 +383,9 @@ public void FailedBuildMany_ConflictingFragment ([Values] AndroidRuntime runtime RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest, runtime: runtime); } - void FailedBuild_ConflictingFragment_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void FailedBuild_ConflictingFragment_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_FRAGMENT"); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_FRAGMENT"); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -411,9 +411,9 @@ public void FailedBuildMany_ConflictingTextView ([Values] AndroidRuntime runtime RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest, runtime: runtime); } - void FailedBuild_ConflictingTextView_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void FailedBuild_ConflictingTextView_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_TEXTVIEW"); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_TEXTVIEW"); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -439,9 +439,9 @@ public void FailedBuildMany_ConflictingButton ([Values] AndroidRuntime runtime) RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingButton_RunTest, runtime: runtime); } - void FailedBuild_ConflictingButton_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void FailedBuild_ConflictingButton_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_BUTTON"); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_BUTTON"); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -467,9 +467,9 @@ public void FailedBuildMany_ConflictingLinearLayout ([Values] AndroidRuntime run RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest, runtime: runtime); } - void FailedBuild_ConflictingLinearLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void FailedBuild_ConflictingLinearLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_LINEARLAYOUT"); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_LINEARLAYOUT"); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -495,9 +495,9 @@ public void FailedBuildMany_ConflictingRelativeLayout ([Values] AndroidRuntime r RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest, runtime: runtime); } - void FailedBuild_ConflictingRelativeLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder) + void FailedBuild_ConflictingRelativeLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder, AndroidRuntime runtime) { - string[] parameters = GetBuildProperties (builder, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_RELATIVELAYOUT"); + string[] parameters = GetBuildProperties (builder, runtime, many, dtb, referenceAndroidX:false, "NOT_CONFLICTING_RELATIVELAYOUT"); bool success = builder.Build (testInfo.ProjectPath, GetBuildTarget (dtb), parameters); CopyLogs (testInfo, true); @@ -516,11 +516,30 @@ string GetBuildTarget (bool isDTB) return isDTB ? "Compile" : "SignAndroidPackage"; } - string[] GetBuildProperties (LocalBuilder builder, bool manyBuild, bool dtbBuild, bool referenceAndroidX, params string[] extraConstants) + string[] GetBuildProperties (LocalBuilder builder, AndroidRuntime runtime, bool manyBuild, bool dtbBuild, bool referenceAndroidX, params string[] extraConstants) { + var noWarn = new List { + "CA1416", + "CS0414", + "CS1591", + "XA1005", + "XA4225", + }; + + if (runtime == AndroidRuntime.NativeAOT) { + // We disable these only on CI, since they would cause the tests to fail there. + string? runningOnCI = Environment.GetEnvironmentVariable ("RunningOnCI"); + if (runningOnCI == "true") { + Console.WriteLine ("CodeBehindTests: using NativeAOT and running on CI, disabling warnings."); + noWarn.Add ("IL2091"); + noWarn.Add ("IL3053"); + noWarn.Add ("XA1040"); + } + } + var ret = new List { "AndroidGenerateLayoutBindings=true", - "\"NoWarn=CS0414;CA1416;CS1591;XA1005;XA4225\"" + $"\"NoWarn={String.Join (';', noWarn)}\"" }; if (manyBuild) ret.Add ("ForceParallelBuild=true"); @@ -586,7 +605,7 @@ void AssertHaveCompilerError (bool haveError, string fileName, int line) /// Generate code in parallel if true, serially otherwise /// Test design-time build if true, regular build otherwise /// Action consituting the main body of the test. Passed parameters are described above in the remarks section. - void RunTest (string testName, bool many, bool dtb, Action runner, AndroidRuntime runtime) + void RunTest (string testName, bool many, bool dtb, Action runner, AndroidRuntime runtime) { bool isRelease = runtime == AndroidRuntime.NativeAOT; if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) { @@ -599,7 +618,7 @@ void RunTest (string testName, bool many, bool dtb, Action Date: Thu, 4 Dec 2025 11:07:00 +0100 Subject: [PATCH 15/16] Try this --- .../Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 3879e6b0d14..13822aafea8 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -528,7 +528,14 @@ string[] GetBuildProperties (LocalBuilder builder, AndroidRuntime runtime, bool if (runtime == AndroidRuntime.NativeAOT) { // We disable these only on CI, since they would cause the tests to fail there. - string? runningOnCI = Environment.GetEnvironmentVariable ("RunningOnCI"); + // It appears that despite us exporting `RunningOnCI` in our pipeline YAML, we actually get + // an all-uppercase version of the variable: + // + // temp/CodeBehind/SuccessfulBuildFewNativeAOT/Release/Directory.Build.props(78,28): message : Property 'RUNNINGONCI' with value 'true' expanded from the environment. + // + string? runningOnCI = + Environment.GetEnvironmentVariable ("RunningOnCI") ?? + Environment.GetEnvironmentVariable ("RUNNINGONCI"); if (runningOnCI == "true") { Console.WriteLine ("CodeBehindTests: using NativeAOT and running on CI, disabling warnings."); noWarn.Add ("IL2091"); From 4e8003c9a139363633014fe649d7ed269eacbb1e Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 4 Dec 2025 12:54:35 +0100 Subject: [PATCH 16/16] One more warning to ignore --- .../Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 13822aafea8..2b55531d7e7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -539,6 +539,7 @@ string[] GetBuildProperties (LocalBuilder builder, AndroidRuntime runtime, bool if (runningOnCI == "true") { Console.WriteLine ("CodeBehindTests: using NativeAOT and running on CI, disabling warnings."); noWarn.Add ("IL2091"); + noWarn.Add ("IL2104"); noWarn.Add ("IL3053"); noWarn.Add ("XA1040"); }