From 00788da758d71b93ae5fd7ac1599529b41fba59d Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Mon, 9 Oct 2017 13:36:06 -0700 Subject: [PATCH] Fix/disable RedHat System.Globalization, System.IO.Pipes, System.IO.FileSystem failures (#24340) * fix System.Globalization RedHat failure * add RedHat version detection * change test behavior also on centos 6.9 * unify RedHat and CentOS detection * disable failing System.IO.Pipes on RedHatFamily69 * Disable Unix_NotFoundDirectory_ReadOnlyVolume * fix version comparison when only major is provided on RedHat * remove confusing checks for non-standard RedHat distro (rhl) * clean up version comparison and reuse properties --- src/Common/tests/System/PlatformDetection.cs | 139 ++++++++++++++++-- .../NumberFormatInfo/NumberFormatInfoData.cs | 1 + .../tests/Directory/Delete.cs | 3 + .../AnonymousPipeTest.Specific.cs | 2 +- .../HttpClientHandlerTest.SslProtocols.cs | 2 +- 5 files changed, 130 insertions(+), 17 deletions(-) diff --git a/src/Common/tests/System/PlatformDetection.cs b/src/Common/tests/System/PlatformDetection.cs index 99f303b20506..baa8b7a42d6b 100644 --- a/src/Common/tests/System/PlatformDetection.cs +++ b/src/Common/tests/System/PlatformDetection.cs @@ -158,10 +158,15 @@ public static bool IsWinRT public static bool IsWindowsSubsystemForLinux => m_isWindowsSubsystemForLinux.Value; public static bool IsNotWindowsSubsystemForLinux => !IsWindowsSubsystemForLinux; - public static bool IsNotFedoraOrRedHatOrCentos => !IsDistroAndVersion("fedora") && !IsDistroAndVersion("rhel") && !IsDistroAndVersion("centos"); - public static bool IsFedora => IsDistroAndVersion("fedora"); + // RedHat family covers RedHat and CentOS + public static bool IsRedHatFamily => IsRedHatFamilyAndVersion(); + public static bool IsRedHatFamily7 => IsRedHatFamilyAndVersion("7"); + public static bool IsRedHatFamily69 => IsRedHatFamilyAndVersion("6.9"); + public static bool IsNotRedHatFamily69 => !IsRedHatFamily69; + public static bool IsNotFedoraOrRedHatFamily => !IsFedora && !IsRedHatFamily; + private static bool GetIsWindowsSubsystemForLinux() { // https://github.com/Microsoft/BashOnWindows/issues/423#issuecomment-221627364 @@ -186,7 +191,6 @@ private static bool GetIsWindowsSubsystemForLinux() public static bool IsDebian => IsDistroAndVersion("debian"); public static bool IsDebian8 => IsDistroAndVersion("debian", "8"); public static bool IsUbuntu1404 => IsDistroAndVersion("ubuntu", "14.04"); - public static bool IsCentos7 => IsDistroAndVersion("centos", "7"); private static readonly Version s_osxProductVersion = GetOSXProductVersion(); @@ -264,6 +268,48 @@ private static bool IsDistroAndVersion(string distroId, string versionId = null) return false; } + private static bool IsRedHatFamilyAndVersion(string versionId = null) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + IdVersionPair v = ParseOsReleaseFile(); + + // RedHat includes minor version. We need to account for that when comparing + if ((v.Id == "rhel" || v.Id == "centos") && VersionEqual(versionId, v.VersionId)) + { + return true; + } + } + + return false; + } + + private static bool VersionEqual(string expectedVersionId, string actualVersionId) + { + if (expectedVersionId == null) + { + return true; + } + + string[] expected = expectedVersionId.Split('.'); + string[] actual = actualVersionId.Split('.'); + + if (expected.Length > actual.Length) + { + return false; + } + + for (int i = 0; i < expected.Length; i++) + { + if (expected[i] != actual[i]) + { + return false; + } + } + + return true; + } + private static IdVersionPair ParseOsReleaseFile() { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Linux)); @@ -278,26 +324,77 @@ private static IdVersionPair ParseOsReleaseFile() { if (line.StartsWith("ID=", System.StringComparison.Ordinal)) { - ret.Id = line.Substring("ID=".Length); + ret.Id = RemoveQuotes(line.Substring("ID=".Length)); } else if (line.StartsWith("VERSION_ID=", System.StringComparison.Ordinal)) { - ret.VersionId = line.Substring("VERSION_ID=".Length); + ret.VersionId = RemoveQuotes(line.Substring("VERSION_ID=".Length)); } } } - - string versionId = ret.VersionId; - if (versionId.Length >= 2 && versionId[0] == '"' && versionId[versionId.Length - 1] == '"') + else { - // Remove quotes. - ret.VersionId = versionId.Substring(1, versionId.Length - 2); - } + string fileName = null; + if (File.Exists("/etc/redhat-release")) + fileName = "/etc/redhat-release"; + + if (fileName == null && File.Exists("/etc/system-release")) + fileName = "/etc/system-release"; + + if (fileName != null) + { + // Parse the format like the following line: + // Red Hat Enterprise Linux Server release 7.3 (Maipo) + using (StreamReader file = new StreamReader(fileName)) + { + string line = file.ReadLine(); + if (!String.IsNullOrEmpty(line)) + { + if (line.StartsWith("Red Hat Enterprise Linux", StringComparison.OrdinalIgnoreCase)) + { + ret.Id = "rhel"; + } + else if (line.StartsWith("Centos", StringComparison.OrdinalIgnoreCase)) + { + ret.Id = "centos"; + } + else + { + // automatically generate the distro label + string [] words = line.Split(' '); + StringBuilder sb = new StringBuilder(); + + foreach (string word in words) + { + if (word.Length > 0) + { + if (Char.IsNumber(word[0]) || + word.Equals("release", StringComparison.OrdinalIgnoreCase) || + word.Equals("server", StringComparison.OrdinalIgnoreCase)) + { + break; + } + sb.Append(Char.ToLower(word[0])); + } + } + ret.Id = sb.ToString(); + } - if (ret.Id.Length >= 2 && ret.Id[0] == '"' && ret.Id[ret.Id.Length - 1] == '"') - { - // Remove quotes. - ret.Id = ret.Id.Substring(1, ret.Id.Length - 2); + int i = 0; + while (i < line.Length && !Char.IsNumber(line[i])) // stop at first number + i++; + + if (i < line.Length) + { + int j = i + 1; + while (j < line.Length && (Char.IsNumber(line[j]) || line[j] == '.')) + j++; + + ret.VersionId = line.Substring(i, j - i); + } + } + } + } } return ret; @@ -348,6 +445,18 @@ private static int GetWindowsBuildNumber() return -1; } + private static string RemoveQuotes(string s) + { + s = s.Trim(); + if (s.Length >= 2 && s[0] == '"' && s[s.Length - 1] == '"') + { + // Remove quotes. + s = s.Substring(1, s.Length - 2); + } + + return s; + } + [DllImport("ntdll.dll")] private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); diff --git a/src/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoData.cs b/src/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoData.cs index 1c57b7f5723d..1f10c9536dc0 100644 --- a/src/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoData.cs +++ b/src/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoData.cs @@ -17,6 +17,7 @@ public static int[] UrINNumberGroupSizes() || (PlatformDetection.IsUbuntu && !PlatformDetection.IsUbuntu1404) || PlatformDetection.IsFedora || (PlatformDetection.IsDebian && !PlatformDetection.IsDebian8) + || PlatformDetection.IsRedHatFamily69 ) { return new int[] { 3 }; diff --git a/src/System.IO.FileSystem/tests/Directory/Delete.cs b/src/System.IO.FileSystem/tests/Directory/Delete.cs index 58621c0a9a9b..d31d6839fa57 100644 --- a/src/System.IO.FileSystem/tests/Directory/Delete.cs +++ b/src/System.IO.FileSystem/tests/Directory/Delete.cs @@ -211,6 +211,9 @@ public void UnixShouldBeAbleToDeleteHiddenDirectory() [Trait(XunitConstants.Category, XunitConstants.RequiresElevation)] public void Unix_NotFoundDirectory_ReadOnlyVolume() { + if (PlatformDetection.IsRedHatFamily69) + return; // [ActiveIssue(https://github.com/dotnet/corefx/issues/21920)] + ReadOnly_FileSystemHelper(readOnlyDirectory => { Assert.Throws(() => Delete(Path.Combine(readOnlyDirectory, "DoesNotExist"))); diff --git a/src/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs b/src/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs index 94f38c6e471d..96b03e58a78b 100644 --- a/src/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs +++ b/src/System.IO.Pipes/tests/AnonymousPipeTests/AnonymousPipeTest.Specific.cs @@ -79,7 +79,7 @@ public static void ClonedClient_ActsAsOriginalClient() } } - [Fact] + [ConditionalFact(nameof(PlatformDetection) + "." + "IsNotRedHatFamily69")] [PlatformSpecific(TestPlatforms.Linux)] // On Linux, setting the buffer size of the server will also set the buffer size of the client public static void Linux_BufferSizeRoundtrips() { diff --git a/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.SslProtocols.cs b/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.SslProtocols.cs index 1b97071aa033..d95e6e91c97f 100644 --- a/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.SslProtocols.cs +++ b/src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.SslProtocols.cs @@ -125,7 +125,7 @@ public async Task GetAsync_SupportedSSLVersion_Succeeds(SslProtocols sslProtocol { using (HttpClientHandler handler = new HttpClientHandler()) { - if (PlatformDetection.IsCentos7) + if (PlatformDetection.IsRedHatFamily7) { // Default protocol selection is always TLSv1 on Centos7 libcurl 7.29.0 // Hence, set the specific protocol on HttpClient that is required by test