diff --git a/test/e2e-scenario/live/agent-turn-latency-helpers.ts b/test/e2e-scenario/live/agent-turn-latency-helpers.ts index 9fde9c79fc5..07e340613bc 100644 --- a/test/e2e-scenario/live/agent-turn-latency-helpers.ts +++ b/test/e2e-scenario/live/agent-turn-latency-helpers.ts @@ -12,6 +12,7 @@ import { } from "../fixtures/clients/sandbox.ts"; import { expect } from "../fixtures/e2e-test.ts"; import type { ShellProbeResult } from "../fixtures/shell-probe.ts"; +import { installShOnboardArgs } from "./install-sh-onboard.ts"; import { isTransientProviderValidationFailure } from "./network-policy-transient-provider.ts"; export const REPO_ROOT = path.resolve(import.meta.dirname, "../../.."); @@ -220,17 +221,13 @@ export async function installSandbox( ): Promise { let install: ShellProbeResult | undefined; for (let attempt = 1; attempt <= INSTALL_ATTEMPTS; attempt += 1) { - install = await host.command( - "bash", - ["install.sh", "--non-interactive", "--yes-i-accept-third-party-software"], - { - artifactName: `${agent}-install-attempt-${attempt}`, - cwd: REPO_ROOT, - env: env(sandboxName, agent, apiKey), - redactionValues: [apiKey], - timeoutMs: 30 * 60_000, - }, - ); + install = await host.command("bash", installShOnboardArgs(), { + artifactName: `${agent}-install-attempt-${attempt}`, + cwd: REPO_ROOT, + env: env(sandboxName, agent, apiKey), + redactionValues: [apiKey], + timeoutMs: 30 * 60_000, + }); const retry = install.exitCode !== 0 && isTransientProviderValidationFailure(install) && diff --git a/test/e2e-scenario/live/cron-preflight-inference-local.test.ts b/test/e2e-scenario/live/cron-preflight-inference-local.test.ts index a31658092b3..73ccb2ef1d3 100644 --- a/test/e2e-scenario/live/cron-preflight-inference-local.test.ts +++ b/test/e2e-scenario/live/cron-preflight-inference-local.test.ts @@ -19,6 +19,7 @@ import { type SandboxClient, validateSandboxName } from "../fixtures/clients/san import { expect, test } from "../fixtures/e2e-test.ts"; import { shouldRunLiveE2EScenarios } from "../fixtures/live-project-gate.ts"; import type { ShellProbeResult } from "../fixtures/shell-probe.ts"; +import { installShOnboardArgs } from "./install-sh-onboard.ts"; import { isTransientProviderValidationFailure } from "./network-policy-transient-provider.ts"; const REPO_ROOT = path.resolve(import.meta.dirname, "../../.."); @@ -265,20 +266,16 @@ test.skipIf(!shouldRunLiveE2EScenarios())( let install: ShellProbeResult | undefined; for (let attempt = 1; attempt <= INSTALL_ATTEMPTS; attempt += 1) { - install = await host.command( - "bash", - ["install.sh", "--non-interactive", "--yes-i-accept-third-party-software"], - { - artifactName: - attempt === 1 - ? "phase-1-install-cron-preflight" - : `phase-1-install-cron-preflight-attempt-${attempt}`, - cwd: REPO_ROOT, - env: commandEnv(apiKey), - redactionValues: [apiKey], - timeoutMs: 20 * 60_000, - }, - ); + install = await host.command("bash", installShOnboardArgs(), { + artifactName: + attempt === 1 + ? "phase-1-install-cron-preflight" + : `phase-1-install-cron-preflight-attempt-${attempt}`, + cwd: REPO_ROOT, + env: commandEnv(apiKey), + redactionValues: [apiKey], + timeoutMs: 20 * 60_000, + }); if (install.exitCode === 0) break; if (isTransientProviderValidationFailure(install) && attempt < INSTALL_ATTEMPTS) { await new Promise((resolve) => setTimeout(resolve, 10_000 * attempt)); diff --git a/test/e2e-scenario/live/install-sh-onboard.ts b/test/e2e-scenario/live/install-sh-onboard.ts new file mode 100644 index 00000000000..beca9c5e41b --- /dev/null +++ b/test/e2e-scenario/live/install-sh-onboard.ts @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Canonical install.sh arguments for live Vitest scenarios that auto-onboard. + * + * Live scenario retries must not inherit a failed persisted onboarding session + * from an earlier failed attempt. `--fresh` makes install.sh bypass the failed + * session classifier and lets the CLI clear stale session state before creating + * the new session. + */ +export function installShOnboardArgs(): string[] { + return ["install.sh", "--non-interactive", "--yes-i-accept-third-party-software", "--fresh"]; +} diff --git a/test/e2e-scenario/support-tests/install-sh-onboard.test.ts b/test/e2e-scenario/support-tests/install-sh-onboard.test.ts new file mode 100644 index 00000000000..3631881279b --- /dev/null +++ b/test/e2e-scenario/support-tests/install-sh-onboard.test.ts @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import fs from "node:fs"; +import path from "node:path"; + +import { describe, expect, it } from "vitest"; + +import { installShOnboardArgs } from "../live/install-sh-onboard.ts"; + +const RETRY_SENSITIVE_LIVE_TESTS = [ + "test/e2e-scenario/live/agent-turn-latency-helpers.ts", + "test/e2e-scenario/live/cron-preflight-inference-local.test.ts", +]; + +describe("live install.sh onboarding arguments", () => { + it("force a fresh onboarding session so retries discard failed session state", () => { + expect(installShOnboardArgs()).toEqual([ + "install.sh", + "--non-interactive", + "--yes-i-accept-third-party-software", + "--fresh", + ]); + }); + + it("routes retry-sensitive live install.sh callers through the fresh-session helper", () => { + for (const relativePath of RETRY_SENSITIVE_LIVE_TESTS) { + const source = fs.readFileSync(path.join(process.cwd(), relativePath), "utf8"); + expect(source, relativePath).toContain("installShOnboardArgs()"); + expect(source, relativePath).not.toContain( + '["install.sh", "--non-interactive", "--yes-i-accept-third-party-software"]', + ); + } + }); +});