diff --git a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs index 75e57c62bc..2ab3c973aa 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs @@ -47,46 +47,58 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators } } - public static readonly bool IsNotMacOs = !TestEnvironment.IsOSX; + // Complicated Xunit ceremony to disable parallel execution of an individual test, + // MultiplePoolInstances_TrimPeriodElapsed_AllAreTrimmed, + // which is strongly timing-sensitive, and might be flaky under high load. + [CollectionDefinition(nameof(NonParallelCollection), DisableParallelization = true)] + public class NonParallelCollection + { + } - // TODO: Investigate failures on MacOS. All handles are released after GC. - // (It seems to happen more consistently on .NET 6.) - [ConditionalFact(nameof(IsNotMacOs))] - public void MultiplePoolInstances_TrimPeriodElapsed_AllAreTrimmed() + [Collection(nameof(NonParallelCollection))] + public class NonParallel { - RemoteExecutor.Invoke(RunTest).Dispose(); + public static readonly bool IsNotMacOs = !TestEnvironment.IsOSX; - static void RunTest() + // TODO: Investigate failures on MacOS. All handles are released after GC. + // (It seems to happen more consistently on .NET 6.) + [ConditionalFact(nameof(IsNotMacOs))] + public void MultiplePoolInstances_TrimPeriodElapsed_AllAreTrimmed() { - var trimSettings1 = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 6_000 }; - var pool1 = new UniformUnmanagedMemoryPool(128, 256, trimSettings1); - Thread.Sleep(8_000); // Let some callbacks fire already - var trimSettings2 = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 3_000 }; - var pool2 = new UniformUnmanagedMemoryPool(128, 256, trimSettings2); - - pool1.Return(pool1.Rent(64)); - pool2.Return(pool2.Rent(64)); - Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); - - // This exercises pool weak reference list trimming: - LeakPoolInstance(); - GC.Collect(); - GC.WaitForPendingFinalizers(); - Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); + RemoteExecutor.Invoke(RunTest).Dispose(); - Thread.Sleep(15_000); - Assert.True( - UnmanagedMemoryHandle.TotalOutstandingHandles <= 64, - $"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 64"); - GC.KeepAlive(pool1); - GC.KeepAlive(pool2); - } + static void RunTest() + { + var trimSettings1 = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 6_000 }; + var pool1 = new UniformUnmanagedMemoryPool(128, 256, trimSettings1); + Thread.Sleep(8_000); // Let some callbacks fire already + var trimSettings2 = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 3_000 }; + var pool2 = new UniformUnmanagedMemoryPool(128, 256, trimSettings2); + + pool1.Return(pool1.Rent(64)); + pool2.Return(pool2.Rent(64)); + Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); + + // This exercises pool weak reference list trimming: + LeakPoolInstance(); + GC.Collect(); + GC.WaitForPendingFinalizers(); + Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); + + Thread.Sleep(15_000); + Assert.True( + UnmanagedMemoryHandle.TotalOutstandingHandles <= 64, + $"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 64"); + GC.KeepAlive(pool1); + GC.KeepAlive(pool2); + } - [MethodImpl(MethodImplOptions.NoInlining)] - static void LeakPoolInstance() - { - var trimSettings = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 4_000 }; - _ = new UniformUnmanagedMemoryPool(128, 256, trimSettings); + [MethodImpl(MethodImplOptions.NoInlining)] + static void LeakPoolInstance() + { + var trimSettings = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 4_000 }; + _ = new UniformUnmanagedMemoryPool(128, 256, trimSettings); + } } }