mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
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:
parent
321a14b36d
commit
2bd0f99e77
@ -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();
|
||||||
}
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user