diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 4cb40d36a0..b4b966a02d 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
@@ -90,16 +90,56 @@ jobs:
if: matrix.options.codecov == true
with:
token: ${{secrets.CODECOV_TOKEN}}
- 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 8fcb5ef405..a89cfcf104 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 346da14be8..604153f976 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 875ede1b2d..40878c5751 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
@@ -322,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
@@ -331,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("{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
shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems*{68a8cc40-6aed-4e96-b524-31b1158fdeea}*SharedItemsImports = 13
@@ -380,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
@@ -415,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/README.md b/README.md
index ceb1e51d22..af8d4f73ae 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ SixLabors.ImageSharp
+[](https://github.com/SixLabors/ImageSharp/actions)
[](https://raw.githubusercontent.com/SixLabors/ImageSharp/master/LICENSE)
[](https://gitter.im/ImageSharp/General?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](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!
diff --git a/ci-build.ps1 b/ci-build.ps1
index ad757dc9e2..17c6e6603b 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 0000000000..a4e846db95
--- /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.props b/tests/Directory.Build.props
index 3d8286971e..64f79e3248 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 9ee9c226d3..137a7a0305 100644
--- a/tests/Directory.Build.targets
+++ b/tests/Directory.Build.targets
@@ -17,7 +17,7 @@
-
+
@@ -28,10 +28,12 @@
true
true
- opencover
+ [SixLabors.*]*
+ lcov
- $(MSBuildThisFileDirectory)..\coverage.xml
-
+ $(MSBuildThisFileDirectory)..\
+ $(CoverletOutputPath)$(AssemblyName).$(TargetFramework).lcov
+
true
@@ -43,13 +45,13 @@
+
-
-
-
+
+
diff --git a/tests/ImageSharp.Sandbox46/README.md b/tests/ImageSharp.Sandbox46/README.md
deleted file mode 100644
index b05afb8538..0000000000
--- a/tests/ImageSharp.Sandbox46/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-## 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.
-
\ No newline at end of file
diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
similarity index 70%
rename from tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
rename to tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
index e89b28dc11..99269e339a 100644
--- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
+++ b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
@@ -2,26 +2,26 @@
- 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.Sandbox46/Program.cs b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
similarity index 88%
rename from tests/ImageSharp.Sandbox46/Program.cs
rename to tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
index 93fe74076e..f041e16eb5 100644
--- a/tests/ImageSharp.Sandbox46/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
new file mode 100644
index 0000000000..43fdab9ef6
--- /dev/null
+++ b/tests/ImageSharp.Tests.ProfilingSandbox/README.md
@@ -0,0 +1,2 @@
+## 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.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
diff --git a/tests/ImageSharp.Tests/AssemblyInfo.cs b/tests/ImageSharp.Tests/AssemblyInfo.cs
new file mode 100644
index 0000000000..944fbe101e
--- /dev/null
+++ b/tests/ImageSharp.Tests/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Runtime.CompilerServices;
+
+[assembly:InternalsVisibleTo("ImageSharp.Tests.ProfilingSandbox")]
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs
index 2485561f1e..59b6963eb9 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 @@ public partial class JpegDecoderTests
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 77bc9f5404..4f155e9c3a 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 @@ public partial class JpegDecoderTests
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 009f86483e..90caea387d 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,9 +24,15 @@ public partial class JpegDecoderTests
public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector;
private const float BaselineTolerance = 0.001F / 100;
+
private const float ProgressiveTolerance = 0.2F / 100;
- private ImageComparer GetImageComparer(TestImageProvider provider)
+ static JpegDecoderTests()
+ {
+ TestEnvironment.PrepareRemoteExecutor();
+ }
+
+ private static ImageComparer GetImageComparer(TestImageProvider provider)
where TPixel : struct, IPixel
{
string file = provider.SourceFileOrDescription;
@@ -88,23 +95,19 @@ public void ParseStream_BasicPropertiesAreCorrect()
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/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj
index 4aabc2f4e2..34cdca49a1 100644
--- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj
+++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj
@@ -18,6 +18,7 @@
+
diff --git a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs
index d38b5b9ddb..227d627784 100644
--- a/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs
+++ b/tests/ImageSharp.Tests/Memory/Alocators/ArrayPoolMemoryAllocatorTests.cs
@@ -4,39 +4,36 @@
// 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;
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();
+ ///
+ /// Contains SUT for tests executed by ,
+ /// recreated in each external process.
+ ///
+ private static MemoryAllocatorFixture StaticFixture { get; } = new MemoryAllocatorFixture();
- return sameBuffers;
+ static ArrayPoolMemoryAllocatorTests()
+ {
+ TestEnvironment.PrepareRemoteExecutor();
}
public class BufferTests : BufferTestSuite
@@ -78,21 +75,21 @@ public void When_PoolSelectorThresholdInBytes_IsGreaterThan_MaxPooledBufferSizeI
[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 +97,15 @@ public unsafe void SmallBuffersArePooled_OfBigValueType()
{
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 +113,13 @@ public unsafe void LaregeBuffersAreNotPooled_OfBigValueType()
[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 +131,8 @@ public void CleaningRequests_AreControlledByAllocationParameter_Clean(Allocation
[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 +140,9 @@ public void ReleaseRetainedResources_ReplacesInnerArrayPool(bool keepBufferAlive
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 +150,69 @@ public void ReleaseRetainedResources_ReplacesInnerArrayPool(bool keepBufferAlive
[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 +220,8 @@ private struct LargeStruct
[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 +229,45 @@ public void AllocateIncorrectAmount_ThrowsCorrect_ArgumentOutOfRangeException(in
[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/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs
index 859be6b205..6706e4077a 100644
--- a/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs
+++ b/tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs
@@ -29,8 +29,8 @@ private static Span AsSpan(T value)
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 @@ public void NormalBlendFunction(TestPixel back, TestPixel(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 @@ public void NormalBlendFunctionBlenderBulk(TestPixel back, TestP
{
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