📷 A modern, cross-platform, 2D Graphics library for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

151 lines
5.6 KiB

using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
using Xunit;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.Memory.DiscontiguousBuffers
{
public class MemoryGroupTests
{
private readonly TestMemoryAllocator memoryAllocator = new TestMemoryAllocator();
public class Allocate
{
private readonly TestMemoryAllocator memoryAllocator = new TestMemoryAllocator();
#pragma warning disable SA1509
public static TheoryData<object, int, int, long, int, int, int> AllocateData =
new TheoryData<object, int, int, long, int, int, int>()
{
{ default(S5), 22, 4, 4, 1, 4, 4 },
{ default(S5), 22, 4, 7, 2, 4, 3 },
{ default(S5), 22, 4, 8, 2, 4, 4 },
{ default(S5), 22, 4, 21, 6, 4, 1 },
{ default(S5), 22, 4, 0, 0, 4, -1 },
{ default(S4), 50, 12, 12, 1, 12, 12 },
{ default(S4), 50, 7, 12, 2, 7, 5 },
{ default(S4), 50, 6, 12, 1, 12, 12 },
{ default(S4), 50, 5, 12, 2, 10, 2 },
{ default(S4), 50, 4, 12, 1, 12, 12 },
{ default(S4), 50, 3, 12, 1, 12, 12 },
{ default(S4), 50, 2, 12, 1, 12, 12 },
{ default(S4), 50, 1, 12, 1, 12, 12 },
{ default(S4), 50, 12, 13, 2, 12, 1 },
{ default(S4), 50, 7, 21, 3, 7, 7 },
{ default(S4), 50, 7, 23, 4, 7, 2 },
{ default(S4), 50, 6, 13, 2, 12, 1 },
{ default(short), 200, 50, 49, 1, 49, 49 },
{ default(short), 200, 50, 1, 1, 1, 1 },
{ default(byte), 1000, 512, 2047, 4, 512, 511 }
};
[Theory]
[MemberData(nameof(AllocateData))]
public void BufferSizesAreCorrect<T>(
T dummy,
int bufferCapacity,
int bufferAlignment,
long totalLength,
int expectedNumberOfBuffers,
int expectedBufferSize,
int expectedSizeOfLastBuffer)
where T : struct
{
this.memoryAllocator.BufferCapacity = bufferCapacity;
// Act:
using var g = MemoryGroup<T>.Allocate(this.memoryAllocator, totalLength, bufferAlignment);
// Assert:
Assert.Equal(expectedNumberOfBuffers, g.Count);
Assert.Equal(expectedBufferSize, g.BufferSize);
if (g.Count == 0)
{
return;
}
for (int i = 0; i < g.Count - 1; i++)
{
Assert.Equal(g[i].Length, expectedBufferSize);
}
Assert.Equal(g.Last().Length, expectedSizeOfLastBuffer);
}
[Fact]
public void WhenBlockAlignmentIsOverCapacity_Throws_InvalidMemoryOperationException()
{
this.memoryAllocator.BufferCapacity = 84; // 42 * Int16
Assert.Throws<InvalidMemoryOperationException>(() =>
{
MemoryGroup<short>.Allocate(this.memoryAllocator, 50, 43);
});
}
[Theory]
[InlineData(AllocationOptions.None)]
[InlineData(AllocationOptions.Clean)]
public void MemoryAllocatorIsUtilizedCorrectly(AllocationOptions allocationOptions)
{
this.memoryAllocator.BufferCapacity = 200;
HashSet<int> bufferHashes;
int expectedBlockCount = 5;
using (var g = MemoryGroup<short>.Allocate(this.memoryAllocator, 500, 100, allocationOptions))
{
IReadOnlyList<TestMemoryAllocator.AllocationRequest> allocationLog = this.memoryAllocator.AllocationLog;
Assert.Equal(expectedBlockCount, allocationLog.Count);
bufferHashes = allocationLog.Select(l => l.HashCodeOfBuffer).ToHashSet();
Assert.Equal(expectedBlockCount, bufferHashes.Count);
Assert.Equal(0, this.memoryAllocator.ReturnLog.Count);
for (int i = 0; i < expectedBlockCount; i++)
{
Assert.Equal(allocationOptions, allocationLog[i].AllocationOptions);
Assert.Equal(100, allocationLog[i].Length);
Assert.Equal(200, allocationLog[i].LengthInBytes);
}
}
Assert.Equal(expectedBlockCount, this.memoryAllocator.ReturnLog.Count);
Assert.True(bufferHashes.SetEquals(this.memoryAllocator.ReturnLog.Select(l => l.HashCodeOfBuffer)));
}
}
[Fact]
public void IsValid_TrueAfterCreation()
{
using var g = MemoryGroup<byte>.Allocate(this.memoryAllocator, 10, 100);
Assert.True(g.IsValid);
}
[Fact]
public void IsValid_FalseAfterDisposal()
{
using var g = MemoryGroup<byte>.Allocate(this.memoryAllocator, 10, 100);
g.Dispose();
Assert.False(g.IsValid);
}
[StructLayout(LayoutKind.Sequential, Size = 5)]
private struct S5
{
public override string ToString() => "S5";
}
[StructLayout(LayoutKind.Sequential, Size = 4)]
private struct S4
{
public override string ToString() => "S4";
}
}
}