Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add IsOSPlatformOrLater and IsOSPlatformEarlierThan methods #39005

Merged
merged 5 commits into from
Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,15 @@ public static partial class RuntimeInformation
public static string OSDescription { get { throw null; } }
public static System.Runtime.InteropServices.Architecture ProcessArchitecture { get { throw null; } }
public static bool IsOSPlatform(System.Runtime.InteropServices.OSPlatform osPlatform) { throw null; }
public static bool IsOSPlatformOrLater(string platformName) { throw null; }
public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; }
public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; }
public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; }
public static bool IsOSPlatformOrLater(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; }
public static bool IsOSPlatformEarlierThan(string platformName) { throw null; }
public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major) { throw null; }
public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor) { throw null; }
public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build) { throw null; }
public static bool IsOSPlatformEarlierThan(System.Runtime.InteropServices.OSPlatform osPlatform, int major, int minor, int build, int revision) { throw null; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<data name="Argument_EmptyValue" xml:space="preserve">
<value>Value cannot be empty.</value>
</data>
<data name="Argument_InvalidPlatfromName" xml:space="preserve">
<value>"{0}" is not valid platform name. It must contain both name and version. Example: "ios14.0".</value>
</data>
<data name="PlatformNotSupported_RuntimeInformation" xml:space="preserve">
<value>RuntimeInformation is not supported for Portable Class Libraries.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Runtime\InteropServices\RuntimeInformation\RuntimeInformation.cs" />
<Compile Include="System\Runtime\InteropServices\RuntimeInformation\RuntimeInformation.PlatformVersion.cs" />
<Compile Include="System\Runtime\InteropServices\RuntimeInformation\Architecture.cs" />
<Compile Include="System\Runtime\InteropServices\RuntimeInformation\OSPlatform.cs" />
</ItemGroup>
Expand Down Expand Up @@ -45,5 +46,6 @@
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.Threading" />
<Reference Include="System.Memory" />
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Runtime.InteropServices
{
public static partial class RuntimeInformation
{
public static bool IsOSPlatformOrLater(string platformName)
{
(OSPlatform platform, Version version) = Parse(platformName);

return IsOSPlatformOrLater(platform, version.Major, version.Minor, version.Build, version.Revision);
}

public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major)
=> IsOSPlatform(osPlatform) && Environment.OSVersion.Version.Major >= major;

public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major, int minor)
=> IsOSPlatform(osPlatform) && IsOSVersionOrLater(major, minor, int.MinValue, int.MinValue);

public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major, int minor, int build)
=> IsOSPlatform(osPlatform) && IsOSVersionOrLater(major, minor, build, int.MinValue);

public static bool IsOSPlatformOrLater(OSPlatform osPlatform, int major, int minor, int build, int revision)
=> IsOSPlatform(osPlatform) && IsOSVersionOrLater(major, minor, build, revision);

public static bool IsOSPlatformEarlierThan(string platformName)
{
(OSPlatform platform, Version version) = Parse(platformName);

return IsOSPlatformEarlierThan(platform, version.Major, version.Minor, version.Build, version.Revision);
}

public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major)
=> IsOSPlatform(osPlatform) && Environment.OSVersion.Version.Major < major;

public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major, int minor)
=> IsOSPlatform(osPlatform) && !IsOSVersionOrLater(major, minor, int.MinValue, int.MinValue);

public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major, int minor, int build)
=> IsOSPlatform(osPlatform) && !IsOSVersionOrLater(major, minor, build, int.MinValue);

public static bool IsOSPlatformEarlierThan(OSPlatform osPlatform, int major, int minor, int build, int revision)
=> IsOSPlatform(osPlatform) && !IsOSVersionOrLater(major, minor, build, revision);

private static bool IsOSVersionOrLater(int major, int minor, int build, int revision)
{
Version current = Environment.OSVersion.Version;
if (current.Major != major)
{
return current.Major > major;
}
if (current.Minor != minor)
{
return current.Minor > minor;
}
if (current.Build != build)
{
return current.Build > build;
}

return current.Revision >= revision;
}

private static (OSPlatform, Version) Parse(string platformName)
{
if (platformName == null)
{
throw new ArgumentNullException(nameof(platformName));
}
if (platformName.Length == 0)
{
throw new ArgumentException(SR.Argument_EmptyValue, nameof(platformName));
}

for (int i = 0; i < platformName.Length; i++)
jeffhandley marked this conversation as resolved.
Show resolved Hide resolved
{
if (char.IsDigit(platformName[i]))
{
if (Version.TryParse(platformName.AsSpan().Slice(i), out var version))
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
{
return (OSPlatform.Create(platformName.Substring(0, i)), version);
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
LuisCesarCosta marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
break;
}
}
}

throw new ArgumentException(SR.Format(SR.Argument_InvalidPlatfromName, platformName), nameof(platformName));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using Xunit;

namespace System.Runtime.InteropServices.RuntimeInformationTests
{
public class PlatformVersionTests
{
public static IEnumerable<object[]> AllKnownOsPlatforms()
{
yield return new object[] { OSPlatform.Windows };
yield return new object[] { OSPlatform.Linux };
yield return new object[] { OSPlatform.OSX };
yield return new object[] { OSPlatform.Browser };
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
}

[Fact]
public void IsOSPlatformOrLater_Null_ThrowsArgumentNullExceptionWithArgumentName()
{
Assert.Throws<ArgumentNullException>("platformName", () => RuntimeInformation.IsOSPlatformOrLater(null));
}

[Fact]
public void IsOSPlatformOrLater_Empty_ThrowsArgumentNullExceptionWithArgumentName()
{
Assert.Throws<ArgumentException>("platformName", () => RuntimeInformation.IsOSPlatformOrLater(string.Empty));
}

[Theory]
[InlineData("ios")] // missing version number
[InlineData("ios14")] // ios14.0 is fine, ios14 is not
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
[InlineData("ios14.0.0.0.0.0")] // too many numbers
public void IsOSPlatformOrLater_InvalidVersionNumber_ThrowsArgumentExceptionWithArgumentName(string platformName)
{
Assert.Throws<ArgumentException>("platformName", () => RuntimeInformation.IsOSPlatformOrLater(platformName));
}

[Theory]
[MemberData(nameof(AllKnownOsPlatforms))]
public void IsOSPlatformOrLater_ReturnsTrue_ForCurrentOS(OSPlatform osPlatform)
{
// IsOSPlatformOrLater("xyz1.2.3.4") running as "xyz1.2.3.4" should return true

bool isCurrentPlatfom = RuntimeInformation.IsOSPlatform(osPlatform);
Version current = Environment.OSVersion.Version;

Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{current}"));

Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major));

if (current.Minor >= 0)
{
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major, current.Minor));

if (current.Build >= 0)
{
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major, current.Minor, current.Build));

if (current.Revision >= 0)
{
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major, current.Minor, current.Build, current.Revision));
}
}
}
}

[Theory]
[MemberData(nameof(AllKnownOsPlatforms))]
public void IsOSPlatformOrLater_ReturnsFalse_ForNewerVersionOfCurrentOS(OSPlatform osPlatform)
{
// IsOSPlatformOrLater("xyz11.0") running as "xyz10.0" should return false

Version currentVersion = Environment.OSVersion.Version;

Version newer = new Version(currentVersion.Major + 1, 0);
Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}"));
Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major));

newer = new Version(currentVersion.Major, currentVersion.Minor + 1);
Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}"));
Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major, newer.Minor));

newer = new Version(currentVersion.Major, currentVersion.Minor, currentVersion.Build + 1);
Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}"));
Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major, newer.Minor, newer.Build));

newer = new Version(currentVersion.Major, currentVersion.Minor, currentVersion.Build, currentVersion.Revision + 1);
Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}"));
Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major, newer.Minor, newer.Build, newer.Revision));
}

[Theory]
[MemberData(nameof(AllKnownOsPlatforms))]
public void IsOSPlatformOrLater_ReturnsTrue_ForOlderVersionOfCurrentOS(OSPlatform osPlatform)
{
// IsOSPlatformOrLater("xyz10.0") running as "xyz11.0" should return true

bool isCurrentPlatfom = RuntimeInformation.IsOSPlatform(osPlatform);
Version current = Environment.OSVersion.Version;

Version older = new Version(current.Major - 1, 0);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major));

if (current.Minor > 0)
{
older = new Version(current.Major, current.Minor - 1);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major, older.Minor));
}

if (current.Build > 0)
{
older = new Version(current.Major, current.Minor, current.Build - 1);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major, older.Minor, older.Build));
}

if (current.Revision > 0)
{
older = new Version(current.Major, current.Minor, current.Build, current.Revision - 1);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major, older.Minor, older.Build, older.Revision));
}
}

[Fact]
public void IsOSPlatformEarlierThan_Null_ThrowsArgumentNullExceptionWithArgumentName()
{
Assert.Throws<ArgumentNullException>("platformName", () => RuntimeInformation.IsOSPlatformEarlierThan(null));
}

[Fact]
public void IsOSPlatformEarlierThan_Empty_ThrowsArgumentNullExceptionWithArgumentName()
{
Assert.Throws<ArgumentException>("platformName", () => RuntimeInformation.IsOSPlatformEarlierThan(string.Empty));
}

[Theory]
[InlineData("ios")] // missing version number
[InlineData("ios14")] // ios14.0 is fine, ios14 is not
[InlineData("ios14.0.0.0.0.0")] // too many numbers
public void IsOSPlatformEarlierThan_InvalidVersionNumber_ThrowsArgumentExceptionWithArgumentName(string platformName)
{
Assert.Throws<ArgumentException>("platformName", () => RuntimeInformation.IsOSPlatformEarlierThan(platformName));
}

[Theory]
[MemberData(nameof(AllKnownOsPlatforms))]
public void IsOSPlatformEarlierThan_ReturnsFalse_ForCurrentOS(OSPlatform osPlatform)
{
// IsOSPlatformEarlierThan("xyz1.2.3.4") running as "xyz1.2.3.4" should return false

Version current = Environment.OSVersion.Version;

Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{current}"));

Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major));

if (current.Minor >= 0)
{
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major, current.Minor));

if (current.Build >= 0)
{
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major, current.Minor, current.Build));

if (current.Revision >= 0)
{
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major, current.Minor, current.Build, current.Revision));
}
}
}
}

[Theory]
[MemberData(nameof(AllKnownOsPlatforms))]
public void IsOSPlatformEarlierThan_ReturnsTrue_ForNewerVersionOfCurrentOS(OSPlatform osPlatform)
{
// IsOSPlatformEarlierThan("xyz11.0") running as "xyz10.0" should return true

bool isCurrentPlatfom = RuntimeInformation.IsOSPlatform(osPlatform);
Version current = Environment.OSVersion.Version;

Version newer = new Version(current.Major + 1, 0);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major));

newer = new Version(current.Major, current.Minor + 1);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major, newer.Minor));

newer = new Version(current.Major, current.Minor, current.Build + 1);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major, newer.Minor, newer.Build));

newer = new Version(current.Major, current.Minor, current.Build, current.Revision + 1);
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}"));
Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major, newer.Minor, newer.Build, newer.Revision));
}

[Theory]
[MemberData(nameof(AllKnownOsPlatforms))]
public void IsOSPlatformEarlierThan_ReturnsFalse_ForOlderVersionOfCurrentOS(OSPlatform osPlatform)
{
// IsOSPlatformEarlierThan("xyz10.0") running as "xyz11.0" should return false

Version current = Environment.OSVersion.Version;

Version older = new Version(current.Major - 1, 0);
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}"));
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major));

if (current.Minor > 0)
{
older = new Version(current.Major, current.Minor - 1);
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}"));
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major, older.Minor));
}

if (current.Build > 0)
{
older = new Version(current.Major, current.Minor, current.Build - 1);
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}"));
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major, older.Minor, older.Build));
}

if (current.Revision > 0)
{
older = new Version(current.Major, current.Minor, current.Build, current.Revision - 1);
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}"));
Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major, older.Minor, older.Build, older.Revision));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser</TargetFrameworks>
Expand All @@ -8,6 +8,7 @@
<Compile Include="CheckPlatformTests.cs" />
<Compile Include="RuntimeIdentifierTests.cs" />
<Compile Include="DescriptionNameTests.cs" />
<Compile Include="PlatformVersionTests.cs" />
<Compile Include="$(CommonPath)Interop\Linux\cgroups\Interop.cgroups.cs"
Link="Common\Interop\Linux\Interop.cgroups.cs" />
</ItemGroup>
Expand Down