mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
Release the slow fixture over a local socket after the fast fixture emits its bypassed completion event. This removes the fixed 30-second delay while preserving event-order assertions and a bounded failure timeout. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: https://github.com/nodejs/node/pull/65980 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: LiviaMedeiros <livia@cirno.name>
91 lines
2.8 KiB
JavaScript
91 lines
2.8 KiB
JavaScript
// Flags: --no-warnings
|
|
|
|
import { mustCall, platformTimeout } from '../common/index.mjs';
|
|
import * as fixtures from '../common/fixtures.mjs';
|
|
import assert from 'node:assert';
|
|
import { once } from 'node:events';
|
|
import { createServer } from 'node:net';
|
|
import { test, run } from 'node:test';
|
|
|
|
const files = [
|
|
fixtures.path('test-runner', 'execution-ordered-bypass', 'slow.mjs'),
|
|
fixtures.path('test-runner', 'execution-ordered-bypass', 'fast-fail.mjs'),
|
|
];
|
|
|
|
test('execution-ordered events bypass FileTest declaration-order buffer', {
|
|
timeout: platformTimeout(30_000),
|
|
}, async (t) => {
|
|
const { promise: fastCompleted, resolve: releaseSlow } = Promise.withResolvers();
|
|
const server = createServer(mustCall((socket) => {
|
|
t.after(() => socket.destroy());
|
|
fastCompleted.then(mustCall(() => {
|
|
socket.end();
|
|
}));
|
|
}));
|
|
t.after(() => server.close());
|
|
await once(server.listen(0, '127.0.0.1'), 'listening');
|
|
|
|
// Concurrency must be a number so the runner does not collapse it to 1 on
|
|
// single-core CI runners (where `concurrency: true` resolves to
|
|
// `availableParallelism() - 1`). Without two slots the runner spawns the
|
|
// files sequentially and fast-fail never starts while slow is waiting.
|
|
const stream = run({
|
|
files,
|
|
isolation: 'process',
|
|
concurrency: 2,
|
|
argv: [String(server.address().port)],
|
|
signal: t.signal,
|
|
});
|
|
|
|
const events = [];
|
|
|
|
stream.on('test:complete', (data) => {
|
|
if (data.name === 'slow' || data.name === 'fast-fail') {
|
|
events.push(`complete:${data.name}`);
|
|
}
|
|
if (data.name === 'fast-fail') {
|
|
releaseSlow();
|
|
}
|
|
});
|
|
|
|
stream.on('test:fail', (data) => {
|
|
if (data.name === 'fast-fail') {
|
|
events.push(`fail:${data.name}`);
|
|
}
|
|
});
|
|
|
|
stream.on('test:log', (data) => {
|
|
events.push(`log:${data.message}`);
|
|
});
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
for await (const _ of stream);
|
|
|
|
const completeFast = events.indexOf('complete:fast-fail');
|
|
const completeSlow = events.indexOf('complete:slow');
|
|
const failFast = events.indexOf('fail:fast-fail');
|
|
|
|
assert.notStrictEqual(completeFast, -1);
|
|
assert.notStrictEqual(completeSlow, -1);
|
|
assert.notStrictEqual(failFast, -1);
|
|
|
|
assert.ok(
|
|
completeFast < completeSlow,
|
|
`test:complete for fast-fail should arrive before slow; events=${events.join(', ')}`,
|
|
);
|
|
|
|
// test:fail is declaration-ordered, so the bypass must not affect it.
|
|
assert.ok(
|
|
failFast > completeSlow,
|
|
`test:fail for fast-fail should arrive after test:complete for slow; events=${events.join(', ')}`,
|
|
);
|
|
|
|
// test:log is execution-ordered, so it must bypass the buffer too.
|
|
const logFast = events.indexOf('log:live');
|
|
assert.notStrictEqual(logFast, -1);
|
|
assert.ok(
|
|
logFast < completeSlow,
|
|
`test:log for fast-fail should arrive before slow's test:complete; events=${events.join(', ')}`,
|
|
);
|
|
});
|