mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
23 changed files with 259 additions and 66 deletions
@ -0,0 +1,77 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using SixLabors.ImageSharp.Diagnostics; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests |
||||
|
{ |
||||
|
public static class MemoryAllocatorValidator |
||||
|
{ |
||||
|
private static readonly AsyncLocal<TestMemoryDiagnostics> LocalInstance = new(); |
||||
|
|
||||
|
public static bool MonitoringAllocations => LocalInstance.Value != null; |
||||
|
|
||||
|
static MemoryAllocatorValidator() |
||||
|
{ |
||||
|
MemoryDiagnostics.MemoryAllocated += MemoryDiagnostics_MemoryAllocated; |
||||
|
MemoryDiagnostics.MemoryReleased += MemoryDiagnostics_MemoryReleased; |
||||
|
} |
||||
|
|
||||
|
private static void MemoryDiagnostics_MemoryReleased() |
||||
|
{ |
||||
|
TestMemoryDiagnostics backing = LocalInstance.Value; |
||||
|
if (backing != null) |
||||
|
{ |
||||
|
backing.TotalRemainingAllocated--; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static void MemoryDiagnostics_MemoryAllocated() |
||||
|
{ |
||||
|
TestMemoryDiagnostics backing = LocalInstance.Value; |
||||
|
if (backing != null) |
||||
|
{ |
||||
|
backing.TotalAllocated++; |
||||
|
backing.TotalRemainingAllocated++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static TestMemoryDiagnostics MonitorAllocations() |
||||
|
{ |
||||
|
var diag = new TestMemoryDiagnostics(); |
||||
|
LocalInstance.Value = diag; |
||||
|
return diag; |
||||
|
} |
||||
|
|
||||
|
public static void StopMonitoringAllocations() => LocalInstance.Value = null; |
||||
|
|
||||
|
public static void ValidateAllocations(int expectedAllocationCount = 0) |
||||
|
=> LocalInstance.Value?.Validate(expectedAllocationCount); |
||||
|
|
||||
|
public class TestMemoryDiagnostics : IDisposable |
||||
|
{ |
||||
|
public int TotalAllocated { get; set; } |
||||
|
|
||||
|
public int TotalRemainingAllocated { get; set; } |
||||
|
|
||||
|
public void Validate(int expectedAllocationCount) |
||||
|
{ |
||||
|
var count = this.TotalRemainingAllocated; |
||||
|
var pass = expectedAllocationCount == count; |
||||
|
Assert.True(pass, $"Expected a {expectedAllocationCount} undisposed buffers but found {count}"); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
this.Validate(0); |
||||
|
if (LocalInstance.Value == this) |
||||
|
{ |
||||
|
StopMonitoringAllocations(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Diagnostics; |
||||
|
using System.Reflection; |
||||
|
using Xunit.Sdk; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests |
||||
|
{ |
||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] |
||||
|
public class ValidateDisposedMemoryAllocationsAttribute : BeforeAfterTestAttribute |
||||
|
{ |
||||
|
private readonly int expected = 0; |
||||
|
|
||||
|
public ValidateDisposedMemoryAllocationsAttribute() |
||||
|
: this(0) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public ValidateDisposedMemoryAllocationsAttribute(int expected) |
||||
|
=> this.expected = expected; |
||||
|
|
||||
|
public override void Before(MethodInfo methodUnderTest) |
||||
|
=> MemoryAllocatorValidator.MonitorAllocations(); |
||||
|
|
||||
|
public override void After(MethodInfo methodUnderTest) |
||||
|
{ |
||||
|
MemoryAllocatorValidator.ValidateAllocations(this.expected); |
||||
|
MemoryAllocatorValidator.StopMonitoringAllocations(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue