diff --git a/nodes/machineGroupControl b/nodes/machineGroupControl index dc27a56..69bdf11 160000 --- a/nodes/machineGroupControl +++ b/nodes/machineGroupControl @@ -1 +1 @@ -Subproject commit dc27a569d9be6e1d0e1d2c7538c30a6bb794c945 +Subproject commit 69bdf11fc473e197f9c16db39f2749aa2a5928b4 diff --git a/test/inflow-overcapacity-stability.integration.test.js b/test/inflow-overcapacity-stability.integration.test.js index cd39f8b..1dcaf65 100644 --- a/test/inflow-overcapacity-stability.integration.test.js +++ b/test/inflow-overcapacity-stability.integration.test.js @@ -22,7 +22,11 @@ test('inflow ≫ capacity: pumps reach steady high-ctrl, no parking, no thrashin // wall time while still exercising the transient (1 s startup + 2 s // warmup). The race conditions we care about are the same — they're // about ORDER, not absolute duration. - const plant = buildPlant({ initialBasinLevel: 2.6 }); + // Start at maxLevel so PS percControl is immediately 100 % (the + // storm condition). Otherwise the basin needs to fill to maxLevel + // first, which on a 2× capacity inflow takes ~2 minutes — longer + // than this test's wall time. + const plant = buildPlant({ initialBasinLevel: 3.5 }); const { ps, mgc, pumps, advance, restore } = plant; try { // Pre-start pumps to operational so the test focuses on STEADY-STATE @@ -39,8 +43,14 @@ test('inflow ≫ capacity: pumps reach steady high-ctrl, no parking, no thrashin let abortLogObservations = 0; // Drive the loop: every tick, refresh pressures, set inflow, - // tick PS (which fires _applyMachineGroupLevelControl). + // tick PS (which fires _applyMachineGroupLevelControl). The + // settlePerTickMs wait is REAL wall-clock so movementManager's + // setInterval timers actually fire between handleInputs — without + // it the test runs too fast for moves to progress and pumps look + // permanently parked even when production behaviour is fine. const ticks = SIM_SECONDS; + const settlePerTickMs = 200; + const realSleep = (ms) => new Promise((r) => setTimeout(r, ms)); let lastCtrl = pumps.map(() => 0); let largeJumpTicks = 0; for (let i = 0; i < ticks; i++) { @@ -48,7 +58,7 @@ test('inflow ≫ capacity: pumps reach steady high-ctrl, no parking, no thrashin ps.setManualInflow(Q_IN, Date.now(), 'm3/s'); advance(TICK_MS); ps.tick(); - await new Promise((r) => setImmediate(r)); + await realSleep(settlePerTickMs); const states = pumps.map((p) => p.state.getCurrentState()); const ctrls = pumps.map((p) => Number(p.state.getCurrentPosition?.()) || 0);