diff --git a/eng/pipelines/libraries/enterprise/linux.yml b/eng/pipelines/libraries/enterprise/linux.yml index 904dc4c87c73c..f395c9814308f 100644 --- a/eng/pipelines/libraries/enterprise/linux.yml +++ b/eng/pipelines/libraries/enterprise/linux.yml @@ -18,10 +18,6 @@ pr: - src/libraries/System.Net.Http/* - src/libraries/System.Net.Security/* -pool: - name: NetCore1ESPool-Svc-Public - demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open - variables: - template: ../variables.yml - name: enterpriseTestsSetup @@ -31,45 +27,54 @@ variables: - name: containerLibrariesRoot value: /repo/src/libraries -steps: -- bash: | - cd $(enterpriseTestsSetup) - docker-compose build - displayName: Build test machine images - env: - DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) +jobs: +- job: EnterpriseLinuxTests + timeoutInMinutes: 120 + pool: + name: NetCore1ESPool-Svc-Public + demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open + steps: + - bash: | + cd $(enterpriseTestsSetup) + docker-compose build + displayName: Build test machine images + env: + DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) -- bash: | - cd $(enterpriseTestsSetup) - docker-compose up -d - displayName: Start test network and machines - env: - DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) + - bash: | + cd $(enterpriseTestsSetup) + docker-compose up -d + displayName: Start test network and machines + env: + DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) -- bash: | - docker exec linuxclient bash /setup/test-webserver.sh - displayName: Test linuxclient connection to web server + - bash: | + docker exec linuxclient bash /setup/test-webserver.sh + displayName: Test linuxclient connection to web server -- bash: | - docker exec linuxclient bash -c '/repo/build.sh -subset clr+libs -runtimeconfiguration release -ci /p:NoPgoOptimize=true' - displayName: Build product sources + - bash: | + docker exec linuxclient bash -c '/repo/build.sh -subset clr+libs -runtimeconfiguration release -ci /p:NoPgoOptimize=true' + docker exec linuxclient bash -c '/repo/dotnet.sh build $(containerLibrariesRoot)/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj' + docker exec linuxclient bash -c '/repo/dotnet.sh build $(containerLibrariesRoot)/System.Net.Security/tests/EnterpriseTests/System.Net.Security.Enterprise.Tests.csproj' + displayName: Build product sources -- bash: | - docker exec linuxclient $(containerRunTestsCommand) $(containerLibrariesRoot)/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj - docker exec linuxclient $(containerRunTestsCommand) $(containerLibrariesRoot)/System.Net.Security/tests/EnterpriseTests/System.Net.Security.Enterprise.Tests.csproj - displayName: Build and run tests + - bash: | + docker exec linuxclient bash -c 'if [ -f /erc/resolv.conf.ORI ]; then cp -f /erc/resolv.conf.ORI /etc/resolv.conf; fi' + docker exec linuxclient $(containerRunTestsCommand) $(containerLibrariesRoot)/System.Net.Http/tests/EnterpriseTests/System.Net.Http.Enterprise.Tests.csproj + docker exec linuxclient $(containerRunTestsCommand) $(containerLibrariesRoot)/System.Net.Security/tests/EnterpriseTests/System.Net.Security.Enterprise.Tests.csproj + displayName: Build and run tests -- bash: | - cd $(enterpriseTestsSetup) - docker-compose down - displayName: Stop test network and machines - env: - DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) + - bash: | + cd $(enterpriseTestsSetup) + docker-compose down + displayName: Stop test network and machines + env: + DOTNET_RUNTIME_REPO_ROOT: $(Build.SourcesDirectory) -- task: PublishTestResults@2 - inputs: - testRunner: 'xUnit' - testResultsFiles: '**/testResults.xml' - testRunTitle: 'Enterprise Tests' - mergeTestResults: true - failTaskOnFailedTests: true + - task: PublishTestResults@2 + inputs: + testRunner: 'xUnit' + testResultsFiles: '**/testResults.xml' + testRunTitle: 'Enterprise Tests' + mergeTestResults: true + failTaskOnFailedTests: true diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index cfc08adbc4340..4d88855ca6a2f 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -167,10 +167,15 @@ if(FEATURE_MERGE_JIT_AND_ENGINE) set(CLRJIT_STATIC clrjit_static) endif(FEATURE_MERGE_JIT_AND_ENGINE) +if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST) + include(CMakeFindFrameworks) + find_library(FOUNDATION Foundation REQUIRED) +endif() + target_sources(coreclr PUBLIC $) -target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks) +target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks ${FOUNDATION}) target_sources(coreclr_static PUBLIC $) -target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable) +target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable ${FOUNDATION}) target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED) if(CLR_CMAKE_TARGET_WIN32) diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/Dockerfile b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/Dockerfile index 0b6a7b19eba88..d3e266f4f7810 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/Dockerfile +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/apacheweb/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20220421022739-9c434db ARG DEBIAN_FRONTEND=noninteractive diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml index c54adfb7caaea..0b524f35b381f 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/docker-compose.yml @@ -60,6 +60,9 @@ services: hostname: linuxclient domainname: linux.contoso.com dns_search: linux.contoso.com + privileged: true + dns: + - 8.8.8.8 volumes: - shared-volume:/SHARED - ${DOTNET_RUNTIME_REPO_ROOT}:/repo diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/kdc/Dockerfile b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/kdc/Dockerfile index 1b28145ff833b..9abd3fa729d3a 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/kdc/Dockerfile +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/kdc/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20220421022739-9c434db COPY ./kdc/kadm5.acl /etc/krb5kdc/ COPY ./kdc/kdc.conf /etc/krb5kdc/ diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile index 853582e7bcf3c..7b7afc1b4a9b9 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20211022152710-047508b +FROM mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-20220421022739-9c434db # Prevents dialog prompting when installing packages ARG DEBIAN_FRONTEND=noninteractive diff --git a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/test-webserver.sh b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/test-webserver.sh index 2afd01f34335c..058604296dc3b 100644 --- a/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/test-webserver.sh +++ b/src/libraries/Common/tests/System/Net/EnterpriseTests/setup/linuxclient/test-webserver.sh @@ -4,3 +4,6 @@ kdestroy echo password | kinit user1 curl --verbose --negotiate -u: http://apacheweb.linux.contoso.com kdestroy + +nslookup github.com + diff --git a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt index 644d7774feffa..f7add30d50b6c 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt @@ -64,6 +64,10 @@ set(NATIVEGLOBALIZATION_SOURCES pal_icushim.c ) +if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_locale.m) +endif() + # time zone names are filtered out of icu data for the browser and associated functionality is disabled if (NOT CLR_CMAKE_TARGET_BROWSER) set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_timeZoneInfo.c) @@ -80,6 +84,11 @@ endif() include_directories("../Common") if (GEN_SHARED_LIB) + if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + include(CMakeFindFrameworks) + find_library(FOUNDATION Foundation REQUIRED) + endif() + add_library(System.Globalization.Native SHARED ${NATIVEGLOBALIZATION_SOURCES} @@ -88,12 +97,12 @@ if (GEN_SHARED_LIB) target_link_libraries(System.Globalization.Native dl + ${FOUNDATION} ) install_with_stripped_symbols (System.Globalization.Native PROGRAMS .) endif() - add_library(System.Globalization.Native-Static STATIC ${NATIVEGLOBALIZATION_SOURCES} diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.c index cd0e25ed8837f..498f713404ca0 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.c @@ -129,12 +129,15 @@ int32_t FixupLocaleName(UChar* value, int32_t valueLength) return i; } -// We use whatever ICU give us as the default locale except if it is en_US_POSIX. We'll map -// this POSIX locale to Invariant instead. The reason is POSIX locale collation behavior -// is not desirable at all because it doesn't support case insensitive string comparisons. +// We use whatever ICU give us as the default locale except if it is en_US_POSIX. +// +// On Apple related platforms (OSX, iOS, tvOS, MacCatalyst), we'll take what the system locale is. +// On all other platforms we'll map this POSIX locale to Invariant instead. +// The reason is POSIX locale collation behavior is not desirable at all because it doesn't support case insensitive string comparisons. const char* DetectDefaultLocaleName() { const char* icuLocale = uloc_getDefault(); + if (strcmp(icuLocale, "en_US_POSIX") == 0) { return ""; @@ -216,6 +219,16 @@ int32_t GlobalizationNative_GetDefaultLocaleName(UChar* value, int32_t valueLeng const char* defaultLocale = DetectDefaultLocaleName(); +#ifdef __APPLE__ + char* appleLocale = NULL; + + if (strcmp(defaultLocale, "") == 0) + { + appleLocale = DetectDefaultAppleLocaleName(); + defaultLocale = appleLocale; + } +#endif + uloc_getBaseName(defaultLocale, localeNameBuffer, ULOC_FULLNAME_CAPACITY, &status); u_charsToUChars_safe(localeNameBuffer, value, valueLength, &status); @@ -236,6 +249,11 @@ int32_t GlobalizationNative_GetDefaultLocaleName(UChar* value, int32_t valueLeng } } +#ifdef __APPLE__ + if (appleLocale) + free(appleLocale); +#endif + return UErrorCodeToBool(status); } diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.m b/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.m new file mode 100644 index 0000000000000..f574b9d14797e --- /dev/null +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_locale.m @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include +#include "pal_locale_internal.h" + +#import + +char* DetectDefaultAppleLocaleName() +{ + NSLocale *currentLocale = [NSLocale currentLocale]; + NSString *localeName = @""; + + if (!currentLocale) + { + return strdup([localeName UTF8String]); + } + + if ([currentLocale.languageCode length] > 0 && [currentLocale.countryCode length] > 0) + { + localeName = [NSString stringWithFormat:@"%@-%@", currentLocale.languageCode, currentLocale.countryCode]; + } + else + { + localeName = currentLocale.localeIdentifier; + } + + return strdup([localeName UTF8String]); +} + diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_locale_internal.h b/src/libraries/Native/Unix/System.Globalization.Native/pal_locale_internal.h index c58436ab77517..c754554bbfdd5 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_locale_internal.h +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_locale_internal.h @@ -51,3 +51,13 @@ Detect the default locale for the machine, defaulting to Invaraint if we can't compute one (different from uloc_getDefault()) would do. */ const char* DetectDefaultLocaleName(void); + +#ifdef __APPLE__ +/* +Function: +DetectDefaultSystemLocaleName + +Detects the default locale string for Apple platforms +*/ +char* DetectDefaultAppleLocaleName(void); +#endif diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs index 9215095756e98..44afccec6b9f8 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoCurrentCulture.cs @@ -33,6 +33,17 @@ public void CurrentCulture() } } + [Fact] + [PlatformSpecific(TestPlatforms.OSX | TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS)] + public void CurrentCulture_Default_Not_Invariant() + { + // On OSX-like platforms, it should default to what the default system culture is + // set to. Since we shouldn't assume en-US, we just test if it's not the invariant + // culture. + Assert.NotEqual(CultureInfo.CurrentCulture, CultureInfo.InvariantCulture); + Assert.NotEqual(CultureInfo.CurrentUICulture, CultureInfo.InvariantCulture); + } + [Fact] public void CurrentCulture_Set_Null_ThrowsArgumentNullException() { @@ -125,7 +136,7 @@ public void CurrentCulture_BasedOnLangEnvVar(string langEnvVar, string expectedC }, expectedCultureName, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); } - [PlatformSpecific(TestPlatforms.AnyUnix)] // When LANG is empty or unset, should default to the invariant culture on Unix. + [PlatformSpecific(TestPlatforms.AnyUnix)] [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData("")] [InlineData(null)] @@ -141,13 +152,28 @@ public void CurrentCulture_DefaultWithNoLang(string langEnvVar) psi.Environment["LANG"] = langEnvVar; } + // When LANG is empty or unset, on Unix it should default to the invariant culture. + // On OSX-like platforms, it should default to what the default system culture is + // set to. Since we shouldn't assume en-US, we just test if it's not the invariant + // culture. RemoteExecutor.Invoke(() => { Assert.NotNull(CultureInfo.CurrentCulture); Assert.NotNull(CultureInfo.CurrentUICulture); - Assert.Equal("", CultureInfo.CurrentCulture.Name); - Assert.Equal("", CultureInfo.CurrentUICulture.Name); + if (PlatformDetection.IsOSXLike) + { + Assert.NotEqual("", CultureInfo.CurrentCulture.Name); + Assert.NotEqual("", CultureInfo.CurrentUICulture.Name); + + Assert.NotEqual(CultureInfo.CurrentCulture, CultureInfo.InvariantCulture); + Assert.NotEqual(CultureInfo.CurrentUICulture, CultureInfo.InvariantCulture); + } + else + { + Assert.Equal("", CultureInfo.CurrentCulture.Name); + Assert.Equal("", CultureInfo.CurrentUICulture.Name); + } }, new RemoteInvokeOptions { StartInfo = psi }).Dispose(); } diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 54a5e44096a11..128ed08f45b61 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -23,7 +23,7 @@ if(HOST_DARWIN) set(OS_LIBS "-framework CoreFoundation" "-framework Foundation") if(CMAKE_SYSTEM_VARIANT STREQUAL "MacCatalyst") - set(OS_LIBS "-lobjc" "-lc++") + set(OS_LIBS ${OS_LIBS} "-lobjc" "-lc++") endif() elseif(HOST_IOS) set(OS_LIBS "-framework CoreFoundation" "-lobjc" "-lc++") @@ -79,6 +79,13 @@ if(HAVE_SYS_ICU) pal_timeZoneInfo.c entrypoints.c ${pal_icushim_sources_base}) + + if (TARGET_DARWIN) + set(icu_shim_sources_base + ${icu_shim_sources_base} + pal_locale.m) + endif() + addprefix(icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}") set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_DEFINITIONS OSX_ICU_LIBRARY_PATH="${OSX_ICU_LIBRARY_PATH}") set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I\"${ICU_INCLUDEDIR}\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/System.Globalization.Native/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/Common/\" ${ICU_FLAGS}")