Skip to content

Commit

Permalink
added tests for out of order dispose scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
marklauter committed May 18, 2024
1 parent b3161c6 commit 18510df
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 42 deletions.
35 changes: 32 additions & 3 deletions src/Pool.Tests/Fakes/Echo.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,47 @@
namespace Pool.Tests.Fakes;
using System.Runtime.CompilerServices;

namespace Pool.Tests.Fakes;

internal sealed class Echo
: IEcho
, IDisposable
{
private bool disposed;

public bool IsReady { get; private set; }

public Task MakeReadyAsync(CancellationToken cancellationToken)
{
ThrowIfDisposed();

IsReady = true;
return Task.CompletedTask;
}

public string Shout(string message)
public string Shout(string message) => message;

public void Dispose()
{
if (disposed)
{
return;
}

disposed = true;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowIfDisposed()
{
return message;
#if NET7_0_OR_GREATER
#pragma warning disable IDE0022 // Use expression body for method
ObjectDisposedException.ThrowIf(disposed, nameof(Echo));
#pragma warning restore IDE0022 // Use expression body for method
#elif NET6_0_OR_GREATER
if (disposed)
{
throw new ObjectDisposedException(nameof(Echo));
}
#endif
}
}
17 changes: 4 additions & 13 deletions src/Pool.Tests/Fakes/EchoFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,15 @@ namespace Pool.Tests.Fakes;
internal sealed class EchoFactory
: IPoolItemFactory<IEcho>
, IReadyCheck<IEcho>

{
public IEcho CreateItem()
{
return new Echo();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP005:Return type should indicate that the value should be disposed", Justification = "items created by the factory are disposed by the pool or the factory")]
public IEcho CreateItem() => new Echo();

public async Task<bool> IsReadyAsync(
IEcho item,
CancellationToken cancellationToken)
{
return await Task.FromResult(item.IsReady);
}
CancellationToken cancellationToken) => await Task.FromResult(item.IsReady);

public async Task MakeReadyAsync(
IEcho item,
CancellationToken cancellationToken)
{
await item.MakeReadyAsync(cancellationToken);
}
CancellationToken cancellationToken) => await item.MakeReadyAsync(cancellationToken);
}
1 change: 1 addition & 0 deletions src/Pool.Tests/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@

[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "unit test naming")]
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "unit test naming")]
[assembly: SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", Justification = "not unnecessary")]
2 changes: 1 addition & 1 deletion src/Pool.Tests/Pool.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="xunit" Version="2.8.0" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.2.1" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
29 changes: 29 additions & 0 deletions src/Pool.Tests/PoolItemFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.Extensions.DependencyInjection;
using Pool.Tests.Fakes;

namespace Pool.Tests;

public sealed class PoolItemFactoryTests
{
[Fact]
[System.Diagnostics.CodeAnalysis.SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP017:Prefer using", Justification = "required for test")]
public async Task PoolItemFactory_Doesnt_Crash_On_Dispose()
{
using var services = new ServiceCollection()
.AddScoped<IEcho, Echo>()
.BuildServiceProvider();

var factory = new DefaultPoolItemFactory<IEcho>(services);
var pool = new Pool<IEcho>(factory, new DefaultReadyCheck<IEcho>(), new PoolOptions { MinSize = 5 });
var item = await pool.LeaseAsync(CancellationToken.None);
Assert.NotNull(item);

await pool.ReleaseAsync(item);

// pool disposes all the items on the queue
pool.Dispose();

// factory disposes the scope, which also disposes the items, so the items need to protect themselves with dispose pattern
factory.Dispose();
}
}
20 changes: 4 additions & 16 deletions src/Pool.Tests/PoolTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,16 @@ namespace Pool.Tests;
public sealed class PoolTests(IPool<IEcho> pool)
{
[Fact]
public void Pool_Is_Injected()
{
Assert.NotNull(pool);
}
public void Pool_Is_Injected() => Assert.NotNull(pool);

[Fact]
public void Allocated_Matches_Min()
{
Assert.Equal(1, pool.ItemsAllocated);
}
public void Allocated_Matches_Min() => Assert.Equal(1, pool.ItemsAllocated);

[Fact]
public void Available_Matches_Allocated()
{
Assert.Equal(pool.ItemsAllocated, pool.ItemsAvailable);
}
public void Available_Matches_Allocated() => Assert.Equal(pool.ItemsAllocated, pool.ItemsAvailable);

[Fact]
public void Backlog_Is_Empty()
{
Assert.Equal(0, pool.QueuedLeases);
}
public void Backlog_Is_Empty() => Assert.Equal(0, pool.QueuedLeases);

[Fact]
public async Task Lease_And_Release()
Expand Down
11 changes: 2 additions & 9 deletions src/Pool.Tests/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ public sealed class Startup
{
private readonly IConfiguration configuration;

public Startup()
{
configuration = new ConfigurationBuilder()
public Startup() => configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "PoolOptions:MinSize", "1" },
Expand All @@ -20,13 +18,8 @@ public Startup()
{ "PoolOptions:ReadyTimeout", "00:00:00.01" },
}!)
.Build();
}

public void ConfigureServices(IServiceCollection services)
{
_ = services
public void ConfigureServices(IServiceCollection services) => _ = services
.AddTransientPool<IEcho, EchoFactory>(configuration)
.AddReadyCheck<IEcho, EchoFactory>();

}
}

0 comments on commit 18510df

Please sign in to comment.