From ad58b6da48c4d5254eb6b2b1dc50298b32962b9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:49:56 +0000 Subject: [PATCH 01/12] Initial plan From 612208fc961dd26b51ced14a38f11528d482d1a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:58:42 +0000 Subject: [PATCH 02/12] Fix OSConditionAttribute to use RuntimeInformation via reflection for .NET Framework Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com> --- .../TestMethod/OSConditionAttribute.cs | 76 ++++++++++++++++++- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 502a3aa5e1..f7ed928700 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -50,9 +50,8 @@ public OSConditionAttribute(OperatingSystems operatingSystems) /// Gets a value indicating whether the test method or test class should be ignored. /// public override bool IsConditionMet -#if NET462 - // On .NET Framework, we are sure we are running on Windows. - => (_operatingSystems & OperatingSystems.Windows) != 0; +#if NETFRAMEWORK + => IsConditionMetNetFramework(); #else { get @@ -79,6 +78,77 @@ public override bool IsConditionMet } #endif +#if NETFRAMEWORK + private bool IsConditionMetNetFramework() + { + // RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+. + // For older .NET Framework versions or environments where the API is not available, + // we fall back to assuming Windows. + // This also handles Mono which supports RuntimeInformation API and can run on non-Windows platforms. + Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") + ?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib"); + + if (runtimeInformationType is null) + { + // API not available, assume Windows + return (_operatingSystems & OperatingSystems.Windows) != 0; + } + + MethodInfo? isOSPlatformMethod = runtimeInformationType.GetMethod("IsOSPlatform", BindingFlags.Public | BindingFlags.Static); + if (isOSPlatformMethod is null) + { + // API not available, assume Windows + return (_operatingSystems & OperatingSystems.Windows) != 0; + } + + Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") + ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib"); + + if (osPlatformType is null) + { + // API not available, assume Windows + return (_operatingSystems & OperatingSystems.Windows) != 0; + } + + if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Windows")) + { + return (_operatingSystems & OperatingSystems.Windows) != 0; + } + else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Linux")) + { + return (_operatingSystems & OperatingSystems.Linux) != 0; + } + else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "OSX")) + { + return (_operatingSystems & OperatingSystems.OSX) != 0; + } + else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "FreeBSD")) + { + return (_operatingSystems & OperatingSystems.FreeBSD) != 0; + } + + return false; + } + + private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, Type osPlatformType, string osName) + { + MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static); + if (createMethod is null) + { + return false; + } + + object? osPlatform = createMethod.Invoke(null, [osName]); + if (osPlatform is null) + { + return false; + } + + object? result = isOSPlatformMethod.Invoke(null, [osPlatform]); + return result is true; + } +#endif + /// /// Gets the group name for this attribute. /// From 573b07c7b93e5f0b2ff8e50e291db7b4f8eef7e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 10:00:18 +0000 Subject: [PATCH 03/12] Address code review feedback: use explicit object array syntax Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com> --- .../Attributes/TestMethod/OSConditionAttribute.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index f7ed928700..a35edbd7b7 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -138,13 +138,13 @@ private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, Typ return false; } - object? osPlatform = createMethod.Invoke(null, [osName]); + object? osPlatform = createMethod.Invoke(null, new object[] { osName }); if (osPlatform is null) { return false; } - object? result = isOSPlatformMethod.Invoke(null, [osPlatform]); + object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform }); return result is true; } #endif From 9ea40f98b6f879e9cc08d91003fe49f980ca564e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 10:03:25 +0000 Subject: [PATCH 04/12] Optimize OS detection with caching and simpler type loading Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com> --- .../TestMethod/OSConditionAttribute.cs | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index a35edbd7b7..836ceade2c 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -21,6 +21,11 @@ public sealed class OSConditionAttribute : ConditionBaseAttribute #endif #endif +#if NETFRAMEWORK + // Cache the detected OS to avoid repeated reflection calls + private static readonly OperatingSystems? s_detectedOS = DetectCurrentOS(); +#endif + private readonly OperatingSystems _operatingSystems; /// @@ -51,7 +56,14 @@ public OSConditionAttribute(OperatingSystems operatingSystems) /// public override bool IsConditionMet #if NETFRAMEWORK - => IsConditionMetNetFramework(); + { + get + { + // If we couldn't detect the OS via reflection, assume Windows + OperatingSystems currentOS = s_detectedOS ?? OperatingSystems.Windows; + return (_operatingSystems & currentOS) != 0; + } + } #else { get @@ -79,65 +91,62 @@ public override bool IsConditionMet #endif #if NETFRAMEWORK - private bool IsConditionMetNetFramework() + private static OperatingSystems? DetectCurrentOS() { // RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+. // For older .NET Framework versions or environments where the API is not available, - // we fall back to assuming Windows. + // we return null to fall back to assuming Windows. // This also handles Mono which supports RuntimeInformation API and can run on non-Windows platforms. - Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") + Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation") ?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib"); if (runtimeInformationType is null) { - // API not available, assume Windows - return (_operatingSystems & OperatingSystems.Windows) != 0; + return null; } MethodInfo? isOSPlatformMethod = runtimeInformationType.GetMethod("IsOSPlatform", BindingFlags.Public | BindingFlags.Static); if (isOSPlatformMethod is null) { - // API not available, assume Windows - return (_operatingSystems & OperatingSystems.Windows) != 0; + return null; } - Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") + Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation") ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib"); if (osPlatformType is null) { - // API not available, assume Windows - return (_operatingSystems & OperatingSystems.Windows) != 0; + return null; } - if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Windows")) + MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static); + if (createMethod is null) { - return (_operatingSystems & OperatingSystems.Windows) != 0; + return null; } - else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Linux")) + + if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Windows")) + { + return OperatingSystems.Windows; + } + else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Linux")) { - return (_operatingSystems & OperatingSystems.Linux) != 0; + return OperatingSystems.Linux; } - else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "OSX")) + else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "OSX")) { - return (_operatingSystems & OperatingSystems.OSX) != 0; + return OperatingSystems.OSX; } - else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "FreeBSD")) + else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "FreeBSD")) { - return (_operatingSystems & OperatingSystems.FreeBSD) != 0; + return OperatingSystems.FreeBSD; } - return false; + return null; } - private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, Type osPlatformType, string osName) + private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, MethodInfo createMethod, string osName) { - MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static); - if (createMethod is null) - { - return false; - } - object? osPlatform = createMethod.Invoke(null, new object[] { osName }); if (osPlatform is null) { From 70f93bfb66921c132995e06c8531a064ba683410 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 10:04:45 +0000 Subject: [PATCH 05/12] Add exception handling for reflection invocations Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com> --- .../TestMethod/OSConditionAttribute.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 836ceade2c..817f703577 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -147,14 +147,22 @@ public override bool IsConditionMet private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, MethodInfo createMethod, string osName) { - object? osPlatform = createMethod.Invoke(null, new object[] { osName }); - if (osPlatform is null) + try { + object? osPlatform = createMethod.Invoke(null, new object[] { osName }); + if (osPlatform is null) + { + return false; + } + + object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform }); + return result is true; + } + catch + { + // Reflection invocation failed, treat as OS not matching return false; } - - object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform }); - return result is true; } #endif From 7128c0af0d34870086600e254335b138981fb50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 28 Nov 2025 17:55:32 +0100 Subject: [PATCH 06/12] Apply suggestions from code review --- .../Attributes/TestMethod/OSConditionAttribute.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 817f703577..bb546bdfb6 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -23,7 +23,7 @@ public sealed class OSConditionAttribute : ConditionBaseAttribute #if NETFRAMEWORK // Cache the detected OS to avoid repeated reflection calls - private static readonly OperatingSystems? s_detectedOS = DetectCurrentOS(); + private static readonly OperatingSystems? DetectedOS = DetectCurrentOS(); #endif private readonly OperatingSystems _operatingSystems; @@ -60,7 +60,7 @@ public override bool IsConditionMet get { // If we couldn't detect the OS via reflection, assume Windows - OperatingSystems currentOS = s_detectedOS ?? OperatingSystems.Windows; + OperatingSystems currentOS = DetectedOS ?? OperatingSystems.Windows; return (_operatingSystems & currentOS) != 0; } } From 9c642633b9095feebd95651e0840b7268fc93406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sun, 30 Nov 2025 07:32:25 +0100 Subject: [PATCH 07/12] Update src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs Co-authored-by: Youssef Victor --- .../TestFramework/Attributes/TestMethod/OSConditionAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index bb546bdfb6..1a3f7c6f25 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -55,7 +55,7 @@ public OSConditionAttribute(OperatingSystems operatingSystems) /// Gets a value indicating whether the test method or test class should be ignored. /// public override bool IsConditionMet -#if NETFRAMEWORK +#if NET462 { get { From 09af2d3f9d78b0a9ddeaa66979b8bf0bc11b3a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sun, 30 Nov 2025 07:32:38 +0100 Subject: [PATCH 08/12] Update src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs Co-authored-by: Youssef Victor --- .../TestFramework/Attributes/TestMethod/OSConditionAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 1a3f7c6f25..81301c2c53 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -21,7 +21,7 @@ public sealed class OSConditionAttribute : ConditionBaseAttribute #endif #endif -#if NETFRAMEWORK +#if NET462 // Cache the detected OS to avoid repeated reflection calls private static readonly OperatingSystems? DetectedOS = DetectCurrentOS(); #endif From 449e696569fe668955f46fd877092810123af784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 1 Dec 2025 10:48:25 +0100 Subject: [PATCH 09/12] Update src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs Co-authored-by: Youssef Victor --- .../TestFramework/Attributes/TestMethod/OSConditionAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 81301c2c53..26d51c278e 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -90,7 +90,7 @@ public override bool IsConditionMet } #endif -#if NETFRAMEWORK +#if NET462 private static OperatingSystems? DetectCurrentOS() { // RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+. From 7f4999d7b4b06734bc336c05925ac264097e3afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 1 Dec 2025 13:24:41 +0100 Subject: [PATCH 10/12] Fix code --- .../TestMethod/OSConditionAttribute.cs | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 26d51c278e..bd542b2e00 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -55,19 +55,14 @@ public OSConditionAttribute(OperatingSystems operatingSystems) /// Gets a value indicating whether the test method or test class should be ignored. /// public override bool IsConditionMet -#if NET462 { get { +#if NET462 // If we couldn't detect the OS via reflection, assume Windows OperatingSystems currentOS = DetectedOS ?? OperatingSystems.Windows; return (_operatingSystems & currentOS) != 0; - } - } #else - { - get - { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return (_operatingSystems & OperatingSystems.Windows) != 0; @@ -86,9 +81,9 @@ public override bool IsConditionMet } return false; +#endif } } -#endif #if NET462 private static OperatingSystems? DetectCurrentOS() @@ -99,7 +94,6 @@ public override bool IsConditionMet // This also handles Mono which supports RuntimeInformation API and can run on non-Windows platforms. Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation") ?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib"); - if (runtimeInformationType is null) { return null; @@ -113,31 +107,32 @@ public override bool IsConditionMet Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation") ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib"); - if (osPlatformType is null) { return null; } - MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static); - if (createMethod is null) - { - return null; - } + // Use the predefined static properties instead of Create() method + // On Mono, the static properties use uppercase strings (e.g., "LINUX") while Create() uses the provided casing, + // and IsOSPlatform performs case-sensitive comparison against the predefined values. + PropertyInfo? windowsProp = osPlatformType.GetProperty("Windows", BindingFlags.Public | BindingFlags.Static); + PropertyInfo? linuxProp = osPlatformType.GetProperty("Linux", BindingFlags.Public | BindingFlags.Static); + PropertyInfo? osxProp = osPlatformType.GetProperty("OSX", BindingFlags.Public | BindingFlags.Static); + PropertyInfo? freebsdProp = osPlatformType.GetProperty("FreeBSD", BindingFlags.Public | BindingFlags.Static); - if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Windows")) + if (windowsProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, windowsProp)) { return OperatingSystems.Windows; } - else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Linux")) + else if (linuxProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, linuxProp)) { return OperatingSystems.Linux; } - else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "OSX")) + else if (osxProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, osxProp)) { return OperatingSystems.OSX; } - else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "FreeBSD")) + else if (freebsdProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, freebsdProp)) { return OperatingSystems.FreeBSD; } @@ -145,24 +140,16 @@ public override bool IsConditionMet return null; } - private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, MethodInfo createMethod, string osName) + private static bool IsOSPlatformViaProperty(MethodInfo isOSPlatformMethod, PropertyInfo osPlatformProperty) { - try - { - object? osPlatform = createMethod.Invoke(null, new object[] { osName }); - if (osPlatform is null) - { - return false; - } - - object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform }); - return result is true; - } - catch + object? osPlatform = osPlatformProperty.GetValue(null); + if (osPlatform is null) { - // Reflection invocation failed, treat as OS not matching return false; } + + object? result = isOSPlatformMethod.Invoke(null, [osPlatform]); + return result is true; } #endif From bf1c2cb458d19113617505b08e033b01099ddb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 2 Dec 2025 10:54:35 +0100 Subject: [PATCH 11/12] Update logic of detection --- .../TestMethod/OSConditionAttribute.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index bd542b2e00..6f6adced68 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -55,14 +55,12 @@ public OSConditionAttribute(OperatingSystems operatingSystems) /// Gets a value indicating whether the test method or test class should be ignored. /// public override bool IsConditionMet +#if NET462 + => DetectedOS is not null && (_operatingSystems & DetectedOS) != 0; +#else { get { -#if NET462 - // If we couldn't detect the OS via reflection, assume Windows - OperatingSystems currentOS = DetectedOS ?? OperatingSystems.Windows; - return (_operatingSystems & currentOS) != 0; -#else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return (_operatingSystems & OperatingSystems.Windows) != 0; @@ -81,11 +79,17 @@ public override bool IsConditionMet } return false; -#endif } } +#endif #if NET462 + /// + /// Detects the current operating system using reflection to maintain compatibility with .NET Framework 4.6.2. + /// + /// + /// The detected operating system, or null if the OS could not be determined. + /// private static OperatingSystems? DetectCurrentOS() { // RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+. @@ -96,20 +100,22 @@ public override bool IsConditionMet ?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib"); if (runtimeInformationType is null) { - return null; + return OperatingSystems.Windows; } MethodInfo? isOSPlatformMethod = runtimeInformationType.GetMethod("IsOSPlatform", BindingFlags.Public | BindingFlags.Static); if (isOSPlatformMethod is null) { - return null; + // Fallback to Windows if the method is not found + return OperatingSystems.Windows; } Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation") ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib"); if (osPlatformType is null) { - return null; + // This should not happen, as OSPlatform is required for IsOSPlatform method + throw ApplicationStateGuard.Unreachable(); } // Use the predefined static properties instead of Create() method @@ -137,17 +143,13 @@ public override bool IsConditionMet return OperatingSystems.FreeBSD; } + // Unknown OS return null; } private static bool IsOSPlatformViaProperty(MethodInfo isOSPlatformMethod, PropertyInfo osPlatformProperty) { object? osPlatform = osPlatformProperty.GetValue(null); - if (osPlatform is null) - { - return false; - } - object? result = isOSPlatformMethod.Invoke(null, [osPlatform]); return result is true; } From a729167f755359b7618dc76eae79a9b71d625fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 2 Dec 2025 11:20:34 +0100 Subject: [PATCH 12/12] Apply suggestion from @Evangelink --- .../Attributes/TestMethod/OSConditionAttribute.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs index 6f6adced68..f12ca33e45 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs @@ -111,12 +111,8 @@ public override bool IsConditionMet } Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation") - ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib"); - if (osPlatformType is null) - { - // This should not happen, as OSPlatform is required for IsOSPlatform method - throw ApplicationStateGuard.Unreachable(); - } + ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib") + ?? throw ApplicationStateGuard.Unreachable(); // Use the predefined static properties instead of Create() method // On Mono, the static properties use uppercase strings (e.g., "LINUX") while Create() uses the provided casing,