Skip to content

Commit 6a1b155

Browse files
authored
Adding MaximumOSVersionAttribute (dotnet/extensions#2715)
\n\nCommit migrated from dotnet/extensions@9f29643
1 parent a145742 commit 6a1b155

File tree

5 files changed

+245
-0
lines changed

5 files changed

+245
-0
lines changed

src/Testing/ref/Microsoft.AspNetCore.Testing.net46.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ public partial interface ITestMethodLifecycle
170170
System.Threading.Tasks.Task OnTestStartAsync(Microsoft.AspNetCore.Testing.TestContext context, System.Threading.CancellationToken cancellationToken);
171171
}
172172
[System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)]
173+
public partial class MaximumOSVersionAttribute : System.Attribute, Microsoft.AspNetCore.Testing.ITestCondition
174+
{
175+
public MaximumOSVersionAttribute(Microsoft.AspNetCore.Testing.OperatingSystems operatingSystem, string maxVersion) { }
176+
public bool IsMet { get { throw null; } }
177+
public string SkipReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
178+
}
179+
[System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)]
173180
public partial class MinimumOSVersionAttribute : System.Attribute, Microsoft.AspNetCore.Testing.ITestCondition
174181
{
175182
public MinimumOSVersionAttribute(Microsoft.AspNetCore.Testing.OperatingSystems operatingSystem, string minVersion) { }

src/Testing/ref/Microsoft.AspNetCore.Testing.netstandard2.0.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ public partial interface ITestMethodLifecycle
170170
System.Threading.Tasks.Task OnTestStartAsync(Microsoft.AspNetCore.Testing.TestContext context, System.Threading.CancellationToken cancellationToken);
171171
}
172172
[System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)]
173+
public partial class MaximumOSVersionAttribute : System.Attribute, Microsoft.AspNetCore.Testing.ITestCondition
174+
{
175+
public MaximumOSVersionAttribute(Microsoft.AspNetCore.Testing.OperatingSystems operatingSystem, string maxVersion) { }
176+
public bool IsMet { get { throw null; } }
177+
public string SkipReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
178+
}
179+
[System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)]
173180
public partial class MinimumOSVersionAttribute : System.Attribute, Microsoft.AspNetCore.Testing.ITestCondition
174181
{
175182
public MinimumOSVersionAttribute(Microsoft.AspNetCore.Testing.OperatingSystems operatingSystem, string minVersion) { }
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
7+
namespace Microsoft.AspNetCore.Testing
8+
{
9+
/// <summary>
10+
/// Skips a test if the OS is the given type (Windows) and the OS version is greater than specified.
11+
/// E.g. Specifying Window 8 skips on Win 10, but not on Linux. Combine with OSSkipConditionAttribute as needed.
12+
/// </summary>
13+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
14+
public class MaximumOSVersionAttribute : Attribute, ITestCondition
15+
{
16+
private readonly OperatingSystems _targetOS;
17+
private readonly Version _maxVersion;
18+
private readonly OperatingSystems _currentOS;
19+
private readonly Version _currentVersion;
20+
private readonly bool _skip;
21+
22+
public MaximumOSVersionAttribute(OperatingSystems operatingSystem, string maxVersion) :
23+
this(operatingSystem, Version.Parse(maxVersion), GetCurrentOS(), GetCurrentOSVersion())
24+
{
25+
}
26+
27+
// to enable unit testing
28+
internal MaximumOSVersionAttribute(OperatingSystems targetOS, Version maxVersion, OperatingSystems currentOS, Version currentVersion)
29+
{
30+
if (targetOS != OperatingSystems.Windows)
31+
{
32+
throw new NotImplementedException("Max version support is only implemented for Windows.");
33+
}
34+
_targetOS = targetOS;
35+
_maxVersion = maxVersion;
36+
_currentOS = currentOS;
37+
_currentVersion = currentVersion;
38+
39+
// Do not skip other OS's, Use OSSkipConditionAttribute or a separate MaximumOsVersionAttribute for that.
40+
_skip = _targetOS == _currentOS && _maxVersion < _currentVersion;
41+
SkipReason = $"This test requires {_targetOS} {_maxVersion} or earlier.";
42+
}
43+
44+
// Since a test would be executed only if 'IsMet' is true, return false if we want to skip
45+
public bool IsMet => !_skip;
46+
47+
public string SkipReason { get; set; }
48+
49+
private static OperatingSystems GetCurrentOS()
50+
{
51+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
52+
{
53+
return OperatingSystems.Windows;
54+
}
55+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
56+
{
57+
return OperatingSystems.Linux;
58+
}
59+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
60+
{
61+
return OperatingSystems.MacOSX;
62+
}
63+
throw new PlatformNotSupportedException();
64+
}
65+
66+
static private Version GetCurrentOSVersion()
67+
{
68+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
69+
{
70+
return Environment.OSVersion.Version;
71+
}
72+
else
73+
{
74+
// Not implemented, but this will still be called before the OS check happens so don't throw.
75+
return new Version(0, 0);
76+
}
77+
}
78+
}
79+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using Xunit;
6+
7+
namespace Microsoft.AspNetCore.Testing
8+
{
9+
public class MaximumOSVersionAttributeTest
10+
{
11+
[Fact]
12+
public void Linux_ThrowsNotImplemeneted()
13+
{
14+
Assert.Throws<NotImplementedException>(() => new MaximumOSVersionAttribute(OperatingSystems.Linux, "2.5"));
15+
}
16+
17+
[Fact]
18+
public void Mac_ThrowsNotImplemeneted()
19+
{
20+
Assert.Throws<NotImplementedException>(() => new MaximumOSVersionAttribute(OperatingSystems.MacOSX, "2.5"));
21+
}
22+
23+
[Fact]
24+
public void WindowsOrLinux_ThrowsNotImplemeneted()
25+
{
26+
Assert.Throws<NotImplementedException>(() => new MaximumOSVersionAttribute(OperatingSystems.Linux | OperatingSystems.Windows, "2.5"));
27+
}
28+
29+
[Fact]
30+
public void DoesNotSkip_EarlierVersions()
31+
{
32+
var osSkipAttribute = new MaximumOSVersionAttribute(
33+
OperatingSystems.Windows,
34+
new Version("2.5"),
35+
OperatingSystems.Windows,
36+
new Version("2.0"));
37+
38+
Assert.True(osSkipAttribute.IsMet);
39+
}
40+
41+
[Fact]
42+
public void DoesNotSkip_SameVersion()
43+
{
44+
var osSkipAttribute = new MaximumOSVersionAttribute(
45+
OperatingSystems.Windows,
46+
new Version("2.5"),
47+
OperatingSystems.Windows,
48+
new Version("2.5"));
49+
50+
Assert.True(osSkipAttribute.IsMet);
51+
}
52+
53+
[Fact]
54+
public void Skip_LaterVersion()
55+
{
56+
var osSkipAttribute = new MaximumOSVersionAttribute(
57+
OperatingSystems.Windows,
58+
new Version("2.5"),
59+
OperatingSystems.Windows,
60+
new Version("3.0"));
61+
62+
Assert.False(osSkipAttribute.IsMet);
63+
}
64+
65+
[Fact]
66+
public void DoesNotSkip_WhenOnlyVersionsMatch()
67+
{
68+
var osSkipAttribute = new MaximumOSVersionAttribute(
69+
OperatingSystems.Windows,
70+
new Version("2.5"),
71+
OperatingSystems.Linux,
72+
new Version("2.5"));
73+
74+
Assert.True(osSkipAttribute.IsMet);
75+
}
76+
}
77+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
using Microsoft.Win32;
7+
using Xunit;
8+
9+
namespace Microsoft.AspNetCore.Testing
10+
{
11+
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
12+
public class MaximumOSVersionTest
13+
{
14+
[ConditionalFact]
15+
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)]
16+
public void RunTest_Win7DoesRunOnWin7()
17+
{
18+
Assert.True(
19+
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
20+
Environment.OSVersion.Version.ToString().StartsWith("6.1"),
21+
"Test should only be running on Win7 or Win2008R2.");
22+
}
23+
24+
[ConditionalTheory]
25+
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)]
26+
[InlineData(1)]
27+
public void RunTheory_Win7DoesRunOnWin7(int arg)
28+
{
29+
Assert.True(
30+
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
31+
Environment.OSVersion.Version.ToString().StartsWith("6.1"),
32+
"Test should only be running on Win7 or Win2008R2.");
33+
}
34+
35+
[ConditionalFact]
36+
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)]
37+
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
38+
public void RunTest_Win10_RS4()
39+
{
40+
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
41+
var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
42+
Assert.NotNull(versionKey);
43+
var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber");
44+
Assert.NotNull(currentVersion);
45+
Assert.True(17134 >= int.Parse(currentVersion));
46+
}
47+
48+
[ConditionalFact]
49+
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H2)]
50+
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
51+
public void RunTest_Win10_19H2()
52+
{
53+
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
54+
var versionKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
55+
Assert.NotNull(versionKey);
56+
var currentVersion = (string)versionKey.GetValue("CurrentBuildNumber");
57+
Assert.NotNull(currentVersion);
58+
Assert.True(18363 >= int.Parse(currentVersion));
59+
}
60+
}
61+
62+
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)]
63+
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
64+
public class OSMaxVersionClassTest
65+
{
66+
[ConditionalFact]
67+
public void TestSkipClass_Win7DoesRunOnWin7()
68+
{
69+
Assert.True(
70+
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
71+
Environment.OSVersion.Version.ToString().StartsWith("6.1"),
72+
"Test should only be running on Win7 or Win2008R2.");
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)