summaryrefslogtreecommitdiff
path: root/cli/tests/workers/test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tests/workers/test.ts')
-rw-r--r--cli/tests/workers/test.ts852
1 files changed, 0 insertions, 852 deletions
diff --git a/cli/tests/workers/test.ts b/cli/tests/workers/test.ts
deleted file mode 100644
index 44cbca0fe..000000000
--- a/cli/tests/workers/test.ts
+++ /dev/null
@@ -1,852 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-
-// Requires to be run with `--allow-net` flag
-
-import {
- assert,
- assertEquals,
- assertThrows,
-} from "../../../test_util/std/testing/asserts.ts";
-import { deferred } from "../../../test_util/std/async/deferred.ts";
-import { fromFileUrl } from "../../../test_util/std/path/mod.ts";
-
-Deno.test({
- name: "worker terminate",
- fn: async function () {
- const promise = deferred();
-
- const jsWorker = new Worker(
- new URL("test_worker.js", import.meta.url).href,
- { type: "module" },
- );
- const tsWorker = new Worker(
- new URL("test_worker.ts", import.meta.url).href,
- { type: "module", name: "tsWorker" },
- );
-
- tsWorker.onmessage = (e) => {
- assertEquals(e.data, "Hello World");
- promise.resolve();
- };
-
- jsWorker.onmessage = (e) => {
- assertEquals(e.data, "Hello World");
- tsWorker.postMessage("Hello World");
- };
-
- jsWorker.onerror = (e: Event) => {
- e.preventDefault();
- jsWorker.postMessage("Hello World");
- };
-
- jsWorker.postMessage("Hello World");
- await promise;
- tsWorker.terminate();
- jsWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker from data url",
- async fn() {
- const promise = deferred();
- const tsWorker = new Worker(
- "data:application/typescript;base64,aWYgKHNlbGYubmFtZSAhPT0gInRzV29ya2VyIikgewogIHRocm93IEVycm9yKGBJbnZhbGlkIHdvcmtlciBuYW1lOiAke3NlbGYubmFtZX0sIGV4cGVjdGVkIHRzV29ya2VyYCk7Cn0KCm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKTogdm9pZCB7CiAgcG9zdE1lc3NhZ2UoZS5kYXRhKTsKICBjbG9zZSgpOwp9Owo=",
- { type: "module", name: "tsWorker" },
- );
-
- tsWorker.onmessage = (e) => {
- assertEquals(e.data, "Hello World");
- promise.resolve();
- };
-
- tsWorker.postMessage("Hello World");
-
- await promise;
- tsWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker nested",
- fn: async function () {
- const promise = deferred();
-
- const nestedWorker = new Worker(
- new URL("nested_worker.js", import.meta.url).href,
- { type: "module", name: "nested" },
- );
-
- nestedWorker.onmessage = (e) => {
- assert(e.data.type !== "error");
- promise.resolve();
- };
-
- nestedWorker.postMessage("Hello World");
- await promise;
- nestedWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker throws when executing",
- fn: async function () {
- const promise = deferred();
- const throwingWorker = new Worker(
- new URL("throwing_worker.js", import.meta.url).href,
- { type: "module" },
- );
-
- // deno-lint-ignore no-explicit-any
- throwingWorker.onerror = (e: any) => {
- e.preventDefault();
- assert(/Uncaught Error: Thrown error/.test(e.message));
- promise.resolve();
- };
-
- await promise;
- throwingWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker globals",
- fn: async function () {
- const promise = deferred();
- const workerOptions: WorkerOptions = { type: "module" };
- const w = new Worker(
- new URL("worker_globals.ts", import.meta.url).href,
- workerOptions,
- );
- w.onmessage = (e) => {
- assertEquals(e.data, "true, true, true, true");
- promise.resolve();
- };
- w.postMessage("Hello, world!");
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker fetch API",
- fn: async function () {
- const promise = deferred();
-
- const fetchingWorker = new Worker(
- new URL("fetching_worker.js", import.meta.url).href,
- { type: "module" },
- );
-
- // deno-lint-ignore no-explicit-any
- fetchingWorker.onerror = (e: any) => {
- e.preventDefault();
- promise.reject(e.message);
- };
-
- // Defer promise.resolve() to allow worker to shut down
- fetchingWorker.onmessage = (e) => {
- assert(e.data === "Done!");
- promise.resolve();
- };
-
- await promise;
- fetchingWorker.terminate();
- },
-});
-
-Deno.test({
- name: "worker terminate busy loop",
- fn: async function () {
- const promise = deferred();
-
- const busyWorker = new Worker(
- new URL("busy_worker.js", import.meta.url),
- { type: "module" },
- );
-
- let testResult = 0;
-
- busyWorker.onmessage = (e) => {
- testResult = e.data;
- if (testResult >= 10000) {
- busyWorker.terminate();
- busyWorker.onmessage = (_e) => {
- throw new Error("unreachable");
- };
- setTimeout(() => {
- assertEquals(testResult, 10000);
- promise.resolve();
- }, 100);
- }
- };
-
- busyWorker.postMessage("ping");
- await promise;
- },
-});
-
-Deno.test({
- name: "worker race condition",
- fn: async function () {
- // See issue for details
- // https://github.com/denoland/deno/issues/4080
- const promise = deferred();
-
- const racyWorker = new Worker(
- new URL("racy_worker.js", import.meta.url),
- { type: "module" },
- );
-
- racyWorker.onmessage = (_e) => {
- setTimeout(() => {
- promise.resolve();
- }, 100);
- };
-
- racyWorker.postMessage("START");
- await promise;
- },
-});
-
-Deno.test({
- name: "worker is event listener",
- fn: async function () {
- let messageHandlersCalled = 0;
- let errorHandlersCalled = 0;
-
- const promise1 = deferred();
- const promise2 = deferred();
-
- const worker = new Worker(
- new URL("event_worker.js", import.meta.url),
- { type: "module" },
- );
-
- worker.onmessage = (_e: Event) => {
- messageHandlersCalled++;
- };
- worker.addEventListener("message", (_e: Event) => {
- messageHandlersCalled++;
- });
- worker.addEventListener("message", (_e: Event) => {
- messageHandlersCalled++;
- promise1.resolve();
- });
-
- worker.onerror = (e) => {
- errorHandlersCalled++;
- e.preventDefault();
- };
- worker.addEventListener("error", (_e: Event) => {
- errorHandlersCalled++;
- });
- worker.addEventListener("error", (_e: Event) => {
- errorHandlersCalled++;
- promise2.resolve();
- });
-
- worker.postMessage("ping");
- await promise1;
- assertEquals(messageHandlersCalled, 3);
-
- worker.postMessage("boom");
- await promise2;
- assertEquals(errorHandlersCalled, 3);
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker scope is event listener",
- fn: async function () {
- const promise1 = deferred();
-
- const worker = new Worker(
- new URL("event_worker_scope.js", import.meta.url),
- { type: "module" },
- );
-
- worker.onmessage = (e: MessageEvent) => {
- const { messageHandlersCalled, errorHandlersCalled } = e.data;
- assertEquals(messageHandlersCalled, 4);
- assertEquals(errorHandlersCalled, 4);
- promise1.resolve();
- };
-
- worker.onerror = (_e) => {
- throw new Error("unreachable");
- };
-
- worker.postMessage("boom");
- worker.postMessage("ping");
- await promise1;
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker with Deno namespace",
- fn: async function () {
- const promise = deferred();
- const promise2 = deferred();
-
- const regularWorker = new Worker(
- new URL("non_deno_worker.js", import.meta.url),
- { type: "module" },
- );
- const denoWorker = new Worker(
- new URL("deno_worker.ts", import.meta.url),
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: "inherit",
- },
- },
- );
-
- regularWorker.onmessage = (e) => {
- assertEquals(e.data, "Hello World");
- regularWorker.terminate();
- promise.resolve();
- };
-
- denoWorker.onmessage = (e) => {
- assertEquals(e.data, "Hello World");
- denoWorker.terminate();
- promise2.resolve();
- };
-
- regularWorker.postMessage("Hello World");
- await promise;
- denoWorker.postMessage("Hello World");
- await promise2;
- },
-});
-
-Deno.test({
- name: "worker with crypto in scope",
- fn: async function () {
- const promise = deferred();
- const w = new Worker(
- new URL("worker_crypto.js", import.meta.url).href,
- { type: "module" },
- );
- w.onmessage = (e) => {
- assertEquals(e.data, true);
- promise.resolve();
- };
- w.postMessage(null);
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker event handler order",
- fn: async function () {
- const promise = deferred();
- const w = new Worker(
- new URL("test_worker.ts", import.meta.url).href,
- { type: "module", name: "tsWorker" },
- );
- const arr: number[] = [];
- w.addEventListener("message", () => arr.push(1));
- w.onmessage = (_e) => {
- arr.push(2);
- };
- w.addEventListener("message", () => arr.push(3));
- w.addEventListener("message", () => {
- assertEquals(arr, [1, 2, 3]);
- promise.resolve();
- });
- w.postMessage("Hello World");
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker immediate close",
- fn: async function () {
- const promise = deferred();
- const w = new Worker(
- new URL("./immediately_close_worker.js", import.meta.url).href,
- { type: "module" },
- );
- setTimeout(() => {
- promise.resolve();
- }, 1000);
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker post undefined",
- fn: async function () {
- const promise = deferred();
- const worker = new Worker(
- new URL("./post_undefined.ts", import.meta.url).href,
- { type: "module" },
- );
-
- const handleWorkerMessage = (e: MessageEvent) => {
- console.log("main <- worker:", e.data);
- worker.terminate();
- promise.resolve();
- };
-
- worker.addEventListener("messageerror", () => console.log("message error"));
- worker.addEventListener("error", () => console.log("error"));
- worker.addEventListener("message", handleWorkerMessage);
-
- console.log("\npost from parent");
- worker.postMessage(undefined);
- await promise;
- },
-});
-
-Deno.test("Worker inherits permissions", async function () {
- const promise = deferred();
- const worker = new Worker(
- new URL("./read_check_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: "inherit",
- },
- },
- );
-
- worker.onmessage = ({ data: hasPermission }) => {
- assert(hasPermission);
- promise.resolve();
- };
-
- worker.postMessage(null);
-
- await promise;
- worker.terminate();
-});
-
-Deno.test("Worker limit children permissions", async function () {
- const promise = deferred();
- const worker = new Worker(
- new URL("./read_check_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- read: false,
- },
- },
- },
- );
-
- worker.onmessage = ({ data: hasPermission }) => {
- assert(!hasPermission);
- promise.resolve();
- };
-
- worker.postMessage(null);
-
- await promise;
- worker.terminate();
-});
-
-Deno.test("Worker limit children permissions granularly", async function () {
- const promise = deferred();
- const worker = new Worker(
- new URL("./read_check_granular_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- read: [
- new URL("./read_check_worker.js", import.meta.url),
- ],
- },
- },
- },
- );
-
- //Routes are relative to the spawned worker location
- const routes = [
- {
- permission: false,
- path: fromFileUrl(
- new URL("read_check_granular_worker.js", import.meta.url),
- ),
- },
- {
- permission: true,
- path: fromFileUrl(new URL("read_check_worker.js", import.meta.url)),
- },
- ];
-
- let checked = 0;
- worker.onmessage = ({ data }) => {
- checked++;
- assertEquals(data.hasPermission, routes[data.index].permission);
- routes.shift();
- if (checked === routes.length) {
- promise.resolve();
- }
- };
-
- routes.forEach(({ path }, index) =>
- worker.postMessage({
- index,
- path,
- })
- );
-
- await promise;
- worker.terminate();
-});
-
-Deno.test("Nested worker limit children permissions", async function () {
- const promise = deferred();
-
- /** This worker has read permissions but doesn't grant them to its children */
- const worker = new Worker(
- new URL("./parent_read_check_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: "inherit",
- },
- },
- );
-
- worker.onmessage = ({ data }) => {
- assert(data.parentHasPermission);
- assert(!data.childHasPermission);
- promise.resolve();
- };
-
- worker.postMessage(null);
-
- await promise;
- worker.terminate();
-});
-
-Deno.test("Nested worker limit children permissions granularly", async function () {
- const promise = deferred();
-
- /** This worker has read permissions but doesn't grant them to its children */
- const worker = new Worker(
- new URL("./parent_read_check_granular_worker.js", import.meta.url)
- .href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- read: [
- new URL("./read_check_granular_worker.js", import.meta.url),
- ],
- },
- },
- },
- );
-
- //Routes are relative to the spawned worker location
- const routes = [
- {
- childHasPermission: false,
- parentHasPermission: true,
- path: fromFileUrl(
- new URL("read_check_granular_worker.js", import.meta.url),
- ),
- },
- {
- childHasPermission: false,
- parentHasPermission: false,
- path: fromFileUrl(new URL("read_check_worker.js", import.meta.url)),
- },
- ];
-
- let checked = 0;
- worker.onmessage = ({ data }) => {
- checked++;
- assertEquals(
- data.childHasPermission,
- routes[data.index].childHasPermission,
- );
- assertEquals(
- data.parentHasPermission,
- routes[data.index].parentHasPermission,
- );
- if (checked === routes.length) {
- promise.resolve();
- }
- };
-
- // Index needed cause requests will be handled asynchronously
- routes.forEach(({ path }, index) =>
- worker.postMessage({
- index,
- path,
- })
- );
-
- await promise;
- worker.terminate();
-});
-
-// This test relies on env permissions not being granted on main thread
-Deno.test("Worker initialization throws on worker permissions greater than parent thread permissions", function () {
- assertThrows(
- () => {
- const worker = new Worker(
- new URL("./deno_worker.ts", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: {
- env: true,
- },
- },
- },
- );
- worker.terminate();
- },
- Deno.errors.PermissionDenied,
- "Can't escalate parent thread permissions",
- );
-});
-
-Deno.test("Worker with disabled permissions", async function () {
- const promise = deferred();
-
- const worker = new Worker(
- new URL("./no_permissions_worker.js", import.meta.url).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: "none",
- },
- },
- );
-
- worker.onmessage = ({ data: sandboxed }) => {
- assert(sandboxed);
- promise.resolve();
- };
-
- worker.postMessage(null);
- await promise;
- worker.terminate();
-});
-
-Deno.test({
- name: "worker location",
- fn: async function () {
- const promise = deferred();
- const workerModuleHref =
- new URL("worker_location.ts", import.meta.url).href;
- const w = new Worker(workerModuleHref, { type: "module" });
- w.onmessage = (e) => {
- assertEquals(e.data, `${workerModuleHref}, true`);
- promise.resolve();
- };
- w.postMessage("Hello, world!");
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker with relative specifier",
- fn: async function () {
- assertEquals(location.href, "http://127.0.0.1:4545/cli/tests/");
- const promise = deferred();
- const w = new Worker(
- "./workers/test_worker.ts",
- { type: "module", name: "tsWorker" },
- );
- w.onmessage = (e) => {
- assertEquals(e.data, "Hello, world!");
- promise.resolve();
- };
- w.postMessage("Hello, world!");
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Worker with top-level-await",
- fn: async function () {
- const result = deferred();
- const worker = new Worker(
- new URL("worker_with_top_level_await.ts", import.meta.url).href,
- { type: "module" },
- );
- worker.onmessage = (e) => {
- if (e.data == "ready") {
- worker.postMessage("trigger worker handler");
- } else if (e.data == "triggered worker handler") {
- result.resolve();
- } else {
- result.reject(new Error("Handler didn't run during top-level delay."));
- }
- };
- await result;
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "Worker with native HTTP",
- fn: async function () {
- const result = deferred();
- const worker = new Worker(
- new URL(
- "./http_worker.js",
- import.meta.url,
- ).href,
- {
- type: "module",
- deno: {
- namespace: true,
- permissions: "inherit",
- },
- },
- );
- worker.onmessage = () => {
- result.resolve();
- };
- await result;
-
- assert(worker);
- const response = await fetch("http://localhost:4506");
- assert(await response.arrayBuffer());
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "structured cloning postMessage",
- fn: async function () {
- const result = deferred();
- const worker = new Worker(
- new URL("worker_structured_cloning.ts", import.meta.url).href,
- { type: "module" },
- );
-
- worker.onmessage = (e) => {
- // self field should reference itself (circular ref)
- const value = e.data.self.self.self;
-
- // fields a and b refer to the same array
- assertEquals(value.a, ["a", true, 432]);
- assertEquals(value.a, ["a", true, 432]);
- value.b[0] = "b";
- value.a[2] += 5;
- assertEquals(value.a, ["b", true, 437]);
- assertEquals(value.b, ["b", true, 437]);
-
- const len = value.c.size;
- value.c.add(1); // This value is already in the set.
- value.c.add(2);
- assertEquals(len + 1, value.c.size);
-
- result.resolve();
- };
-
- worker.postMessage("START");
- await result;
- worker.terminate();
- },
-});
-
-Deno.test({
- name: "worker with relative specifier",
- fn: async function () {
- assertEquals(location.href, "http://127.0.0.1:4545/cli/tests/");
- const promise = deferred();
- const w = new Worker(
- "./workers/test_worker.ts",
- { type: "module", name: "tsWorker" },
- );
- w.onmessage = (e) => {
- assertEquals(e.data, "Hello, world!");
- promise.resolve();
- };
- w.postMessage("Hello, world!");
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "worker SharedArrayBuffer",
- fn: async function () {
- const promise = deferred();
- const workerOptions: WorkerOptions = { type: "module" };
- const w = new Worker(
- new URL("shared_array_buffer.ts", import.meta.url).href,
- workerOptions,
- );
- const sab1 = new SharedArrayBuffer(1);
- const sab2 = new SharedArrayBuffer(1);
- const bytes1 = new Uint8Array(sab1);
- const bytes2 = new Uint8Array(sab2);
- assertEquals(bytes1[0], 0);
- assertEquals(bytes2[0], 0);
- w.onmessage = () => {
- w.postMessage([sab1, sab2]);
- w.onmessage = () => {
- assertEquals(bytes1[0], 1);
- assertEquals(bytes2[0], 2);
- promise.resolve();
- };
- };
- await promise;
- w.terminate();
- },
-});
-
-Deno.test({
- name: "Send MessagePorts from / to workers",
- fn: async function () {
- const result = deferred();
- const worker = new Worker(
- new URL("message_port.ts", import.meta.url).href,
- { type: "module" },
- );
-
- const channel = new MessageChannel();
-
- worker.onmessage = (e) => {
- assertEquals(e.data, "1");
- assertEquals(e.ports.length, 1);
- const port1 = e.ports[0];
- port1.onmessage = (e) => {
- assertEquals(e.data, true);
- port1.close();
- worker.postMessage("3", [channel.port1]);
- };
- port1.postMessage("2");
- };
-
- channel.port2.onmessage = (e) => {
- assertEquals(e.data, true);
- channel.port2.close();
- result.resolve();
- };
-
- await result;
- worker.terminate();
- },
-});