From 31126f8325db4c7b3bb3061eb0c839a9b62d97d5 Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Fri, 12 Jun 2026 14:17:05 -0400 Subject: [PATCH 1/7] test(e2e): migrate test-gateway-health-honest.sh to vitest Reserve Phase 4 E2E migration work for test-gateway-health-honest.sh. Refs #5098 From 852e81e9e8d4cfa82fd2f532c54f6f6d55b65a06 Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Fri, 12 Jun 2026 15:26:47 -0400 Subject: [PATCH 2/7] test(e2e): migrate test-gateway-health-honest.sh to vitest --- .github/workflows/e2e-vitest-scenarios.yaml | 53 ++++++ .../live/gateway-health-honest.test.ts | 163 ++++++++++++++++++ .../e2e-scenarios-workflow.test.ts | 18 +- tools/e2e-scenarios/free-standing-jobs.env | 6 +- tools/e2e-scenarios/workflow-boundary.mts | 1 + 5 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 test/e2e-scenario/live/gateway-health-honest.test.ts diff --git a/.github/workflows/e2e-vitest-scenarios.yaml b/.github/workflows/e2e-vitest-scenarios.yaml index f199050c83d..4a1b6c1bf20 100644 --- a/.github/workflows/e2e-vitest-scenarios.yaml +++ b/.github/workflows/e2e-vitest-scenarios.yaml @@ -1692,6 +1692,58 @@ jobs: docker logout docker.io || true rm -rf "${DOCKER_CONFIG}" + gateway-health-honest-vitest: + needs: generate-matrix + if: ${{ (inputs.jobs == '' && inputs.scenarios == '') || contains(format(',{0},', inputs.jobs), ',gateway-health-honest-vitest,') || contains(format(',{0},', inputs.scenarios), ',gateway-health-honest,') }} + runs-on: ubuntu-latest + timeout-minutes: 20 + env: + E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/vitest/gateway-health-honest + NEMOCLAW_CLI_BIN: ${{ github.workspace }}/bin/nemoclaw.js + NEMOCLAW_RUN_E2E_SCENARIOS: "1" + NEMOCLAW_NON_INTERACTIVE: "1" + NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1" + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Set up Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.0.0 + with: + node-version: 22 + cache: npm + + - name: Install root dependencies + run: npm ci --ignore-scripts + + - name: Build CLI + run: npm run build:cli + + - name: Install OpenShell CLI + run: bash scripts/install-openshell.sh + + - name: Run gateway health honesty live test + # Migrated from test/e2e/test-gateway-health-honest.sh. It invokes + # real startGateway() with a sabotaged Docker-driver gateway binary + # and asserts the crashed process is never reported healthy. + run: | + set -euo pipefail + export PATH="$HOME/.local/bin:$HOME/.npm-global/bin:$PATH" + npx vitest run --project e2e-scenarios-live \ + test/e2e-scenario/live/gateway-health-honest.test.ts \ + --silent=false --reporter=default + + - name: Upload gateway health honesty artifacts + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: e2e-vitest-scenarios-gateway-health-honest + path: e2e-artifacts/vitest/gateway-health-honest/ + include-hidden-files: false + if-no-files-found: ignore + retention-days: 14 + # Focused coverage slice for the #2603/#3145 OpenClaw websocket # protocol/history contract. The retained legacy bash lane remains the # source for full closeout until a later PR proves replacement and deletes it. @@ -1890,6 +1942,7 @@ jobs: double-onboard-vitest, model-router-provider-routed-inference-vitest, sandbox-survival-vitest, + gateway-health-honest-vitest, openclaw-tui-chat-correlation-vitest, gateway-guard-recovery, issue-4434-tui-unreachable-inference-vitest, diff --git a/test/e2e-scenario/live/gateway-health-honest.test.ts b/test/e2e-scenario/live/gateway-health-honest.test.ts new file mode 100644 index 00000000000..15db824db09 --- /dev/null +++ b/test/e2e-scenario/live/gateway-health-honest.test.ts @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Live Vitest replacement for test/e2e/test-gateway-health-honest.sh. + * + * Preserves the legacy #3111 contract by invoking the real compiled + * `startGateway()` path with a sabotaged OpenShell Docker-driver gateway + * binary that exits immediately with GLIBC-style stderr. The assertion is + * intentionally about user-visible behavior: onboarding must not print the + * misleading "Docker-driver gateway is healthy" message when the child died + * before serving a TCP probe, and it must surface a gateway-start failure. + */ + +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; + +import { buildAvailabilityProbeEnv } from "../fixtures/availability-env.ts"; +import { resultText } from "../fixtures/clients/index.ts"; +import { expect, test } from "../fixtures/e2e-test.ts"; +import { shouldRunLiveE2EScenarios } from "../fixtures/live-project-gate.ts"; + +const REPO_ROOT = path.resolve(import.meta.dirname, "../../.."); +const GATEWAY_NAME = "nemoclaw-18080"; + +function gatewayStateDir(): string { + return path.join(os.homedir(), ".local", "state", "nemoclaw", "openshell-docker-gateway-18080"); +} + +function writeExecutable(file: string, content: string): void { + fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 }); + fs.writeFileSync(file, content, { encoding: "utf8", mode: 0o755 }); + fs.chmodSync(file, 0o755); +} + +test.skipIf(!shouldRunLiveE2EScenarios())( + "onboard surfaces crashed Docker-driver gateway instead of reporting healthy (#3111)", + async ({ artifacts, cleanup, host }) => { + const stateDir = gatewayStateDir(); + const sabotageBin = artifacts.pathFor("bin/openshell-gateway-sabotage"); + const gatewayLog = path.join(stateDir, "openshell-gateway.log"); + const gatewayPidFile = path.join(stateDir, "openshell-gateway.pid"); + + await artifacts.writeJson("scenario.json", { + id: "gateway-health-honest", + runner: "vitest", + boundary: "real-startGateway-openshell-docker-driver-process", + legacySource: "test/e2e/test-gateway-health-honest.sh", + contracts: [ + "startGateway() invokes a real OpenShell Docker-driver gateway child process", + "a crashed gateway binary does not log 'Docker-driver gateway is healthy'", + "startGateway() exits non-zero and surfaces a gateway-start failure", + "the gateway log proves the sabotaged GLIBC-failure binary was executed", + ], + }); + + writeExecutable( + sabotageBin, + [ + "#!/usr/bin/env bash", + 'printf \'%s\\n\' "$(basename \\"$0\\"): /lib/x86_64-linux-gnu/libc.so.6: version \\`GLIBC_2.38\' not found (required by $(basename \\"$0\\"))" >&2', + 'printf \'%s\\n\' "$(basename \\"$0\\"): /lib/x86_64-linux-gnu/libc.so.6: version \\`GLIBC_2.39\' not found (required by $(basename \\"$0\\"))" >&2', + "exit 127", + "", + ].join("\n"), + ); + + fs.mkdirSync(stateDir, { recursive: true, mode: 0o700 }); + fs.rmSync(gatewayPidFile, { force: true }); + fs.rmSync(gatewayLog, { force: true }); + fs.rmSync(path.join(stateDir, "runtime-marker.json"), { force: true }); + fs.rmSync(path.join(stateDir, "openshell-gateway.toml"), { force: true }); + await host.command( + "sh", + [ + "-lc", + `command -v openshell >/dev/null 2>&1 && openshell gateway remove ${GATEWAY_NAME} || true`, + ], + { + artifactName: "pre-cleanup-openshell-gateway-remove-gateway-health-honest", + env: buildAvailabilityProbeEnv(), + timeoutMs: 30_000, + }, + ); + + cleanup.add("remove sabotaged OpenShell gateway metadata", async () => { + await host.command( + "sh", + [ + "-lc", + `command -v openshell >/dev/null 2>&1 && openshell gateway remove ${GATEWAY_NAME} || true`, + ], + { + artifactName: "cleanup-openshell-gateway-remove-gateway-health-honest", + env: buildAvailabilityProbeEnv(), + timeoutMs: 30_000, + }, + ); + }); + cleanup.add("remove sabotaged gateway runtime files", () => { + const pid = fs.existsSync(gatewayPidFile) + ? Number.parseInt(fs.readFileSync(gatewayPidFile, "utf8"), 10) + : Number.NaN; + if (Number.isInteger(pid) && pid > 0) { + try { + process.kill(pid, "SIGTERM"); + } catch { + // Best-effort: the expected child has already exited. + } + } + fs.rmSync(gatewayPidFile, { force: true }); + fs.rmSync(path.join(stateDir, "runtime-marker.json"), { force: true }); + fs.rmSync(path.join(stateDir, "openshell-gateway.toml"), { force: true }); + fs.rmSync(sabotageBin, { force: true }); + }); + + const result = await host.command( + "node", + [ + "-e", + [ + 'const { startGateway } = require("./dist/lib/onboard");', + "startGateway(null)", + " .then(() => { console.log('__onboard_startGateway_returned_successfully__'); process.exit(0); })", + " .catch((error) => { console.error('__onboard_startGateway_threw__'); console.error(error && error.stack ? error.stack : error); process.exit(3); });", + ].join("\n"), + ], + { + artifactName: "start-gateway-with-sabotaged-binary", + cwd: REPO_ROOT, + env: { + ...buildAvailabilityProbeEnv(), + NEMOCLAW_GATEWAY_PORT: "18080", + NEMOCLAW_HEALTH_POLL_COUNT: "3", + NEMOCLAW_HEALTH_POLL_INTERVAL: "1", + NEMOCLAW_OPENSHELL_GATEWAY_BIN: sabotageBin, + NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH: "0", + NEMOCLAW_OPENSHELL_GATEWAY_STATE_DIR: stateDir, + }, + timeoutMs: 60_000, + }, + ); + + const output = resultText(result); + await artifacts.writeText( + "gateway-log-tail.txt", + fs.existsSync(gatewayLog) ? fs.readFileSync(gatewayLog, "utf8") : "", + ); + + expect( + fs.existsSync(gatewayLog) ? fs.readFileSync(gatewayLog, "utf8") : "", + "sabotage binary must have been executed before health assertions are trusted", + ).toMatch(/GLIBC_2\.3(?:8|9)|openshell-gateway-sabotage/); + + expect(output).not.toContain("Docker-driver gateway is healthy"); + expect(result.exitCode, output).not.toBe(0); + expect(output).not.toContain("__onboard_startGateway_returned_successfully__"); + expect(output).toMatch( + /Docker-driver gateway failed to start|Gateway process exited with code 127|__onboard_startGateway_threw__/i, + ); + }, +); diff --git a/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts b/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts index 354712ecde2..82fcc940d6d 100644 --- a/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts +++ b/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts @@ -255,6 +255,22 @@ describe("e2e-vitest-scenarios workflow boundary", () => { selectedFreeStandingJobs: ["model-router-provider-routed-inference-vitest"], registryScenarios: [], }); + expect( + evaluateE2eVitestWorkflowDispatchSelectors({ scenarios: "gateway-health-honest" }), + ).toMatchObject({ + valid: true, + liveScenariosRuns: false, + selectedFreeStandingJobs: ["gateway-health-honest-vitest"], + registryScenarios: [], + }); + expect( + evaluateE2eVitestWorkflowDispatchSelectors({ jobs: "gateway-health-honest-vitest" }), + ).toMatchObject({ + valid: true, + liveScenariosRuns: false, + selectedFreeStandingJobs: ["gateway-health-honest-vitest"], + registryScenarios: [], + }); }); it("keeps the free-standing inventory internally consistent and data-only", () => { @@ -376,7 +392,7 @@ describe("e2e-vitest-scenarios workflow boundary", () => { registryScenarios: [], }); } - }); + }, 15_000); it("flags direct dispatch-input interpolation and unsafe artifact upload", () => { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "e2e-vitest-workflow-")); diff --git a/tools/e2e-scenarios/free-standing-jobs.env b/tools/e2e-scenarios/free-standing-jobs.env index 68ce23e36df..f44e67fda9f 100644 --- a/tools/e2e-scenarios/free-standing-jobs.env +++ b/tools/e2e-scenarios/free-standing-jobs.env @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -allowed_jobs=openshell-version-pin-vitest,onboard-negative-paths-vitest,skill-agent-vitest,inference-routing-vitest,credential-migration-vitest,runtime-overrides-vitest,hermes-e2e-vitest,hermes-root-entrypoint-smoke-vitest,network-policy-vitest,shields-config-vitest,rebuild-openclaw-vitest,sandbox-rebuild-vitest,token-rotation-vitest,launchable-smoke-vitest,openclaw-tui-chat-correlation-vitest,gateway-guard-recovery,double-onboard-vitest,issue-4434-tui-unreachable-inference-vitest,model-router-provider-routed-inference-vitest,credential-sanitization-vitest,sandbox-survival-vitest -free_standing_scenarios_csv=openshell-version-pin,onboard-negative-paths,skill-agent,inference-routing,runtime-overrides,hermes-e2e,hermes-root-entrypoint-smoke,network-policy,shields-config,rebuild-openclaw,sandbox-rebuild,token-rotation,openclaw-tui-chat-correlation,double-onboard,issue-4434-tui-unreachable-inference,model-router-provider-routed-inference,credential-sanitization,sandbox-survival -free_standing_scenario_jobs_csv=openshell-version-pin:openshell-version-pin-vitest,onboard-negative-paths:onboard-negative-paths-vitest,skill-agent:skill-agent-vitest,inference-routing:inference-routing-vitest,runtime-overrides:runtime-overrides-vitest,hermes-e2e:hermes-e2e-vitest,hermes-root-entrypoint-smoke:hermes-root-entrypoint-smoke-vitest,network-policy:network-policy-vitest,shields-config:shields-config-vitest,rebuild-openclaw:rebuild-openclaw-vitest,sandbox-rebuild:sandbox-rebuild-vitest,token-rotation:token-rotation-vitest,openclaw-tui-chat-correlation:openclaw-tui-chat-correlation-vitest,double-onboard:double-onboard-vitest,issue-4434-tui-unreachable-inference:issue-4434-tui-unreachable-inference-vitest,model-router-provider-routed-inference:model-router-provider-routed-inference-vitest,credential-sanitization:credential-sanitization-vitest,sandbox-survival:sandbox-survival-vitest +allowed_jobs=openshell-version-pin-vitest,onboard-negative-paths-vitest,skill-agent-vitest,inference-routing-vitest,credential-migration-vitest,runtime-overrides-vitest,hermes-e2e-vitest,hermes-root-entrypoint-smoke-vitest,network-policy-vitest,shields-config-vitest,rebuild-openclaw-vitest,sandbox-rebuild-vitest,token-rotation-vitest,launchable-smoke-vitest,openclaw-tui-chat-correlation-vitest,gateway-guard-recovery,double-onboard-vitest,issue-4434-tui-unreachable-inference-vitest,model-router-provider-routed-inference-vitest,credential-sanitization-vitest,sandbox-survival-vitest,gateway-health-honest-vitest +free_standing_scenarios_csv=openshell-version-pin,onboard-negative-paths,skill-agent,inference-routing,runtime-overrides,hermes-e2e,hermes-root-entrypoint-smoke,network-policy,shields-config,rebuild-openclaw,sandbox-rebuild,token-rotation,openclaw-tui-chat-correlation,double-onboard,issue-4434-tui-unreachable-inference,model-router-provider-routed-inference,credential-sanitization,sandbox-survival,gateway-health-honest +free_standing_scenario_jobs_csv=openshell-version-pin:openshell-version-pin-vitest,onboard-negative-paths:onboard-negative-paths-vitest,skill-agent:skill-agent-vitest,inference-routing:inference-routing-vitest,runtime-overrides:runtime-overrides-vitest,hermes-e2e:hermes-e2e-vitest,hermes-root-entrypoint-smoke:hermes-root-entrypoint-smoke-vitest,network-policy:network-policy-vitest,shields-config:shields-config-vitest,rebuild-openclaw:rebuild-openclaw-vitest,sandbox-rebuild:sandbox-rebuild-vitest,token-rotation:token-rotation-vitest,openclaw-tui-chat-correlation:openclaw-tui-chat-correlation-vitest,double-onboard:double-onboard-vitest,issue-4434-tui-unreachable-inference:issue-4434-tui-unreachable-inference-vitest,model-router-provider-routed-inference:model-router-provider-routed-inference-vitest,credential-sanitization:credential-sanitization-vitest,sandbox-survival:sandbox-survival-vitest,gateway-health-honest:gateway-health-honest-vitest diff --git a/tools/e2e-scenarios/workflow-boundary.mts b/tools/e2e-scenarios/workflow-boundary.mts index 9e55fc3ff31..1b772e143a8 100644 --- a/tools/e2e-scenarios/workflow-boundary.mts +++ b/tools/e2e-scenarios/workflow-boundary.mts @@ -2126,6 +2126,7 @@ export function validateE2eVitestScenariosWorkflowBoundary( "openclaw-tui-chat-correlation", ); validateFreeStandingJobSelector(errors, jobs, "gateway-guard-recovery"); + validateFreeStandingJobSelector(errors, jobs, "gateway-health-honest-vitest", "gateway-health-honest"); validateFreeStandingJobSelector( errors, jobs, From dc483f1955b9790c4f63eca1a6708e77c973a8e8 Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Fri, 12 Jun 2026 17:37:45 -0400 Subject: [PATCH 3/7] test(e2e): assert gateway crash leaves no live pid --- .../live/gateway-health-honest.test.ts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/e2e-scenario/live/gateway-health-honest.test.ts b/test/e2e-scenario/live/gateway-health-honest.test.ts index 15db824db09..c97e6c64eeb 100644 --- a/test/e2e-scenario/live/gateway-health-honest.test.ts +++ b/test/e2e-scenario/live/gateway-health-honest.test.ts @@ -159,5 +159,37 @@ test.skipIf(!shouldRunLiveE2EScenarios())( expect(output).toMatch( /Docker-driver gateway failed to start|Gateway process exited with code 127|__onboard_startGateway_threw__/i, ); + + const lingeringGateway = await host.command( + "bash", + [ + "-lc", + String.raw` +set -euo pipefail +pid_file="$1" +if [ ! -f "$pid_file" ]; then + exit 0 +fi +pid="$(tr -d '[:space:]' <"$pid_file" 2>/dev/null || true)" +if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then + exit 0 +fi +state="$(ps -p "$pid" -o state= 2>/dev/null | tr -d '[:space:]')" +if [ -n "$state" ] && [ "$state" != "Z" ]; then + printf 'live non-zombie gateway pid remains: pid=%s state=%s\n' "$pid" "$state" >&2 + exit 1 +fi +exit 0 +`, + "gateway-lingering-process-check", + gatewayPidFile, + ], + { + artifactName: "gateway-lingering-process-check", + env: buildAvailabilityProbeEnv(), + timeoutMs: 30_000, + }, + ); + expect(lingeringGateway.exitCode, resultText(lingeringGateway)).toBe(0); }, ); From fcd4b67c59b7e8be91e44027522197cd8075e4e3 Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Fri, 12 Jun 2026 17:44:52 -0400 Subject: [PATCH 4/7] test(e2e): harden gateway pid check --- test/e2e-scenario/live/gateway-health-honest.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/e2e-scenario/live/gateway-health-honest.test.ts b/test/e2e-scenario/live/gateway-health-honest.test.ts index c97e6c64eeb..4d6ff2c903a 100644 --- a/test/e2e-scenario/live/gateway-health-honest.test.ts +++ b/test/e2e-scenario/live/gateway-health-honest.test.ts @@ -174,12 +174,12 @@ pid="$(tr -d '[:space:]' <"$pid_file" 2>/dev/null || true)" if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then exit 0 fi -state="$(ps -p "$pid" -o state= 2>/dev/null | tr -d '[:space:]')" -if [ -n "$state" ] && [ "$state" != "Z" ]; then - printf 'live non-zombie gateway pid remains: pid=%s state=%s\n' "$pid" "$state" >&2 - exit 1 +state="$(ps -p "$pid" -o state= 2>/dev/null | tr -d '[:space:]' || true)" +if [ -z "$state" ] || [[ "$state" == Z* ]]; then + exit 0 fi -exit 0 +printf 'live non-zombie gateway pid remains: pid=%s state=%s\n' "$pid" "$state" >&2 +exit 1 `, "gateway-lingering-process-check", gatewayPidFile, From 2780f0710ad3a163009f2995cb89dc770bc50a7f Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Fri, 12 Jun 2026 17:54:54 -0400 Subject: [PATCH 5/7] test(e2e): tolerate absent gateway pid state --- .../live/gateway-health-honest.test.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/e2e-scenario/live/gateway-health-honest.test.ts b/test/e2e-scenario/live/gateway-health-honest.test.ts index 4d6ff2c903a..38ecc5bc0ca 100644 --- a/test/e2e-scenario/live/gateway-health-honest.test.ts +++ b/test/e2e-scenario/live/gateway-health-honest.test.ts @@ -52,6 +52,7 @@ test.skipIf(!shouldRunLiveE2EScenarios())( "a crashed gateway binary does not log 'Docker-driver gateway is healthy'", "startGateway() exits non-zero and surfaces a gateway-start failure", "the gateway log proves the sabotaged GLIBC-failure binary was executed", + "no live non-zombie gateway process remains after the simulated crash", ], }); @@ -165,19 +166,18 @@ test.skipIf(!shouldRunLiveE2EScenarios())( [ "-lc", String.raw` -set -euo pipefail +set -u pid_file="$1" -if [ ! -f "$pid_file" ]; then - exit 0 -fi +[ -f "$pid_file" ] || exit 0 pid="$(tr -d '[:space:]' <"$pid_file" 2>/dev/null || true)" -if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then - exit 0 -fi -state="$(ps -p "$pid" -o state= 2>/dev/null | tr -d '[:space:]' || true)" -if [ -z "$state" ] || [[ "$state" == Z* ]]; then - exit 0 -fi +case "$pid" in + ""|*[!0-9]*) exit 0 ;; +esac +kill -0 "$pid" 2>/dev/null || exit 0 +state="$(ps -p "$pid" -o state= 2>/dev/null | tr -d '[:space:]')" || state="" +case "$state" in + ""|Z*) exit 0 ;; +esac printf 'live non-zombie gateway pid remains: pid=%s state=%s\n' "$pid" "$state" >&2 exit 1 `, From df4f705cd5b9fbdc4c77c2c6394f77746d0d9f4d Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Fri, 12 Jun 2026 19:20:38 -0400 Subject: [PATCH 6/7] test(e2e): fix workflow timeout option --- test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts b/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts index fdc74ed4d3a..0eefaacb0c4 100644 --- a/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts +++ b/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts @@ -392,7 +392,7 @@ describe("e2e-vitest-scenarios workflow boundary", () => { registryScenarios: [], }); } - }, 15_000); + }); it("flags direct dispatch-input interpolation and unsafe artifact upload", () => { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "e2e-vitest-workflow-")); From eb164cc9f96a5dfda78696d89ac32663b0963133 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Fri, 12 Jun 2026 20:24:25 -0700 Subject: [PATCH 7/7] test(e2e): relax workflow inventory support timeout --- test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts b/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts index f49ab955382..fc79308d263 100644 --- a/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts +++ b/test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts @@ -480,7 +480,7 @@ jobs: } }); - it("keeps each free-standing scenario out of the registry matrix", { timeout: 60_000 }, () => { + it("keeps each free-standing scenario out of the registry matrix", { timeout: 120_000 }, () => { const inventory = readFreeStandingJobsInventory(); for (const job of inventory.allowedJobs) { expect(generateMatrixForDispatch({ JOBS: job, SCENARIOS: "" })).toMatchObject({