From ae9bb37751156432d0ee3ae2d976520ec79a717a Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Fri, 10 Apr 2026 19:15:42 -0400 Subject: [PATCH] qa-lab: parse compose ps json arrays --- extensions/qa-lab/src/docker-runtime.ts | 30 +++++++++++++++---- .../qa-lab/src/docker-up.runtime.test.ts | 2 +- .../matrix/matrix-harness.runtime.test.ts | 2 +- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/extensions/qa-lab/src/docker-runtime.ts b/extensions/qa-lab/src/docker-runtime.ts index bd3f01d8d4f..f8b24032a8b 100644 --- a/extensions/qa-lab/src/docker-runtime.ts +++ b/extensions/qa-lab/src/docker-runtime.ts @@ -174,6 +174,29 @@ function normalizeDockerServiceStatus(row?: { Health?: string; State?: string }) return "unknown"; } +function parseDockerComposePsRows(stdout: string) { + const trimmed = stdout.trim(); + if (!trimmed) { + return [] as Array<{ Health?: string; State?: string }>; + } + + try { + const parsed = JSON.parse(trimmed) as + | Array<{ Health?: string; State?: string }> + | { Health?: string; State?: string }; + if (Array.isArray(parsed)) { + return parsed; + } + return [parsed]; + } catch { + return trimmed + .split("\n") + .map((line) => line.trim()) + .filter(Boolean) + .map((line) => JSON.parse(line) as { Health?: string; State?: string }); + } +} + export async function waitForDockerServiceHealth( service: string, composeFile: string, @@ -194,12 +217,7 @@ export async function waitForDockerServiceHealth( ["compose", "-f", composeFile, "ps", "--format", "json", service], repoRoot, ); - const rows = stdout - .trim() - .split("\n") - .map((line) => line.trim()) - .filter(Boolean) - .map((line) => JSON.parse(line) as { Health?: string; State?: string }); + const rows = parseDockerComposePsRows(stdout); const row = rows[0]; lastStatus = normalizeDockerServiceStatus(row); if (lastStatus === "healthy" || lastStatus === "running") { diff --git a/extensions/qa-lab/src/docker-up.runtime.test.ts b/extensions/qa-lab/src/docker-up.runtime.test.ts index d34d8395b29..320a6e6f357 100644 --- a/extensions/qa-lab/src/docker-up.runtime.test.ts +++ b/extensions/qa-lab/src/docker-up.runtime.test.ts @@ -49,7 +49,7 @@ describe("runQaDockerUp", () => { async runCommand(command, args, cwd) { calls.push([command, ...args, `@${cwd}`].join(" ")); if (args.join(" ").includes("ps --format json openclaw-qa-gateway")) { - return { stdout: '{"Health":"healthy","State":"running"}\n', stderr: "" }; + return { stdout: '[{"Health":"healthy","State":"running"}]\n', stderr: "" }; } return { stdout: "", stderr: "" }; }, diff --git a/extensions/qa-lab/src/live-transports/matrix/matrix-harness.runtime.test.ts b/extensions/qa-lab/src/live-transports/matrix/matrix-harness.runtime.test.ts index b6fdfabd865..e1451fe2b39 100644 --- a/extensions/qa-lab/src/live-transports/matrix/matrix-harness.runtime.test.ts +++ b/extensions/qa-lab/src/live-transports/matrix/matrix-harness.runtime.test.ts @@ -62,7 +62,7 @@ describe("matrix harness runtime", () => { async runCommand(command, args, cwd) { calls.push([command, ...args, `@${cwd}`].join(" ")); if (args.join(" ").includes("ps --format json")) { - return { stdout: '{"State":"running"}\n', stderr: "" }; + return { stdout: '[{"State":"running"}]\n', stderr: "" }; } return { stdout: "", stderr: "" }; },