diff --git a/Robust.UnitTesting/Pool/ExternalTestContext.cs b/Robust.UnitTesting/Pool/ExternalTestContext.cs new file mode 100644 index 000000000..6fda45d1c --- /dev/null +++ b/Robust.UnitTesting/Pool/ExternalTestContext.cs @@ -0,0 +1,12 @@ +using System.IO; + +namespace Robust.UnitTesting.Pool; + +/// +/// Generic implementation of for usage outside of actual tests. +/// +public sealed class ExternalTestContext(string name, TextWriter writer) : ITestContextLike +{ + public string FullName => name; + public TextWriter Out => writer; +} diff --git a/Robust.UnitTesting/Pool/ITestContextLike.cs b/Robust.UnitTesting/Pool/ITestContextLike.cs new file mode 100644 index 000000000..d0485aa92 --- /dev/null +++ b/Robust.UnitTesting/Pool/ITestContextLike.cs @@ -0,0 +1,14 @@ +using System.IO; +using NUnit.Framework; + +namespace Robust.UnitTesting.Pool; + +/// +/// Something that looks like a , for passing to integration tests. +/// +public interface ITestContextLike +{ + string FullName { get; } + TextWriter Out { get; } +} + diff --git a/Robust.UnitTesting/Pool/NUnitTestContextWrap.cs b/Robust.UnitTesting/Pool/NUnitTestContextWrap.cs new file mode 100644 index 000000000..25a6be2fc --- /dev/null +++ b/Robust.UnitTesting/Pool/NUnitTestContextWrap.cs @@ -0,0 +1,13 @@ +using System.IO; +using NUnit.Framework; + +namespace Robust.UnitTesting.Pool; + +/// +/// Canonical implementation of for usage in actual NUnit tests. +/// +public sealed class NUnitTestContextWrap(TestContext context, TextWriter writer) : ITestContextLike +{ + public string FullName => context.Test.FullName; + public TextWriter Out => writer; +} diff --git a/Robust.UnitTesting/Pool/PoolManager.cs b/Robust.UnitTesting/Pool/PoolManager.cs index 572602b6c..df2ab4323 100644 --- a/Robust.UnitTesting/Pool/PoolManager.cs +++ b/Robust.UnitTesting/Pool/PoolManager.cs @@ -113,9 +113,9 @@ public class PoolManager : BasePoolManager where TPair : class, ITestPair TestPrototypes.Clear(); } - protected virtual string GetDefaultTestName(TestContext testContext) + protected virtual string GetDefaultTestName(ITestContextLike testContext) { - return testContext.Test.FullName.Replace("Robust.UnitTesting.", ""); + return testContext.FullName.Replace("Robust.UnitTesting.", ""); } public string DeathReport() @@ -140,16 +140,17 @@ public class PoolManager : BasePoolManager where TPair : class, ITestPair public virtual PairSettings DefaultSettings => new(); - public async Task GetPair(PairSettings? settings = null) + public async Task GetPair( + PairSettings? settings = null, + ITestContextLike? testContext = null) { if (!_initialized) throw new InvalidOperationException($"Pool manager has not been initialized"); settings ??= DefaultSettings; - // Trust issues with the AsyncLocal that backs this. - var testContext = TestContext.CurrentContext; - var testOut = TestContext.Out; + testContext ??= new NUnitTestContextWrap(TestContext.CurrentContext, TestContext.Out); + var testOut = testContext.Out; DieIfPoolFailure(); var currentTestName = settings.TestName ?? GetDefaultTestName(testContext); diff --git a/Robust.UnitTesting/Pool/TestPair.Recycle.cs b/Robust.UnitTesting/Pool/TestPair.Recycle.cs index 1fe2b0bcb..0d43685af 100644 --- a/Robust.UnitTesting/Pool/TestPair.Recycle.cs +++ b/Robust.UnitTesting/Pool/TestPair.Recycle.cs @@ -8,6 +8,7 @@ using Robust.Shared; using Robust.Shared.Exceptions; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Utility; namespace Robust.UnitTesting.Pool; @@ -79,6 +80,7 @@ public partial class TestPair var returnTime = Watch.Elapsed; await TestOut.WriteLineAsync($"{nameof(CleanReturnAsync)}: PoolManager took {returnTime.TotalMilliseconds} ms to put pair {Id} back into the pool"); + State = PairState.Ready; } public async ValueTask CleanReturnAsync() @@ -89,7 +91,7 @@ public partial class TestPair await TestOut.WriteLineAsync($"{nameof(CleanReturnAsync)}: Return of pair {Id} started"); State = PairState.CleanDisposed; await OnCleanDispose(); - State = PairState.Ready; + DebugTools.Assert(State is PairState.Dead or PairState.Ready); Manager.Return(this); ClearContext(); }