GFramework/GFramework.Core.Tests/extensions/ArrayPoolExtensionsTests.cs
GeWuYou eb763a9bc4 feat(pool): 重构对象池系统增加统计和容量控制功能
- 引入 PoolInfo 类来管理对象池的核心数据结构和统计信息
- 添加对象池容量限制功能,超过容量时自动销毁多余对象
- 实现对象池统计功能,跟踪创建、获取、释放、销毁等操作计数
- 新增 GetPoolSize 和 GetActiveCount 方法获取池状态信息
- 添加 SetMaxCapacity 方法设置池的最大容量限制
- 实现 Prewarm 功能用于预创建对象提高性能
- 提供 GetStatistics 方法获取详细的池统计信息
- 添加 IsExternalInit 支持旧版 .NET 框架的 init-only 属性
- 扩展 ArrayPool 添加便捷的扩展方法和自动释放功能
- 新增 StringBuilderPool 提供高性能的字符串构建器复用
- 完善单元测试覆盖新增的所有功能特性
2026-02-25 20:40:02 +08:00

195 lines
4.5 KiB
C#

using System.Buffers;
using GFramework.Core.extensions;
using NUnit.Framework;
namespace GFramework.Core.Tests.extensions;
/// <summary>
/// 测试 ArrayPoolExtensions 的功能
/// </summary>
[TestFixture]
public class ArrayPoolExtensionsTests
{
private ArrayPool<int> _pool = null!;
[SetUp]
public void SetUp()
{
_pool = ArrayPool<int>.Shared;
}
[Test]
public void RentArray_Should_Return_Array()
{
// Act
var array = _pool.RentArray(100);
// Assert
Assert.That(array, Is.Not.Null);
Assert.That(array.Length, Is.GreaterThanOrEqualTo(100));
// Cleanup
_pool.ReturnArray(array);
}
[Test]
public void ReturnArray_Should_Not_Throw()
{
// Arrange
var array = _pool.RentArray(100);
// Act & Assert
Assert.DoesNotThrow(() => _pool.ReturnArray(array));
}
[Test]
public void ReturnArray_With_Clear_Should_Clear_Array()
{
// Arrange
var array = _pool.RentArray(10);
array[0] = 42;
array[5] = 99;
// Act
_pool.ReturnArray(array, clearArray: true);
// Assert
Assert.That(array[0], Is.EqualTo(0));
Assert.That(array[5], Is.EqualTo(0));
}
[Test]
public void GetScoped_Should_Return_Disposable_Wrapper()
{
// Act
using var scoped = _pool.GetScoped(100);
// Assert
Assert.That(scoped.Array, Is.Not.Null);
Assert.That(scoped.Array.Length, Is.GreaterThanOrEqualTo(100));
Assert.That(scoped.Length, Is.GreaterThanOrEqualTo(100));
}
[Test]
public void GetScoped_Should_Auto_Return_On_Dispose()
{
// Arrange & Act
int[] array;
using (var scoped = _pool.GetScoped(100))
{
array = scoped.Array;
array[0] = 42;
}
// Assert - 如果没有异常就说明正常归还了
Assert.Pass();
}
[Test]
public void ScopedArray_AsSpan_Should_Return_Span()
{
// Arrange
using var scoped = _pool.GetScoped(100);
// Act
var span = scoped.AsSpan();
// Assert
Assert.That(span.Length, Is.EqualTo(scoped.Length));
}
[Test]
public void ScopedArray_AsSpan_With_Range_Should_Return_Slice()
{
// Arrange
using var scoped = _pool.GetScoped(100);
// Act
var span = scoped.AsSpan(10, 20);
// Assert
Assert.That(span.Length, Is.EqualTo(20));
}
[Test]
public void GetScoped_With_ClearOnReturn_Should_Clear_Array()
{
// Arrange
int[] array;
using (var scoped = _pool.GetScoped(10, clearOnReturn: true))
{
array = scoped.Array;
array[0] = 42;
array[5] = 99;
}
// Assert
Assert.That(array[0], Is.EqualTo(0));
Assert.That(array[5], Is.EqualTo(0));
}
[Test]
public void Multiple_Scoped_Arrays_Should_Work_Independently()
{
// Act
using var scoped1 = _pool.GetScoped(50);
using var scoped2 = _pool.GetScoped(100);
scoped1.Array[0] = 1;
scoped2.Array[0] = 2;
// Assert
Assert.That(scoped1.Array[0], Is.EqualTo(1));
Assert.That(scoped2.Array[0], Is.EqualTo(2));
Assert.That(scoped1.Array, Is.Not.SameAs(scoped2.Array));
}
[Test]
public void RentArray_Should_Be_Reusable()
{
// Arrange
var array1 = _pool.RentArray(100);
array1[0] = 42;
_pool.ReturnArray(array1, clearArray: true);
// Act
var array2 = _pool.RentArray(100);
// Assert
// 可能是同一个数组(已清空),也可能是不同的数组
Assert.That(array2, Is.Not.Null);
Assert.That(array2.Length, Is.GreaterThanOrEqualTo(100));
// Cleanup
_pool.ReturnArray(array2);
}
[Test]
public void ScopedArray_Should_Work_With_Using_Declaration()
{
// Act
using var scoped = _pool.GetScoped(50);
scoped.Array[0] = 123;
// Assert
Assert.That(scoped.Array[0], Is.EqualTo(123));
}
[Test]
public void AsSpan_Should_Allow_Span_Operations()
{
// Arrange
using var scoped = _pool.GetScoped(10);
var span = scoped.AsSpan();
// Act
span.Fill(42);
// Assert
for (var i = 0; i < span.Length; i++)
{
Assert.That(span[i], Is.EqualTo(42));
}
}
}