chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { assert, expect, test } from 'vitest'
|
||||
|
||||
import { InvalidArgumentError, Sandbox } from '../../src'
|
||||
import { isDebug, template, wait } from '../setup.js'
|
||||
|
||||
test.skipIf(isDebug)(
|
||||
'filesystem-only auto-pause cannot be combined with auto-resume',
|
||||
async () => {
|
||||
// A filesystem-only auto-pause snapshot can only be resumed explicitly, so
|
||||
// keepMemory:false with autoResume is rejected client-side.
|
||||
await expect(
|
||||
Sandbox.create(template, {
|
||||
timeoutMs: 3_000,
|
||||
lifecycle: {
|
||||
onTimeout: { action: 'pause', keepMemory: false },
|
||||
autoResume: true,
|
||||
},
|
||||
})
|
||||
).rejects.toThrowError(InvalidArgumentError)
|
||||
}
|
||||
)
|
||||
|
||||
test.skipIf(isDebug)(
|
||||
'keepMemory is not allowed when onTimeout action is kill',
|
||||
async () => {
|
||||
// The discriminated union forbids keepMemory on `action: 'kill'` at compile
|
||||
// time (asserted by @ts-expect-error). The runtime guard below additionally
|
||||
// rejects it for untyped (JS) callers that bypass the type.
|
||||
await expect(
|
||||
Sandbox.create(template, {
|
||||
timeoutMs: 3_000,
|
||||
lifecycle: {
|
||||
// @ts-expect-error keepMemory is not allowed with action: 'kill'
|
||||
onTimeout: { action: 'kill', keepMemory: false },
|
||||
},
|
||||
})
|
||||
).rejects.toThrowError(InvalidArgumentError)
|
||||
}
|
||||
)
|
||||
|
||||
test.skipIf(isDebug)(
|
||||
'auto-pause without auto-resume requires connect to wake',
|
||||
async () => {
|
||||
const sandbox = await Sandbox.create(template, {
|
||||
timeoutMs: 3_000,
|
||||
lifecycle: {
|
||||
onTimeout: 'pause',
|
||||
autoResume: false,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
await wait(5_000)
|
||||
|
||||
assert.equal((await sandbox.getInfo()).state, 'paused')
|
||||
assert.isFalse(await sandbox.isRunning())
|
||||
|
||||
await sandbox.connect()
|
||||
|
||||
assert.equal((await sandbox.getInfo()).state, 'running')
|
||||
assert.isTrue(await sandbox.isRunning())
|
||||
} finally {
|
||||
await sandbox.kill().catch(() => {})
|
||||
}
|
||||
},
|
||||
60_000
|
||||
)
|
||||
|
||||
test.skipIf(isDebug)(
|
||||
'filesystem-only auto-pause reboots on connect',
|
||||
async () => {
|
||||
// keepMemory:false makes the timeout auto-pause filesystem-only, so resuming
|
||||
// cold-boots the sandbox from disk.
|
||||
const sandbox = await Sandbox.create(template, {
|
||||
timeoutMs: 3_000,
|
||||
lifecycle: { onTimeout: { action: 'pause', keepMemory: false } },
|
||||
})
|
||||
|
||||
try {
|
||||
const marker = 'auto-pause-fs-only'
|
||||
await sandbox.files.write('/home/user/auto-pause-marker.txt', marker)
|
||||
const bootBefore = (
|
||||
await sandbox.files.read('/proc/sys/kernel/random/boot_id')
|
||||
).trim()
|
||||
|
||||
await wait(5_000)
|
||||
|
||||
assert.equal((await sandbox.getInfo()).state, 'paused')
|
||||
|
||||
// A filesystem-only snapshot cannot auto-resume on traffic; connect
|
||||
// resumes it by cold-booting.
|
||||
await sandbox.connect()
|
||||
|
||||
const persisted = (
|
||||
await sandbox.files.read('/home/user/auto-pause-marker.txt')
|
||||
).trim()
|
||||
assert.equal(persisted, marker)
|
||||
|
||||
const bootAfter = (
|
||||
await sandbox.files.read('/proc/sys/kernel/random/boot_id')
|
||||
).trim()
|
||||
assert.notEqual(bootAfter, bootBefore)
|
||||
} finally {
|
||||
await sandbox.kill().catch(() => {})
|
||||
}
|
||||
},
|
||||
60_000
|
||||
)
|
||||
|
||||
test.skipIf(isDebug)(
|
||||
'auto-resume wakes paused sandbox on http request',
|
||||
async () => {
|
||||
const sandbox = await Sandbox.create(template, {
|
||||
timeoutMs: 3_000,
|
||||
lifecycle: {
|
||||
onTimeout: 'pause',
|
||||
autoResume: true,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
await sandbox.commands.run('python3 -m http.server 8000', {
|
||||
background: true,
|
||||
})
|
||||
|
||||
await wait(5_000)
|
||||
|
||||
const url = `https://${sandbox.getHost(8000)}`
|
||||
const res = await fetch(url, { signal: AbortSignal.timeout(15_000) })
|
||||
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal((await sandbox.getInfo()).state, 'running')
|
||||
assert.isTrue(await sandbox.isRunning())
|
||||
} finally {
|
||||
await sandbox.kill().catch(() => {})
|
||||
}
|
||||
},
|
||||
60_000
|
||||
)
|
||||
Reference in New Issue
Block a user