test: bound memory used by the runtime Electron audit (#26049)

This commit is contained in:
Neil
2026-10-06 20:21:34 -07:00
committed by GitHub
parent 7c9c3d431a
commit d3e1494674
3 changed files with 67 additions and 19 deletions
@@ -113,11 +113,20 @@ const externalNativeAddons = {
// Why `plugins`: lets a test add an Electron import to a real file in memory, never on disk.
export async function collectElectronImporters(entryPoints, { plugins = [] } = {}) {
const result = await build({
entryPoints,
// Export every entry through one bundle so shared dependencies are emitted once.
stdin: {
contents: entryPoints
.map(
(entry, index) =>
`export * as entry_${index} from ${JSON.stringify(path.resolve(ROOT, entry))}`
)
.join('\n'),
resolveDir: ROOT,
loader: 'ts',
sourcefile: 'runtime-electron-ratchet-entry.ts'
},
bundle: true,
write: false,
// Why outdir with write:false: esbuild refuses multiple entry points without one,
// even though nothing is emitted — the metafile is all this reads.
outdir: path.join(ROOT, 'runtime-electron-ratchet-metafile-only'),
platform: 'node',
target: 'node20',
@@ -94,21 +94,61 @@ describe('structured chat coverage', () => {
}
)
it('finds Electron through a package imported by each unwired future lane', async () => {
it.each([true, false])(
'finds Electron through an unwired lane package (sideEffects=%s)',
async (sideEffects) => {
const root = fixture({
...requiredLanes,
'src/main/acp/adapter.ts': "import 'acp-desktop-package'",
'src/main/provider-process/worker.ts': "import 'provider-desktop-package'",
'node_modules/acp-desktop-package/package.json': JSON.stringify({
main: 'index.js',
sideEffects
}),
'node_modules/acp-desktop-package/index.js': "require('electron')",
'node_modules/provider-desktop-package/package.json': JSON.stringify({
main: 'index.js',
sideEffects
}),
'node_modules/provider-desktop-package/index.js': "require('electron')"
})
const current = await collectElectronImporters(collectStructuredChatEntryPoints(root))
expect(current.map((file) => file.split('/node_modules/').pop())).toEqual([
'acp-desktop-package/index.js',
'provider-desktop-package/index.js'
])
}
)
it('bounds shared dependency output without dropping any entry point', async () => {
const entries = Array.from({ length: 40 }, (_, index) => `entry-${index}.ts`)
const root = fixture({
...requiredLanes,
'src/main/acp/adapter.ts': "import 'acp-desktop-package'",
'src/main/provider-process/worker.ts': "import 'provider-desktop-package'",
'node_modules/acp-desktop-package/package.json': '{"main":"index.js"}',
'node_modules/acp-desktop-package/index.js': "require('electron')",
'node_modules/provider-desktop-package/package.json': '{"main":"index.js"}',
'node_modules/provider-desktop-package/index.js': "require('electron')"
'shared.ts': `export const payload = ${JSON.stringify('x'.repeat(64 * 1024))}`,
...Object.fromEntries(
entries.map((file) => [file, "import 'electron'; export { payload } from './shared'"])
)
})
const current = await collectElectronImporters(collectStructuredChatEntryPoints(root))
expect(current.map((file) => file.split('/node_modules/').pop())).toEqual([
'acp-desktop-package/index.js',
'provider-desktop-package/index.js'
])
let emittedBytes = 0
const current = await collectElectronImporters(
entries.map((file) => path.join(root, file)),
{
plugins: [
{
name: 'measure-audit-output',
setup(builder) {
builder.onEnd((result) => {
emittedBytes = result.outputFiles.reduce(
(bytes, file) => bytes + file.contents.byteLength,
0
)
})
}
}
]
}
)
expect(current.map((file) => path.basename(file)).sort()).toEqual(entries.sort())
expect(emittedBytes).toBeLessThan(128 * 1024)
})
})
@@ -50,8 +50,7 @@ import {
type StructuredAgentSessionRestartResume
} from './structured-agent-session-restart-resume-host'
import { structuredAgentSessionRestartResumeSurfaces } from './structured-agent-session-restart-resume-wiring'
import { createStructuredAgentSessionConversationDelivery } from './structured-agent-session-host-delivery'
import type * as conversation from './structured-agent-session-host-delivery'
import * as conversation from './structured-agent-session-host-delivery'
import { structuredAgentSessionConversationFence } from './structured-agent-session-provider-child'
import { wireStructuredAgentSessionQueuedMessages } from './structured-agent-session-queued-wiring'
import * as sessionLogger from './structured-agent-session-logger'
@@ -117,7 +116,7 @@ export class StructuredAgentSessionHost {
...(deps.probeOwners ? { probeMany: deps.probeOwners } : {}),
now: () => this.now()
})
this.conversationDelivery = createStructuredAgentSessionConversationDelivery({
this.conversationDelivery = conversation.createStructuredAgentSessionConversationDelivery({
deps,
sessions: this.sessions,
serialize: (sessionId, task) => this.serialize(sessionId, task),