Browse Source

remove ArrayPoolMemoryAllocator from tests

af/UniformUnmanagedMemoryPoolMemoryAllocator-02-MemoryGuards
Anton Firszov 5 years ago
parent
commit
58a23cdf1d
  1. 6
      tests/ImageSharp.Tests/Image/ImageFrameTests.cs
  2. 11
      tests/ImageSharp.Tests/Image/ImageTests.cs
  3. 276
      tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs
  4. 22
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
  5. 8
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs
  6. 10
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  7. 6
      tests/ImageSharp.Tests/TestUtilities/TestUtils.cs

6
tests/ImageSharp.Tests/Image/ImageFrameTests.cs

@ -4,6 +4,7 @@
using System;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Memory;
using Xunit;
namespace SixLabors.ImageSharp.Tests
@ -16,10 +17,7 @@ namespace SixLabors.ImageSharp.Tests
private void LimitBufferCapacity(int bufferCapacityInBytes)
{
// TODO: Create a test-only MemoryAllocator for this
#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete
var allocator = ArrayPoolMemoryAllocator.CreateDefault();
#pragma warning restore CS0618
var allocator = new TestMemoryAllocator();
allocator.BufferCapacityInBytes = bufferCapacityInBytes;
this.configuration.MemoryAllocator = allocator;
}

11
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -97,15 +97,8 @@ namespace SixLabors.ImageSharp.Tests
{
private readonly Configuration configuration = Configuration.CreateDefaultInstance();
private void LimitBufferCapacity(int bufferCapacityInBytes)
{
// TODO: Create a test-only MemoryAllocator for this
#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete
var allocator = ArrayPoolMemoryAllocator.CreateDefault();
#pragma warning restore CS0618
allocator.BufferCapacityInBytes = bufferCapacityInBytes;
this.configuration.MemoryAllocator = allocator;
}
private void LimitBufferCapacity(int bufferCapacityInBytes) =>
this.configuration.MemoryAllocator = new TestMemoryAllocator { BufferCapacityInBytes = bufferCapacityInBytes };
[Theory]
[InlineData(false)]

276
tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs

@ -1,276 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Memory;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Memory.Allocators
{
#pragma warning disable CS0618
public class ArrayPoolMemoryAllocatorTests
{
private const int MaxPooledBufferSizeInBytes = 2048;
private const int PoolSelectorThresholdInBytes = MaxPooledBufferSizeInBytes / 2;
/// <summary>
/// Gets the SUT for in-process tests.
/// </summary>
private MemoryAllocatorFixture LocalFixture { get; } = new MemoryAllocatorFixture();
/// <summary>
/// Gets the SUT for tests executed by <see cref="RemoteExecutor"/>,
/// recreated in each external process.
/// </summary>
private static MemoryAllocatorFixture StaticFixture { get; } = new MemoryAllocatorFixture();
public class BufferTests : BufferTestSuite
{
public BufferTests()
: base(new ArrayPoolMemoryAllocator(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes))
{
}
}
public class Constructor
{
[Fact]
public void WhenBothParametersPassedByUser()
{
var mgr = new ArrayPoolMemoryAllocator(1111, 666);
Assert.Equal(1111, mgr.MaxPoolSizeInBytes);
Assert.Equal(666, mgr.PoolSelectorThresholdInBytes);
}
[Fact]
public void WhenPassedOnly_MaxPooledBufferSizeInBytes_SmallerThresholdValueIsAutoCalculated()
{
var mgr = new ArrayPoolMemoryAllocator(5000);
Assert.Equal(5000, mgr.MaxPoolSizeInBytes);
Assert.True(mgr.PoolSelectorThresholdInBytes < mgr.MaxPoolSizeInBytes);
}
[Fact]
public void When_PoolSelectorThresholdInBytes_IsGreaterThan_MaxPooledBufferSizeInBytes_ExceptionIsThrown()
=> Assert.ThrowsAny<Exception>(() => new ArrayPoolMemoryAllocator(100, 200));
}
[Theory]
[InlineData(32)]
[InlineData(512)]
[InlineData(MaxPooledBufferSizeInBytes - 1)]
public void SmallBuffersArePooled_OfByte(int size) => Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer<byte>(size));
[Theory]
[InlineData(128 * 1024 * 1024)]
[InlineData(MaxPooledBufferSizeInBytes + 1)]
public void LargeBuffersAreNotPooled_OfByte(int size)
{
static void RunTest(string sizeStr)
{
int size = int.Parse(sizeStr);
StaticFixture.CheckIsRentingPooledBuffer<byte>(size);
}
RemoteExecutor.Invoke(RunTest, size.ToString()).Dispose();
}
[Fact]
public unsafe void SmallBuffersArePooled_OfBigValueType()
{
int count = (MaxPooledBufferSizeInBytes / sizeof(LargeStruct)) - 1;
Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer<LargeStruct>(count));
}
[Fact]
public unsafe void LaregeBuffersAreNotPooled_OfBigValueType()
{
int count = (MaxPooledBufferSizeInBytes / sizeof(LargeStruct)) + 1;
Assert.False(this.LocalFixture.CheckIsRentingPooledBuffer<LargeStruct>(count));
}
[Theory]
[InlineData(AllocationOptions.None)]
[InlineData(AllocationOptions.Clean)]
public void CleaningRequests_AreControlledByAllocationParameter_Clean(AllocationOptions options)
{
MemoryAllocator memoryAllocator = this.LocalFixture.MemoryAllocator;
using (IMemoryOwner<int> firstAlloc = memoryAllocator.Allocate<int>(42))
{
BufferExtensions.GetSpan(firstAlloc).Fill(666);
}
using (IMemoryOwner<int> secondAlloc = memoryAllocator.Allocate<int>(42, options))
{
int expected = options == AllocationOptions.Clean ? 0 : 666;
Assert.Equal(expected, BufferExtensions.GetSpan(secondAlloc)[0]);
}
}
[Fact]
public unsafe void Allocate_MemoryIsPinnableMultipleTimes()
{
ArrayPoolMemoryAllocator allocator = this.LocalFixture.MemoryAllocator;
using IMemoryOwner<byte> memoryOwner = allocator.Allocate<byte>(100);
using (MemoryHandle pin = memoryOwner.Memory.Pin())
{
Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer);
}
using (MemoryHandle pin = memoryOwner.Memory.Pin())
{
Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer);
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void ReleaseRetainedResources_ReplacesInnerArrayPool(bool keepBufferAlive)
{
MemoryAllocator memoryAllocator = this.LocalFixture.MemoryAllocator;
IMemoryOwner<int> buffer = memoryAllocator.Allocate<int>(32);
ref int ptrToPrev0 = ref MemoryMarshal.GetReference(BufferExtensions.GetSpan(buffer));
if (!keepBufferAlive)
{
buffer.Dispose();
}
memoryAllocator.ReleaseRetainedResources();
buffer = memoryAllocator.Allocate<int>(32);
Assert.False(Unsafe.AreSame(ref ptrToPrev0, ref BufferExtensions.GetReference(buffer)));
}
[Fact]
public void ReleaseRetainedResources_DisposingPreviouslyAllocatedBuffer_IsAllowed()
{
MemoryAllocator memoryAllocator = this.LocalFixture.MemoryAllocator;
IMemoryOwner<int> buffer = memoryAllocator.Allocate<int>(32);
memoryAllocator.ReleaseRetainedResources();
buffer.Dispose();
}
[Fact]
public void AllocationOverLargeArrayThreshold_UsesDifferentPool()
{
static void RunTest()
{
const int ArrayLengthThreshold = PoolSelectorThresholdInBytes / sizeof(int);
IMemoryOwner<int> small = StaticFixture.MemoryAllocator.Allocate<int>(ArrayLengthThreshold - 1);
ref int ptr2Small = ref BufferExtensions.GetReference(small);
small.Dispose();
IMemoryOwner<int> large = StaticFixture.MemoryAllocator.Allocate<int>(ArrayLengthThreshold + 1);
Assert.False(Unsafe.AreSame(ref ptr2Small, ref BufferExtensions.GetReference(large)));
}
RemoteExecutor.Invoke(RunTest).Dispose();
}
[Fact]
public void CreateWithAggressivePooling()
{
static void RunTest()
{
StaticFixture.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithAggressivePooling();
Assert.True(StaticFixture.CheckIsRentingPooledBuffer<SmallStruct>(4096 * 4096));
}
RemoteExecutor.Invoke(RunTest).Dispose();
}
[Fact]
public void CreateDefault()
{
static void RunTest()
{
StaticFixture.MemoryAllocator = ArrayPoolMemoryAllocator.CreateDefault();
Assert.False(StaticFixture.CheckIsRentingPooledBuffer<SmallStruct>(2 * 4096 * 4096));
Assert.True(StaticFixture.CheckIsRentingPooledBuffer<SmallStruct>(2048 * 2048));
}
RemoteExecutor.Invoke(RunTest).Dispose();
}
[Fact]
public void CreateWithModeratePooling()
{
static void RunTest()
{
StaticFixture.MemoryAllocator = ArrayPoolMemoryAllocator.CreateWithModeratePooling();
Assert.False(StaticFixture.CheckIsRentingPooledBuffer<SmallStruct>(2048 * 2048));
Assert.True(StaticFixture.CheckIsRentingPooledBuffer<SmallStruct>(1024 * 16));
}
RemoteExecutor.Invoke(RunTest).Dispose();
}
[Theory]
[InlineData(-1)]
[InlineData(-111)]
public void Allocate_Negative_Throws_ArgumentOutOfRangeException(int length)
{
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() =>
this.LocalFixture.MemoryAllocator.Allocate<LargeStruct>(length));
Assert.Equal("length", ex.ParamName);
}
[Fact]
public void AllocateZero()
{
using IMemoryOwner<int> buffer = this.LocalFixture.MemoryAllocator.Allocate<int>(0);
Assert.Equal(0, buffer.Memory.Length);
}
private class MemoryAllocatorFixture
{
public ArrayPoolMemoryAllocator MemoryAllocator { get; set; } =
new ArrayPoolMemoryAllocator(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes);
/// <summary>
/// Rent a buffer -> return it -> re-rent -> verify if it's span points to the previous location.
/// </summary>
public bool CheckIsRentingPooledBuffer<T>(int length)
where T : struct
{
IMemoryOwner<T> buffer = this.MemoryAllocator.Allocate<T>(length);
ref T ptrToPrevPosition0 = ref BufferExtensions.GetReference(buffer);
buffer.Dispose();
buffer = this.MemoryAllocator.Allocate<T>(length);
bool sameBuffers = Unsafe.AreSame(ref ptrToPrevPosition0, ref BufferExtensions.GetReference(buffer));
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
{
}
}
#pragma warning restore CS0618
}

22
tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs

@ -24,18 +24,17 @@ namespace SixLabors.ImageSharp.Tests
// are shared between PixelTypes.Color & PixelTypes.Rgba32
private class Key : IEquatable<Key>
{
private readonly Tuple<PixelTypes, string, Type, int> commonValues;
private readonly Tuple<PixelTypes, string, Type> commonValues;
private readonly Dictionary<string, object> decoderParameters;
public Key(PixelTypes pixelType, string filePath, int allocatorBufferCapacity, IImageDecoder customDecoder)
public Key(PixelTypes pixelType, string filePath, IImageDecoder customDecoder)
{
Type customType = customDecoder?.GetType();
this.commonValues = new Tuple<PixelTypes, string, Type, int>(
this.commonValues = new Tuple<PixelTypes, string, Type>(
pixelType,
filePath,
customType,
allocatorBufferCapacity);
customType);
this.decoderParameters = GetDecoderParameters(customDecoder);
}
@ -153,20 +152,13 @@ namespace SixLabors.ImageSharp.Tests
{
Guard.NotNull(decoder, nameof(decoder));
if (!TestEnvironment.Is64BitProcess)
// Do not cache with 64 bits or if image has been created with non-default MemoryAllocator
if (!TestEnvironment.Is64BitProcess || this.Configuration.MemoryAllocator != MemoryAllocator.Default)
{
return this.LoadImage(decoder);
}
int bufferCapacity = -1;
#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete
if (this.Configuration.MemoryAllocator is ArrayPoolMemoryAllocator arrayPoolMemoryAllocator)
#pragma warning restore CS0618
{
bufferCapacity = arrayPoolMemoryAllocator.BufferCapacityInBytes;
}
var key = new Key(this.PixelType, this.FilePath, bufferCapacity, decoder);
var key = new Key(this.PixelType, this.FilePath, decoder);
Image<TPixel> cachedImage = Cache.GetOrAdd(key, _ => this.LoadImage(decoder));

8
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs

@ -21,17 +21,11 @@ namespace SixLabors.ImageSharp.Tests
public abstract partial class TestImageProvider<TPixel> : ITestImageProvider, IXunitSerializable
where TPixel : unmanaged, IPixel<TPixel>
{
public TestImageProvider()
{
this.Configuration = Configuration.CreateDefaultInstance();
this.Configuration.MemoryAllocator = Configuration.Default.MemoryAllocator;
}
public PixelTypes PixelType { get; private set; } = typeof(TPixel).GetPixelType();
public virtual string SourceFileOrDescription => string.Empty;
public Configuration Configuration { get; set; }
public Configuration Configuration { get; set; } = Configuration.CreateDefaultInstance();
/// <summary>
/// Gets the utility instance to provide information about the test image & manage input/output.

10
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -12,6 +12,7 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors;
using SixLabors.ImageSharp.Tests.Memory;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit;
@ -692,10 +693,7 @@ namespace SixLabors.ImageSharp.Tests
this TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
// TODO: Use a test-only allocator for this.
#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete
var allocator = ArrayPoolMemoryAllocator.CreateDefault();
#pragma warning restore
var allocator = new TestMemoryAllocator();
provider.Configuration.MemoryAllocator = allocator;
return new AllocatorBufferCapacityConfigurator(allocator, Unsafe.SizeOf<TPixel>());
}
@ -781,10 +779,10 @@ namespace SixLabors.ImageSharp.Tests
internal class AllocatorBufferCapacityConfigurator
{
#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete
private readonly ArrayPoolMemoryAllocator allocator;
private readonly TestMemoryAllocator allocator;
private readonly int pixelSizeInBytes;
public AllocatorBufferCapacityConfigurator(ArrayPoolMemoryAllocator allocator, int pixelSizeInBytes)
public AllocatorBufferCapacityConfigurator(TestMemoryAllocator allocator, int pixelSizeInBytes)
{
this.allocator = allocator;
this.pixelSizeInBytes = pixelSizeInBytes;

6
tests/ImageSharp.Tests/TestUtilities/TestUtils.cs

@ -12,6 +12,7 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.Memory;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit;
@ -165,10 +166,7 @@ namespace SixLabors.ImageSharp.Tests
int width = expected.Width;
expected.Mutate(process);
// TODO: Use a test-only allocator for this
#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete
var allocator = ArrayPoolMemoryAllocator.CreateDefault();
#pragma warning restore CS0618
var allocator = new TestMemoryAllocator();
provider.Configuration.MemoryAllocator = allocator;
allocator.BufferCapacityInBytes = bufferCapacityInPixelRows * width * Unsafe.SizeOf<TPixel>();

Loading…
Cancel
Save