test: update test-abortsignal-cloneable to use node:test

PR-URL: https://github.com/nodejs/node/pull/54581
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
James M Snell 2024-08-26 18:52:27 -07:00
parent 321a14b36d
commit 2bd0f99e77

View File

@ -1,83 +1,91 @@
'use strict'; 'use strict';
const common = require('../common'); require('../common');
const { ok, strictEqual } = require('assert'); const { ok, strictEqual } = require('assert');
const { setImmediate: pause } = require('timers/promises'); const { setImmediate: sleep } = require('timers/promises');
const { const {
transferableAbortSignal, transferableAbortSignal,
transferableAbortController, transferableAbortController,
} = require('util'); } = require('util');
const {
test,
mock,
} = require('node:test');
test('Can create a transferable abort controller', async () => {
function deferred() {
let res;
const promise = new Promise((resolve) => res = resolve);
return { res, promise };
}
(async () => {
const ac = transferableAbortController(); const ac = transferableAbortController();
const mc = new MessageChannel(); const mc = new MessageChannel();
const deferred1 = deferred(); const setup1 = Promise.withResolvers();
const deferred2 = deferred(); const setup2 = Promise.withResolvers();
const resolvers = [deferred1, deferred2]; const setupResolvers = [setup1, setup2];
mc.port1.onmessage = common.mustCall(({ data }) => { const abort1 = Promise.withResolvers();
data.addEventListener('abort', common.mustCall(() => { const abort2 = Promise.withResolvers();
const abort3 = Promise.withResolvers();
const abortResolvers = [abort1, abort2, abort3];
mc.port1.onmessage = ({ data }) => {
data.addEventListener('abort', () => {
strictEqual(data.reason, 'boom'); strictEqual(data.reason, 'boom');
})); abortResolvers.shift().resolve();
resolvers.shift().res(); });
}, 2); setupResolvers.shift().resolve();
};
mc.port2.postMessage(ac.signal, [ac.signal]); mc.port2.postMessage(ac.signal, [ac.signal]);
// Can be cloned/transferd multiple times and they all still work // Can be cloned/transferd multiple times and they all still work
mc.port2.postMessage(ac.signal, [ac.signal]); mc.port2.postMessage(ac.signal, [ac.signal]);
mc.port2.close();
// Although we're using transfer semantics, the local AbortSignal // Although we're using transfer semantics, the local AbortSignal
// is still usable locally. // is still usable locally.
ac.signal.addEventListener('abort', common.mustCall(() => { ac.signal.addEventListener('abort', () => {
strictEqual(ac.signal.reason, 'boom'); strictEqual(ac.signal.reason, 'boom');
})); abortResolvers.shift().resolve();
});
await Promise.all([ deferred1.promise, deferred2.promise ]); await Promise.all([ setup1.promise, setup2.promise ]);
ac.abort('boom'); ac.abort('boom');
await Promise.all([ abort1.promise, abort2.promise, abort3.promise ]);
mc.port2.close();
});
test('Can create a transferable abort signal', async () => {
const signal = transferableAbortSignal(AbortSignal.abort('boom'));
ok(signal.aborted);
strictEqual(signal.reason, 'boom');
const mc = new MessageChannel();
const { promise, resolve } = Promise.withResolvers();
mc.port1.onmessage = ({ data }) => {
ok(data instanceof AbortSignal);
ok(data.aborted);
strictEqual(data.reason, 'boom');
resolve();
};
mc.port2.postMessage(signal, [signal]);
await promise;
mc.port1.close();
});
test('A cloned AbortSignal does not keep the event loop open', async () => {
const ac = transferableAbortController();
const mc = new MessageChannel();
const fn = mock.fn();
mc.port1.onmessage = fn;
mc.port2.postMessage(ac.signal, [ac.signal]);
// Because the postMessage used by the underlying AbortSignal // Because the postMessage used by the underlying AbortSignal
// takes at least one turn of the event loop to be processed, // takes at least one turn of the event loop to be processed,
// and because it is unref'd, it won't, by itself, keep the // and because it is unref'd, it won't, by itself, keep the
// event loop open long enough for the test to complete, so // event loop open long enough for the test to complete, so
// we schedule two back to back turns of the event to ensure // we schedule two back to back turns of the event to ensure
// the loop runs long enough for the test to complete. // the loop runs long enough for the test to complete.
await pause(); await sleep();
await pause(); await sleep();
strictEqual(fn.mock.calls.length, 1);
})().then(common.mustCall());
{
const signal = transferableAbortSignal(AbortSignal.abort('boom'));
ok(signal.aborted);
strictEqual(signal.reason, 'boom');
const mc = new MessageChannel();
mc.port1.onmessage = common.mustCall(({ data }) => {
ok(data instanceof AbortSignal);
ok(data.aborted);
strictEqual(data.reason, 'boom');
mc.port1.close();
});
mc.port2.postMessage(signal, [signal]);
}
{
// The cloned AbortSignal does not keep the event loop open
// waiting for the abort to be triggered.
const ac = transferableAbortController();
const mc = new MessageChannel();
mc.port1.onmessage = common.mustCall();
mc.port2.postMessage(ac.signal, [ac.signal]);
mc.port2.close(); mc.port2.close();
} });