Skip to content

Commit fbd56c1

Browse files
authored
Enable more tests to run on all 3 runtimes, part 11 (#10625)
This expands test coverage across multiple test classes to ensure all tests are executed for every supported `AndroidRuntime` (MonoVM, CoreCLR, NativeAOT). Key changes include: **Test Parameterization and Runtime Handling:** * Parameterized numerous `[Test]` methods across `AndroidResourceTests`, `CheckClientHandlerTypeTests`, `LinkerTests`, `ManagedResourceParserTests`, and `ResolveMonoAndroidSdksTests` to run with all values of the `AndroidRuntime` enum using `[Values] AndroidRuntime runtime`. * Updated project creation in tests to set `IsRelease` based on the runtime (e.g., `NativeAOT` implies release), and called `SetRuntime(runtime)` on test projects to ensure correct configuration. * Added runtime-aware skip logic using `IgnoreUnsupportedConfiguration(runtime, release: isRelease)` to bypass incompatible test configurations. **Test Data and Behavior Adjustments:** * Refactored test data sources to generate cases for all `AndroidRuntime` values, ensuring comprehensive coverage. * Adjusted test logic and assertions to handle differences in build outputs and behaviors between runtimes, particularly for NativeAOT (e.g., output directory structure, test skips for known issues). **Miscellaneous:** * Added necessary `using` directives and minor code cleanups to support new logic.
1 parent 740256f commit fbd56c1

File tree

5 files changed

+181
-37
lines changed

5 files changed

+181
-37
lines changed

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/AndroidResourceTests.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,17 @@ public void UserLayout ()
154154
Assert.True (mainText.Contains ("FixedWidth"), "'FixedWidth' was converted to 'fixedwidth'");
155155
Directory.Delete (path, recursive: true);
156156
}
157-
157+
158158
[Test]
159-
public void AdaptiveIcon ()
159+
public void AdaptiveIcon ([Values] AndroidRuntime runtime)
160160
{
161+
bool isRelease = runtime == AndroidRuntime.NativeAOT;
162+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
163+
return;
164+
}
165+
161166
var proj = new XamarinAndroidApplicationProject {
167+
IsRelease = isRelease,
162168
SupportedOSPlatformVersion = "26",
163169
AndroidResources = {
164170
new AndroidItem.AndroidResource ("Resources\\values\\colors.xml") {
@@ -193,6 +199,7 @@ public void AdaptiveIcon ()
193199
},
194200
}
195201
};
202+
proj.SetRuntime (runtime);
196203

197204
using var b = CreateApkBuilder ();
198205
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/CheckClientHandlerTypeTests.cs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,44 @@ namespace Xamarin.Android.Build.Tests
1414
{
1515
public class CheckClientHandlerTypeTests : BaseTest
1616
{
17+
static IEnumerable<object[]> Get_ErrorIsNotRaised_Data ()
18+
{
19+
var ret = new List<object[]> ();
20+
21+
foreach (AndroidRuntime runtime in Enum.GetValues (typeof (AndroidRuntime))) {
22+
AddTestData ("Xamarin.Android.Net.AndroidMessageHandler", runtime);
23+
AddTestData ("System.Net.Http.SocketsHttpHandler, System.Net.Http", runtime);
24+
}
25+
26+
return ret;
27+
28+
void AddTestData (string handler, AndroidRuntime runtime)
29+
{
30+
ret.Add (new object[] {
31+
handler,
32+
runtime,
33+
});
34+
}
35+
}
36+
1737
[Test]
18-
[TestCase ("Xamarin.Android.Net.AndroidMessageHandler")]
19-
[TestCase ("System.Net.Http.SocketsHttpHandler, System.Net.Http")]
20-
public void ErrorIsNotRaised (string handler)
38+
[TestCaseSource (nameof (Get_ErrorIsNotRaised_Data))]
39+
public void ErrorIsNotRaised (string handler, AndroidRuntime runtime)
2140
{
41+
const bool isRelease = false;
42+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
43+
return;
44+
}
45+
2246
string path = Path.Combine (Root, "temp", TestName);
2347
Directory.CreateDirectory (path);
2448
string intermediatePath;
2549
bool shouldSkip = handler.Contains ("Xamarin.Android.Net.AndroidMessageHandler");
2650
bool targetSkipped;
2751
var proj = new XamarinAndroidApplicationProject () {
28-
IsRelease = false,
52+
IsRelease = isRelease,
2953
};
54+
proj.SetRuntime (runtime);
3055
proj.SetProperty ("AndroidHttpClientHandlerType", handler);
3156
using (var b = CreateApkBuilder (path)) {
3257
b.Verbosity = LoggerVerbosity.Detailed;
@@ -56,16 +81,41 @@ public void ErrorIsNotRaised (string handler)
5681
Assert.True (task.Execute (), $"task should have succeeded. {string.Join (";", errors.Select (x => x.Message))}");
5782
}
5883

84+
static IEnumerable<object[]> Get_ErrorIsRaised_Data ()
85+
{
86+
var ret = new List<object[]> ();
87+
88+
foreach (AndroidRuntime runtime in Enum.GetValues (typeof (AndroidRuntime))) {
89+
AddTestData ("Xamarin.Android.Net.AndroidClientHandler", runtime);
90+
}
91+
92+
return ret;
93+
94+
void AddTestData (string handler, AndroidRuntime runtime)
95+
{
96+
ret.Add (new object[] {
97+
handler,
98+
runtime,
99+
});
100+
}
101+
}
102+
59103
[Test]
60-
[TestCase ("Xamarin.Android.Net.AndroidClientHandler")]
61-
public void ErrorIsRaised (string handler)
104+
[TestCaseSource (nameof (Get_ErrorIsRaised_Data))]
105+
public void ErrorIsRaised (string handler, AndroidRuntime runtime)
62106
{
107+
const bool isRelease = false;
108+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
109+
return;
110+
}
111+
63112
var path = Path.Combine (Root, "temp", TestName);
64113
Directory.CreateDirectory (path);
65114
string intermediatePath;
66115
var proj = new XamarinAndroidApplicationProject () {
67-
IsRelease = false,
116+
IsRelease = isRelease,
68117
};
118+
proj.SetRuntime (runtime);
69119
proj.PackageReferences.Add (new Package() { Id = "System.Net.Http", Version = "*" });
70120
using (var b = CreateApkBuilder ()) {
71121
b.ThrowOnBuildFailure = false;

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,17 @@ private void PreserveCustomHttpClientHandler (
167167
string handlerAssembly,
168168
string testProjectName,
169169
string assemblyPath,
170-
TrimMode trimMode)
170+
TrimMode trimMode,
171+
AndroidRuntime runtime)
171172
{
173+
const bool isRelease = true;
174+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
175+
return;
176+
}
172177
testProjectName += trimMode.ToString ();
173178

174179
var class_library = new XamarinAndroidLibraryProject {
175-
IsRelease = true,
180+
IsRelease = isRelease,
176181
ProjectName = "MyClassLibrary",
177182
Sources = {
178183
new BuildItem.Source ("MyCustomHandler.cs") {
@@ -189,20 +194,22 @@ class MyCustomHandler : System.Net.Http.HttpMessageHandler
189194
}
190195
}
191196
};
197+
class_library.SetRuntime (runtime);
192198
using (var libBuilder = CreateDllBuilder ($"{testProjectName}/{class_library.ProjectName}")) {
193199
Assert.IsTrue (libBuilder.Build (class_library), $"Build for {class_library.ProjectName} should have succeeded.");
194200
}
195201

196202
var proj = new XamarinAndroidApplicationProject {
197203
ProjectName = "MyApp",
198-
IsRelease = true,
204+
IsRelease = isRelease,
199205
TrimModeRelease = trimMode,
200206
Sources = {
201207
new BuildItem.Source ("Foo.cs") {
202208
TextContent = () => "public class Foo : Bar { }",
203209
}
204210
}
205211
};
212+
proj.SetRuntime (runtime);
206213
proj.AddReference (class_library);
207214
proj.AddReferences ("System.Net.Http");
208215
string handlerTypeFullName = string.IsNullOrEmpty(handlerAssembly) ? handlerType : handlerType + ", " + handlerAssembly;
@@ -218,19 +225,22 @@ class MyCustomHandler : System.Net.Http.HttpMessageHandler
218225
}
219226

220227
[Test]
221-
public void PreserveCustomHttpClientHandlers ([Values (TrimMode.Partial, TrimMode.Full)] TrimMode trimMode)
228+
public void PreserveCustomHttpClientHandlers ([Values (TrimMode.Partial, TrimMode.Full)] TrimMode trimMode, [Values] AndroidRuntime runtime)
222229
{
223230
PreserveCustomHttpClientHandler ("Xamarin.Android.Net.AndroidMessageHandler", "",
224-
"temp/PreserveAndroidMessageHandler", "android-arm64/linked/Mono.Android.dll", trimMode);
231+
$"temp/PreserveAndroidMessageHandler{trimMode}{runtime}", "android-arm64/linked/Mono.Android.dll", trimMode, runtime);
225232
PreserveCustomHttpClientHandler ("System.Net.Http.SocketsHttpHandler", "System.Net.Http",
226-
"temp/PreserveSocketsHttpHandler", "android-arm64/linked/System.Net.Http.dll", trimMode);
233+
$"temp/PreserveSocketsHttpHandler{trimMode}{runtime}", "android-arm64/linked/System.Net.Http.dll", trimMode, runtime);
227234
PreserveCustomHttpClientHandler ("MyCustomHandler", "MyClassLibrary",
228-
"temp/MyCustomHandler", "android-arm64/linked/MyClassLibrary.dll", trimMode);
235+
$"temp/MyCustomHandler{trimMode}{runtime}", "android-arm64/linked/MyClassLibrary.dll", trimMode, runtime);
229236
}
230237

231238
[Test]
232-
public void WarnAboutAppDomains ([Values (true, false)] bool isRelease)
239+
public void WarnAboutAppDomains ([Values] bool isRelease, [Values] AndroidRuntime runtime)
233240
{
241+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
242+
return;
243+
}
234244
if (isRelease) {
235245
// NOTE: trimmer warnings are hidden by default in .NET 7 rc1
236246
Assert.Ignore("https://github.com/dotnet/linker/issues/2982");
@@ -246,8 +256,10 @@ public void WarnAboutAppDomains ([Values (true, false)] bool isRelease)
246256
}
247257
}
248258
};
259+
lib.SetRuntime (runtime);
249260

250261
var app = new XamarinAndroidApplicationProject { IsRelease = isRelease };
262+
app.SetRuntime (runtime);
251263
app.SetAndroidSupportedAbis ("arm64-v8a");
252264
app.AddReference (lib);
253265
using var libBuilder = CreateDllBuilder (Path.Combine (path, lib.ProjectName));
@@ -366,10 +378,14 @@ public void LinkDescription ([Values (true, false)] bool useAssemblyStore, [Valu
366378
}
367379

368380
[Test]
369-
public void LinkWithNullAttribute ()
381+
public void LinkWithNullAttribute ([Values] AndroidRuntime runtime)
370382
{
383+
const bool isRelease = true;
384+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
385+
return;
386+
}
371387
var proj = new XamarinAndroidApplicationProject {
372-
IsRelease = true,
388+
IsRelease = isRelease,
373389
OtherBuildItems = {
374390
new BuildItem ("Compile", "NullAttribute.cs") { TextContent = () => @"
375391
using System;
@@ -402,6 +418,7 @@ public AttributedButtonStub (Context context) : base (context)
402418
}
403419
};
404420

421+
proj.SetRuntime (runtime);
405422
proj.MainActivity = proj.DefaultMainActivity.Replace ("//${AFTER_ONCREATE}",
406423
$@" var myButton = new AttributedButtonStub (this);
407424
myButton.Text = ""Bug #35710"";
@@ -416,7 +433,7 @@ static IEnumerable<object[]> Get_AndroidAddKeepAlivesData ()
416433
{
417434
var ret = new List<object[]> ();
418435

419-
foreach (AndroidRuntime runtime in new[] { AndroidRuntime.MonoVM, AndroidRuntime.CoreCLR }) {
436+
foreach (AndroidRuntime runtime in Enum.GetValues (typeof (AndroidRuntime))) {
420437
// Debug configuration
421438
AddTestData (isRelease: false, setAndroidAddKeepAlivesTrue: false, setLinkModeNone: false, shouldAddKeepAlives: false, runtime);
422439

@@ -448,6 +465,10 @@ void AddTestData (bool isRelease, bool setAndroidAddKeepAlivesTrue, bool setLink
448465
[TestCaseSource (nameof (Get_AndroidAddKeepAlivesData))]
449466
public void AndroidAddKeepAlives (bool isRelease, bool setAndroidAddKeepAlivesTrue, bool setLinkModeNone, bool shouldAddKeepAlives, AndroidRuntime runtime)
450467
{
468+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
469+
return;
470+
}
471+
451472
if (runtime == AndroidRuntime.CoreCLR && isRelease && !setAndroidAddKeepAlivesTrue && setLinkModeNone && shouldAddKeepAlives) {
452473
// This currently fails with the following exception:
453474
//
@@ -512,7 +533,12 @@ public unsafe bool MyMethod (Android.OS.IBinder windowToken, [global::Android.Ru
512533
var assemblyFile = "UnnamedProject.dll";
513534
if (!isRelease || setLinkModeNone) {
514535
foreach (string abi in proj.GetRuntimeIdentifiersAsAbis ()) {
515-
CheckAssembly (b.Output.GetIntermediaryPath (Path.Combine ("android", "assets", abi, assemblyFile)), projectDir);
536+
string assemblyDir = runtime switch {
537+
AndroidRuntime.NativeAOT => Path.Combine (MonoAndroidHelper.AbiToRid (abi), "linked"),
538+
_ => Path.Combine ("android", "assets", abi)
539+
};
540+
541+
CheckAssembly (b.Output.GetIntermediaryPath (Path.Combine (assemblyDir, assemblyFile)), projectDir);
516542
}
517543
} else {
518544
CheckAssembly (BuildTest.GetLinkedPath (b, true, assemblyFile), projectDir);
@@ -553,9 +579,15 @@ void CheckAssembly (string assemblyPath, string projectDir)
553579
}
554580

555581
[Test]
556-
public void AndroidUseNegotiateAuthentication ([Values (true, false, null)] bool? useNegotiateAuthentication)
582+
public void AndroidUseNegotiateAuthentication ([Values (true, false, null)] bool? useNegotiateAuthentication, [Values] AndroidRuntime runtime)
557583
{
584+
bool isRelease = runtime == AndroidRuntime.NativeAOT;
585+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
586+
return;
587+
}
588+
558589
var proj = new XamarinAndroidApplicationProject { IsRelease = true };
590+
proj.SetRuntime (runtime);
559591
proj.AddReferences ("System.Net.Http");
560592
proj.MainActivity = proj.DefaultMainActivity.Replace (
561593
"base.OnCreate (bundle);",
@@ -585,9 +617,14 @@ public void AndroidUseNegotiateAuthentication ([Values (true, false, null)] bool
585617
}
586618

587619
[Test]
588-
public void PreserveIX509TrustManagerSubclasses ([Values(true, false)] bool hasServerCertificateCustomValidationCallback)
620+
public void PreserveIX509TrustManagerSubclasses ([Values] bool hasServerCertificateCustomValidationCallback, [Values] AndroidRuntime runtime)
589621
{
590-
var proj = new XamarinAndroidApplicationProject { IsRelease = true };
622+
const bool isRelease = true;
623+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
624+
return;
625+
}
626+
var proj = new XamarinAndroidApplicationProject { IsRelease = isRelease };
627+
proj.SetRuntime (runtime);
591628
proj.AddReferences ("System.Net.Http");
592629
proj.MainActivity = proj.DefaultMainActivity.Replace (
593630
"base.OnCreate (bundle);",
@@ -619,15 +656,21 @@ public void PreserveIX509TrustManagerSubclasses ([Values(true, false)] bool hasS
619656
}
620657

621658
[Test]
622-
public void PreserveServices ()
659+
public void PreserveServices ([Values] AndroidRuntime runtime)
623660
{
661+
const bool isRelease = true;
662+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
663+
return;
664+
}
665+
624666
var proj = new XamarinAndroidApplicationProject {
625-
IsRelease = true,
667+
IsRelease = isRelease,
626668
TrimModeRelease = TrimMode.Full,
627669
PackageReferences = {
628670
new Package { Id = "Plugin.Firebase.CloudMessaging", Version = "3.0.0" },
629671
}
630672
};
673+
proj.SetRuntime (runtime);
631674
proj.MainActivity = proj.DefaultMainActivity
632675
.Replace ("//${FIELDS}",
633676
"""
@@ -759,9 +802,15 @@ void Assert64Bit(string rid, bool expected64)
759802
}
760803

761804
[Test]
762-
public void WarnWithReferenceToPreserveAttribute ()
805+
public void WarnWithReferenceToPreserveAttribute ([Values] AndroidRuntime runtime)
763806
{
764-
var proj = new XamarinAndroidApplicationProject { IsRelease = true };
807+
const bool isRelease = true;
808+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
809+
return;
810+
}
811+
812+
var proj = new XamarinAndroidApplicationProject { IsRelease = isRelease };
813+
proj.SetRuntime (runtime);
765814
proj.AddReferences ("System.Net.Http");
766815
proj.MainActivity = proj.DefaultMainActivity.Replace (
767816
"protected override void OnCreate",

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,18 @@ public void CreateResourceDirectory (string path)
299299
File.WriteAllText (Path.Combine (Root, path, "lp", "__res_name_case_map.txt"), "menu/Options.xml;menu/options.xml");
300300
}
301301

302-
void BuildLibraryWithResources (string path)
302+
void BuildLibraryWithResources (string path, AndroidRuntime runtime)
303303
{
304+
bool isRelease = runtime == AndroidRuntime.NativeAOT;
305+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
306+
return;
307+
}
308+
304309
var library = new XamarinAndroidLibraryProject () {
310+
IsRelease = isRelease,
305311
ProjectName = "Library",
306312
};
313+
library.SetRuntime (runtime);
307314

308315
var libraryStrings = library.AndroidResources.FirstOrDefault (r => r.Include () == @"Resources\values\Strings.xml");
309316

@@ -425,8 +432,15 @@ public void GenerateDesignerFileWithÜmläüts ()
425432
}
426433

427434
[Test]
428-
public void GenerateDesignerFileFromRtxt ([Values (false, true)] bool withLibraryReference)
435+
public void GenerateDesignerFileFromRtxt ([Values] bool withLibraryReference, [Values] AndroidRuntime runtime)
429436
{
437+
// TODO: fix NativeAOT, it currently fails with:
438+
//
439+
// bin/TestDebug/temp/GenerateDesignerFileFromRtxtTrueNativeAOT Some Space/Resource.designer.cs and bin/TestDebug/Expected/GenerateDesignerFileWithLibraryReferenceExpected.cs do not match.
440+
if (runtime == AndroidRuntime.NativeAOT) {
441+
Assert.Ignore ("NativeAOT currently doesn't work with this test.");
442+
}
443+
430444
var path = Path.Combine ("temp", TestName + " Some Space");
431445
CreateResourceDirectory (path);
432446
var mapTask = CreateCaseMapTask (path);
@@ -436,7 +450,7 @@ public void GenerateDesignerFileFromRtxt ([Values (false, true)] bool withLibrar
436450
File.WriteAllText (task.RTxtFile, Rtxt);
437451
if (withLibraryReference) {
438452
var libraryPath = Path.Combine (path, "Library");
439-
BuildLibraryWithResources (libraryPath);
453+
BuildLibraryWithResources (libraryPath, runtime);
440454
task.References = new TaskItem [] {
441455
new TaskItem (Path.Combine (Root, libraryPath, "bin", "Debug", "Library.dll"))
442456
};

0 commit comments

Comments
 (0)