Files
SirRoboGarage/common_libs/test_framework/runner_process.nim
T
SirStone 57a1915b10 feat: add shared integration test framework for garages (#126)
Implements:
- BattleResult type and JSON-lines parser (#127)
- TR server lifecycle manager (#128)
- Bot compiler using nim c (#129)
- runBattle() orchestrator (#130)
- Example test in OscillatorBot_garage (#131)
- Framework usage guide (#132)
- TestBattleRunner.java for external server (#133)
- BattleRunner process lifecycle (#134)

Fix: runner_process.nim was redefining TimeoutError locally; now
uses std/net.TimeoutError consistently with server_manager.nim.
2026-08-30 12:03:35 +02:00

62 lines
2.0 KiB
Nim

## BattleRunner Java subprocess — capture stdout JSON-lines output.
import std/[osproc, os, strutils, streams, times, net]
const
DefaultRunnerJar = "/home/davide/Projects/tank-royale/runner/examples/lib/robocode-tankroyale-runner.jar"
ScriptDir = currentSourcePath().parentDir() / ".." / ".." / "tools" / "battle_runner"
proc runBattleRunner*(serverUrl: string, botDirs: seq[string], rounds: int,
timeout: int = 30000): 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 = @[
"-cp", classDir & ":" & jar,
"TestBattleRunner",
"--server-url", serverUrl,
"--rounds", $rounds,
"--bot-dirs", botDirs.join(",")
]
let p = startProcess("java", args = args,
options = {poUsePath, poStdErrToStdOut})
defer:
p.close()
let deadline = epochTime() + timeout.float / 1000.0
var stdout = ""
var line: string
while epochTime() < deadline:
if p.peekExitCode() != -1:
# Process finished; drain remaining output
while p.outputStream.readLine(line):
stdout.add(line & "\n")
break
if p.outputStream.readLine(line):
stdout.add(line & "\n")
if epochTime() >= deadline and p.peekExitCode() == -1:
p.terminate()
raise newException(TimeoutError,
"BattleRunner timed out after " & $timeout & "ms")
let code = p.waitForExit()
if code != 0:
raise newException(IOError,
"BattleRunner exited with code " & $code & "\nOutput:\n" & stdout)
result = stdout
when isMainModule:
echo "runner_process.nim — usage:"
echo " runBattleRunner(serverUrl, botDirs, rounds, timeout)"
echo ""
echo "Env vars:"
echo " TR_BATTLE_RUNNER JAR path (default: " & DefaultRunnerJar & ")"
echo " TR_BATTLE_RUNNER_DIR class dir (default: tools/battle_runner/)"
echo ""
echo "Cannot self-test without a running TR server. Start one first."