refactor(e2b): keep provider layer substrate-only

This commit is contained in:
Tianyi Cui
2026-07-29 19:07:11 +08:00
parent 65b345c96a
commit 917a7493f7
28 changed files with 280 additions and 578 deletions

View File

@@ -49,10 +49,7 @@ class FakeRemote {
nextReadError: unknown
nextRenameError: unknown
nextRemoveError: unknown
boundedOutput: string | undefined
boundedError: unknown
nodeExecutable = '/usr/bin/node\n'
abortAfterBoundedCommand: AbortController | undefined
canonicalOutput: string | undefined
abortAfterRename: AbortController | undefined
disappearOnInfo = new Set<string>()
private clock = 1
@@ -239,18 +236,18 @@ class FakeRemote {
this.nextCommandError = undefined
throw error
}
if (command.startsWith('realpath -m -- ')) {
const input = command.slice('realpath -m -- '.length).slice(1, -1)
const realpathPrefix = 'set -o pipefail; realpath -mz -- '
const realpathSuffix = ' | base64 -w0'
if (command.startsWith(realpathPrefix) && command.endsWith(realpathSuffix)) {
const quoted = command.slice(realpathPrefix.length, -realpathSuffix.length)
const input = quoted.slice(1, -1).replaceAll(String.raw`'"'"'`, '\'')
const node = this.nodes.get(input)
return { exitCode: 0, stdout: `${node?.symlinkTarget ?? input}\n`, stderr: '' }
}
if (command === 'command -v -- node') {
return { exitCode: 0, stdout: this.nodeExecutable, stderr: '' }
}
if (command.includes('dsh-e2b-bounded-reader')) {
if (this.boundedError !== undefined) throw this.boundedError
this.abortAfterBoundedCommand?.abort('after bounded read')
return { exitCode: 0, stdout: this.boundedOutput ?? '{"kind":"ok","data":""}', stderr: '' }
const canonical = `${node?.symlinkTarget ?? input}\0`
return {
exitCode: 0,
stdout: this.canonicalOutput ?? Buffer.from(canonical).toString('base64'),
stderr: '',
}
}
const chmod = /^chmod ([0-7]+) -- '([^']+)'$/.exec(command)
if (chmod !== null) this.required(chmod[2]!).mode = Number.parseInt(chmod[1]!, 8)
@@ -340,6 +337,28 @@ describe('E2BFileSystem identity, metadata, and reads', () => {
.toThrow('expected an absolute process path')
})
it('preserves newline and multibyte canonical paths through strict ASCII framing', async () => {
const remote = new FakeRemote()
const path = '/workspace/你好\nfile.ts'
remote.file(path, 'text')
const { fs } = await setup(remote)
await expect(fs.resolve(path)).resolves.toEqual({ targetKey: path, displayPath: path })
})
it.each([
['invalid base64', '!!!!'],
['missing terminator', Buffer.from('/workspace/file').toString('base64')],
['multiple records', Buffer.from('/workspace/file\0/other\0').toString('base64')],
['invalid UTF-8', Buffer.from([47, 0xff, 0]).toString('base64')],
['relative path', Buffer.from('workspace/file\0').toString('base64')],
])('rejects %s from canonical path transport', async (_label, output) => {
const remote = new FakeRemote()
remote.canonicalOutput = output
const { fs } = await setup(remote)
await expectCode(fs.resolve('file'), 'FS_IO_ERROR')
})
it('reads whole and streamed UTF-8 across chunk boundaries', async () => {
const remote = new FakeRemote()
remote.file('/workspace/text.txt', 'A€B')
@@ -424,78 +443,6 @@ describe('E2BFileSystem identity, metadata, and reads', () => {
await expectCode(fs.readText(await fs.resolve('a')), 'FS_ABORTED')
})
it('performs stable bounded reads through the remote no-follow reader', async () => {
const remote = new FakeRemote()
remote.file('/workspace/a', 'unused')
const { fs } = await setup(remote)
const target = await fs.resolve('a')
remote.boundedOutput = JSON.stringify({ kind: 'ok', data: Buffer.from('hello 你好').toString('base64') })
await expect(fs.readTextBounded(target, 64)).resolves.toBe('hello 你好')
expect(remote.commands.some(command => command.includes('dsh-e2b-bounded-reader'))).toBe(true)
await expect(fs.readTextBounded(target, 0)).rejects.toThrow('positive safe integer')
await expect(fs.readTextBounded(target, 1.5)).rejects.toThrow('positive safe integer')
await expect(fs.readTextBounded(target, 64, AbortSignal.abort())).rejects.toMatchObject({ code: 'FS_ABORTED' })
})
it('maps bounded-reader file, size, and open failures', async () => {
const remote = new FakeRemote()
remote.file('/workspace/a', 'unused')
const { fs } = await setup(remote)
const target = await fs.resolve('a')
const cases: Array<[unknown, string]> = [
[{ kind: 'not-file' }, 'FS_NOT_REGULAR_FILE'],
[{ kind: 'oversize', size: 65 }, 'FS_IO_ERROR'],
[{ kind: 'grew' }, 'FS_IO_ERROR'],
[{ kind: 'open-error', message: 'ENOENT: no such file' }, 'FS_NOT_FOUND'],
[{ kind: 'open-error', message: 'EACCES: permission denied' }, 'FS_PERMISSION_DENIED'],
[{ kind: 'open-error', message: 'ELOOP: symbolic link' }, 'FS_IO_ERROR'],
[{ kind: 'oversize', size: 'large' }, 'FS_IO_ERROR'],
[{ kind: 'open-error', message: 7 }, 'FS_IO_ERROR'],
[{ kind: 'unknown' }, 'FS_IO_ERROR'],
]
for (const [response, code] of cases) {
remote.boundedOutput = JSON.stringify(response)
await expectCode(fs.readTextBounded(target, 64), code)
}
})
it('rejects malformed bounded-reader transports and bytes', async () => {
const remote = new FakeRemote()
remote.file('/workspace/a', 'unused')
const { fs } = await setup(remote)
const target = await fs.resolve('a')
remote.boundedOutput = 'not-json'
await expectCode(fs.readTextBounded(target, 4), 'FS_IO_ERROR')
remote.boundedOutput = JSON.stringify({ kind: 'ok', data: '!!!!' })
await expectCode(fs.readTextBounded(target, 4), 'FS_IO_ERROR')
remote.boundedOutput = JSON.stringify({ kind: 'ok', data: Buffer.from('12345').toString('base64') })
await expectCode(fs.readTextBounded(target, 4), 'FS_IO_ERROR')
remote.boundedOutput = JSON.stringify({ kind: 'ok', data: Buffer.from([0]).toString('base64') })
await expectCode(fs.readTextBounded(target, 4), 'FS_NOT_TEXT')
remote.boundedOutput = JSON.stringify({ kind: 'ok', data: Buffer.from([0xff]).toString('base64') })
await expectCode(fs.readTextBounded(target, 4), 'FS_NOT_TEXT')
remote.nodeExecutable = 'node\n'
await expectCode(fs.readTextBounded(target, 4), 'FS_IO_ERROR')
remote.nodeExecutable = '/usr/bin/node\n/other\n'
await expectCode(fs.readTextBounded(target, 4), 'FS_IO_ERROR')
remote.nodeExecutable = '/usr/bin/node\n'
remote.boundedError = new Error('reader transport failed')
await expectCode(fs.readTextBounded(target, 4), 'FS_IO_ERROR')
})
it('does not turn a post-read abort into successful source text', async () => {
const remote = new FakeRemote()
remote.file('/workspace/a', 'unused')
const controller = new AbortController()
remote.abortAfterBoundedCommand = controller
remote.boundedOutput = JSON.stringify({ kind: 'ok', data: Buffer.from('text').toString('base64') })
const { fs } = await setup(remote)
await expectCode(fs.readTextBounded(await fs.resolve('a'), 4, controller.signal), 'FS_ABORTED')
})
it('rejects empty paths and directory-listing type errors', async () => {
const remote = new FakeRemote()
remote.file('/workspace/file', 'x')
@@ -686,17 +633,34 @@ describe('E2B filesystem adapter integration edges', () => {
await expectCode(fs.readText(target), 'FS_IO_ERROR')
})
it('keeps a listed child whose metadata disappears as an other entry', async () => {
it('uses listing metadata directly and canonicalizes only symbolic links', async () => {
const remote = new FakeRemote()
remote.file('/workspace/a', 'a')
remote.disappearOnInfo.add('/workspace/a')
remote.file('/workspace/target', 'target')
remote.file('/workspace/gone', 'gone')
remote.symlink('/workspace/link', '/workspace/target')
remote.symlink('/workspace/vanished-link', '/workspace/gone')
remote.disappearOnInfo.add('/workspace/gone')
const { fs } = await setup(remote)
const listed = await fs.listDir(await fs.resolve('/workspace'))
expect(listed).toEqual([{
name: 'a',
const directory = await fs.resolve('/workspace')
const commandsBefore = remote.commands.length
const getInfo = vi.spyOn(remote.sandbox.files, 'getInfo')
const listed = await fs.listDir(directory)
expect(listed.find(entry => entry.name === 'a')).toMatchObject({
type: 'file', target: { targetKey: '/workspace/a' }, size: 1,
})
expect(listed.find(entry => entry.name === 'link')).toMatchObject({
type: 'file', target: { targetKey: '/workspace/target' }, size: 6,
})
expect(listed.find(entry => entry.name === 'vanished-link')).toEqual({
name: 'vanished-link',
type: 'other',
target: { targetKey: '/workspace/a', displayPath: '/workspace/a' },
}])
target: { targetKey: '/workspace/gone', displayPath: '/workspace/vanished-link' },
})
expect(remote.commands.slice(commandsBefore)).toHaveLength(2)
expect(getInfo).toHaveBeenCalledTimes(3)
})
it('registers the package-owned empty invariant installer', async () => {