fix(test_framework): pass --max-speed to Java runner and drain stdout to prevent pipe stall

- 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 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 09:02:20 +02:00
parent c671e0b0e3
commit 8f454285aa
@@ -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)