Skip to content

Commit 68fce5c

Browse files
GiniGini
authored andcommitted
test: prove provisioning cancellation cleanup
1 parent 12044c8 commit 68fce5c

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

server/onecomputer-sandbox-runner.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,35 @@ describe('OneComputerSandboxRuntimeAdapter', () => {
105105
expect(store.verifyChain(task.id)).toBe(true)
106106
})
107107

108+
it('deletes the known provider sandbox when cancellation occurs during provisioning', async () => {
109+
const root = await mkdtemp(path.join(tmpdir(), 'onevibe-onecomputer-cancel-provisioning-'))
110+
roots.push(root)
111+
const { TaskStore } = await import('./store.js')
112+
const { OneComputerSandboxRuntimeAdapter } = await import('./onecomputer-sandbox-runner.js')
113+
const store = new TaskStore(root)
114+
await store.initialize()
115+
const task = await store.createTask('Cancel while a sandbox provisions', 'onecomputer')
116+
const client = {
117+
createSandbox: vi.fn(async () => ({ id: 'sandbox-provisioning', state: 'provisioning', provider: 'kasm-local' })),
118+
getSandbox: vi.fn(async () => ({ id: 'sandbox-provisioning', state: 'provisioning', provider: 'kasm-local' })),
119+
deleteSandbox: vi.fn(async () => undefined),
120+
exec: vi.fn(),
121+
startVisualRuntime: vi.fn(),
122+
getVisualScreenshot: vi.fn(),
123+
} as unknown as OneComputerClient
124+
const adapter = new OneComputerSandboxRuntimeAdapter(client, { gatewayEnforced: true, retainSandbox: false, visualRuntime: false, pollMilliseconds: 10_000 })
125+
const controller = new AbortController()
126+
const run = adapter.run({ task, store, signal: controller.signal, prompt: task.prompt, continuation: false, requestUserInput: async () => 'unused' })
127+
128+
await vi.waitFor(() => expect(store.getTask(task.id).securityContext).toMatchObject({ sandboxId: 'sandbox-provisioning', sandboxState: 'provisioning', executionBoundary: 'onecomputer_sandbox' }))
129+
controller.abort()
130+
131+
await expect(run).rejects.toMatchObject({ name: 'AbortError' })
132+
expect(client.deleteSandbox).toHaveBeenCalledWith('sandbox-provisioning')
133+
expect(store.getTask(task.id).securityContext).toMatchObject({ sandboxId: 'sandbox-provisioning', sandboxState: 'destroyed' })
134+
expect(store.listEvents(task.id).some((event) => event.label === 'Ephemeral sandbox destroyed')).toBe(true)
135+
})
136+
108137
it('reuses an explicitly retained sandbox for a continuation', async () => {
109138
const root = await mkdtemp(path.join(tmpdir(), 'onevibe-onecomputer-retained-'))
110139
roots.push(root)

0 commit comments

Comments
 (0)