-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Expand test coverage for native AOT on android #121217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Expand native AOT smoke tests to all libraries tests - Add job for runtime smoke tests using native AOT on emulator
Move NDK compiler logic to a shared props file and import it in test and build projects to unify Android NativeAOT and Mono builds.
- Set ASSETS_DIR for crypto tests (using same pattern as existing crypto test) - Set AppContext.BaseDirectory We should probably change crypto tests to use just AppContext.BaseDirectory.
- Use ReferenceXUnitWrapperGenerator != false to define SINGLE_FILE_TEST_RUNNER (android & singlefile targets) instead of IsFunctionalTest - Condition SingleFileTestRunner compile and TrimmerRootAssembly (TestUtilities) on wrapper/generator and SkipTestUtilitiesReference - Add Android NativeAOT publish/trim settings and set NativeLib/CustomNativeMain for android nativeaot - Make DisableImplicitFrameworkReferences respect preexisting value and add explicit DisableImplicitFrameworkReferences=false in nativeaot tests dir - Import testing\tests.targets when TargetsAndroid is true - Update many NativeAOT smoke tests Main signatures to public static int Main(string[] args) to match runner invocation
- Ensure they have Main entry point - Tighten MSBuild conditions: - Only set NativeLib/CustomNativeMain for Android when OutputType == Exe - Only import testing/tests.targets for Android when using MicrosoftNETSdk and building executables - Make TestNativeAOT/UseNativeAOTRuntime defaults apply when TestBuildMode == nativeaot and only include monodroid-nativeaot.cs for executable/XUnit-wrapper cases
This reverts commit 4ed06ec.
- Avoid importing logic for SharedLibrary - Fix library filename - Set HasMergedInTests to ensure projects build
This reverts commit 37b7b4e.
This import is now covered by the IsMergedTestRunnerAssembly property. Fixes a warning about a double import. Fixes issue where mono runtime tests are getting incorrect assembly name due to this undesired import.
src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs
Outdated
Show resolved
Hide resolved
src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs
Outdated
Show resolved
Hide resolved
.../Microsoft.Extensions.Hosting/tests/UnitTests/Microsoft.Extensions.Hosting.Unit.Tests.csproj
Outdated
Show resolved
Hide resolved
| class Program | ||
| { | ||
| [Method] | ||
| static int Main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look sustainable. src\tests\nativeaot is not different from the rest of src\tests. We would have to do these changes to all of src\tests to ship Android.
I assume this is needed because monodroid-nativeaot.cs needs to call main?
Can we make this work with the CustomMain approach? See the src\tests\nativeaot\CustomMain test - in that test we start in native code in CustomMainWithStubExeNative.cpp and call a magic __managed__Main symbol to reach the managed main.
If we let the compiler generate __managed__Main for these, monodroid-nativeaot.cs could just do:
[DllImport("*" /* Magic name that hard-binds the symbol at linker time*/, EntryPoint="__managed__Main")]
static extern int ManagedMain(int argc, void** argv);
And then p/invoke that (yep, it's weird, we're in managed code, we do a p/invoke transition, and the first thing managed_main will do is to transition back to managed; should be fine; the important part is that this gives us a very stable symbol name and signature).
This should match what iOS testing is doing: #87260, the only difference is that iOS testing calls managed__Main from native code and we would call it from managed code.
The trick at the project level should be:
OutputType = ExeNativeLib = Shared(orStaticwould work too, but I think this is using Shared right now)CustomNativeMain= true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use this approach for the runtime tests, thanks!
I already had to set CustomNativeMain to get around an error when using OutputType=Exe with NativeLib=Shared, and had it on my list to check if that would cause an unnecessary export. Now I know!
I was wondering how dotnet/android avoids the error - apparently they override OutputType so that it's always Library.
- Use ActiveIssue - Re-enable tests that are passing with AppContext.BaseDirectory fix - Disable tests failing after merge - Update issue link for System.Diagnostics.Debug.Tests
20fbe86 to
d08f20b
Compare
| internal static class TestFiles | ||
| { | ||
| internal const string TestDataFolder = "TestData"; | ||
| internal static readonly string? TestDataRoot = Environment.GetEnvironmentVariable("ASSETS_DIR") ?? AppContext.BaseDirectory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need an adjustment with this in place?
runtime/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
Lines 43 to 45 in d08f20b
| var filesDir = env->GetStringUTFChars(j_files_dir) ?? string.Empty; | |
| AppContext.SetData("APP_CONTEXT_BASE_DIRECTORY", filesDir); | |
| Environment.CurrentDirectory = filesDir; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, cleaned this up. I'm planning to clean up other uses of the TEST_ASSETS env var in a separate PR.
src/tests/nativeaot/SmokeTests/HardwareIntrinsics/Directory.Build.props
Outdated
Show resolved
Hide resolved
src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.csproj
Outdated
Show resolved
Hide resolved
src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs
Show resolved
Hide resolved
- Clean up whitespace diffs - Clean up TEST_ASSETS reference - ifdef out test logic that fails on Android - Work around failure by not using libc++
|
/azp run runtime-android |
|
/azp run runtime-androidemulator |
|
Azure Pipelines successfully started running 1 pipeline(s). |
1 similar comment
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for running NativeAOT tests on Android by implementing the necessary infrastructure changes. The changes enable Android NativeAOT tests to build, package as APKs, and run on Android devices/emulators through Helix.
Key Changes
- Adds Android-specific build configuration for NativeAOT tests
- Implements custom entry point handling for NativeAOT on Android via
monodroid-nativeaot.cstemplate - Configures CI/CD pipelines to build and run NativeAOT tests on Android
- Excludes several tests that are incompatible with Android NativeAOT
Reviewed Changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/tests/nativeaot/Directory.Build.props | Adds Android-specific build properties including library import generator settings and test runner configuration |
| src/tests/Directory.Build.props | Enables aggressive trimming for Android NativeAOT, similar to iOS/tvOS |
| src/tests/Directory.Build.targets | Adds logic to skip OutputType inference and handle DisableImplicitFrameworkReferences for Android NativeAOT |
| src/tests/build.proj | Imports Android NDK compiler properties and adds RuntimeFlavor resolution for Android builds |
| src/tests/Common/mergedrunner*.targets | Adds ExpectedExitCode file generation and conditions for mobile targets |
| src/tests/Common/helixpublishwitharcade.proj | Reads ExpectedExitCode from file for Android test payloads |
| src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs | Implements entry point execution via __managed__Main for Android NativeAOT tests |
| eng/testing/Android/AndroidNdkCompiler.props | New file that centralizes Android NDK compiler/linker path configuration |
| src/mono/msbuild/android/build/AndroidBuild.props | Imports centralized AndroidNdkCompiler.props instead of defining CppCompilerAndLinker locally |
| eng/testing/tests.*.targets | Updates conditions to use ReferenceXUnitWrapperGenerator and adds NativeAOT-specific properties for Android |
| eng/pipelines/extra-platforms/*.yml | Adds new Android NativeAOT CI jobs and removes /p:RunSmokeTestsOnly=true |
| eng/pipelines/common/platform-matrix.yml | Parameterizes runtimeFlavor for Android platforms |
| src/tests/nativeaot/SmokeTests/*/?.csproj | Marks several smoke tests as unsupported on Android with explanatory comments |
| src/tests/issues.targets | Excludes nativeaot/SmokeTests/UnitTests from Android NativeAOT |
| src/libraries/tests.proj | Excludes multiple library test projects that fail on Android NativeAOT |
| src/libraries//tests/.cs | Adds ActiveIssue attributes for tests that fail on Android NativeAOT |
| src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs | Removes trailing whitespace |
Fixes #120715