summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-08-25 21:48:58 +0200
committerDaniel Bevenius <daniel.bevenius@gmail.com>2019-09-06 06:12:47 +0200
commit72650bcf7283c7b9eb9df9154f981eabdf8c523a (patch)
tree771b2eb895d9cc0d72a9bbf2d99ef2fba2939722 /test
parent754d5a9375beecd95ab7f26de769259ee090e5f6 (diff)
downloadandroid-node-v8-72650bcf7283c7b9eb9df9154f981eabdf8c523a.tar.gz
android-node-v8-72650bcf7283c7b9eb9df9154f981eabdf8c523a.tar.bz2
android-node-v8-72650bcf7283c7b9eb9df9154f981eabdf8c523a.zip
worker: make transfer list behave like web MessagePort
Allow generic iterables as transfer list arguments, as well as an options object with a `transfer` option, for web compatibility. PR-URL: https://github.com/nodejs/node/pull/29319 Refs: https://github.com/nodejs/node/pull/28033#discussion_r289964991 Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'test')
-rw-r--r--test/parallel/test-worker-message-port-terminate-transfer-list.js26
-rw-r--r--test/parallel/test-worker-message-port.js63
2 files changed, 87 insertions, 2 deletions
diff --git a/test/parallel/test-worker-message-port-terminate-transfer-list.js b/test/parallel/test-worker-message-port-terminate-transfer-list.js
new file mode 100644
index 0000000000..a066405d9d
--- /dev/null
+++ b/test/parallel/test-worker-message-port-terminate-transfer-list.js
@@ -0,0 +1,26 @@
+'use strict';
+const common = require('../common');
+
+const { parentPort, MessageChannel, Worker } = require('worker_threads');
+
+// Do not use isMainThread so that this test itself can be run inside a Worker.
+if (!process.env.HAS_STARTED_WORKER) {
+ process.env.HAS_STARTED_WORKER = 1;
+ const w = new Worker(__filename);
+ w.once('message', common.mustCall(() => {
+ w.once('message', common.mustNotCall());
+ setTimeout(() => w.terminate(), 100);
+ }));
+} else {
+ const { port1 } = new MessageChannel();
+
+ parentPort.postMessage('ready');
+
+ // Make sure we don’t end up running JS after the infinite loop is broken.
+ port1.postMessage({}, {
+ transfer: (function*() { while (true); })()
+ });
+
+ parentPort.postMessage('UNREACHABLE');
+ process.kill(process.pid, 'SIGINT');
+}
diff --git a/test/parallel/test-worker-message-port.js b/test/parallel/test-worker-message-port.js
index d1c58216fd..d128dc7edb 100644
--- a/test/parallel/test-worker-message-port.js
+++ b/test/parallel/test-worker-message-port.js
@@ -72,22 +72,81 @@ const { MessageChannel, MessagePort } = require('worker_threads');
{
const { port1, port2 } = new MessageChannel();
- port2.on('message', common.mustCall(4));
+ port2.on('message', common.mustCall(6));
port1.postMessage(1, null);
port1.postMessage(2, undefined);
port1.postMessage(3, []);
port1.postMessage(4, {});
+ port1.postMessage(5, { transfer: undefined });
+ port1.postMessage(6, { transfer: [] });
const err = {
constructor: TypeError,
code: 'ERR_INVALID_ARG_TYPE',
- message: 'Optional transferList argument must be an array'
+ message: 'Optional transferList argument must be an iterable'
};
assert.throws(() => port1.postMessage(5, 0), err);
assert.throws(() => port1.postMessage(5, false), err);
assert.throws(() => port1.postMessage(5, 'X'), err);
assert.throws(() => port1.postMessage(5, Symbol('X')), err);
+
+ const err2 = {
+ constructor: TypeError,
+ code: 'ERR_INVALID_ARG_TYPE',
+ message: 'Optional options.transfer argument must be an iterable'
+ };
+
+ assert.throws(() => port1.postMessage(5, { transfer: null }), err2);
+ assert.throws(() => port1.postMessage(5, { transfer: 0 }), err2);
+ assert.throws(() => port1.postMessage(5, { transfer: false }), err2);
+ assert.throws(() => port1.postMessage(5, { transfer: {} }), err2);
+ assert.throws(() => port1.postMessage(5, {
+ transfer: { [Symbol.iterator]() { return {}; } }
+ }), err2);
+ assert.throws(() => port1.postMessage(5, {
+ transfer: { [Symbol.iterator]() { return { next: 42 }; } }
+ }), err2);
+ assert.throws(() => port1.postMessage(5, {
+ transfer: { [Symbol.iterator]() { return { next: null }; } }
+ }), err2);
+ port1.close();
+}
+
+{
+ // Make sure these ArrayBuffers end up detached, i.e. are actually being
+ // transferred because the transfer list provides them.
+ const { port1, port2 } = new MessageChannel();
+ port2.on('message', common.mustCall((msg) => {
+ assert.strictEqual(msg.ab.byteLength, 10);
+ }, 4));
+
+ {
+ const ab = new ArrayBuffer(10);
+ port1.postMessage({ ab }, [ ab ]);
+ assert.strictEqual(ab.byteLength, 0);
+ }
+
+ {
+ const ab = new ArrayBuffer(10);
+ port1.postMessage({ ab }, { transfer: [ ab ] });
+ assert.strictEqual(ab.byteLength, 0);
+ }
+
+ {
+ const ab = new ArrayBuffer(10);
+ port1.postMessage({ ab }, (function*() { yield ab; })());
+ assert.strictEqual(ab.byteLength, 0);
+ }
+
+ {
+ const ab = new ArrayBuffer(10);
+ port1.postMessage({ ab }, {
+ transfer: (function*() { yield ab; })()
+ });
+ assert.strictEqual(ab.byteLength, 0);
+ }
+
port1.close();
}