Skip to content

Commit c37508e

Browse files
committed
Add TestCancellationToken to v2 and v3 TestWithLoggingBase
Both versions now implement IAsyncLifetime with per-test cancellation. v2 uses a standalone CTS; v3 links to TestContext.Current.CancellationToken. QueueTestBase updated to override base DisposeAsync.
1 parent a6cfd75 commit c37508e

3 files changed

Lines changed: 65 additions & 5 deletions

File tree

‎src/Foundatio.TestHarness/Queue/QueueTestBase.cs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1815,8 +1815,10 @@ await queue.StartWorkingAsync(async item =>
18151815
}
18161816
}
18171817

1818-
public async ValueTask DisposeAsync()
1818+
public override async ValueTask DisposeAsync()
18191819
{
1820+
await base.DisposeAsync();
1821+
18201822
using var queue = GetQueue();
18211823
if (queue is null)
18221824
return;

‎src/Foundatio.Xunit.v3/Logging/TestWithLoggingBase.cs‎

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
using System.Threading;
2+
using System.Threading.Tasks;
23
using Microsoft.Extensions.Logging;
34
using Xunit;
45

56
namespace Foundatio.Xunit;
67

7-
public abstract class TestWithLoggingBase
8+
public abstract class TestWithLoggingBase : IAsyncLifetime
89
{
10+
private readonly CancellationTokenSource _testCancellationTokenSource =
11+
CancellationTokenSource.CreateLinkedTokenSource(TestContext.Current.CancellationToken);
912
protected readonly ILogger _logger;
1013

1114
protected TestWithLoggingBase(ITestOutputHelper output)
@@ -17,7 +20,29 @@ protected TestWithLoggingBase(ITestOutputHelper output)
1720
protected TestLogger Log { get; }
1821

1922
/// <summary>
20-
/// Gets the cancellation token for the current test. This token is automatically cancelled when the test times out.
23+
/// Gets a cancellation token that is cancelled when the current test completes or
24+
/// when the test run is aborted/timed out. Pass this token to
25+
/// <see cref="Foundatio.Messaging.IMessageSubscriber.SubscribeAsync{T}"/>
26+
/// and other async operations to ensure automatic cleanup between tests.
2127
/// </summary>
22-
protected static CancellationToken TestCancellationToken => TestContext.Current.CancellationToken;
28+
/// <remarks>
29+
/// <para>
30+
/// This token is linked to <c>TestContext.Current.CancellationToken</c>, so it triggers on
31+
/// both per-test disposal (via <see cref="DisposeAsync"/>) and run-level abort or timeout.
32+
/// xUnit creates a new class instance per <c>[Fact]</c>, so each test gets a fresh linked token.
33+
/// </para>
34+
/// </remarks>
35+
protected CancellationToken TestCancellationToken => _testCancellationTokenSource.Token;
36+
37+
public virtual ValueTask InitializeAsync()
38+
{
39+
return ValueTask.CompletedTask;
40+
}
41+
42+
public virtual ValueTask DisposeAsync()
43+
{
44+
_testCancellationTokenSource.Cancel();
45+
_testCancellationTokenSource.Dispose();
46+
return ValueTask.CompletedTask;
47+
}
2348
}

‎src/Foundatio.Xunit/Logging/TestWithLoggingBase.cs‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
13
using Microsoft.Extensions.Logging;
4+
using Xunit;
25
using Xunit.Abstractions;
36

47
namespace Foundatio.Xunit;
58

6-
public abstract class TestWithLoggingBase
9+
public abstract class TestWithLoggingBase : IAsyncLifetime
710
{
11+
private readonly CancellationTokenSource _testCancellationTokenSource = new();
812
protected readonly ILogger _logger;
913

1014
protected TestWithLoggingBase(ITestOutputHelper output)
@@ -14,4 +18,33 @@ protected TestWithLoggingBase(ITestOutputHelper output)
1418
}
1519

1620
protected TestLogger Log { get; }
21+
22+
/// <summary>
23+
/// Gets a cancellation token that is cancelled when the current test completes.
24+
/// Pass this token to <see cref="Foundatio.Messaging.IMessageSubscriber.SubscribeAsync{T}"/>
25+
/// and other async operations to ensure automatic cleanup between tests.
26+
/// </summary>
27+
/// <remarks>
28+
/// <para>
29+
/// This token is cancelled in <see cref="DisposeAsync"/> after each test.
30+
/// xUnit creates a new class instance per <c>[Fact]</c>, so each test gets a fresh token.
31+
/// </para>
32+
/// <para>
33+
/// In Foundatio.Xunit.v3, this property uses a linked token source that also
34+
/// respects <c>TestContext.Current.CancellationToken</c> for run-level abort and timeout.
35+
/// </para>
36+
/// </remarks>
37+
protected CancellationToken TestCancellationToken => _testCancellationTokenSource.Token;
38+
39+
public virtual Task InitializeAsync()
40+
{
41+
return Task.CompletedTask;
42+
}
43+
44+
public virtual Task DisposeAsync()
45+
{
46+
_testCancellationTokenSource.Cancel();
47+
_testCancellationTokenSource.Dispose();
48+
return Task.CompletedTask;
49+
}
1750
}

0 commit comments

Comments
 (0)