From c52674b375943feca3eea8714101bb6bdfc34fe4 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 00:51:59 +0100 Subject: [PATCH 01/23] update xunit & workaround conversion issues --- tests/Directory.Build.targets | 4 +- .../PorterDuffFunctionsTests_TPixel.cs | 90 +++++++++---------- .../PixelOperations/PixelOperationsTests.cs | 20 ++--- .../TestUtilities/TestPixel.cs | 5 -- 4 files changed, 57 insertions(+), 62 deletions(-) diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index 9ee9c226d..da21cbb75 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -48,8 +48,8 @@ - - + + diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs index 859be6b20..6706e4077 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs @@ -29,8 +29,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void NormalBlendFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.NormalSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.NormalSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -38,8 +38,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void NormalBlendFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.NormalSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.NormalSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.NormalSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData MultiplyFunctionData = new TheoryData { @@ -68,8 +68,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void MultiplyFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.MultiplySrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.MultiplySrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -77,8 +77,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void MultiplyFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.MultiplySrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.MultiplySrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.MultiplySrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData AddFunctionData = new TheoryData { @@ -107,8 +107,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void AddFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.AddSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.AddSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -116,8 +116,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void AddFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.AddSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.AddSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.AddSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData SubtractFunctionData = new TheoryData { @@ -146,8 +146,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void SubtractFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.SubtractSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.SubtractSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -155,8 +155,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void SubtractFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.SubtractSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.SubtractSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -166,7 +166,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.SubtractSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData ScreenFunctionData = new TheoryData { @@ -185,8 +185,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void ScreenFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.ScreenSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.ScreenSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -194,8 +194,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void ScreenFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.ScreenSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.ScreenSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -205,7 +205,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.ScreenSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData DarkenFunctionData = new TheoryData { @@ -224,8 +224,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void DarkenFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.DarkenSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.DarkenSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -233,8 +233,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void DarkenFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.DarkenSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.DarkenSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -244,7 +244,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.DarkenSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData LightenFunctionData = new TheoryData { @@ -263,8 +263,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void LightenFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.LightenSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.LightenSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -272,8 +272,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void LightenFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.LightenSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.LightenSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -283,7 +283,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.LightenSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData OverlayFunctionData = new TheoryData { @@ -302,8 +302,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void OverlayFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.OverlaySrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.OverlaySrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -311,8 +311,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void OverlayFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.OverlaySrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.OverlaySrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -322,7 +322,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.OverlaySrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } public static TheoryData HardLightFunctionData = new TheoryData { @@ -341,8 +341,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void HardLightFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = PorterDuffFunctions.HardLightSrcOver((TPixel)back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = PorterDuffFunctions.HardLightSrcOver(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -350,8 +350,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders public void HardLightFunctionBlender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { - TPixel actual = new DefaultPixelBlenders.HardLightSrcOver().Blend(back, source, amount); - VectorAssert.Equal(expected, actual, 2); + TPixel actual = new DefaultPixelBlenders.HardLightSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); + VectorAssert.Equal(expected.AsPixel(), actual, 2); } [Theory] @@ -361,7 +361,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders { var dest = new Span(new TPixel[1]); new DefaultPixelBlenders.HardLightSrcOver().Blend(this.Configuration, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); - VectorAssert.Equal(expected, dest[0], 2); + VectorAssert.Equal(expected.AsPixel(), dest[0], 2); } } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index ef2531060..9b6814f9a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; using SixLabors.ImageSharp.ColorSpaces.Companding; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; - +using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; using Xunit.Abstractions; @@ -279,20 +279,20 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations } - public static readonly TheoryData Generic_To_Data = new TheoryData + public static readonly TheoryData Generic_To_Data = new TheoryData { - default(Rgba32), - default(Bgra32), - default(Rgb24), - default(L8), - default(L16), - default(Rgb48), - default(Rgba64) + new TestPixel(), + new TestPixel(), + new TestPixel(), + new TestPixel(), + new TestPixel(), + new TestPixel(), + new TestPixel() }; [Theory] [MemberData(nameof(Generic_To_Data))] - public void Generic_To(TDestPixel dummy) + public void Generic_To(TestPixel dummy) where TDestPixel : struct, IPixel { const int Count = 2134; diff --git a/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs b/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs index 1e1a45f07..f3be50e9a 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs @@ -29,11 +29,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities public float Blue { get; set; } public float Alpha { get; set; } - public static implicit operator TPixel(TestPixel d) - { - return d?.AsPixel() ?? default(TPixel); - } - public TPixel AsPixel() { TPixel pix = default(TPixel); From a626e3a712221ddea2fe5de6d679f5446c89322b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 03:20:52 +0100 Subject: [PATCH 02/23] Run ArrayPoolMemoryAllocatorTests in separate process, implement BasicSerializer --- ImageSharp.sln | 1 + .../ArrayPoolMemoryAllocatorTests.cs | 182 +++++++++--------- .../TestUtilities/BasicSerializer.cs | 87 +++++++++ .../Tests/BasicSerializerTests.cs | 43 +++++ tests/NuGet.config | 8 + 5 files changed, 233 insertions(+), 88 deletions(-) create mode 100644 tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs create mode 100644 tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs create mode 100644 tests/NuGet.config diff --git a/ImageSharp.sln b/ImageSharp.sln index 875ede1b2..a5ab1b297 100644 --- a/ImageSharp.sln +++ b/ImageSharp.sln @@ -44,6 +44,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{56801022 ProjectSection(SolutionItems) = preProject tests\Directory.Build.props = tests\Directory.Build.props tests\Directory.Build.targets = tests\Directory.Build.targets + tests\NuGet.config = tests\NuGet.config EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Images", "Images", "{FA55F5DE-11A6-487D-ABA4-BC93A02717DD}" diff --git a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs index d38b5b9dd..8b850b91f 100644 --- a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs @@ -6,38 +6,28 @@ using System; using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Microsoft.DotNet.RemoteExecutor; using SixLabors.ImageSharp.Tests; using Xunit; namespace SixLabors.ImageSharp.Memory.Tests { - // TODO: Re-enable memory-intensive tests with arcade RemoteExecutor: - // https://github.com/dotnet/runtime/blob/master/docs/project/writing-tests.md#remoteexecutor public class ArrayPoolMemoryAllocatorTests { private const int MaxPooledBufferSizeInBytes = 2048; private const int PoolSelectorThresholdInBytes = MaxPooledBufferSizeInBytes / 2; - private MemoryAllocator MemoryAllocator { get; set; } = - new ArrayPoolMemoryAllocator(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes); - /// - /// Rent a buffer -> return it -> re-rent -> verify if it's span points to the previous location. + /// Contains SUT for in-process tests. /// - private bool CheckIsRentingPooledBuffer(int length) - where T : struct - { - IMemoryOwner buffer = this.MemoryAllocator.Allocate(length); - ref T ptrToPrevPosition0 = ref buffer.GetReference(); - buffer.Dispose(); + private MemoryAllocatorFixture LocalFixture { get; } = new MemoryAllocatorFixture(); - buffer = this.MemoryAllocator.Allocate(length); - bool sameBuffers = Unsafe.AreSame(ref ptrToPrevPosition0, ref buffer.GetReference()); - buffer.Dispose(); - - return sameBuffers; - } + /// + /// Contains SUT for tests executed by , + /// recreated in each external process. + /// + private static MemoryAllocatorFixture StaticFixture { get; } = new MemoryAllocatorFixture(); public class BufferTests : BufferTestSuite { @@ -78,21 +68,21 @@ namespace SixLabors.ImageSharp.Memory.Tests [InlineData(MaxPooledBufferSizeInBytes - 1)] public void SmallBuffersArePooled_OfByte(int size) { - Assert.True(this.CheckIsRentingPooledBuffer(size)); + Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer(size)); } - [Theory(Skip = "Should be executed from a separate process.")] + [Theory] [InlineData(128 * 1024 * 1024)] [InlineData(MaxPooledBufferSizeInBytes + 1)] public void LargeBuffersAreNotPooled_OfByte(int size) { - if (!TestEnvironment.Is64BitProcess) + static void RunTest(string sizeStr) { - // can lead to OutOfMemoryException - return; + int size = int.Parse(sizeStr); + StaticFixture.CheckIsRentingPooledBuffer(size); } - Assert.False(this.CheckIsRentingPooledBuffer(size)); + RemoteExecutor.Invoke(RunTest, size.ToString()).Dispose(); } [Fact] @@ -100,21 +90,15 @@ namespace SixLabors.ImageSharp.Memory.Tests { int count = (MaxPooledBufferSizeInBytes / sizeof(LargeStruct)) - 1; - Assert.True(this.CheckIsRentingPooledBuffer(count)); + Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer(count)); } - [Fact(Skip = "Should be executed from a separate process.")] + [Fact] public unsafe void LaregeBuffersAreNotPooled_OfBigValueType() { - if (!TestEnvironment.Is64BitProcess) - { - // can lead to OutOfMemoryException - return; - } - int count = (MaxPooledBufferSizeInBytes / sizeof(LargeStruct)) + 1; - Assert.False(this.CheckIsRentingPooledBuffer(count)); + Assert.False(this.LocalFixture.CheckIsRentingPooledBuffer(count)); } [Theory] @@ -122,12 +106,13 @@ namespace SixLabors.ImageSharp.Memory.Tests [InlineData(AllocationOptions.Clean)] public void CleaningRequests_AreControlledByAllocationParameter_Clean(AllocationOptions options) { - using (IMemoryOwner firstAlloc = this.MemoryAllocator.Allocate(42)) + MemoryAllocator memoryAllocator = this.LocalFixture.MemoryAllocator; + using (IMemoryOwner firstAlloc = memoryAllocator.Allocate(42)) { firstAlloc.GetSpan().Fill(666); } - using (IMemoryOwner secondAlloc = this.MemoryAllocator.Allocate(42, options)) + using (IMemoryOwner secondAlloc = memoryAllocator.Allocate(42, options)) { int expected = options == AllocationOptions.Clean ? 0 : 666; Assert.Equal(expected, secondAlloc.GetSpan()[0]); @@ -139,7 +124,8 @@ namespace SixLabors.ImageSharp.Memory.Tests [InlineData(true)] public void ReleaseRetainedResources_ReplacesInnerArrayPool(bool keepBufferAlive) { - IMemoryOwner buffer = this.MemoryAllocator.Allocate(32); + MemoryAllocator memoryAllocator = this.LocalFixture.MemoryAllocator; + IMemoryOwner buffer = memoryAllocator.Allocate(32); ref int ptrToPrev0 = ref MemoryMarshal.GetReference(buffer.GetSpan()); if (!keepBufferAlive) @@ -147,9 +133,9 @@ namespace SixLabors.ImageSharp.Memory.Tests buffer.Dispose(); } - this.MemoryAllocator.ReleaseRetainedResources(); + memoryAllocator.ReleaseRetainedResources(); - buffer = this.MemoryAllocator.Allocate(32); + buffer = memoryAllocator.Allocate(32); Assert.False(Unsafe.AreSame(ref ptrToPrev0, ref buffer.GetReference())); } @@ -157,87 +143,69 @@ namespace SixLabors.ImageSharp.Memory.Tests [Fact] public void ReleaseRetainedResources_DisposingPreviouslyAllocatedBuffer_IsAllowed() { - IMemoryOwner buffer = this.MemoryAllocator.Allocate(32); - this.MemoryAllocator.ReleaseRetainedResources(); + MemoryAllocator memoryAllocator = this.LocalFixture.MemoryAllocator; + IMemoryOwner buffer = memoryAllocator.Allocate(32); + memoryAllocator.ReleaseRetainedResources(); buffer.Dispose(); } - [Fact(Skip = "Should be executed from a separate process.")] + [Fact] public void AllocationOverLargeArrayThreshold_UsesDifferentPool() { - if (!TestEnvironment.Is64BitProcess) + static void RunTest() { - // can lead to OutOfMemoryException - return; - } + const int ArrayLengthThreshold = PoolSelectorThresholdInBytes / sizeof(int); - const int ArrayLengthThreshold = PoolSelectorThresholdInBytes / sizeof(int); + IMemoryOwner small = StaticFixture.MemoryAllocator.Allocate(ArrayLengthThreshold - 1); + ref int ptr2Small = ref small.GetReference(); + small.Dispose(); - IMemoryOwner small = this.MemoryAllocator.Allocate(ArrayLengthThreshold - 1); - ref int ptr2Small = ref small.GetReference(); - small.Dispose(); + IMemoryOwner large = StaticFixture.MemoryAllocator.Allocate(ArrayLengthThreshold + 1); - IMemoryOwner large = this.MemoryAllocator.Allocate(ArrayLengthThreshold + 1); + Assert.False(Unsafe.AreSame(ref ptr2Small, ref large.GetReference())); + } - Assert.False(Unsafe.AreSame(ref ptr2Small, ref large.GetReference())); + RemoteExecutor.Invoke(RunTest).Dispose(); } - [Fact(Skip = "Should be executed from a separate process.")] + [Fact] public void CreateWithAggressivePooling() { - if (!TestEnvironment.Is64BitProcess) + static void RunTest() { - // can lead to OutOfMemoryException - return; + StaticFixture.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithAggressivePooling(); + Assert.True(StaticFixture.CheckIsRentingPooledBuffer(4096 * 4096)); } - this.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithAggressivePooling(); - - Assert.True(this.CheckIsRentingPooledBuffer(4096 * 4096)); + RemoteExecutor.Invoke(RunTest).Dispose(); } - [Fact(Skip = "Should be executed from a separate process.")] + [Fact] public void CreateDefault() { - if (!TestEnvironment.Is64BitProcess) + static void RunTest() { - // can lead to OutOfMemoryException - return; - } + StaticFixture.MemoryAllocator = ArrayPoolMemoryAllocator.CreateDefault(); - this.MemoryAllocator = ArrayPoolMemoryAllocator.CreateDefault(); + Assert.False(StaticFixture.CheckIsRentingPooledBuffer(2 * 4096 * 4096)); + Assert.True(StaticFixture.CheckIsRentingPooledBuffer(2048 * 2048)); + } - Assert.False(this.CheckIsRentingPooledBuffer(2 * 4096 * 4096)); - Assert.True(this.CheckIsRentingPooledBuffer(2048 * 2048)); + RemoteExecutor.Invoke(RunTest).Dispose(); } [Fact] public void CreateWithModeratePooling() { - if (!TestEnvironment.Is64BitProcess) + static void RunTest() { - // can lead to OutOfMemoryException - return; + StaticFixture.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithModeratePooling(); + Assert.False(StaticFixture.CheckIsRentingPooledBuffer(2048 * 2048)); + Assert.True(StaticFixture.CheckIsRentingPooledBuffer(1024 * 16)); } - this.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithModeratePooling(); - - Assert.False(this.CheckIsRentingPooledBuffer(2048 * 2048)); - Assert.True(this.CheckIsRentingPooledBuffer(1024 * 16)); - } - - [StructLayout(LayoutKind.Sequential)] - private struct Rgba32 - { - private readonly uint dummy; - } - - private const int SizeOfLargeStruct = MaxPooledBufferSizeInBytes / 5; - - [StructLayout(LayoutKind.Explicit, Size = SizeOfLargeStruct)] - private struct LargeStruct - { + RemoteExecutor.Invoke(RunTest).Dispose(); } [Theory] @@ -245,7 +213,8 @@ namespace SixLabors.ImageSharp.Memory.Tests [InlineData((int.MaxValue / SizeOfLargeStruct) + 1)] public void AllocateIncorrectAmount_ThrowsCorrect_ArgumentOutOfRangeException(int length) { - ArgumentOutOfRangeException ex = Assert.Throws(() => this.MemoryAllocator.Allocate(length)); + ArgumentOutOfRangeException ex = Assert.Throws(() => + this.LocalFixture.MemoryAllocator.Allocate(length)); Assert.Equal("length", ex.ParamName); } @@ -253,8 +222,45 @@ namespace SixLabors.ImageSharp.Memory.Tests [InlineData(-1)] public void AllocateManagedByteBuffer_IncorrectAmount_ThrowsCorrect_ArgumentOutOfRangeException(int length) { - ArgumentOutOfRangeException ex = Assert.Throws(() => this.MemoryAllocator.AllocateManagedByteBuffer(length)); + ArgumentOutOfRangeException ex = Assert.Throws(() => + this.LocalFixture.MemoryAllocator.AllocateManagedByteBuffer(length)); Assert.Equal("length", ex.ParamName); } + + private class MemoryAllocatorFixture + { + public MemoryAllocator MemoryAllocator { get; set; } = + new ArrayPoolMemoryAllocator(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes); + + /// + /// Rent a buffer -> return it -> re-rent -> verify if it's span points to the previous location. + /// + public bool CheckIsRentingPooledBuffer(int length) + where T : struct + { + IMemoryOwner buffer = MemoryAllocator.Allocate(length); + ref T ptrToPrevPosition0 = ref buffer.GetReference(); + buffer.Dispose(); + + buffer = MemoryAllocator.Allocate(length); + bool sameBuffers = Unsafe.AreSame(ref ptrToPrevPosition0, ref buffer.GetReference()); + buffer.Dispose(); + + return sameBuffers; + } + } + + [StructLayout(LayoutKind.Sequential)] + private struct SmallStruct + { + private readonly uint dummy; + } + + private const int SizeOfLargeStruct = MaxPooledBufferSizeInBytes / 5; + + [StructLayout(LayoutKind.Explicit, Size = SizeOfLargeStruct)] + private struct LargeStruct + { + } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs new file mode 100644 index 000000000..971e6c54e --- /dev/null +++ b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.IO; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.TestUtilities +{ + /// + /// -compatible serialization for cross-process use-cases. + /// + internal class BasicSerializer : IXunitSerializationInfo + { + private readonly Dictionary map = new Dictionary(); + + public const char Separator = ':'; + + private string DumpToString() + { + using var ms = new MemoryStream(); + using var writer = new StreamWriter(ms); + foreach (KeyValuePair kv in this.map) + { + writer.WriteLine($"{kv.Key}{Separator}{kv.Value}"); + } + writer.Flush(); + byte[] data = ms.ToArray(); + return System.Convert.ToBase64String(data); + } + + private void LoadDump(string dump) + { + byte[] data = System.Convert.FromBase64String(dump); + + using var ms = new MemoryStream(data); + using var reader = new StreamReader(ms); + for (string s = reader.ReadLine(); s != null ; s = reader.ReadLine()) + { + string[] kv = s.Split(Separator); + this.map[kv[0]] = kv[1]; + } + } + + public static string Serialize(IXunitSerializable serializable) + { + var serializer = new BasicSerializer(); + serializable.Serialize(serializer); + return serializer.DumpToString(); + } + + public static T Deserialize(string dump) where T : IXunitSerializable + { + T result = Activator.CreateInstance(); + var serializer = new BasicSerializer(); + serializer.LoadDump(dump); + result.Deserialize(serializer); + return result; + } + + public void AddValue(string key, object value, Type type = null) + { + Guard.NotNull(key, nameof(key)); + if (value == null) + { + return; + } + type ??= value.GetType(); + + this.map[key] = TypeDescriptor.GetConverter(type).ConvertToInvariantString(value); + } + + public object GetValue(string key, Type type) + { + Guard.NotNull(key, nameof(key)); + + if (!this.map.TryGetValue(key, out string str)) + { + return type.IsValueType ? Activator.CreateInstance(type) : null; + } + + return TypeDescriptor.GetConverter(type).ConvertFromInvariantString(str); + } + + public T GetValue(string key) => (T)this.GetValue(key, typeof(T)); + } +} diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs new file mode 100644 index 000000000..ba5bdb219 --- /dev/null +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs @@ -0,0 +1,43 @@ +using SixLabors.ImageSharp.Tests.TestUtilities; +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests +{ + public class BasicSerializerTests + { + class TestObj : IXunitSerializable + { + public double Length { get; set; } + public string Name { get; set; } + public int Lives { get; set; } + + public void Deserialize(IXunitSerializationInfo info) + { + info.AddValue(nameof(Length), Length); + info.AddValue(nameof(Name), Name); + info.AddValue(nameof(this.Lives), Lives); + } + + public void Serialize(IXunitSerializationInfo info) + { + this.Length = info.GetValue(nameof(Length)); + this.Name = info.GetValue(nameof(Name)); + this.Lives = info.GetValue(nameof(Lives)); + } + } + + [Fact] + public void SerializeDeserialize_ShouldPreserveValues() + { + var obj = new TestObj() {Length = 123, Name = "Lol123!", Lives = 7}; + + string str = BasicSerializer.Serialize(obj); + TestObj mirror = BasicSerializer.Deserialize(str); + + Assert.Equal(obj.Length, mirror.Length); + Assert.Equal(obj.Name, mirror.Name); + Assert.Equal(obj.Lives, mirror.Lives); + } + } +} diff --git a/tests/NuGet.config b/tests/NuGet.config new file mode 100644 index 000000000..8f9bf7e10 --- /dev/null +++ b/tests/NuGet.config @@ -0,0 +1,8 @@ + + + + + + + + From 967e4eabb1b1b2426fdccf5f257900b80dec6598 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 03:45:18 +0100 Subject: [PATCH 03/23] use RemoteExecutor in JpegDecoderTests --- .../Formats/Jpg/JpegDecoderTests.Baseline.cs | 17 ++++++----- .../Jpg/JpegDecoderTests.Progressive.cs | 19 +++++++----- .../Formats/Jpg/JpegDecoderTests.cs | 2 +- .../TestUtilities/BasicSerializer.cs | 15 ++++++---- .../ImageProviders/LambdaProvider.cs | 7 ++++- .../ImageProviders/TestImageProvider.cs | 2 +- .../Tests/BasicSerializerTests.cs | 29 +++++++++++++++---- 7 files changed, 63 insertions(+), 28 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs index 2485561f1..59b6963eb 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs @@ -2,7 +2,9 @@ // Licensed under the Apache License, Version 2.0. +using Microsoft.DotNet.RemoteExecutor; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; // ReSharper disable InconsistentNaming @@ -15,22 +17,23 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void DecodeBaselineJpeg(TestImageProvider provider) where TPixel : struct, IPixel { - if (SkipTest(provider)) + static void RunTest(string providerDump) { - // skipping to avoid OutOfMemoryException on CI - return; - } + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); - using (Image image = provider.GetImage(JpegDecoder)) - { + using Image image = provider.GetImage(JpegDecoder); image.DebugSave(provider); provider.Utility.TestName = DecodeBaselineJpegOutputName; image.CompareToReferenceOutput( - this.GetImageComparer(provider), + GetImageComparer(provider), provider, appendPixelTypeToFileName: false); } + + string providerDump = BasicSerializer.Serialize(provider); + RemoteExecutor.Invoke(RunTest, providerDump).Dispose(); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs index 77bc9f540..4f155e9c3 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs @@ -1,7 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using Microsoft.DotNet.RemoteExecutor; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; // ReSharper disable InconsistentNaming @@ -16,22 +18,23 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void DecodeProgressiveJpeg(TestImageProvider provider) where TPixel : struct, IPixel { - if (SkipTest(provider)) + static void RunTest(string providerDump) { - // skipping to avoid OutOfMemoryException on CI - return; - } + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); - using (Image image = provider.GetImage(JpegDecoder)) - { + using Image image = provider.GetImage(JpegDecoder); image.DebugSave(provider); provider.Utility.TestName = DecodeProgressiveJpegOutputName; image.CompareToReferenceOutput( - this.GetImageComparer(provider), + GetImageComparer(provider), provider, appendPixelTypeToFileName: false); } + + string dump = BasicSerializer.Serialize(provider); + RemoteExecutor.Invoke(RunTest, dump).Dispose(); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 009f86483..669205908 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg private const float BaselineTolerance = 0.001F / 100; private const float ProgressiveTolerance = 0.2F / 100; - private ImageComparer GetImageComparer(TestImageProvider provider) + private static ImageComparer GetImageComparer(TestImageProvider provider) where TPixel : struct, IPixel { string file = provider.SourceFileOrDescription; diff --git a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs index 971e6c54e..1c600ed80 100644 --- a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs @@ -16,10 +16,11 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities public const char Separator = ':'; - private string DumpToString() + private string DumpToString(Type type) { using var ms = new MemoryStream(); using var writer = new StreamWriter(ms); + writer.WriteLine(type.FullName); foreach (KeyValuePair kv in this.map) { writer.WriteLine($"{kv.Key}{Separator}{kv.Value}"); @@ -29,31 +30,35 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities return System.Convert.ToBase64String(data); } - private void LoadDump(string dump) + private Type LoadDump(string dump) { byte[] data = System.Convert.FromBase64String(dump); using var ms = new MemoryStream(data); using var reader = new StreamReader(ms); + var type = Type.GetType(reader.ReadLine()); for (string s = reader.ReadLine(); s != null ; s = reader.ReadLine()) { string[] kv = s.Split(Separator); this.map[kv[0]] = kv[1]; } + + return type; } public static string Serialize(IXunitSerializable serializable) { var serializer = new BasicSerializer(); serializable.Serialize(serializer); - return serializer.DumpToString(); + return serializer.DumpToString(serializable.GetType()); } public static T Deserialize(string dump) where T : IXunitSerializable { - T result = Activator.CreateInstance(); var serializer = new BasicSerializer(); - serializer.LoadDump(dump); + Type type = serializer.LoadDump(dump); + + var result = (T) Activator.CreateInstance(type); result.Deserialize(serializer); return result; } diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs index 5bd53a4c0..b39c4f676 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs @@ -18,6 +18,11 @@ namespace SixLabors.ImageSharp.Tests { private readonly Func> factoryFunc; + public LambdaProvider() + { + throw new NotSupportedException(); + } + public LambdaProvider(Func> factoryFunc) { this.factoryFunc = factoryFunc; @@ -26,4 +31,4 @@ namespace SixLabors.ImageSharp.Tests public override Image GetImage() => this.factoryFunc(); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs index 63de4c96f..6443050d3 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests /// Provides instances for parametric unit tests. /// /// The pixel format of the image - public abstract partial class TestImageProvider : ITestImageProvider + public abstract partial class TestImageProvider : ITestImageProvider, IXunitSerializable where TPixel : struct, IPixel { public PixelTypes PixelType { get; private set; } = typeof(TPixel).GetPixelType(); diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs index ba5bdb219..71ab5b262 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs @@ -6,20 +6,20 @@ namespace SixLabors.ImageSharp.Tests { public class BasicSerializerTests { - class TestObj : IXunitSerializable + class BaseObj : IXunitSerializable { public double Length { get; set; } public string Name { get; set; } public int Lives { get; set; } - public void Deserialize(IXunitSerializationInfo info) + public virtual void Deserialize(IXunitSerializationInfo info) { info.AddValue(nameof(Length), Length); info.AddValue(nameof(Name), Name); info.AddValue(nameof(this.Lives), Lives); } - public void Serialize(IXunitSerializationInfo info) + public virtual void Serialize(IXunitSerializationInfo info) { this.Length = info.GetValue(nameof(Length)); this.Name = info.GetValue(nameof(Name)); @@ -27,17 +27,36 @@ namespace SixLabors.ImageSharp.Tests } } + class DerivedObj : BaseObj + { + public double Strength { get; set; } + + public override void Deserialize(IXunitSerializationInfo info) + { + this.Strength = info.GetValue(nameof(Strength)); + base.Deserialize(info); + } + + public override void Serialize(IXunitSerializationInfo info) + { + base.Serialize(info); + info.AddValue(nameof(Strength), Strength); + } + } + [Fact] public void SerializeDeserialize_ShouldPreserveValues() { - var obj = new TestObj() {Length = 123, Name = "Lol123!", Lives = 7}; + var obj = new DerivedObj() {Length = 123.1, Name = "Lol123!", Lives = 7, Strength = 4.8}; string str = BasicSerializer.Serialize(obj); - TestObj mirror = BasicSerializer.Deserialize(str); + BaseObj mirrorBase = BasicSerializer.Deserialize(str); + DerivedObj mirror = Assert.IsType(mirrorBase); Assert.Equal(obj.Length, mirror.Length); Assert.Equal(obj.Name, mirror.Name); Assert.Equal(obj.Lives, mirror.Lives); + Assert.Equal(obj.Strength, mirror.Strength); } } } From 7723adfb19e3a29868bad89a5af80b62f69340ab Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 05:27:57 +0100 Subject: [PATCH 04/23] workaround RemoteExecutor assembly redirect issue on 472, run BokehBlurTests in separate process --- .../Formats/Jpg/JpegDecoderTests.cs | 25 ++++---- .../ArrayPoolMemoryAllocatorTests.cs | 5 ++ .../Processors/Convolution/BokehBlurTest.cs | 62 +++++++++++++++---- .../TestUtilities/TestEnvironment.cs | 34 ++++++++-- 4 files changed, 99 insertions(+), 27 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 669205908..22df9966b 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -4,11 +4,12 @@ using System; using System.IO; using System.Linq; - +using Microsoft.DotNet.RemoteExecutor; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; +using SixLabors.ImageSharp.Tests.TestUtilities; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; @@ -23,8 +24,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector; private const float BaselineTolerance = 0.001F / 100; + private const float ProgressiveTolerance = 0.2F / 100; + static JpegDecoderTests() + { + TestEnvironment.InitRemoteExecutorAssemblyRedirects(); + } + private static ImageComparer GetImageComparer(TestImageProvider provider) where TPixel : struct, IPixel { @@ -88,23 +95,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void JpegDecoder_IsNotBoundToSinglePixelType(TestImageProvider provider) where TPixel : struct, IPixel { - if (SkipTest(provider)) - { - return; - } - - // For 32 bit test environments: - provider.Configuration.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithModeratePooling(); - - using (Image image = provider.GetImage(JpegDecoder)) + static void RunTest(string providerDump) { + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); + using Image image = provider.GetImage(JpegDecoder); image.DebugSave(provider); provider.Utility.TestName = DecodeBaselineJpegOutputName; image.CompareToReferenceOutput(ImageComparer.Tolerant(BaselineTolerance), provider, appendPixelTypeToFileName: false); } - provider.Configuration.MemoryAllocator.ReleaseRetainedResources(); + string dump = BasicSerializer.Serialize(provider); + RemoteExecutor.Invoke(RunTest, dump).Dispose(); } // DEBUG ONLY! diff --git a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs index 8b850b91f..d2ed56a37 100644 --- a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs @@ -29,6 +29,11 @@ namespace SixLabors.ImageSharp.Memory.Tests /// private static MemoryAllocatorFixture StaticFixture { get; } = new MemoryAllocatorFixture(); + static ArrayPoolMemoryAllocatorTests() + { + TestEnvironment.InitRemoteExecutorAssemblyRedirects(); + } + public class BufferTests : BufferTestSuite { public BufferTests() diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs index cd3f74f8e..42b5de376 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs @@ -6,11 +6,12 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; +using Microsoft.DotNet.RemoteExecutor; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Convolution; - +using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; using Xunit.Abstractions; @@ -18,6 +19,11 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution { public class BokehBlurTest { + static BokehBlurTest() + { + TestEnvironment.InitRemoteExecutorAssemblyRedirects(); + } + private static readonly string Components10x2 = @" [[ 0.00451261+0.0165137j 0.02161237-0.00299122j 0.00387479-0.02682816j -0.02752798-0.01788438j -0.03553877+0.0154543j -0.01428268+0.04224722j @@ -124,10 +130,22 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution public void BokehBlurFilterProcessor(TestImageProvider provider, BokehBlurInfo value) where TPixel : struct, IPixel { - provider.RunValidatingProcessorTest( - x => x.BokehBlur(value.Radius, value.Components, value.Gamma), - testOutputDetails: value.ToString(), - appendPixelTypeToFileName: false); + static void RunTest(string providerDump, string infoDump) + { + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); + BokehBlurInfo value = BasicSerializer.Deserialize(infoDump); + + provider.RunValidatingProcessorTest( + x => x.BokehBlur(value.Radius, value.Components, value.Gamma), + testOutputDetails: value.ToString(), + appendPixelTypeToFileName: false); + + } + + RemoteExecutor + .Invoke(RunTest, BasicSerializer.Serialize(provider), BasicSerializer.Serialize(value)) + .Dispose(); } [Theory] @@ -137,9 +155,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution public void BokehBlurFilterProcessor_WorksWithAllPixelTypes(TestImageProvider provider) where TPixel : struct, IPixel { - provider.RunValidatingProcessorTest( - x => x.BokehBlur(8, 2, 3), - appendSourceFileOrDescription: false); + static void RunTest(string providerDump) + { + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); + provider.RunValidatingProcessorTest( + x => x.BokehBlur(8, 2, 3), + appendSourceFileOrDescription: false); + } + + RemoteExecutor + .Invoke(RunTest, BasicSerializer.Serialize(provider)) + .Dispose(); } @@ -148,15 +175,26 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution public void BokehBlurFilterProcessor_Bounded(TestImageProvider provider, BokehBlurInfo value) where TPixel : struct, IPixel { - provider.RunValidatingProcessorTest( - x => + static void RunTest(string providerDump, string infoDump) + { + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); + BokehBlurInfo value = BasicSerializer.Deserialize(infoDump); + + provider.RunValidatingProcessorTest( + x => { Size size = x.GetCurrentSize(); var bounds = new Rectangle(10, 10, size.Width / 2, size.Height / 2); x.BokehBlur(value.Radius, value.Components, value.Gamma, bounds); }, - testOutputDetails: value.ToString(), - appendPixelTypeToFileName: false); + testOutputDetails: value.ToString(), + appendPixelTypeToFileName: false); + } + + RemoteExecutor + .Invoke(RunTest, BasicSerializer.Serialize(provider), BasicSerializer.Serialize(value)) + .Dispose(); } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs index a5a3e332c..3b6c8c064 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Tests return directory.FullName; } - private static string GetFullPath(string relativePath) => + private static string GetFullPath(string relativePath) => Path.Combine(SolutionDirectoryFullPath, relativePath) .Replace('\\', Path.DirectorySeparatorChar); @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Tests /// Gets the correct full path to the Input Images directory. /// internal static string InputImagesDirectoryFullPath => GetFullPath(InputImagesRelativePath); - + /// /// Gets the correct full path to the Actual Output directory. (To be written to by the test cases.) /// @@ -100,13 +100,15 @@ namespace SixLabors.ImageSharp.Tests actualOutputFileName.Replace("ActualOutput", @"External\ReferenceOutput").Replace('\\', Path.DirectorySeparatorChar); internal static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); - + internal static bool IsMono => Type.GetType("Mono.Runtime") != null; // https://stackoverflow.com/a/721194 internal static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); internal static bool Is64BitProcess => IntPtr.Size == 8; + internal static bool IsFramework => string.IsNullOrEmpty(NetCoreVersion); + /// /// Creates the image output directory. /// @@ -132,6 +134,30 @@ namespace SixLabors.ImageSharp.Tests return path; } + /// + /// Need to create Microsoft.DotNet.RemoteExecutor.exe.config on .NET 4.7.2 (-_-) + /// + internal static void InitRemoteExecutorAssemblyRedirects() + { + if (!IsFramework) + { + return; + } + + var assemblyFile = new FileInfo(typeof(TestEnvironment).GetTypeInfo().Assembly.Location); + string remoteExecutorConfigPath = + Path.Combine(assemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe.config"); + + if (File.Exists(remoteExecutorConfigPath)) + { + return; + } + + string testProjectConfigPath = assemblyFile.FullName + ".config"; + + File.Copy(testProjectConfigPath, remoteExecutorConfigPath); + } + /// /// Solution borrowed from: /// https://github.com/dotnet/BenchmarkDotNet/issues/448#issuecomment-308424100 @@ -146,4 +172,4 @@ namespace SixLabors.ImageSharp.Tests return ""; } } -} \ No newline at end of file +} From d0d0da2658fe81e3f5bf441ba9358d869bfa8010 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 05:32:14 +0100 Subject: [PATCH 05/23] add .csproj change --- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 4aabc2f4e..59534c2a4 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -20,6 +20,7 @@ + From 9c279dcd1b6b8aac41b1526c0b0bbaed9fdab78f Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 06:30:55 +0100 Subject: [PATCH 06/23] when running tests in 32 bits, enforce 32bit execution of RemoteExecutor.exe --- .../Formats/Jpg/JpegDecoderTests.cs | 2 +- .../ArrayPoolMemoryAllocatorTests.cs | 4 +- .../Processors/Convolution/BokehBlurTest.cs | 2 +- .../TestUtilities/TestEnvironment.cs | 65 ++++++++++++++++++- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 22df9966b..90caea387 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg static JpegDecoderTests() { - TestEnvironment.InitRemoteExecutorAssemblyRedirects(); + TestEnvironment.PrepareRemoteExecutor(); } private static ImageComparer GetImageComparer(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs index d2ed56a37..227d62778 100644 --- a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs @@ -4,9 +4,11 @@ // ReSharper disable InconsistentNaming using System; using System.Buffers; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.DotNet.RemoteExecutor; +using Microsoft.Win32; using SixLabors.ImageSharp.Tests; using Xunit; @@ -31,7 +33,7 @@ namespace SixLabors.ImageSharp.Memory.Tests static ArrayPoolMemoryAllocatorTests() { - TestEnvironment.InitRemoteExecutorAssemblyRedirects(); + TestEnvironment.PrepareRemoteExecutor(); } public class BufferTests : BufferTestSuite diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs index 42b5de376..34b016513 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution { static BokehBlurTest() { - TestEnvironment.InitRemoteExecutorAssemblyRedirects(); + TestEnvironment.PrepareRemoteExecutor(); } private static readonly string Components10x2 = @" diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs index 3b6c8c064..cf5f536ae 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; @@ -135,9 +136,11 @@ namespace SixLabors.ImageSharp.Tests } /// - /// Need to create Microsoft.DotNet.RemoteExecutor.exe.config on .NET 4.7.2 (-_-) + /// Creates Microsoft.DotNet.RemoteExecutor.exe.config for .NET framework, + /// When running in 32 bits, enforces 32 bit execution of Microsoft.DotNet.RemoteExecutor.exe + /// with the help of corflags.exe found in Windows SDK. /// - internal static void InitRemoteExecutorAssemblyRedirects() + internal static void PrepareRemoteExecutor() { if (!IsFramework) { @@ -156,6 +159,64 @@ namespace SixLabors.ImageSharp.Tests string testProjectConfigPath = assemblyFile.FullName + ".config"; File.Copy(testProjectConfigPath, remoteExecutorConfigPath); + + if (Is64BitProcess) + { + return; + } + + string windowsSdksDir = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMFILES(x86)"), + "Microsoft SDKs", "Windows"); + + FileInfo corFlagsFile = Find(new DirectoryInfo(windowsSdksDir), "corflags.exe"); + + string remoteExecutorPath = Path.Combine(assemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe"); + + string args = $"{remoteExecutorPath} /32Bit+ /Force"; + + var si = new ProcessStartInfo() + { + FileName = corFlagsFile.FullName, + Arguments = args, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + + try + { + using var proc = Process.Start(si); + proc.WaitForExit(); + string standardOutput = proc.StandardOutput.ReadToEnd(); + string standardError = proc.StandardError.ReadToEnd(); + Debug.Print(standardOutput); + Debug.Print(standardError); + } + catch (Exception ex) + { + // Avoid fatal exceptions here + Debug.Print(ex.Message); + } + + static FileInfo Find(DirectoryInfo root, string name) + { + FileInfo fi = root.EnumerateFiles().FirstOrDefault(f => f.Name.ToLower() == name); + if (fi != null) + { + return fi; + } + + foreach (DirectoryInfo dir in root.EnumerateDirectories()) + { + fi = Find(dir, name); + if (fi != null) + { + return fi; + } + } + + return null; + } } /// From 10b3921ec12cdc9576019434ea3945af2a7d5da6 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 21 Jan 2020 06:57:02 +0100 Subject: [PATCH 07/23] avoid exceptions in PrepareRemoteExecutor() --- .../TestUtilities/TestEnvironment.cs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs index cf5f536ae..d7d16cfcd 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs @@ -165,26 +165,27 @@ namespace SixLabors.ImageSharp.Tests return; } - string windowsSdksDir = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMFILES(x86)"), - "Microsoft SDKs", "Windows"); + // Locate and run CorFlags.exe: + try + { + string windowsSdksDir = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMFILES(x86)"), + "Microsoft SDKs", "Windows"); - FileInfo corFlagsFile = Find(new DirectoryInfo(windowsSdksDir), "corflags.exe"); + FileInfo corFlagsFile = Find(new DirectoryInfo(windowsSdksDir), "corflags.exe"); - string remoteExecutorPath = Path.Combine(assemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe"); + string remoteExecutorPath = Path.Combine(assemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe"); - string args = $"{remoteExecutorPath} /32Bit+ /Force"; + string args = $"{remoteExecutorPath} /32Bit+ /Force"; - var si = new ProcessStartInfo() - { - FileName = corFlagsFile.FullName, - Arguments = args, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true - }; + var si = new ProcessStartInfo() + { + FileName = corFlagsFile.FullName, + Arguments = args, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true + }; - try - { using var proc = Process.Start(si); proc.WaitForExit(); string standardOutput = proc.StandardOutput.ReadToEnd(); From 6aaf7e43e5e2ecab27ea32e35b2b1a0fd0c69930 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 00:37:10 +0100 Subject: [PATCH 08/23] cleanup PrepareRemoteExecutor() --- .../TestUtilities/TestEnvironment.cs | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs index d7d16cfcd..fee05ad1c 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Tests { @@ -46,13 +47,12 @@ namespace SixLabors.ImageSharp.Tests internal static string SolutionDirectoryFullPath => SolutionDirectoryFullPathLazy.Value; + private static readonly FileInfo TestAssemblyFile = + new FileInfo(typeof(TestEnvironment).GetTypeInfo().Assembly.Location); + private static string GetSolutionDirectoryFullPathImpl() { - string assemblyLocation = typeof(TestEnvironment).GetTypeInfo().Assembly.Location; - - var assemblyFile = new FileInfo(assemblyLocation); - - DirectoryInfo directory = assemblyFile.Directory; + DirectoryInfo directory = TestAssemblyFile.Directory; while (!directory.EnumerateFiles(ImageSharpSolutionFileName).Any()) { @@ -63,13 +63,13 @@ namespace SixLabors.ImageSharp.Tests catch (Exception ex) { throw new Exception( - $"Unable to find ImageSharp solution directory from {assemblyLocation} because of {ex.GetType().Name}!", + $"Unable to find ImageSharp solution directory from {TestAssemblyFile} because of {ex.GetType().Name}!", ex); } if (directory == null) { - throw new Exception($"Unable to find ImageSharp solution directory from {assemblyLocation}!"); + throw new Exception($"Unable to find ImageSharp solution directory from {TestAssemblyFile}!"); } } @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Tests /// /// Creates Microsoft.DotNet.RemoteExecutor.exe.config for .NET framework, /// When running in 32 bits, enforces 32 bit execution of Microsoft.DotNet.RemoteExecutor.exe - /// with the help of corflags.exe found in Windows SDK. + /// with the help of CorFlags.exe found in Windows SDK. /// internal static void PrepareRemoteExecutor() { @@ -147,16 +147,16 @@ namespace SixLabors.ImageSharp.Tests return; } - var assemblyFile = new FileInfo(typeof(TestEnvironment).GetTypeInfo().Assembly.Location); string remoteExecutorConfigPath = - Path.Combine(assemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe.config"); + Path.Combine(TestAssemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe.config"); if (File.Exists(remoteExecutorConfigPath)) { + // already prepared return; } - string testProjectConfigPath = assemblyFile.FullName + ".config"; + string testProjectConfigPath = TestAssemblyFile.FullName + ".config"; File.Copy(testProjectConfigPath, remoteExecutorConfigPath); @@ -165,43 +165,43 @@ namespace SixLabors.ImageSharp.Tests return; } - // Locate and run CorFlags.exe: - try - { - string windowsSdksDir = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMFILES(x86)"), - "Microsoft SDKs", "Windows"); + EnsureRemoteExecutorIs32Bit(); + } + + /// + /// Locate and run CorFlags.exe /32Bit+ + /// https://docs.microsoft.com/en-us/dotnet/framework/tools/corflags-exe-corflags-conversion-tool + /// + private static void EnsureRemoteExecutorIs32Bit() + { + string windowsSdksDir = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMFILES(x86)"), + "Microsoft SDKs", "Windows"); - FileInfo corFlagsFile = Find(new DirectoryInfo(windowsSdksDir), "corflags.exe"); + FileInfo corFlagsFile = Find(new DirectoryInfo(windowsSdksDir), "CorFlags.exe"); - string remoteExecutorPath = Path.Combine(assemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe"); + string remoteExecutorPath = Path.Combine(TestAssemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe"); - string args = $"{remoteExecutorPath} /32Bit+ /Force"; + string args = $"{remoteExecutorPath} /32Bit+ /Force"; - var si = new ProcessStartInfo() - { - FileName = corFlagsFile.FullName, - Arguments = args, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true - }; - - using var proc = Process.Start(si); - proc.WaitForExit(); - string standardOutput = proc.StandardOutput.ReadToEnd(); - string standardError = proc.StandardError.ReadToEnd(); - Debug.Print(standardOutput); - Debug.Print(standardError); - } - catch (Exception ex) + var si = new ProcessStartInfo() { - // Avoid fatal exceptions here - Debug.Print(ex.Message); - } + FileName = corFlagsFile.FullName, + Arguments = args, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + + using var proc = Process.Start(si); + proc.WaitForExit(); + string standardOutput = proc.StandardOutput.ReadToEnd(); + string standardError = proc.StandardError.ReadToEnd(); + Debug.Print(standardOutput); + Debug.Print(standardError); static FileInfo Find(DirectoryInfo root, string name) { - FileInfo fi = root.EnumerateFiles().FirstOrDefault(f => f.Name.ToLower() == name); + FileInfo fi = root.EnumerateFiles(name).FirstOrDefault(); if (fi != null) { return fi; From eed284bf0d2a83f3bcd340d5d7f8d0da46969115 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 00:45:43 +0100 Subject: [PATCH 09/23] Sandbox46: reference Test classes rather than include --- tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj | 8 ++++---- tests/ImageSharp.Tests/AssemblyInfo.cs | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 tests/ImageSharp.Tests/AssemblyInfo.cs diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index e89b28dc1..5828713cd 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -14,14 +14,14 @@ false - - - - + + + + diff --git a/tests/ImageSharp.Tests/AssemblyInfo.cs b/tests/ImageSharp.Tests/AssemblyInfo.cs new file mode 100644 index 000000000..4a87fedc0 --- /dev/null +++ b/tests/ImageSharp.Tests/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly:InternalsVisibleTo("SixLabors.ImageSharp.Sandbox46")] From c4bd8812ff4f5c36bfd4193784bd6ff9dfc878d5 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 00:48:19 +0100 Subject: [PATCH 10/23] rename Sandbox46 to ImageSharp.Tests.ProfilingSandbox --- ImageSharp.sln | 30 +++++++++---------- .../ImageSharp.Tests.ProfilingSandbox.csproj} | 0 .../Program.cs | 0 .../README.md | 0 .../app.config | 0 5 files changed, 15 insertions(+), 15 deletions(-) rename tests/{ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj => ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj} (100%) rename tests/{ImageSharp.Sandbox46 => ImageSharp.Tests.ProfilingSandbox}/Program.cs (100%) rename tests/{ImageSharp.Sandbox46 => ImageSharp.Tests.ProfilingSandbox}/README.md (100%) rename tests/{ImageSharp.Sandbox46 => ImageSharp.Tests.ProfilingSandbox}/app.config (100%) diff --git a/ImageSharp.sln b/ImageSharp.sln index a5ab1b297..5d74f7332 100644 --- a/ImageSharp.sln +++ b/ImageSharp.sln @@ -323,8 +323,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Tests", "tests\I EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Benchmarks", "tests\ImageSharp.Benchmarks\ImageSharp.Benchmarks.csproj", "{2BF743D8-2A06-412D-96D7-F448F00C5EA5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Sandbox46", "tests\ImageSharp.Sandbox46\ImageSharp.Sandbox46.csproj", "{561B880A-D9EE-44EF-90F5-817C54A9D9AB}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{C0D7754B-5277-438E-ABEB-2BA34401B5A7}" ProjectSection(SolutionItems) = preProject .github\workflows\build-and-test.yml = .github\workflows\build-and-test.yml @@ -332,6 +330,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedInfrastructure", "shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.shproj", "{68A8CC40-6AED-4E96-B524-31B1158FDEEA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp.Tests.ProfilingSandbox", "tests\ImageSharp.Tests.ProfilingSandbox\ImageSharp.Tests.ProfilingSandbox.csproj", "{FC527290-2F22-432C-B77B-6E815726B02C}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems*{68a8cc40-6aed-4e96-b524-31b1158fdeea}*SharedItemsImports = 13 @@ -381,18 +381,18 @@ Global {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x64.Build.0 = Release|Any CPU {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x86.ActiveCfg = Release|Any CPU {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x86.Build.0 = Release|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Debug|x64.ActiveCfg = Debug|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Debug|x64.Build.0 = Debug|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Debug|x86.ActiveCfg = Debug|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Debug|x86.Build.0 = Debug|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Release|Any CPU.Build.0 = Release|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Release|x64.ActiveCfg = Release|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Release|x64.Build.0 = Release|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Release|x86.ActiveCfg = Release|Any CPU - {561B880A-D9EE-44EF-90F5-817C54A9D9AB}.Release|x86.Build.0 = Release|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x64.ActiveCfg = Debug|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x64.Build.0 = Debug|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x86.Build.0 = Debug|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Release|Any CPU.Build.0 = Release|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x64.ActiveCfg = Release|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x64.Build.0 = Release|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x86.ActiveCfg = Release|Any CPU + {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -416,9 +416,9 @@ Global {E1C42A6F-913B-4A7B-B1A8-2BB62843B254} = {9DA226A1-8656-49A8-A58A-A8B5C081AD66} {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} {2BF743D8-2A06-412D-96D7-F448F00C5EA5} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} - {561B880A-D9EE-44EF-90F5-817C54A9D9AB} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} {C0D7754B-5277-438E-ABEB-2BA34401B5A7} = {1799C43E-5C54-4A8F-8D64-B1475241DB0D} {68A8CC40-6AED-4E96-B524-31B1158FDEEA} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} + {FC527290-2F22-432C-B77B-6E815726B02C} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5F8B9D1F-CD8B-4CC5-8216-D531E25BD795} diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj similarity index 100% rename from tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj rename to tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs similarity index 100% rename from tests/ImageSharp.Sandbox46/Program.cs rename to tests/ImageSharp.Tests.ProfilingSandbox/Program.cs diff --git a/tests/ImageSharp.Sandbox46/README.md b/tests/ImageSharp.Tests.ProfilingSandbox/README.md similarity index 100% rename from tests/ImageSharp.Sandbox46/README.md rename to tests/ImageSharp.Tests.ProfilingSandbox/README.md diff --git a/tests/ImageSharp.Sandbox46/app.config b/tests/ImageSharp.Tests.ProfilingSandbox/app.config similarity index 100% rename from tests/ImageSharp.Sandbox46/app.config rename to tests/ImageSharp.Tests.ProfilingSandbox/app.config From aa576e8532f9a1593144b2c99faea73b664dfb11 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 00:57:41 +0100 Subject: [PATCH 11/23] cleanup ProfilingSandbox --- .../ImageSharp.Tests.ProfilingSandbox.csproj | 6 ++--- .../Program.cs | 14 ++++------ .../README.md | 26 ++----------------- tests/ImageSharp.Tests/AssemblyInfo.cs | 3 +++ .../TestUtilities/BasicSerializer.cs | 3 +++ 5 files changed, 16 insertions(+), 36 deletions(-) diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj index 5828713cd..99269e339 100644 --- a/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj +++ b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj @@ -2,14 +2,14 @@ - SixLabors.ImageSharp.Sandbox46 + ImageSharp.Tests.ProfilingSandbox A cross-platform library for processing of image files written in C# Exe false - SixLabors.ImageSharp.Sandbox46 + SixLabors.ImageSharp.Tests.ProfilingSandbox win7-x64 netcoreapp3.1;netcoreapp2.1;net472 - SixLabors.ImageSharp.Sandbox46.Program + SixLabors.ImageSharp.Tests.ProfilingSandbox.Program false diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs index 93fe74076..f041e16eb 100644 --- a/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs +++ b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs @@ -1,18 +1,14 @@ -// -// Copyright (c) James Jackson-South and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -// +using System; +using SixLabors.ImageSharp.Tests.Formats.Jpg; using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations; using SixLabors.ImageSharp.Tests.ProfilingBenchmarks; +using Xunit.Abstractions; -namespace SixLabors.ImageSharp.Sandbox46 +namespace SixLabors.ImageSharp.Tests.ProfilingSandbox { - using System; - using SixLabors.ImageSharp.Tests.Formats.Jpg; - - using Xunit.Abstractions; - public class Program { private class ConsoleOutput : ITestOutputHelper diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/README.md b/tests/ImageSharp.Tests.ProfilingSandbox/README.md index b05afb853..43fdab9ef 100644 --- a/tests/ImageSharp.Tests.ProfilingSandbox/README.md +++ b/tests/ImageSharp.Tests.ProfilingSandbox/README.md @@ -1,24 +1,2 @@ -## Purpose -This project aims to workaround certain .NET Core tooling issues in Visual Studio based developer workflow at the time of it's creation (January 2017): -- .NET Core Performance profiling is not possible neither with Visual Studio nor with JetBrains profilers -- ~~JetBrains Unit Test explorer does not work with .NET Core projects~~ - -## How does it work? -- By referencing .NET 4.5 dll-s created by net45 target's of ImageSharp projects. NOTE: These are not project references! -- By including test classes (and utility classes) of the `ImageSharp.Tests` project using MSBUILD `` -- Compiling `ImageSharp.Sandbox46` should trigger the compilation of ImageSharp subprojects using a manually defined solution dependencies - -## How to profile unit tests - -#### 1. With Visual Studio 2015 Test Runner -- **Do not** build `ImageSharp.Tests` -- Build `ImageSharp.Sandbox46` -- Use the [context menu in Test Explorer](https://adamprescott.net/2012/12/12/performance-profiling-for-unit-tests/) - -NOTE: -There was no *Profile test* option in my VS Professional. Maybe things were messed by VS2017 RC installation. [This post suggests](http://stackoverflow.com/questions/32034375/profiling-tests-in-visual-studio-community-2015) it's necessary to own Premium or Ultimate edition of Visual Studio to profile tests. - -#### 2. With JetBrains ReSharper Ultimate -- The `Sandbox46` project is no longer needed here. The classic `ImageSharp.Tests` project can be discovered by Unit Test Explorer. -- You can use [context menus](https://www.jetbrains.com/resharper/features/unit_testing.html) from your test class, or from unit Test Exporer/Unit Test Sessions windows. -![Context Menu](https://www.jetbrains.com/resharper/features/screenshots/100/unit_testing_profiling.png) \ No newline at end of file +## ImageSharp.Tests.ProfilingSandbox +Helper project to run and profile unit tests or other "sandbox" code from a single .exe entry point. diff --git a/tests/ImageSharp.Tests/AssemblyInfo.cs b/tests/ImageSharp.Tests/AssemblyInfo.cs index 4a87fedc0..5f6c8fac1 100644 --- a/tests/ImageSharp.Tests/AssemblyInfo.cs +++ b/tests/ImageSharp.Tests/AssemblyInfo.cs @@ -1,3 +1,6 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + using System.Runtime.CompilerServices; [assembly:InternalsVisibleTo("SixLabors.ImageSharp.Sandbox46")] diff --git a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs index 1c600ed80..80ca0dc6d 100644 --- a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs @@ -1,3 +1,6 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + using System; using System.Collections.Generic; using System.ComponentModel; From 70a28cfc3c4d3000b37d63871364c6d6a5567922 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 01:08:55 +0100 Subject: [PATCH 12/23] minor fixes --- tests/ImageSharp.Tests/AssemblyInfo.cs | 2 +- tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Tests/AssemblyInfo.cs b/tests/ImageSharp.Tests/AssemblyInfo.cs index 5f6c8fac1..944fbe101 100644 --- a/tests/ImageSharp.Tests/AssemblyInfo.cs +++ b/tests/ImageSharp.Tests/AssemblyInfo.cs @@ -3,4 +3,4 @@ using System.Runtime.CompilerServices; -[assembly:InternalsVisibleTo("SixLabors.ImageSharp.Sandbox46")] +[assembly:InternalsVisibleTo("ImageSharp.Tests.ProfilingSandbox")] diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs index fee05ad1c..1bc4f47c7 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs @@ -196,8 +196,12 @@ namespace SixLabors.ImageSharp.Tests proc.WaitForExit(); string standardOutput = proc.StandardOutput.ReadToEnd(); string standardError = proc.StandardError.ReadToEnd(); - Debug.Print(standardOutput); - Debug.Print(standardError); + + if (proc.ExitCode != 0) + { + throw new Exception( + $@"Failed to run {si.FileName} {si.Arguments}:\n STDOUT: {standardOutput}\n STDERR: {standardError}"); + } static FileInfo Find(DirectoryInfo root, string name) { From da8fcfc4a83c79cdcd79ac89de627b1617db6afb Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 01:41:09 +0100 Subject: [PATCH 13/23] comments --- tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs | 4 +++- tests/NuGet.config | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs index 80ca0dc6d..09944b875 100644 --- a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs @@ -11,7 +11,9 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.TestUtilities { /// - /// -compatible serialization for cross-process use-cases. + /// RemoteExecutor can only execute static methods, which can only consume static arguments. + /// To overcome this, data has to be serialized to string. This utility allows serialization + /// of types to strings. /// internal class BasicSerializer : IXunitSerializationInfo { diff --git a/tests/NuGet.config b/tests/NuGet.config index 8f9bf7e10..1bb9a0fc2 100644 --- a/tests/NuGet.config +++ b/tests/NuGet.config @@ -2,7 +2,10 @@ - + From 7f0dc53d655729d85a2e65ecc0e553b7748ba617 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 22 Jan 2020 01:51:06 +0100 Subject: [PATCH 14/23] fix comment text --- tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs index 09944b875..48469db43 100644 --- a/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs @@ -11,8 +11,8 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.TestUtilities { /// - /// RemoteExecutor can only execute static methods, which can only consume static arguments. - /// To overcome this, data has to be serialized to string. This utility allows serialization + /// RemoteExecutor can only execute static methods, which can only consume string arguments, + /// because data is being passed on command line interface. This utility allows serialization /// of types to strings. /// internal class BasicSerializer : IXunitSerializationInfo From 460ca626bd5a1694eea776500b7e852f34c64384 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Jan 2020 13:44:14 +1100 Subject: [PATCH 15/23] Update codecov calc and use inbuild ref source/targets --- .github/workflows/build-and-test.yml | 51 +++++++++++++++++-- .gitignore | 2 +- Directory.Build.props | 3 +- ImageSharp.sln | 4 +- ci-build.ps1 | 15 ++---- ci-pack.ps1 | 11 ++++ tests/Directory.Build.targets | 10 ++-- .../ImageSharp.Tests/ImageSharp.Tests.csproj | 2 +- tests/NuGet.config | 11 ---- 9 files changed, 73 insertions(+), 36 deletions(-) create mode 100644 ci-pack.ps1 delete mode 100644 tests/NuGet.config diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 4cb40d36a..28e109dac 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -82,7 +82,7 @@ jobs: shell: pwsh run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" env: - CI : True + CI: True XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit - name: Update Codecov @@ -93,13 +93,54 @@ jobs: file: "coverage.${{matrix.options.framework}}.xml" flags: unittests - - name: Pack # We can use this filter as we know it happens only once and takes the most time to complete. - if: (github.event_name == 'push') && (matrix.options.codecov == true) + Publish: + needs: [Build] + + runs-on: windows-latest + + if: (github.event_name == 'push') + + steps: + - uses: actions/checkout@v2 + + - name: Install NuGet + uses: NuGet/setup-nuget@v1 + + - name: Setup Git + shell: bash + run: | + git config --global core.autocrlf false + git config --global core.longpaths true + git fetch --prune --unshallow + git submodule -q update --init --recursive + + - name: Fetch Tags for GitVersion + run: | + git fetch --tags + + - name: Fetch master for GitVersion + if: github.ref != 'refs/heads/master' + run: git branch --create-reflog master origin/master + + - name: Install GitVersion + uses: gittools/actions/setup-gitversion@v0.3 + with: + versionSpec: "5.1.x" + + - name: Use GitVersion + id: gitversion # step id used as reference for output values + uses: gittools/actions/execute-gitversion@v0.3 + + - name: Setup DotNet SDK + uses: actions/setup-dotnet@v1 + with: + dotnet-version: "3.1.101" + + - name: Pack shell: pwsh - run: ./ci-build.ps1 "${{steps.gitversion.outputs.nuGetVersion}}" + run: ./ci-pack.ps1 "${{steps.gitversion.outputs.nuGetVersion}}" - name: Publish to MyGet - if: (github.event_name == 'push') && (matrix.options.codecov == true) shell: pwsh run: nuget.exe push .\artifacts\*.nupkg ${{secrets.MYGET_TOKEN}} -Source https://www.myget.org/F/sixlabors/api/v2/package # TODO: If github.ref starts with 'refs/tags' then it was tag push and we can optionally push out package to nuget.org diff --git a/.gitignore b/.gitignore index 8fcb5ef40..a89cfcf10 100644 --- a/.gitignore +++ b/.gitignore @@ -216,7 +216,7 @@ artifacts/ *.csproj.bak #CodeCoverage -/ImageSharp.Coverage.xml +*.lcov # Tests **/Images/ActualOutput diff --git a/Directory.Build.props b/Directory.Build.props index 346da14be..604153f97 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -91,8 +91,9 @@ git https://www.myget.org/F/sixlabors/api/v3/index.json; - https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json; https://api.nuget.org/v3/index.json; + + https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json; 002400000c8000009400000006020000002400005253413100040000010001000147e6fe6766715eec6cfed61f1e7dcdbf69748a3e355c67e9d8dfd953acab1d5e012ba34b23308166fdc61ee1d0390d5f36d814a6091dd4b5ed9eda5a26afced924c683b4bfb4b3d64b0586a57eff9f02b1f84e3cb0ddd518bd1697f2c84dcbb97eb8bb5c7801be12112ed0ec86db934b0e9a5171e6bb1384b6d2f7d54dfa97 true diff --git a/ImageSharp.sln b/ImageSharp.sln index 5d74f7332..40878c575 100644 --- a/ImageSharp.sln +++ b/ImageSharp.sln @@ -10,6 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore .gitmodules = .gitmodules ci-build.ps1 = ci-build.ps1 + ci-pack.ps1 = ci-pack.ps1 ci-test.ps1 = ci-test.ps1 Directory.Build.props = Directory.Build.props Directory.Build.targets = Directory.Build.targets @@ -44,7 +45,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{56801022 ProjectSection(SolutionItems) = preProject tests\Directory.Build.props = tests\Directory.Build.props tests\Directory.Build.targets = tests\Directory.Build.targets - tests\NuGet.config = tests\NuGet.config EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Images", "Images", "{FA55F5DE-11A6-487D-ABA4-BC93A02717DD}" @@ -330,7 +330,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedInfrastructure", "shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.shproj", "{68A8CC40-6AED-4E96-B524-31B1158FDEEA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp.Tests.ProfilingSandbox", "tests\ImageSharp.Tests.ProfilingSandbox\ImageSharp.Tests.ProfilingSandbox.csproj", "{FC527290-2F22-432C-B77B-6E815726B02C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Tests.ProfilingSandbox", "tests\ImageSharp.Tests.ProfilingSandbox\ImageSharp.Tests.ProfilingSandbox.csproj", "{FC527290-2F22-432C-B77B-6E815726B02C}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution diff --git a/ci-build.ps1 b/ci-build.ps1 index ad757dc9e..17c6e6603 100644 --- a/ci-build.ps1 +++ b/ci-build.ps1 @@ -1,20 +1,13 @@ param( [Parameter(Mandatory, Position = 0)] [string]$version, - [Parameter(Mandatory = $false, Position = 1)] - [string]$targetFramework = 'ALL' + [Parameter(Mandatory = $true, Position = 1)] + [string]$targetFramework ) dotnet clean -c Release $repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY" -if ($targetFramework -ne 'ALL') { - # Building for a specific framework. - dotnet build -c Release -f $targetFramework /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl -} -else { - - # Building for packing and publishing. - dotnet pack -c Release --output "$PSScriptRoot/artifacts" /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl -} +# Building for a specific framework. +dotnet build -c Release -f $targetFramework /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl diff --git a/ci-pack.ps1 b/ci-pack.ps1 new file mode 100644 index 000000000..a4e846db9 --- /dev/null +++ b/ci-pack.ps1 @@ -0,0 +1,11 @@ +param( + [Parameter(Mandatory, Position = 0)] + [string]$version +) + +dotnet clean -c Release + +$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY" + +# Building for packing and publishing. +dotnet pack -c Release --output "$PSScriptRoot/artifacts" /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index da21cbb75..22c70d8ca 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -28,10 +28,12 @@ true true - opencover + [SixLabors.*]* + lcov - $(MSBuildThisFileDirectory)..\coverage.xml - + $(MSBuildThisFileDirectory)..\ + $(CoverletOutputPath)$(AssemblyName).$(TargetFramework).lcov + true @@ -43,11 +45,11 @@ + - diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 59534c2a4..34cdca49a 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -18,9 +18,9 @@ + - diff --git a/tests/NuGet.config b/tests/NuGet.config deleted file mode 100644 index 1bb9a0fc2..000000000 --- a/tests/NuGet.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - From 3d367c4504c9233fbe312b41d2f8736ebfe8214b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Jan 2020 14:52:45 +1100 Subject: [PATCH 16/23] Actually upload report --- .github/workflows/build-and-test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 28e109dac..b4b966a02 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -90,7 +90,6 @@ jobs: if: matrix.options.codecov == true with: token: ${{secrets.CODECOV_TOKEN}} - file: "coverage.${{matrix.options.framework}}.xml" flags: unittests Publish: From f2f52f3c939b0d9bddc74df34fb49d8866e383a7 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Jan 2020 23:37:00 +1100 Subject: [PATCH 17/23] Test to see if colorspace tests are ran? --- .../Colorspaces/Conversion/RgbAndHslConversionTest.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs index 8b1fed84c..9ee78ed3e 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -5,6 +5,7 @@ using System; using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.ColorSpaces.Conversion; using Xunit; +using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { @@ -21,6 +22,13 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion private static readonly ColorSpaceConverter Converter = new ColorSpaceConverter(); private static readonly ApproximateColorSpaceComparer ColorSpaceComparer = new ApproximateColorSpaceComparer(.0001F); + private readonly ITestOutputHelper output; + + public RgbAndHslConversionTest(ITestOutputHelper output) + { + this.output = output; + } + /// /// Tests conversion from to . /// @@ -54,6 +62,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { Assert.Equal(expected, actualSpan[i], ColorSpaceComparer); } + + this.output.WriteLine("Y No Coverage??"); } /// From d3f03a2a8d62ea9797a56a990b26ce614fc0043b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Jan 2020 23:51:06 +1100 Subject: [PATCH 18/23] Revert "Test to see if colorspace tests are ran?" This reverts commit 2cb6567b654b30e9ea940840d60cdf3c012a1bec. --- .../Colorspaces/Conversion/RgbAndHslConversionTest.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs index 9ee78ed3e..8b1fed84c 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -5,7 +5,6 @@ using System; using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.ColorSpaces.Conversion; using Xunit; -using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { @@ -22,13 +21,6 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion private static readonly ColorSpaceConverter Converter = new ColorSpaceConverter(); private static readonly ApproximateColorSpaceComparer ColorSpaceComparer = new ApproximateColorSpaceComparer(.0001F); - private readonly ITestOutputHelper output; - - public RgbAndHslConversionTest(ITestOutputHelper output) - { - this.output = output; - } - /// /// Tests conversion from to . /// @@ -62,8 +54,6 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { Assert.Equal(expected, actualSpan[i], ColorSpaceComparer); } - - this.output.WriteLine("Y No Coverage??"); } /// From 94ce58b1d1f6d5de421763318912fd534ac3bbc7 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 22 Jan 2020 23:52:58 +1100 Subject: [PATCH 19/23] Run codecov tests in debug mode. --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b4b966a02..8b47b0f76 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -80,7 +80,7 @@ jobs: - name: Test shell: pwsh - run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" + run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" Debug env: CI: True XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit From 9b57a30fd91c604fa6acf6097ff6294ff5f9661f Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 23 Jan 2020 01:04:44 +1100 Subject: [PATCH 20/23] Filter xunit references so testrunner does not throw. --- .github/workflows/build-and-test.yml | 2 +- tests/Directory.Build.props | 2 +- tests/Directory.Build.targets | 2 +- .../Conversion/RgbAndHslConversionTest.cs | 23 +++++++++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 8b47b0f76..b4b966a02 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -80,7 +80,7 @@ jobs: - name: Test shell: pwsh - run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" Debug + run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" env: CI: True XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 3d8286971..64f79e324 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -24,7 +24,7 @@ - + diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index 22c70d8ca..137a7a030 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -17,7 +17,7 @@ - + diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs index 8b1fed84c..21f32861d 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -5,6 +5,7 @@ using System; using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.ColorSpaces.Conversion; using Xunit; +using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { @@ -21,6 +22,24 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion private static readonly ColorSpaceConverter Converter = new ColorSpaceConverter(); private static readonly ApproximateColorSpaceComparer ColorSpaceComparer = new ApproximateColorSpaceComparer(.0001F); + public static TheoryData Hsl_To_Rgb + = new TheoryData + { + { 0, 0, 0, 0, 0, 0 }, + { 0, 1, 1, 1, 1, 1 }, + { 360, 1, 1, 1, 1, 1 }, + { 0, 1, .5F, 1, 0, 0 }, + { 120, 1, .5F, 0, 1, 0 }, + { 240, 1, .5F, 0, 0, 1 } + }; + + private readonly ITestOutputHelper output; + + public RgbAndHslConversionTest(ITestOutputHelper output) + { + this.output = output; + } + /// /// Tests conversion from to . /// @@ -31,6 +50,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion [InlineData(0, 1, .5F, 1, 0, 0)] [InlineData(120, 1, .5F, 0, 1, 0)] [InlineData(240, 1, .5F, 0, 0, 1)] + //[Theory] + //[MemberData(nameof(Hsl_To_Rgb))] public void Convert_Hsl_To_Rgb(float h, float s, float l, float r, float g, float b) { // Arrange @@ -54,6 +75,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { Assert.Equal(expected, actualSpan[i], ColorSpaceComparer); } + + this.output.WriteLine("Verifying Convert_Hsl_To_Rgb is run"); } /// From aeb01003613e976be4df788adffc9471888fdecc Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 25 Jan 2020 04:25:58 +0100 Subject: [PATCH 21/23] LambdaProvider -> serializable MemberMethodProvider --- .../Attributes/WithMemberFactoryAttribute.cs | 16 +---- .../ImageProviders/LambdaProvider.cs | 34 --------- .../ImageProviders/MemberMethodProvider.cs | 69 +++++++++++++++++++ .../ImageProviders/TestImageProvider.cs | 5 +- 4 files changed, 74 insertions(+), 50 deletions(-) delete mode 100644 tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs create mode 100644 tests/ImageSharp.Tests/TestUtilities/ImageProviders/MemberMethodProvider.cs diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithMemberFactoryAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithMemberFactoryAttribute.cs index cdf5fcb08..5aed3b364 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithMemberFactoryAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithMemberFactoryAttribute.cs @@ -31,21 +31,9 @@ namespace SixLabors.ImageSharp.Tests protected override object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) { - MethodInfo m = testMethod.DeclaringType.GetMethod(this.memberMethodName); - - Type[] args = factoryType.GetGenericArguments(); - Type colorType = args.Single(); - - Type imgType = typeof(Image<>).MakeGenericType(colorType); - - Type funcType = typeof(Func<>).MakeGenericType(imgType); - - MethodInfo genericMethod = m.MakeGenericMethod(args); - - Delegate d = genericMethod.CreateDelegate(funcType); - return new object[] { d }; + return new object[] { testMethod.DeclaringType.FullName, this.memberMethodName}; } protected override string GetFactoryMethodName(MethodInfo testMethod) => "Lambda"; } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs deleted file mode 100644 index b39c4f676..000000000 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/LambdaProvider.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; - -using SixLabors.ImageSharp.PixelFormats; - -namespace SixLabors.ImageSharp.Tests -{ - /// - /// Provides instances for parametric unit tests. - /// - /// The pixel format of the image - public abstract partial class TestImageProvider - where TPixel : struct, IPixel - { - private class LambdaProvider : TestImageProvider - { - private readonly Func> factoryFunc; - - public LambdaProvider() - { - throw new NotSupportedException(); - } - - public LambdaProvider(Func> factoryFunc) - { - this.factoryFunc = factoryFunc; - } - - public override Image GetImage() => this.factoryFunc(); - } - } -} diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/MemberMethodProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/MemberMethodProvider.cs new file mode 100644 index 000000000..077dc622f --- /dev/null +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/MemberMethodProvider.cs @@ -0,0 +1,69 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Linq; +using System.Reflection; +using SixLabors.ImageSharp.PixelFormats; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests +{ + /// + /// Provides instances for parametric unit tests. + /// + /// The pixel format of the image + public abstract partial class TestImageProvider + where TPixel : struct, IPixel + { + private class MemberMethodProvider : TestImageProvider + { + private string declaringTypeName; + private string methodName; + private Func> factoryFunc; + + public MemberMethodProvider() + { + } + + public MemberMethodProvider(string declaringTypeName, string methodName) + { + this.declaringTypeName = declaringTypeName; + this.methodName = methodName; + } + + public override Image GetImage() + { + this.factoryFunc ??= this.GetFactory(); + return this.factoryFunc(); + } + + public override void Serialize(IXunitSerializationInfo info) + { + base.Serialize(info); + + info.AddValue(nameof(this.declaringTypeName), this.declaringTypeName); + info.AddValue(nameof(this.methodName), this.methodName); + } + + public override void Deserialize(IXunitSerializationInfo info) + { + base.Deserialize(info); + + this.methodName = info.GetValue(nameof(this.methodName)); + this.declaringTypeName = info.GetValue(nameof(this.declaringTypeName)); + } + + private Func> GetFactory() + { + var declaringType = Type.GetType(this.declaringTypeName); + MethodInfo m = declaringType.GetMethod(this.methodName); + Type pixelType = typeof(TPixel); + Type imgType = typeof(Image<>).MakeGenericType(pixelType); + Type funcType = typeof(Func<>).MakeGenericType(imgType); + MethodInfo genericMethod = m.MakeGenericMethod(pixelType); + return (Func>) genericMethod.CreateDelegate(funcType); + } + } + } +} diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs index 6443050d3..8b165a8be 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs @@ -73,10 +73,11 @@ namespace SixLabors.ImageSharp.Tests } public static TestImageProvider Lambda( - Func> factoryFunc, + string declaringTypeName, + string methodName, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) - => new LambdaProvider(factoryFunc).Init(testMethod, pixelTypeOverride); + => new MemberMethodProvider(declaringTypeName, methodName).Init(testMethod, pixelTypeOverride); public static TestImageProvider Solid( int width, From 6ddd5f6e28a05be0b7ff375daca981ba26f92984 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 25 Jan 2020 18:48:21 +1100 Subject: [PATCH 22/23] Revert HSL<=>Rgb test changes --- .../Conversion/RgbAndHslConversionTest.cs | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs index 21f32861d..8b1fed84c 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -5,7 +5,6 @@ using System; using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.ColorSpaces.Conversion; using Xunit; -using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { @@ -22,24 +21,6 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion private static readonly ColorSpaceConverter Converter = new ColorSpaceConverter(); private static readonly ApproximateColorSpaceComparer ColorSpaceComparer = new ApproximateColorSpaceComparer(.0001F); - public static TheoryData Hsl_To_Rgb - = new TheoryData - { - { 0, 0, 0, 0, 0, 0 }, - { 0, 1, 1, 1, 1, 1 }, - { 360, 1, 1, 1, 1, 1 }, - { 0, 1, .5F, 1, 0, 0 }, - { 120, 1, .5F, 0, 1, 0 }, - { 240, 1, .5F, 0, 0, 1 } - }; - - private readonly ITestOutputHelper output; - - public RgbAndHslConversionTest(ITestOutputHelper output) - { - this.output = output; - } - /// /// Tests conversion from to . /// @@ -50,8 +31,6 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion [InlineData(0, 1, .5F, 1, 0, 0)] [InlineData(120, 1, .5F, 0, 1, 0)] [InlineData(240, 1, .5F, 0, 0, 1)] - //[Theory] - //[MemberData(nameof(Hsl_To_Rgb))] public void Convert_Hsl_To_Rgb(float h, float s, float l, float r, float g, float b) { // Arrange @@ -75,8 +54,6 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion { Assert.Equal(expected, actualSpan[i], ColorSpaceComparer); } - - this.output.WriteLine("Verifying Convert_Hsl_To_Rgb is run"); } /// From 3fa41b70fdbceb2b6d1ca8dd1076fa267ed21b63 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 25 Jan 2020 19:28:55 +1100 Subject: [PATCH 23/23] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ceb1e51d2..af8d4f73a 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ SixLabors.ImageSharp
+[![Build Status](https://img.shields.io/github/workflow/status/SixLabors/ImageSharp/Build/master)](https://github.com/SixLabors/ImageSharp/actions) [![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/SixLabors/ImageSharp/master/LICENSE) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ImageSharp/General?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=flat&logo=twitter)](https://twitter.com/intent/tweet?hashtags=imagesharp,dotnet,oss&text=ImageSharp.+A+new+cross-platform+2D+graphics+API+in+C%23&url=https%3a%2f%2fgithub.com%2fSixLabors%2fImageSharp&via=sixlabors) @@ -45,12 +46,13 @@ The **ImageSharp** library is made up of multiple packages: - Transform methods like Resize, Crop, Skew, Rotate - anything that alters the dimensions of the image - Non-transform methods like Gaussian Blur, Pixelate, Edge Detection - anything that maintains the original image dimensions + ### Questions? - Do you have questions? We are happy to help! Please [join our gitter channel](https://gitter.im/ImageSharp/General), or ask them on [stackoverflow](https://stackoverflow.com) using the `ImageSharp` tag. **Do not** open issues for questions!