Add IgnoreIf attribute to only run SDC tests on Windows

This commit is contained in:
Malte Rosenbjerg 2023-01-29 22:55:35 +01:00
parent 11997d91f9
commit fb6865587a
5 changed files with 166 additions and 17 deletions

View file

@ -11,6 +11,7 @@
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFMpegCore.Extensions.System.Drawing.Common; using FFMpegCore.Extensions.System.Drawing.Common;
using FFMpegCore.Test.Utilities;
namespace FFMpegCore.Test namespace FFMpegCore.Test
{ {
@ -66,8 +67,8 @@ public void Audio_Add()
Assert.IsTrue(File.Exists(outputFile)); Assert.IsTrue(File.Exists(outputFile));
} }
[TestMethod] [TestMethodWithIgnoreIfSupport]
[SupportedOSPlatform("windows")] [IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Image_AddAudio() public void Image_AddAudio()
{ {
using var outputFile = new TemporaryFile("out.mp4"); using var outputFile = new TemporaryFile("out.mp4");

View file

@ -0,0 +1,39 @@
using System;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FFMpegCore.Test.Utilities;
// https://matt.kotsenas.com/posts/ignoreif-mstest
/// <summary>
/// An extension to the [Ignore] attribute. Instead of using test lists / test categories to conditionally
/// skip tests, allow a [TestClass] or [TestMethod] to specify a method to run. If the method returns
/// `true` the test method will be skipped. The "ignore criteria" method must be `static`, return a single
/// `bool` value, and not accept any parameters. By default, it is named "IgnoreIf".
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class IgnoreIfAttribute : Attribute
{
public string IgnoreCriteriaMethodName { get; set; }
public IgnoreIfAttribute(string ignoreCriteriaMethodName = "IgnoreIf")
{
IgnoreCriteriaMethodName = ignoreCriteriaMethodName;
}
internal bool ShouldIgnore(ITestMethod testMethod)
{
try
{
// Search for the method specified by name in this class or any parent classes.
var searchFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static;
var method = testMethod.MethodInfo.DeclaringType!.GetMethod(IgnoreCriteriaMethodName, searchFlags);
return (bool) method?.Invoke(null, null)!;
}
catch (Exception e)
{
var message = $"Conditional ignore method {IgnoreCriteriaMethodName} not found. Ensure the method is in the same class as the test method, marked as `static`, returns a `bool`, and doesn't accept any parameters.";
throw new ArgumentException(message, e);
}
}
}

View file

@ -0,0 +1,11 @@
using System.Runtime.InteropServices;
namespace FFMpegCore.Test.Utilities;
public static class OperatingSystemUtils
{
public static bool NotWindows()
{
return !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
}
}

View file

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FFMpegCore.Test.Utilities;
// https://matt.kotsenas.com/posts/ignoreif-mstest
/// <summary>
/// An extension to the [TestMethod] attribute. It walks the method and class hierarchy looking
/// for an [IgnoreIf] attribute. If one or more are found, they are each evaluated, if the attribute
/// returns `true`, evaluation is short-circuited, and the test method is skipped.
/// </summary>
public class TestMethodWithIgnoreIfSupportAttribute : TestMethodAttribute
{
public override TestResult[] Execute(ITestMethod testMethod)
{
var ignoreResults = TestMethodUtils.GetIgnoreResults(testMethod);
return ignoreResults.Any()
? ignoreResults
: base.Execute(testMethod);
}
}
public class DataTestMethodWithIgnoreIfSupportAttribute : DataTestMethodAttribute
{
public override TestResult[] Execute(ITestMethod testMethod)
{
var ignoreResults = TestMethodUtils.GetIgnoreResults(testMethod);
return ignoreResults.Any()
? ignoreResults
: base.Execute(testMethod);
}
}
internal class TestMethodUtils
{
internal static TestResult[] GetIgnoreResults(ITestMethod testMethod)
{
var ignoreAttributes = FindAttributes(testMethod);
// Evaluate each attribute, and skip if one returns `true`
foreach (var ignoreAttribute in ignoreAttributes)
{
if (ignoreAttribute.ShouldIgnore(testMethod))
{
var message = $"Test not executed. Conditional ignore method '{ignoreAttribute.IgnoreCriteriaMethodName}' evaluated to 'true'.";
{
return new[]
{
new TestResult { Outcome = UnitTestOutcome.Inconclusive, TestFailureException = new AssertInconclusiveException(message) }
};
}
}
}
return Array.Empty<TestResult>();
}
private static IEnumerable<IgnoreIfAttribute> FindAttributes(ITestMethod testMethod)
{
// Look for an [IgnoreIf] on the method, including any virtuals this method overrides
var ignoreAttributes = new List<IgnoreIfAttribute>();
ignoreAttributes.AddRange(testMethod.GetAttributes<IgnoreIfAttribute>(inherit: true));
// Walk the class hierarchy looking for an [IgnoreIf] attribute
var type = testMethod.MethodInfo.DeclaringType;
while (type != null)
{
ignoreAttributes.AddRange(type.GetCustomAttributes<IgnoreIfAttribute>(inherit: true));
type = type.DeclaringType;
}
return ignoreAttributes;
}
}

View file

@ -10,10 +10,12 @@
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.Versioning;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFMpegCore.Extensions.System.Drawing.Common; using FFMpegCore.Extensions.System.Drawing.Common;
using FFMpegCore.Test.Utilities;
namespace FFMpegCore.Test namespace FFMpegCore.Test
{ {
@ -86,7 +88,9 @@ public void Video_ToH265_MKV_Args()
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[DataTestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[DataTestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
public void Video_ToMP4_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat) public void Video_ToMP4_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
@ -102,7 +106,9 @@ public void Video_ToMP4_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[TestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Video_ToMP4_Args_Pipe_DifferentImageSizes() public void Video_ToMP4_Args_Pipe_DifferentImageSizes()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
@ -121,8 +127,9 @@ public void Video_ToMP4_Args_Pipe_DifferentImageSizes()
.ProcessSynchronously()); .ProcessSynchronously());
} }
[SupportedOSPlatform("windows")]
[TestMethod, Timeout(10000)] [TestMethodWithIgnoreIfSupport, Timeout(10000)][SupportedOSPlatform("windows")]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public async Task Video_ToMP4_Args_Pipe_DifferentImageSizes_Async() public async Task Video_ToMP4_Args_Pipe_DifferentImageSizes_Async()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
@ -141,7 +148,9 @@ public async Task Video_ToMP4_Args_Pipe_DifferentImageSizes_Async()
.ProcessAsynchronously()); .ProcessAsynchronously());
} }
[TestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Video_ToMP4_Args_Pipe_DifferentPixelFormats() public void Video_ToMP4_Args_Pipe_DifferentPixelFormats()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
@ -160,8 +169,9 @@ public void Video_ToMP4_Args_Pipe_DifferentPixelFormats()
.ProcessSynchronously()); .ProcessSynchronously());
} }
[SupportedOSPlatform("windows")]
[TestMethod, Timeout(10000)] [TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public async Task Video_ToMP4_Args_Pipe_DifferentPixelFormats_Async() public async Task Video_ToMP4_Args_Pipe_DifferentPixelFormats_Async()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
@ -315,7 +325,9 @@ public void Video_ToTS_Args()
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[DataTestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[DataTestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
public async Task Video_ToTS_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat) public async Task Video_ToTS_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat)
@ -347,7 +359,9 @@ public async Task Video_ToOGV_Resize()
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[DataTestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[DataTestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
// [DataRow(PixelFormat.Format48bppRgb)] // [DataRow(PixelFormat.Format48bppRgb)]
@ -382,7 +396,9 @@ public void Scale_Mp4_Multithreaded()
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[DataTestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[DataTestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
[DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format24bppRgb)]
[DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)] [DataRow(System.Drawing.Imaging.PixelFormat.Format32bppArgb)]
// [DataRow(PixelFormat.Format48bppRgb)] // [DataRow(PixelFormat.Format48bppRgb)]
@ -399,7 +415,9 @@ public void Video_ToMP4_Resize_Args_Pipe(System.Drawing.Imaging.PixelFormat pixe
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[TestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Video_Snapshot_InMemory() public void Video_Snapshot_InMemory()
{ {
var input = FFProbe.Analyse(TestResources.Mp4Video); var input = FFProbe.Analyse(TestResources.Mp4Video);
@ -410,7 +428,9 @@ public void Video_Snapshot_InMemory()
Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png); Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png);
} }
[TestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Video_Snapshot_PersistSnapshot() public void Video_Snapshot_PersistSnapshot()
{ {
var outputPath = new TemporaryFile("out.png"); var outputPath = new TemporaryFile("out.png");
@ -446,7 +466,8 @@ public void Video_Join()
Assert.AreEqual(input.PrimaryVideoStream.Width, result.PrimaryVideoStream.Width); Assert.AreEqual(input.PrimaryVideoStream.Width, result.PrimaryVideoStream.Width);
} }
[TestMethod, Timeout(10000)] [TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Video_Join_Image_Sequence() public void Video_Join_Image_Sequence()
{ {
var imageSet = new List<ImageInfo>(); var imageSet = new List<ImageInfo>();
@ -555,7 +576,9 @@ public void Video_OutputsData()
Assert.IsTrue(File.Exists(outputFile)); Assert.IsTrue(File.Exists(outputFile));
} }
[TestMethod, Timeout(10000)] [SupportedOSPlatform("windows")]
[TestMethodWithIgnoreIfSupport, Timeout(10000)]
[IgnoreIf(nameof(OperatingSystemUtils.NotWindows))]
public void Video_TranscodeInMemory() public void Video_TranscodeInMemory()
{ {
using var resStream = new MemoryStream(); using var resStream = new MemoryStream();