Files
sandbox-runtime/test/sandbox/linux-bridge-spawn-error.test.ts
Mohamad El Hajj 188f9a110d Merge main into elhajj/credential-deny-mode
Resolves conflicts in linux-sandbox-utils.ts (keep both
resolveSymlinkDenyDest and pushReadDenyDirMounts; skip symlink aliases
in the new file-mask re-emission loop so it never targets a symlink
bind dest) and sandbox-manager.ts (keep both the randomBytes import
and the CredentialsConfig type import).

Also suppresses await-thenable on linux-bridge-spawn-error.test.ts:27
where bun-types misdeclares .rejects matchers as void; lint-staged
flagged it during the merge commit (CI only lints src/).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-17 18:22:53 +00:00

41 lines
1.6 KiB
TypeScript

import { describe, test, expect, beforeEach, afterEach } from 'bun:test'
import { initializeLinuxNetworkBridge } from '../../src/sandbox/linux-sandbox-utils.js'
// When spawn() cannot start socat (e.g. the binary is missing or not
// executable), the ChildProcess gets no pid and emits an asynchronous
// 'error' event. initializeLinuxNetworkBridge must have an 'error'
// listener attached before it throws on the missing pid — otherwise the
// queued event fires with no listener and escalates to an
// uncaughtException, crashing the host process even though the caller
// handled the rejection.
describe('initializeLinuxNetworkBridge spawn failure', () => {
const uncaught: Error[] = []
const onUncaught = (err: Error): void => {
uncaught.push(err)
}
beforeEach(() => {
uncaught.length = 0
process.on('uncaughtException', onUncaught)
})
afterEach(() => {
process.off('uncaughtException', onUncaught)
})
test('rejects without an unhandled error event when socat cannot be spawned', async () => {
// bun-types declares .rejects matchers as returning void, but bun returns
// a Promise at runtime — the await is load-bearing for the assertion.
// eslint-disable-next-line @typescript-eslint/await-thenable
await expect(
initializeLinuxNetworkBridge(0, 0, '/nonexistent-for-test/socat'),
).rejects.toThrow('Failed to start HTTP bridge process')
// Give the queued 'error' event a tick to fire so we can assert it was
// absorbed by the bridge's own listener.
await new Promise(r => setTimeout(r, 50))
expect(uncaught).toEqual([])
})
})