diff --git a/eng/testing/tests.android.targets b/eng/testing/tests.android.targets
index 5bcd9d4bc63d2e..1cc807a1e6c96d 100644
--- a/eng/testing/tests.android.targets
+++ b/eng/testing/tests.android.targets
@@ -12,10 +12,18 @@
AndroidBuild
-
+
$(DefineConstants);SINGLE_FILE_TEST_RUNNER
+
+
+
+
+ true
+ <_UseNativeLibPrefix>true
+
+
@@ -25,7 +33,8 @@
- AndroidTestRunner.dll
+ AndroidTestRunner.dll
+ lib$(TargetName).so
$(PublishDir)
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index 685c3b98aff181..1c0ed5772ab653 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -1,7 +1,7 @@
- $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
+ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
$(AppBundleRoot)tests\$(AssemblyName)
$(AppBundleRoot)runonly\$(AssemblyName)
$([MSBuild]::NormalizeDirectory('$(PublishDir)', 'AppBundle'))
diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets
index 05b2c15a018946..709467b7aad17d 100644
--- a/eng/testing/tests.singlefile.targets
+++ b/eng/testing/tests.singlefile.targets
@@ -32,7 +32,7 @@
true
-
+
$(DefineConstants);SINGLE_FILE_TEST_RUNNER
diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
index 24617d110df62c..b07b0b30821e17 100644
--- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
+++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/CompositeMLDsa/CompositeMLDsaFactoryTests.cs
@@ -4,6 +4,7 @@
using System.Formats.Asn1;
using System.Linq;
using Microsoft.DotNet.RemoteExecutor;
+using Microsoft.DotNet.XUnitExtensions;
using Xunit;
using Xunit.Sdk;
@@ -60,6 +61,7 @@ public static void ImportBadPrivateKey_ShortTradKey(CompositeMLDsaAlgorithm algo
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPrivateKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
@@ -311,6 +313,7 @@ public static void ImportBadPublicKey_ShortTradKey(CompositeMLDsaAlgorithm algor
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
@@ -321,6 +324,7 @@ public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.Compos
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedECDsaAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPublicKey_ECDsa_Uncompressed(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
@@ -419,6 +423,7 @@ public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorith
}
[Theory]
+ [SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
index 5e92d4c17aafcb..5d11e46a12f0c1 100644
--- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
+++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
@@ -288,7 +288,7 @@ public static bool IsMetadataTokenSupported
public static bool IsDomainJoinedMachine => !Environment.MachineName.Equals(Environment.UserDomainName, StringComparison.OrdinalIgnoreCase);
public static bool IsNotDomainJoinedMachine => !IsDomainJoinedMachine;
- public static bool IsOpenSslSupported => IsLinux || IsFreeBSD || Isillumos || IsSolaris;
+ public static bool IsOpenSslSupported => (IsLinux && !IsAndroid) || IsFreeBSD || Isillumos || IsSolaris;
public static bool OpenSslNotPresentOnSystem => !OpenSslPresentOnSystem;
public static bool UsesAppleCrypto => IsOSX || IsMacCatalyst || IsiOS || IstvOS;
diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs
index c12eddf33ab180..17e0574ceee9b5 100644
--- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs
+++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs
@@ -52,8 +52,8 @@ internal static partial class Interop
{
internal static partial class AndroidCrypto
{
- [DllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyCreateByOid")]
- internal static extern System.IntPtr EcKeyCreateByOid(string oid);
+ [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyCreateByOid", StringMarshalling = StringMarshalling.Utf8)]
+ internal static partial System.IntPtr EcKeyCreateByOid(string oid);
[DllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyDestroy")]
internal static extern void EcKeyDestroy(System.IntPtr r);
diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs
index 3a54623527d8d6..48a2d1ba096093 100644
--- a/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/Rfc2898OneShotTests.cs
@@ -285,7 +285,7 @@ public static void Pbkdf2_Rfc6070(string password, string salt, int iterations,
Assert.Equal(expected, actual);
}
- [Theory]
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsOpenSslSupported))]
[MemberData(nameof(Pbkdf2_OpenSsl_Vectors))]
public static void Pbkdf2_OpenSsl(string hashAlgorithm, string password, string salt, int iterations, string expectedHex)
{
diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs
index b9d1c6beb90efb..2a5a2bcd7ba161 100644
--- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs
+++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CrlBuilderTests.cs
@@ -297,6 +297,7 @@ public static void BuildWithEmptyHashAlgorithm(CertKind certKind)
[Theory]
[MemberData(nameof(NoHashAlgorithmCertKinds))]
+ [SkipOnPlatform(TestPlatforms.Android, "No algorithms are supported")]
public static void BuildPqcWithHashAlgorithm(CertKind certKind)
{
BuildCertificateAndRun(
diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs
index 7015c10fd621f3..f13d7034307e6d 100644
--- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs
+++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestFiles.cs
@@ -8,7 +8,8 @@ namespace System.Security.Cryptography.X509Certificates.Tests
{
internal static class TestFiles
{
- internal const string TestDataFolder = "TestData";
+ internal static readonly string? TestDataRoot = Environment.GetEnvironmentVariable("ASSETS_DIR") ?? AppContext.BaseDirectory;
+ internal static readonly string TestDataFolder = Path.Combine(TestDataRoot, "TestData");
// Certs
internal static readonly string MsCertificateDerFile = Path.Combine(TestDataFolder, "MS.cer");
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 0438f60445292c..53208f5c2ec814 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -608,6 +608,9 @@
+
+
+
diff --git a/src/mono/msbuild/android/build/AndroidBuild.props b/src/mono/msbuild/android/build/AndroidBuild.props
index 96513e0442f990..6abfd8adfba125 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.props
+++ b/src/mono/msbuild/android/build/AndroidBuild.props
@@ -23,6 +23,7 @@
$(ANDROID_NDK_ROOT)\toolchains\llvm\prebuilt\$(NdkToolchainPrebuiltOS)\bin\clang
Publish
+
$(_ReadRuntimeComponentsManifestTargetName);
_InitializeCommonProperties;
@@ -42,9 +43,9 @@
_AfterAndroidBuild
- $(AndroidBuildDependsOn);
- CopyNativeBinary;
- _CopyAotSymbols
+ CopyNativeBinary;
+ _CopyAotSymbols;
+ $(AndroidBuildDependsOn)
diff --git a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
index c384a85066804b..c74e585836a573 100644
--- a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
+++ b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
@@ -91,6 +91,7 @@ public static void initializeRuntime(String entryPointLibName, Context context)
// set environment variables
setEnv("HOME", filesDir);
+ setEnv("ASSETS_DIR", filesDir);
setEnv("TMPDIR", cacheDir);
setEnv("TEST_RESULTS_DIR", testResultsDir);
diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
index 8678a1f43cfea5..8e7ca31bf6cdfe 100644
--- a/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
+++ b/src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
@@ -1,14 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Runtime.InteropServices;
-using System.Runtime;
using System;
+using System.IO;
+using System.Linq;
+using System.Runtime;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using JObject = nint;
using JString = nint;
using JObjectArray = nint;
+using JSize = int;
namespace MonoDroid.NativeAOT;
@@ -21,14 +24,18 @@ public static void SetEnv(JNIEnv* env, JObject thiz, JString j_key, JString j_va
{
string? key = env->GetStringUTFChars(j_key);
string? value = env->GetStringUTFChars(j_value);
+ Console.WriteLine($"SetEnv: {key ?? "null"} = {value ?? "null"}");
if (key != null && value != null)
+ {
Environment.SetEnvironmentVariable(key, value);
+ }
}
// int Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_dir, jstring j_entryPointLibName, long current_local_time);
[UnmanagedCallersOnly(EntryPoint = "Java_net_dot_MonoRunner_initRuntime", CallConvs = [typeof(CallConvCdecl)])]
public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JString j_entryPointLibName, long current_local_time)
{
+ Console.WriteLine("Initializing Android crypto native library");
// The NativeAOT runtime does not need to be initialized, but the crypto library does.
JavaVM* javaVM = env->GetJavaVM();
AndroidCryptoNative_InitLibraryOnLoad(javaVM, null);
@@ -42,7 +49,26 @@ public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JS
[UnmanagedCallersOnly(EntryPoint = "Java_net_dot_MonoRunner_execEntryPoint", CallConvs = [typeof(CallConvCdecl)])]
public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPointLibName, JObjectArray j_args)
{
- return Program.Main();
+ int argc = env->GetArrayLength(j_args);
+ string[] args = new string[argc];
+ for (int i = 0; i < argc; i++)
+ {
+ JObject j_arg = env->GetObjectArrayElement(j_args, i);
+ args[i] = env->GetStringUTFChars((JString)j_arg);
+ }
+
+#if SINGLE_FILE_TEST_RUNNER
+ string excludesFile = Path.Combine(Environment.GetEnvironmentVariable("HOME"), "xunit-excludes.txt");
+ if (File.Exists(excludesFile))
+ {
+ args = args.Concat(File.ReadAllLines(excludesFile).SelectMany(trait => new string[]{"-notrait", trait})).ToArray();
+ }
+ // SingleFile unit tests
+ return SingleFileTestRunner.Main(args);
+#else
+ // Functional tests
+ return Program.Main(args);
+#endif
}
// void Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz);
@@ -88,6 +114,22 @@ internal unsafe struct JNIEnv
}
}
+ public JSize GetArrayLength(JObjectArray array)
+ {
+ fixed (JNIEnv* thisptr = &this)
+ {
+ return NativeInterface->GetArrayLength(thisptr, array);
+ }
+ }
+
+ public JObject GetObjectArrayElement(JObjectArray array, JSize index)
+ {
+ fixed (JNIEnv* thisptr = &this)
+ {
+ return NativeInterface->GetObjectArrayElement(thisptr, array, index);
+ }
+ }
+
[StructLayout(LayoutKind.Sequential)]
unsafe struct JNINativeInterface
{
@@ -312,11 +354,10 @@ unsafe struct JNINativeInterface
delegate* unmanaged[Cdecl] GetStringUTFLength;
public delegate* unmanaged[Cdecl] GetStringUTFChars;
public delegate* unmanaged[Cdecl] ReleaseStringUTFChars;
-
- void* GetArrayLength;
+ public delegate* unmanaged[Cdecl] GetArrayLength;
void* NewObjectArray;
- void* GetObjectArrayElement;
+ public delegate* unmanaged[Cdecl] GetObjectArrayElement;
void* SetObjectArrayElement;
void* NewBooleanArray;
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs
index 81bf00c64bc256..b685e385fd0b60 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/JIT/Program.cs
@@ -5,7 +5,7 @@
public class Program
{
- public static int Main()
+ public static int Main(string[] args)
{
Console.WriteLine("Hello, Android!"); // logcat
return 42;
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
index 15886021dd3d62..54f275fe9a3565 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Android.Device_Emulator.NativeAOT.Test.csproj
@@ -4,19 +4,12 @@
Library
true
$(NetCoreAppCurrent)
- lib$(MSBuildProjectName)
- $(TargetName).so
42
true
true
true
-
-
-
-
-
diff --git a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
index f8430023829079..136a417dddf7f0 100644
--- a/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
+++ b/src/tests/FunctionalTests/Android/Device_Emulator/NativeAOT/Program.cs
@@ -5,7 +5,7 @@
public class Program
{
- public static int Main()
+ public static int Main(string[] args)
{
string message = "Hello, Android!";
Console.WriteLine(message); // logcat