fix(e2e): report gauntlet log write failures

This commit is contained in:
Vincent Koc
2026-06-04 04:31:12 +02:00
parent 658f90f845
commit 546aa5770a
3 changed files with 41 additions and 9 deletions

View File

@@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai
- Release/CI/E2E: restore package changelog extraction after the post-2026.6.1 version bump, keep hydrated pnpm modules under `node_modules` for ARM/Linux package lifecycle scripts, keep OpenAI live-cache prerequisites advisory while Anthropic prerequisites stay blocking, retry Windows Parallels background log appends on transient file-lock errors, bound candidate GitHub and cross-OS Discord fetches, harden ARM smoke/browser checks, show Docker build heartbeats, reset Crabbox pnpm hydrate state, and isolate Testbox/Docker/release journey artifacts.
- Release/CI/E2E: keep Crabbox hydrate pnpm stores on the persistent cache volume while still resetting volatile modules, reducing cold installs and runner memory churn.
- Release/CI/E2E: fail secret-provider proof startup immediately when the gateway exits by signal instead of waiting for the readiness timeout.
- Release/CI/E2E: report plugin gateway gauntlet command-log write failures as failed rows instead of crashing the harness from child-process callbacks.
## 2026.6.1

View File

@@ -559,24 +559,33 @@ export function runMeasuredCommandLive(params) {
]
.filter(Boolean)
.join("\n");
const diagnosticFailure = detectCommandDiagnosticFailure(stdout, finalStderr);
const logPath = writeCommandLog({
logDir: params.logDir,
label: params.label,
command: [params.command, ...params.args],
stdout,
stderr: finalStderr,
});
let logPath = null;
let logWriteError = null;
try {
logPath = writeCommandLog({
logDir: params.logDir,
label: params.label,
command: [params.command, ...params.args],
stdout,
stderr: finalStderr,
});
} catch (error) {
logWriteError = error instanceof Error ? error.message : String(error);
}
const outputDiagnosticFailure = detectCommandDiagnosticFailure(stdout, finalStderr);
const diagnosticFailure =
outputDiagnosticFailure ?? (logWriteError ? "command-log-write-failure" : null);
resolve({
label: params.label,
phase: params.phase,
pluginId: params.pluginId ?? null,
status: finalStatus,
status: logWriteError ? 1 : finalStatus,
diagnosticFailure,
signal: signal ?? null,
timedOut,
spawnError,
logPath,
...(logWriteError ? { logWriteError } : {}),
...parseTimedMetrics(finalStderr, wallMs, mode),
});
};

View File

@@ -563,6 +563,28 @@ setInterval(() => {}, 1000);
await expect(fs.readFile(row.logPath, "utf8")).resolves.toContain("live stderr");
});
it("returns a failed row when measured command log writing fails", async () => {
const logDir = path.join(repoRoot, "not-a-directory");
await fs.writeFile(logDir, "blocks log directory creation", "utf8");
const row = await runMeasuredCommandLive({
cwd: repoRoot,
env: process.env,
logDir,
command: process.execPath,
args: ["-e", "console.log('live stdout')"],
label: "live-log-failure",
phase: "probe",
timeoutMs: 1000,
timeMode: "none",
});
expect(row.status).toBe(1);
expect(row.diagnosticFailure).toBe("command-log-write-failure");
expect(row.logPath).toBeNull();
expect(row.logWriteError).toMatch(/EEXIST|ENOTDIR|not a directory/u);
});
it("cleans parent signal handlers after live measured commands settle", async () => {
const logDir = path.join(repoRoot, "logs");
const before = process.listenerCount("SIGTERM");