41 lines
2.4 KiB
C#
41 lines
2.4 KiB
C#
using NUnit.Framework;
|
|
|
|
namespace SVSim.BattleEngine.Tests
|
|
{
|
|
// Shared base for every network-emit test fixture (M13 EmitPathReadOracleTests, the
|
|
// construction-probe's OnEmit seam test, and any M14+ network fixture to come).
|
|
//
|
|
// WHY this exists — the global-state leak it closes:
|
|
// HeadlessEngineEnv.NewNetworkEmitBattle() mutates two PROCESS globals that no per-mgr
|
|
// teardown reverts on its own:
|
|
// - Wizard.ToolboxGame.RealTimeNetworkAgent: a non-null agent is injected so the engine's
|
|
// NetworkBattleSender ToolboxGame.RealTimeNetworkAgent.* calls resolve (the capture seam).
|
|
// - BattleManagerBase.IsForecast: the emit path needs this FALSE, so the harness flips it from
|
|
// the EnsureInitialized default of TRUE.
|
|
// HeadlessEngineEnv.EnsureInitialized() is _done-guarded — it sets IsForecast=true exactly once
|
|
// and then NO-OPs forever after. So once a network-emit fixture leaves IsForecast=false behind,
|
|
// nothing restores it: a later SOLO fixture (e.g. RandomDrawOracleTests) that assumes
|
|
// IsForecast=true would silently run with IsForecast=false (un-suppressed VFX) and a stale
|
|
// injected agent. Currently latent-benign, but a real hygiene gap M14's added network fixtures
|
|
// could turn flaky.
|
|
//
|
|
// Deriving from this base means NUnit runs the base-class [TearDown] after EVERY test in the
|
|
// derived fixture automatically, so the reset can never be forgotten when a new network-emit
|
|
// fixture is added — inherit this, don't re-roll a local teardown.
|
|
public abstract class NetworkEmitFixtureBase
|
|
{
|
|
[TearDown]
|
|
public void ResetNetworkEmitGlobals()
|
|
{
|
|
// Clear the injected agent (the solo oracles don't read it, but clearing it is defensive,
|
|
// mirroring RandomDrawOracleTests.ResetRandomDrawGate).
|
|
Wizard.ToolboxGame.SetRealTimeNetworkBattle(null);
|
|
// Restore the EnsureInitialized default. This is the load-bearing restore: every solo
|
|
// oracle and EnsureInitialized assume IsForecast=TRUE, and EnsureInitialized only sets it
|
|
// once (guarded), so without restoring it here a solo fixture running after a network-emit
|
|
// fixture would see IsForecast=false and un-suppressed VFX.
|
|
BattleManagerBase.IsForecast = true;
|
|
}
|
|
}
|
|
}
|