From 0cee4aaff9cde26bfb1c09b3266ff392e0ad2db3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 08:27:01 -0700 Subject: [PATCH] [release/7.0] Fix loading app-local ICU (#77118) * Fix loading app-local ICU * Restrict the platforms to run the tests on * Adjust the test supported platforms * Test Platforms * Fix the test OS filtering * address the feedback * More feedback addressing * Fix the test Co-authored-by: Tarek Mahmoud Sayed --- .../System/PlatformDetection.Unix.cs | 2 +- .../IcuAppLocal/IcuAppLocal.Tests.csproj | 25 +++++++++ .../tests/IcuAppLocal/IcuAppLocal.cs | 51 +++++++++++++++++++ .../System.Globalization.Native/pal_icushim.c | 1 + 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.Tests.csproj create mode 100644 src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.cs diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs index 33c4f5f930423..256a3075b4129 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs @@ -14,7 +14,7 @@ public static partial class PlatformDetection // do it in a way that failures don't cascade. // - private static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + public static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); public static bool IsOpenSUSE => IsDistroAndVersion("opensuse"); public static bool IsUbuntu => IsDistroAndVersion("ubuntu"); public static bool IsDebian => IsDistroAndVersion("debian"); diff --git a/src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.Tests.csproj b/src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.Tests.csproj new file mode 100644 index 0000000000000..3b9800574da64 --- /dev/null +++ b/src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.Tests.csproj @@ -0,0 +1,25 @@ + + + $(NetCoreAppCurrent) + true + true + + + + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.cs b/src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.cs new file mode 100644 index 0000000000000..aa0a0df938c40 --- /dev/null +++ b/src/libraries/System.Globalization/tests/IcuAppLocal/IcuAppLocal.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.DotNet.RemoteExecutor; +using System.Diagnostics; +using System.Reflection; +using Xunit; + +namespace System.Globalization.Tests +{ + public class IcuAppLocalTests + { + private static bool SupportsIcuPackageDownload => RemoteExecutor.IsSupported && + ((PlatformDetection.IsWindows && !PlatformDetection.IsArmProcess) || + (PlatformDetection.IsLinux && (PlatformDetection.IsX64Process || PlatformDetection.IsArm64Process) && + !PlatformDetection.IsAlpine && !PlatformDetection.IsLinuxBionic)); + + + [ConditionalFact(nameof(SupportsIcuPackageDownload))] + public void TestIcuAppLocal() + { + // We define this switch dynamically during the runtime using RemoteExecutor. + // The reason is, if we enable ICU app-local here, this test will compile and run + // on all supported OSs even the ICU NuGet package not have native bits support such OSs. + // Note, it doesn't matter if we have test case conditioned to not run on such OSs, because + // the test has to start running first before filtering the test cases and the globalization + // code will run and fail fast at that time. + + ProcessStartInfo psi = new ProcessStartInfo(); + psi.Environment.Add("DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU", "68.2.0.9"); + + RemoteExecutor.Invoke(() => + { + // Ensure initializing globalization code before checking the ICU version. + CultureInfo ci = CultureInfo.GetCultureInfo("en-US"); + + Type? interopGlobalization = Type.GetType("Interop+Globalization, System.Private.CoreLib"); + Assert.NotNull(interopGlobalization); + + MethodInfo? methodInfo = interopGlobalization.GetMethod("GetICUVersion", BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull(methodInfo); + + // Assert the ICU version 0x44020009 is 68.2.0.9 + Assert.Equal(0x44020009, (int)methodInfo.Invoke(null, null)); + + // Now call globalization API to ensure the binding working without any problem. + Assert.Equal(-1, ci.CompareInfo.Compare("sample\u0000", "Sample\u0000", CompareOptions.IgnoreSymbols)); + }, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); + } + } +} diff --git a/src/native/libs/System.Globalization.Native/pal_icushim.c b/src/native/libs/System.Globalization.Native/pal_icushim.c index d23499c80b1ee..d6ae58dd1b35b 100644 --- a/src/native/libs/System.Globalization.Native/pal_icushim.c +++ b/src/native/libs/System.Globalization.Native/pal_icushim.c @@ -539,6 +539,7 @@ void GlobalizationNative_InitICUFunctions(void* icuuc, void* icuin, const char* ValidateICUDataCanLoad(); InitializeVariableMaxAndTopPointers(symbolVersion); + InitializeUColClonePointers(symbolVersion); } #undef PER_FUNCTION_BLOCK