Skip to content

Commit

Permalink
Skip UDS unit tests on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
mayuki committed Dec 19, 2024
1 parent 2521356 commit 08fd962
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Xunit;
using Xunit.Sdk;

namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("_YetAnotherHttpHandler.Test.Helpers.Testing." + nameof(ConditionalFactDiscoverer), "YetAnotherHttpHandler.Test")]
public class ConditionalFactAttribute : FactAttribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit.Abstractions;
using Xunit.Sdk;

// Do not change this namespace without changing the usage in ConditionalFactAttribute
namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

internal sealed class ConditionalFactDiscoverer : FactDiscoverer
{
private readonly IMessageSink _diagnosticMessageSink;

public ConditionalFactDiscoverer(IMessageSink diagnosticMessageSink)
: base(diagnosticMessageSink)
{
_diagnosticMessageSink = diagnosticMessageSink;
}

protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
var skipReason = testMethod.EvaluateSkipConditions();
return skipReason != null
? new SkippedTestCase(skipReason, _diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod)
: base.CreateTestCase(discoveryOptions, testMethod, factAttribute);
}
}
11 changes: 11 additions & 0 deletions test/YetAnotherHttpHandler.Test/Helpers/Testing/ITestCondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

public interface ITestCondition
{
bool IsMet { get; }

string SkipReason { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// https://github.com/dotnet/aspnetcore/tree/v7.0.0/src/Testing/src

using System.Runtime.InteropServices;
using System;

namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
public class OSSkipConditionAttribute : Attribute, ITestCondition
{
private readonly OperatingSystems _excludedOperatingSystem;
private readonly OperatingSystems _osPlatform;

public OSSkipConditionAttribute(OperatingSystems operatingSystem) :
this(operatingSystem, GetCurrentOS())
{
}

[Obsolete("Use the Minimum/MaximumOSVersionAttribute for version checks.", error: true)]
public OSSkipConditionAttribute(OperatingSystems operatingSystem, params string[] versions) :
this(operatingSystem, GetCurrentOS())
{
}

// to enable unit testing
internal OSSkipConditionAttribute(OperatingSystems operatingSystem, OperatingSystems osPlatform)
{
_excludedOperatingSystem = operatingSystem;
_osPlatform = osPlatform;
}

public bool IsMet
{
get
{
var skip = (_excludedOperatingSystem & _osPlatform) == _osPlatform;
// Since a test would be excuted only if 'IsMet' is true, return false if we want to skip
return !skip;
}
}

public string SkipReason { get; set; } = "Test cannot run on this operating system.";

private static 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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

[Flags]
public enum OperatingSystems
{
Linux = 1,
MacOSX = 2,
Windows = 4,
}
49 changes: 49 additions & 0 deletions test/YetAnotherHttpHandler.Test/Helpers/Testing/SkippedTestCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Xunit.Abstractions;
using Xunit.Sdk;
#pragma warning disable CS8625

namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

public class SkippedTestCase : XunitTestCase
{
private string? _skipReason;

[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public SkippedTestCase() : base()
{
}

public SkippedTestCase(
string skipReason,
IMessageSink diagnosticMessageSink,
TestMethodDisplay defaultMethodDisplay,
TestMethodDisplayOptions defaultMethodDisplayOptions,
ITestMethod testMethod,
object[] testMethodArguments = null)
: base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments)
{
_skipReason = skipReason;
}

protected override string GetSkipReason(IAttributeInfo factAttribute)
=> _skipReason ?? base.GetSkipReason(factAttribute);

public override void Deserialize(IXunitSerializationInfo data)
{
_skipReason = data.GetValue<string>(nameof(_skipReason));

// We need to call base after reading our value, because Deserialize will call
// into GetSkipReason.
base.Deserialize(data);
}

public override void Serialize(IXunitSerializationInfo data)
{
base.Serialize(data);
data.AddValue(nameof(_skipReason), _skipReason);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;

namespace _YetAnotherHttpHandler.Test.Helpers.Testing;

public static class TestMethodExtensions
{
public static string? EvaluateSkipConditions(this ITestMethod testMethod)
{
var testClass = testMethod.TestClass.Class;
var assembly = testMethod.TestClass.TestCollection.TestAssembly.Assembly;
var conditionAttributes = testMethod.Method
.GetCustomAttributes(typeof(ITestCondition))
.Concat(testClass.GetCustomAttributes(typeof(ITestCondition)))
.Concat(assembly.GetCustomAttributes(typeof(ITestCondition)))
.OfType<ReflectionAttributeInfo>()
.Select(attributeInfo => attributeInfo.Attribute);

foreach (ITestCondition condition in conditionAttributes)
{
if (!condition.IsMet)
{
return condition.SkipReason;
}
}

return null;
}
}
Loading

0 comments on commit 08fd962

Please sign in to comment.