Add OSMinVersionAttribute (dotnet/extensions#2449)

\n\nCommit migrated from ddc00c0f2f
This commit is contained in:
Chris Ross 2019-10-03 21:03:01 -07:00 committed by GitHub
parent 8116c35f54
commit f31f20e70a
4 changed files with 249 additions and 0 deletions

View File

@ -0,0 +1,81 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Testing
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
public class OSMinVersionAttribute : Attribute, ITestCondition
{
private readonly OperatingSystems _targetOS;
private readonly Version _minVersion;
private readonly OperatingSystems _currentOS;
private readonly Version _currentVersion;
private readonly bool _skip;
/// <summary>
/// Used to indicate the minimum version a test can run on for the given operating system.
/// Also add <see cref="OSSkipConditionAttribute"/> to skip other operating systems.
/// </summary>
/// <param name="targetOS">The OS to check for a version. Only Windows is currently supported.</param>
/// <param name="minVersion">The minimum OS version NOT to skip.</param>
public OSMinVersionAttribute(OperatingSystems targetOS, string minVersion) :
this(targetOS, Version.Parse(minVersion), GetCurrentOS(), GetCurrentOSVersion())
{
}
// to enable unit testing
internal OSMinVersionAttribute(OperatingSystems targetOS, Version minVersion, OperatingSystems currentOS, Version currentVersion)
{
if (targetOS != OperatingSystems.Windows)
{
throw new NotImplementedException(targetOS.ToString());
}
_targetOS = targetOS;
_minVersion = minVersion;
_currentOS = currentOS;
_currentVersion = currentVersion;
_skip = _targetOS == _currentOS && _minVersion > _currentVersion;
SkipReason = $"The test cannot run on this operating system version '{currentVersion}'.";
}
// Since a test would be excuted only if 'IsMet' is true, return false if we want to skip
public bool IsMet => !_skip;
public string SkipReason { get; set; }
static private OperatingSystems GetCurrentOS()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return OperatingSystems.Windows;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return OperatingSystems.Linux;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return OperatingSystems.MacOSX;
}
throw new PlatformNotSupportedException();
}
static private Version GetCurrentOSVersion()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Environment.OSVersion.Version;
}
else
{
// Not implmeneted, but this will still be called before the OS check happens so don't throw.
return new Version(0, 0);
}
}
}
}

View File

@ -3,6 +3,9 @@
namespace Microsoft.AspNetCore.Testing
{
/// <summary>
/// https://en.wikipedia.org/wiki/Windows_10_version_history
/// </summary>
public static class WindowsVersions
{
public const string Win7 = "6.1";
@ -14,5 +17,20 @@ namespace Microsoft.AspNetCore.Testing
public const string Win81 = "6.3";
public const string Win10 = "10.0";
/// <summary>
/// 1803, RS4, 17134
/// </summary>
public const string Win10_RS4 = "10.0.17134";
/// <summary>
/// 1909, 19H2, 18363
/// </summary>
public const string Win10_19H2 = "10.0.18363";
/// <summary>
/// _, 20H2, 18990
/// </summary>
public const string Win10_20H1 = "10.0.18990";
}
}

View File

@ -0,0 +1,77 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Xunit;
namespace Microsoft.AspNetCore.Testing
{
public class OSMinVersionAttributeTest
{
[Fact]
public void Linux_ThrowsNotImplemeneted()
{
Assert.Throws<NotImplementedException>(() => new OSMinVersionAttribute(OperatingSystems.Linux, "2.5"));
}
[Fact]
public void Mac_ThrowsNotImplemeneted()
{
Assert.Throws<NotImplementedException>(() => new OSMinVersionAttribute(OperatingSystems.MacOSX, "2.5"));
}
[Fact]
public void WindowsOrLinux_ThrowsNotImplemeneted()
{
Assert.Throws<NotImplementedException>(() => new OSMinVersionAttribute(OperatingSystems.Linux | OperatingSystems.Windows, "2.5"));
}
[Fact]
public void DoesNotSkip_LaterVersions()
{
var osSkipAttribute = new OSMinVersionAttribute(
OperatingSystems.Windows,
new Version("2.0"),
OperatingSystems.Windows,
new Version("2.5"));
Assert.True(osSkipAttribute.IsMet);
}
[Fact]
public void DoesNotSkip_SameVersion()
{
var osSkipAttribute = new OSMinVersionAttribute(
OperatingSystems.Windows,
new Version("2.5"),
OperatingSystems.Windows,
new Version("2.5"));
Assert.True(osSkipAttribute.IsMet);
}
[Fact]
public void Skip_EarlierVersion()
{
var osSkipAttribute = new OSMinVersionAttribute(
OperatingSystems.Windows,
new Version("3.0"),
OperatingSystems.Windows,
new Version("2.5"));
Assert.False(osSkipAttribute.IsMet);
}
[Fact]
public void DoesNotSkip_WhenOnlyVersionsMatch()
{
var osSkipAttribute = new OSMinVersionAttribute(
OperatingSystems.Windows,
new Version("2.5"),
OperatingSystems.Linux,
new Version("2.5"));
Assert.True(osSkipAttribute.IsMet);
}
}
}

View File

@ -0,0 +1,73 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Xunit;
namespace Microsoft.AspNetCore.Testing
{
public class OSMinVersionTest
{
[ConditionalFact]
[OSMinVersion(OperatingSystems.Windows, WindowsVersions.Win8)]
public void RunTest_Win8DoesNotRunOnWin7()
{
Assert.False(
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
Environment.OSVersion.Version.ToString().StartsWith("6.1"),
"Test should not be running on Win7 or Win2008R2.");
}
[ConditionalTheory]
[OSMinVersion(OperatingSystems.Windows, WindowsVersions.Win8)]
[InlineData(1)]
public void RunTheory_Win8DoesNotRunOnWin7(int arg)
{
Assert.False(
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
Environment.OSVersion.Version.ToString().StartsWith("6.1"),
"Test should not be running on Win7 or Win2008R2.");
}
[ConditionalFact]
[OSMinVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public void RunTest_Win10_RS4()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
Assert.NotNull(versionKey);
var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber");
Assert.NotNull(currentVersion);
Assert.True(17134 <= int.Parse(currentVersion));
}
[ConditionalFact]
[OSMinVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H2)]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public void RunTest_Win10_19H2()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
Assert.NotNull(versionKey);
var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber");
Assert.NotNull(currentVersion);
Assert.True(18363 <= int.Parse(currentVersion));
}
}
[OSMinVersion(OperatingSystems.Windows, WindowsVersions.Win8)]
public class OSMinVersionClassTest
{
[ConditionalFact]
public void TestSkipClass_Win8DoesNotRunOnWin7()
{
Assert.False(
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
Environment.OSVersion.Version.ToString().StartsWith("6.1"),
"Test should not be running on Win7 or Win2008R2.");
}
}
}