Skip to content

Commit 0978441

Browse files
committed
test(e2e): retain Brev readiness failure evidence
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
1 parent 7ba0122 commit 0978441

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

test/e2e/fixtures/brev-launchable.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,29 @@ export class BrevLaunchableFixture {
194194
timeoutMs = DEFAULT_BREV_EXEC_READY_TIMEOUT_MS,
195195
): Promise<void> {
196196
const deadline = Date.now() + timeoutMs;
197+
let attempts = 0;
198+
let lastResult: ShellProbeResult | undefined;
197199
while (Date.now() < deadline) {
200+
attempts += 1;
198201
const remaining = deadline - Date.now();
199202
const result = await this.exec(ownership, "true", {
200203
artifactName: "brev-exec-readiness",
201204
persistArtifacts: false,
202205
timeoutMs: Math.min(30_000, remaining),
203206
});
204207
if (result.exitCode === 0) return;
208+
lastResult = result;
205209
await delay(Math.min(this.pollMs, Math.max(1, deadline - Date.now())));
206210
}
207-
throw new Error("Brev exec readiness timed out");
211+
await this.artifacts.writeJson("brev-exec-readiness-failure.json", {
212+
attempts,
213+
lastResult,
214+
workspaceId: ownership.id,
215+
workspaceName: ownership.name,
216+
});
217+
throw new Error(
218+
`Brev exec readiness timed out after ${attempts} attempts: ${lastResult ? resultText(lastResult) : "no command result"}`,
219+
);
208220
}
209221

210222
private async exec(

test/e2e/support/brev-launchable-fixture.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,25 @@ describe("the Brev Launchable fixture binds staging identity and workspace lifec
293293
expect(ownership.id).toBe("owned-id");
294294
});
295295

296+
it("records the last failed Brev exec readiness attempt", async () => {
297+
const root = temporaryRoot();
298+
const command = vi.fn(ownedExecCommand("", 1, "ssh unavailable"));
299+
const fixture = createFixture(root, command);
300+
301+
await expect(fixture.waitForExec(recordedOwnership(), 10)).rejects.toThrow(
302+
"Brev exec readiness timed out",
303+
);
304+
const evidence = JSON.parse(
305+
fs.readFileSync(path.join(root, "brev-exec-readiness-failure.json"), "utf8"),
306+
);
307+
expect(evidence).toMatchObject({
308+
attempts: expect.any(Number),
309+
lastResult: { exitCode: 1, stderr: "ssh unavailable" },
310+
workspaceId: "owned-id",
311+
workspaceName: "fixture-workspace",
312+
});
313+
});
314+
296315
it("refuses a replacement before Brev exec readiness without executing on it", async () => {
297316
const root = temporaryRoot();
298317
const lifecycle = replaceableWorkspaceCommand();
@@ -496,13 +515,15 @@ function recordedOwnership(): BrevWorkspaceOwnership {
496515

497516
function ownedExecCommand(
498517
stdout: string,
518+
exitCode = 0,
519+
stderr = "",
499520
): (_binary: string, args: string[], _options?: ShellProbeRunOptions) => Promise<ShellProbeResult> {
500521
return async (_binary, args, _options) => {
501522
switch (args[0]) {
502523
case "ls":
503524
return workspaceResult("owned-id");
504525
case "exec":
505-
return result(stdout);
526+
return { ...result(stdout), exitCode, stderr };
506527
default:
507528
throw new Error(`unexpected command: ${args.join(" ")}`);
508529
}

0 commit comments

Comments
 (0)