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