Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/lib/onboard/sandbox-gpu-create-flow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,10 @@ describe("runSandboxGpuCreateFlow proof authorization", () => {
});

describe("runSandboxGpuCreateFlow native failure and readiness", () => {
it("threads restart-safe startup resource limits on the no-GPU Docker route", async () => {
it("defers restart-safe no-GPU recreation until the create process exits (#8720)", async () => {
const input = createInput();
const patch = createPatch();
mocks.createDockerGpuSandboxCreatePatch.mockReturnValueOnce(patch);
input.sandboxGpuConfig = {
...input.sandboxGpuConfig,
mode: "0",
Expand All @@ -534,6 +536,17 @@ describe("runSandboxGpuCreateFlow native failure and readiness", () => {
requiredUlimits: input.requiredUlimits,
}),
);
expect(mocks.streamSandboxCreate).toHaveBeenCalledWith(
"openshell",
["sandbox", "create"],
input.sandboxEnv,
expect.objectContaining({ waitForReadyTermination: true }),
);
const onPoll = mocks.streamSandboxCreate.mock.calls[0]?.[3]?.onPoll;
expect(onPoll).toBeTypeOf("function");
onPoll();
expect(patch.maybeApplyDuringCreate).not.toHaveBeenCalled();
expect(patch.ensureApplied).toHaveBeenCalledOnce();
Comment on lines +539 to +549

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Exercise onPoll before the stream resolves.

The explicit call at Line 547 occurs after the stream invocation in the test body. It does not prove that an active create poll skips maybeApplyDuringCreate() or that ensureApplied() runs after ownership release. Configure the stream mock to invoke onPoll before it resolves, then assert the order: poll, stream completion, ensureApplied().

As per path instructions, review tests for behavioral confidence rather than implementation lock-in.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard/sandbox-gpu-create-flow.test.ts` around lines 539 - 549,
Update the sandbox creation test around streamSandboxCreate so its mock invokes
the captured onPoll callback before the stream promise resolves, rather than
calling it afterward in the test body. Assert the behavioral order of the poll,
stream completion, and ensureApplied(), while verifying maybeApplyDuringCreate()
is skipped; avoid assertions that depend on implementation-specific call
structure.

Source: Path instructions

});

it("does not replace a native GPU container solely to persist its startup command", async () => {
Expand Down
12 changes: 9 additions & 3 deletions src/lib/onboard/sandbox-gpu-create-run-attempt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,18 @@ export function createSandboxGpuCreateAttemptRunner(
},
})
: null;
const persistRestartSafeStartup =
input.persistStartupCommand === true && (route !== "native" || hasRequiredUlimits);
const deferRestartSafeCutover =
!managedLifecycle && !compatibility && persistRestartSafeStartup;
const runtimePatch =
managedLifecycle?.patch ??
createDockerGpuSandboxCreatePatch({
route,
// The startup clone preserves native CDI devices, so DCode can apply its
// exact required limits without replacing the native GPU envelope.
// Other native routes are not swapped solely to persist a command.
persistStartupCommand:
input.persistStartupCommand === true && (route !== "native" || hasRequiredUlimits),
persistStartupCommand: persistRestartSafeStartup,
externalRecreation: false,
sandboxName: input.sandboxName,
gpuDevice: input.sandboxGpuConfig.sandboxGpuDevice,
Expand All @@ -161,13 +164,16 @@ export function createSandboxGpuCreateAttemptRunner(
const list = deps.runCaptureOpenshell(["sandbox", "list"], { ignoreError: true });
return isSandboxReady(list, input.sandboxName);
},
onPoll: () => runtimePatch.maybeApplyDuringCreate(),
onPoll: () => {
if (!deferRestartSafeCutover) runtimePatch.maybeApplyDuringCreate();
},
readyCheckOutputPatterns: getReadyCheckOutputPatternsForAgent(
input.terminalAgent,
input.sandboxEnv,
),
failureCheck: runtimePatch.createFailureMessage,
traceEvent: addTraceEvent,
waitForReadyTermination: deferRestartSafeCutover,
initialPhase:
compatibility && (input.prebuild.imageRef || state.compatibilityArgv)
? "create"
Expand Down
Loading