File size: 2,354 Bytes
3144483 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | import assert from "node:assert/strict";
import { setImmediate } from "node:timers/promises";
import { createDeferred } from "../../test/helpers/promise.js";
import { runUtf8CommandWithTimeout } from "./exec-runner.js";
const gc = globalThis.gc;
assert.ok(gc, "The retention child requires --expose-gc");
const emittedBytes = 128 * 1024;
const cap = 16;
const observed = [];
for (const mode of ["head", "combined-head", "tail"] as const) {
let clipped: WeakRef<ArrayBufferLike> | undefined;
let bytes = 0;
const output = createDeferred();
const control = new WeakRef(new ArrayBuffer(1024));
const abort = new AbortController();
const command = runUtf8CommandWithTimeout(
[
process.execPath,
"-e",
`process.stdout.write(Buffer.alloc(${emittedBytes}, 88)); setInterval(() => {}, 1000);`,
],
{
baseEnv: {},
timeoutMs: 10_000,
signal: abort.signal,
outputCapture: mode === "tail" ? "tail" : "head",
maxOutputBytes: mode === "combined-head" ? emittedBytes : cap,
...(mode === "combined-head" ? { maxCombinedOutputBytes: cap } : {}),
onOutputChunk(chunk, stream) {
assert.equal(stream, "stdout");
if (bytes < cap && bytes + chunk.byteLength > cap) {
clipped = new WeakRef(chunk.buffer);
}
bytes += chunk.byteLength;
if (bytes === emittedBytes) {
output.resolve();
}
},
},
);
try {
await Promise.race([
output.promise,
command.then(() => {
throw new Error("Command finished before the retention checkpoint");
}),
]);
assert.ok(clipped, "The child must emit a buffer crossing the capture boundary");
// Dereferencing during collection would keep the target alive for that job.
for (let pass = 0; pass < 8; pass += 1) {
await setImmediate();
gc();
}
assert.equal(control.deref(), undefined, "The uncached GC control must be collected");
observed.push({ mode, retained: clipped.deref() !== undefined });
} finally {
abort.abort();
const result = await command;
assert.equal(result.stdout, "X".repeat(cap));
assert.equal(result.stderr, "");
assert.equal(result.stdoutTruncatedBytes, emittedBytes - cap);
assert.equal(result.termination, "signal");
}
}
process.stdout.write(JSON.stringify(observed));
|