Files

82 lines
2.0 KiB
JavaScript

const assert = require('node:assert/strict')
function subprocess() {
let dataListener
let exitListener
return {
pid: 424242,
getForegroundProcess: () => null,
write() {},
resize() {},
signal() {},
kill() {
exitListener?.(0)
},
forceKill() {
exitListener?.(137)
},
terminateOwnedTree: () => 'unavailable',
onData(listener) {
dataListener = listener
},
onExit(listener) {
exitListener = listener
},
dispose() {
dataListener = undefined
exitListener = undefined
},
emitData(data) {
dataListener?.(data)
},
emitExit(code) {
exitListener?.(code)
}
}
}
// These callbacks must not share a lexical context with the request's signal.
const streamClient = { onData() {}, onExit() {} }
function startWithInputs(host, sessionId) {
const controller = new AbortController()
const env = { RETENTION_FIXTURE: 'x'.repeat(1024) }
const historySeedChunks = ['retention-seed\r\n']
const options = {
sessionId,
cols: 80,
rows: 24,
env,
historySeedChunks,
streamClient,
cancelSignal: controller.signal,
isCanceled: () => controller.signal.aborted
}
return {
refs: {
options: new WeakRef(options),
env: new WeakRef(env),
history: new WeakRef(historySeedChunks),
signal: new WeakRef(controller.signal)
},
creation: host.createOrAttach(options)
}
}
function counts(refs) {
return Object.fromEntries(
['options', 'env', 'history', 'signal'].map((key) => [
key,
refs.filter((ref) => ref[key].deref() !== undefined).length
])
)
}
const expected = (count) => ({ options: count, env: count, history: count, signal: count })
async function collect() {
assert.equal(typeof global.gc, 'function')
for (let round = 0; round < 4; round += 1) {
await new Promise((resolve) => setImmediate(resolve))
global.gc()
}
}
module.exports = { subprocess, streamClient, startWithInputs, counts, expected, collect }