Skip to content

Commit b58d460

Browse files
authored
Enable more tests to run on all 3 runtimes, part 12 (#10632)
This pull request extends runtime testing capabilities by enabling more tests to run across all three Android runtimes (MonoVM, CoreCLR, and NativeAOT). The changes are part 12 of a larger effort to ensure comprehensive runtime test coverage. **Key Changes:** - Refactored test parameters to use `[Values] AndroidRuntime` instead of hardcoded runtime values, enabling tests to run with all available runtimes - Converted static test case arrays to dynamic test case generators that iterate through runtime enumerations - Added NativeAOT-specific handling for file paths and test assertions, with appropriate ignore conditions for currently unsupported scenarios
1 parent fbd56c1 commit b58d460

File tree

4 files changed

+272
-111
lines changed

4 files changed

+272
-111
lines changed

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,12 +765,15 @@ static void AssertApplicationConfigIsIdentical (ApplicationConfig_MonoVM firstAp
765765
Assert.AreEqual (firstAppConfig.android_package_name, secondAppConfig.android_package_name, $"Field 'android_package_name' has different value in environment file '{secondEnvFile}' than in environment file '{firstEnvFile}'");
766766
}
767767

768-
public static List<EnvironmentFile> GatherEnvironmentFiles (string outputDirectoryRoot, string supportedAbis, bool required)
768+
// TODO: remove the default from the `runtime` parameter once all tests are updated
769+
public static List<EnvironmentFile> GatherEnvironmentFiles (string outputDirectoryRoot, string supportedAbis, bool required, AndroidRuntime runtime = AndroidRuntime.CoreCLR)
769770
{
770771
var environmentFiles = new List <EnvironmentFile> ();
772+
bool isNativeAOT = runtime == AndroidRuntime.NativeAOT;
771773

772774
foreach (string abi in supportedAbis.Split (';')) {
773-
string envFilePath = Path.Combine (outputDirectoryRoot, "android", $"environment.{abi}.ll");
775+
string prefixDir = isNativeAOT ? MonoAndroidHelper.AbiToRid (abi) : String.Empty;
776+
string envFilePath = Path.Combine (outputDirectoryRoot, prefixDir, "android", $"environment.{abi}.ll");
774777

775778
Assert.IsTrue (File.Exists (envFilePath), $"Environment file {envFilePath} does not exist");
776779
environmentFiles.Add (new EnvironmentFile (envFilePath, abi));

tests/MSBuildDeviceIntegration/Tests/BundleToolNoAbiSplitTests.cs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
namespace Xamarin.Android.Build.Tests
1111
{
12-
[TestFixture (AndroidRuntime.MonoVM)]
13-
[TestFixture (AndroidRuntime.CoreCLR)]
12+
[TestFixtureSource (nameof (Get_ConstructorParameters))]
1413
[Category ("UsesDevice")]
1514
public class BundleToolNoAbiSplitTests : DeviceTest
1615
{
@@ -37,6 +36,11 @@ public class BundleToolNoAbiSplitTests : DeviceTest
3736
}";
3837
readonly AndroidRuntime runtime;
3938

39+
static Array Get_ConstructorParameters ()
40+
{
41+
return Enum.GetValues (typeof (AndroidRuntime));
42+
}
43+
4044
public BundleToolNoAbiSplitTests (AndroidRuntime runtime)
4145
{
4246
this.runtime = runtime;
@@ -127,19 +131,22 @@ public void OneTimeSetUp ()
127131
List<EnvironmentHelper.EnvironmentFile> envFiles = EnvironmentHelper.GatherEnvironmentFiles (
128132
objPath,
129133
String.Join (";", Abis),
130-
true
134+
true,
135+
runtime
131136
);
132137

133-
EnvironmentHelper.IApplicationConfig app_config = EnvironmentHelper.ReadApplicationConfig (envFiles, runtime);
138+
if (runtime != AndroidRuntime.NativeAOT) { // NAOT doesn't have ApplicationConfig
139+
EnvironmentHelper.IApplicationConfig app_config = EnvironmentHelper.ReadApplicationConfig (envFiles, runtime);
134140

135-
Assert.That (app_config, Is.Not.Null, "application_config must be present in the environment files");
141+
Assert.That (app_config, Is.Not.Null, "application_config must be present in the environment files");
136142

137-
bool ignoreSplitConfigs = runtime switch {
138-
AndroidRuntime.MonoVM => ((EnvironmentHelper.ApplicationConfig_MonoVM)app_config).ignore_split_configs,
139-
AndroidRuntime.CoreCLR => ((EnvironmentHelper.ApplicationConfig_CoreCLR)app_config).ignore_split_configs,
140-
_ => throw new NotSupportedException ($"Unsupported runtime '{runtime}'")
141-
};
142-
Assert.AreEqual (ignoreSplitConfigs, true, $"App config should indicate that split configs must be ignored");
143+
bool ignoreSplitConfigs = runtime switch {
144+
AndroidRuntime.MonoVM => ((EnvironmentHelper.ApplicationConfig_MonoVM)app_config).ignore_split_configs,
145+
AndroidRuntime.CoreCLR => ((EnvironmentHelper.ApplicationConfig_CoreCLR)app_config).ignore_split_configs,
146+
_ => throw new NotSupportedException ($"Unsupported runtime '{runtime}'")
147+
};
148+
Assert.AreEqual (ignoreSplitConfigs, true, $"App config should indicate that split configs must be ignored");
149+
}
143150
}
144151

145152
[TearDown]
@@ -161,6 +168,18 @@ public void OneTimeTearDown ()
161168
[Test]
162169
public void InstallAndRun ()
163170
{
171+
// TODO: fix under NativeAOT. Currently fails with an exception at run time:
172+
//
173+
// FATAL UNHANDLED EXCEPTION: System.InvalidCastException: Unable to convert instance of type 'AndroidX.AppCompat.Widget.AppCompatImageButton' to type 'AndroidX.AppCompat.Widget.Toolbar'.
174+
// at Java.Interop.JavaObjectExtensions._JavaCast[TResult](IJavaObject) + 0x165
175+
// at Android.Runtime.Extensions.JavaCast[TResult](IJavaObject) + 0x10
176+
// at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnCreate(Bundle, ActivationFlags) + 0x601
177+
// at UnnamedProject.MainActivity.OnCreate(Bundle savedInstanceState) + 0x3c
178+
// at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) + 0x72
179+
//
180+
if (runtime == AndroidRuntime.NativeAOT) {
181+
Assert.Ignore ("NativeAOT crashes with an InvalidCastException exception");
182+
}
164183
Assert.IsTrue (appBuilder.Install (app), "Install should have succeeded.");
165184
RunProjectAndAssert (app, appBuilder);
166185
Assert.True (

tests/MSBuildDeviceIntegration/Tests/BundleToolTests.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ static IEnumerable<object[]> Get_FixtureArgs ()
4848
new object[] { false },
4949
new object[] { true },
5050
};
51-
var runtimes = new [] { AndroidRuntime.MonoVM, AndroidRuntime.CoreCLR };
5251
var ret = new List<object[]> ();
5352

5453
foreach (object[] args in fixtureArgs) {
55-
foreach (AndroidRuntime runtime in runtimes) {
54+
foreach (AndroidRuntime runtime in Enum.GetValues (typeof (AndroidRuntime))) {
5655
ret.Add (new object[] {
5756
args[0],
5857
runtime,
@@ -72,10 +71,15 @@ public BundleToolTests (bool usesAssemblyBlobs, AndroidRuntime runtime)
7271
[OneTimeSetUp]
7372
public void OneTimeSetUp ()
7473
{
74+
const bool isRelease = true;
75+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
76+
return;
77+
}
78+
7579
var path = Path.Combine ("temp", TestName);
7680
lib = new XamarinAndroidLibraryProject {
7781
ProjectName = "Localization",
78-
IsRelease = true,
82+
IsRelease = isRelease,
7983
OtherBuildItems = {
8084
new BuildItem ("EmbeddedResource", "Foo.resx") {
8185
TextContent = () => InlineData.ResxWithContents ("<data name=\"CancelButton\"><value>Cancel</value></data>")
@@ -91,7 +95,7 @@ public void OneTimeSetUp ()
9195

9296
var bytes = new byte [1024];
9397
app = new XamarinFormsMapsApplicationProject {
94-
IsRelease = true,
98+
IsRelease = isRelease,
9599
AotAssemblies = false, // Release defaults to Profiled AOT for .NET 6
96100
PackageName = "com.xamarin.bundletooltests",
97101
};
@@ -186,6 +190,11 @@ public void BaseZip ()
186190
expectedFiles.Add ("root/play-services-tasks.properties");
187191

188192
foreach (var abi in Abis) {
193+
if (runtime == AndroidRuntime.NativeAOT) {
194+
expectedFiles.Add ($"lib/{abi}/libUnnamedProject.so");
195+
continue;
196+
}
197+
189198
// All assemblies are in per-abi directories now
190199
if (usesAssemblyBlobs) {
191200
expectedFiles.Add ($"{blobEntryPrefix}{abi}/lib_Java.Interop.dll.so");
@@ -250,6 +259,11 @@ public void AppBundle ()
250259
expectedFiles.Add ("base/root/play-services-tasks.properties");
251260

252261
foreach (var abi in Abis) {
262+
if (runtime == AndroidRuntime.NativeAOT) {
263+
expectedFiles.Add ($"base/lib/{abi}/libUnnamedProject.so");
264+
continue;
265+
}
266+
253267
// All assemblies are in per-abi directories now
254268
if (usesAssemblyBlobs) {
255269
expectedFiles.Add ($"{blobEntryPrefix}{abi}/lib_Java.Interop.dll.so");

0 commit comments

Comments
 (0)