From 8f454285aaa11130d72a22ce94a6e9ab392eed1e Mon Sep 17 00:00:00 2001 From: Davide Cappellini Date: Wed, 16 Sep 2026 09:02:20 +0200 Subject: [PATCH] fix(test_framework): pass --max-speed to Java runner and drain stdout to prevent pipe stall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add maxSpeed param (default true) to runBattleRunner/runBattle - Drain stdout in poll loop — Java blocked on full pipe buffer causing timeout - TestBattleRunner.java already had --max-speed; .class was stale and needed recompile Co-Authored-By: Claude Sonnet 4.6 --- common_libs/test_framework/runner_process.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common_libs/test_framework/runner_process.nim b/common_libs/test_framework/runner_process.nim index 87b7c0c..a6dc24d 100644 --- a/common_libs/test_framework/runner_process.nim +++ b/common_libs/test_framework/runner_process.nim @@ -7,19 +7,20 @@ const ScriptDir = currentSourcePath().parentDir() / ".." / ".." / "tools" / "battle_runner" proc runBattleRunner*(serverUrl: string, botDirs: seq[string], rounds: int, - timeout: int = 30000): string = + timeout: int = 30000, maxSpeed: bool = true): string = ## Starts TestBattleRunner as a subprocess. Returns captured stdout on success. ## Raises IOError on non-zero exit or TimeoutError on timeout. let jar = getEnv("TR_BATTLE_RUNNER", DefaultRunnerJar) let classDir = getEnv("TR_BATTLE_RUNNER_DIR", ScriptDir) - let args = @[ + var args = @[ "-cp", classDir & ":" & jar, "TestBattleRunner", "--server-url", serverUrl, "--rounds", $rounds, "--bot-dirs", botDirs.join(",") ] + if maxSpeed: args.add("--max-speed") let p = startProcess("java", args = args, options = {poUsePath, poStdErrToStdOut}) @@ -29,13 +30,12 @@ proc runBattleRunner*(serverUrl: string, botDirs: seq[string], rounds: int, let deadline = epochTime() + timeout.float / 1000.0 var stdout = "" var line: string - # ponytail: poll instead of blocking readLine; 50ms sleep is fine for battle timescales while epochTime() < deadline: + # Drain stdout every iteration to prevent pipe-buffer stall + while p.outputStream.atEnd == false: + discard p.outputStream.readLine(line) + stdout.add(line & "\n") if p.peekExitCode() != -1: - # Process finished; drain remaining output without blocking - while p.outputStream.atEnd == false: - discard p.outputStream.readLine(line) - stdout.add(line & "\n") break sleep(50)