diff --git a/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs b/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs index 12794fb..d0342b2 100644 --- a/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs +++ b/SVSim.UnitTests/BattleNode/Integration/HeadlessConductorTests.cs @@ -12,6 +12,7 @@ namespace SVSim.UnitTests.BattleNode.Integration; /// SVSim.UnitTests process. /// [TestFixture] +[NonParallelizable] public class HeadlessConductorTests { [Test] diff --git a/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs b/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs index d743385..3811415 100644 --- a/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs +++ b/SVSim.UnitTests/BattleNode/Integration/NodeNativeBattleHarness.cs @@ -39,14 +39,20 @@ internal sealed class NodeNativeBattleHarness : IDisposable public const long DefaultSeatAViewerId = 1001; public const long DefaultSeatBViewerId = 1002; - /// Spellboost cost-reducer card (looking ahead to M-HC-3). Present in cards.json. + /// Spellboost cost-reducer card (looking ahead to M-HC-3). Known id present in cards.json + /// (sourced from tk2 battle capture / existing engine tests); a cards.json regeneration that drops + /// it will produce a traceable failure here. public const long SpellboostCardId = 101314020; - /// A second spellboost card seen in the tk2 capture; present in cards.json. + /// A second spellboost card seen in the tk2 capture. Known id present in cards.json + /// (sourced from tk2 battle capture / existing engine tests); a cards.json regeneration that drops + /// it will produce a traceable failure here. public const long SpellboostCardIdAlt = 100314020; /// A plain vanilla follower the engine resolution path proved out - /// (HeadlessFixture.FollowerId). The bulk of the deterministic deck. + /// (HeadlessFixture.FollowerId). The bulk of the deterministic deck. Known id present in cards.json + /// (sourced from tk2 battle capture / existing engine tests); a cards.json regeneration that drops + /// it will produce a traceable failure here. public const long VanillaFollowerId = 100011010; public BattleSessionState State { get; } @@ -135,8 +141,10 @@ internal sealed class NodeNativeBattleHarness : IDisposable public void Dispose() { /* engine holds no unmanaged resources; nothing to release. */ } /// Minimal test-only exposing only the - /// + that the harness reads. All broker members are - /// no-ops — the harness drives the engine directly, never the session relay. + /// + that the harness reads. Broker members + /// (PushAsync, RunAsync, TerminateAsync) throw + /// — the harness drives the engine directly, so a frame must never reach the participant relay. + /// Silent no-ops would let a misrouted push pass undetected. internal sealed class StubParticipant : IBattleParticipant { public long ViewerId { get; } @@ -152,9 +160,12 @@ internal sealed class NodeNativeBattleHarness : IDisposable public event Func? FrameEmitted; #pragma warning restore CS0067 - public Task PushAsync(MsgEnvelope envelope, Stock stock, CancellationToken ct) => Task.CompletedTask; - public Task RunAsync(CancellationToken ct) => Task.CompletedTask; - public Task TerminateAsync(BattleFinishReason reason) => Task.CompletedTask; + public Task PushAsync(MsgEnvelope envelope, Stock stock, CancellationToken ct) => + throw new NotSupportedException("StubParticipant.PushAsync — harness drives the engine directly; a frame must not reach the participant relay."); + public Task RunAsync(CancellationToken ct) => + throw new NotSupportedException("StubParticipant.RunAsync should not be called in harness tests."); + public Task TerminateAsync(BattleFinishReason reason) => + throw new NotSupportedException("StubParticipant.TerminateAsync should not be called in harness tests."); public ValueTask DisposeAsync() => ValueTask.CompletedTask; } }