1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

chore: Promote some integration tests to js_unit_tests (#22355)

- Move a workers test to js_unit_tests and make it work
- (slightly) repair the websocketstream_test and make it a JS unit test.
This test was being ignored and rotted quite a bit, but there's some
value in running as much of it as we can.
 - Merge the two websocket test files
This commit is contained in:
Matt Mastracci 2024-02-08 13:09:47 -07:00 committed by GitHub
parent d704007e5f
commit a417772bd7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 440 additions and 495 deletions

View file

@ -105,9 +105,10 @@ util::unit_test_factory!(
webcrypto_test, webcrypto_test,
webgpu_test, webgpu_test,
websocket_test, websocket_test,
websocketstream_test,
webstorage_test, webstorage_test,
worker_permissions_test, worker_permissions_test,
worker_types, worker_test,
write_file_test, write_file_test,
write_text_file_test, write_text_file_test,
] ]
@ -123,7 +124,7 @@ fn js_unit_test(test: String) {
.arg("cli/tests/config/deno.json") .arg("cli/tests/config/deno.json")
.arg("--no-lock") .arg("--no-lock")
.arg("--unstable") .arg("--unstable")
.arg("--location=http://js-unit-tests/foo/bar") .arg("--location=http://127.0.0.1:4545/")
.arg("--no-prompt"); .arg("--no-prompt");
// TODO(mmastrac): it would be better to just load a test CA for all tests // TODO(mmastrac): it would be better to just load a test CA for all tests

View file

@ -4390,49 +4390,6 @@ itest!(ext_flag_takes_precedence_over_extension {
exit_code: 0, exit_code: 0,
}); });
#[test]
fn websocket() {
let _g = util::http_server();
let script = util::testdata_path().join("run/websocket_test.ts");
let root_ca = util::testdata_path().join("tls/RootCA.pem");
let status = util::deno_cmd()
.arg("test")
.arg("--unstable")
.arg("--allow-net")
.arg("--cert")
.arg(root_ca)
.arg(script)
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(status.success());
}
#[ignore]
#[test]
fn websocketstream() {
let _g = util::http_server();
let script = util::testdata_path().join("run/websocketstream_test.ts");
let root_ca = util::testdata_path().join("tls/RootCA.pem");
let status = util::deno_cmd()
.arg("test")
.arg("--unstable")
.arg("--allow-net")
.arg("--cert")
.arg(root_ca)
.arg(script)
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(status.success());
}
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn websocketstream_ping() { async fn websocketstream_ping() {
let _g = util::http_server(); let _g = util::http_server();

View file

@ -1,11 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
itest!(workers {
args: "test --reload --location http://127.0.0.1:4545/ -A --unstable-worker-options workers/test.ts",
output: "workers/test.ts.out",
http_server: true,
});
itest!(worker_error { itest!(worker_error {
args: "run -A workers/worker_error.ts", args: "run -A workers/worker_error.ts",
output: "workers/worker_error.ts.out", output: "workers/worker_error.ts.out",

View file

@ -1,308 +0,0 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import {
assert,
assertEquals,
assertThrows,
fail,
} from "../../../../test_util/std/assert/mod.ts";
Deno.test("invalid scheme", () => {
assertThrows(() => new WebSocket("foo://localhost:4242"));
});
Deno.test("fragment", () => {
assertThrows(() => new WebSocket("ws://localhost:4242/#"));
assertThrows(() => new WebSocket("ws://localhost:4242/#foo"));
});
Deno.test("duplicate protocols", () => {
assertThrows(() => new WebSocket("ws://localhost:4242", ["foo", "foo"]));
});
Deno.test("invalid server", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:2121");
let err = false;
ws.onerror = () => {
err = true;
};
ws.onclose = () => {
if (err) {
resolve();
} else {
fail();
}
};
ws.onopen = () => fail();
await promise;
});
Deno.test("connect & close", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => {
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & abort", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.close();
let err = false;
ws.onerror = () => {
err = true;
};
ws.onclose = () => {
if (err) {
resolve();
} else {
fail();
}
};
ws.onopen = () => fail();
await promise;
});
Deno.test("connect & close custom valid code", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => ws.close(1000);
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & close custom invalid code", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => {
assertThrows(() => ws.close(1001));
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & close custom valid reason", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => ws.close(1000, "foo");
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & close custom invalid reason", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => {
assertThrows(() => ws.close(1000, "".padEnd(124, "o")));
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo string", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => ws.send("foo");
ws.onmessage = (e) => {
assertEquals(e.data, "foo");
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo string tls", async () => {
const deferred1 = Promise.withResolvers<void>();
const deferred2 = Promise.withResolvers<void>();
const ws = new WebSocket("wss://localhost:4243");
ws.onerror = () => fail();
ws.onopen = () => ws.send("foo");
ws.onmessage = (e) => {
assertEquals(e.data, "foo");
ws.close();
deferred1.resolve();
};
ws.onclose = () => {
deferred2.resolve();
};
await deferred1.promise;
await deferred2.promise;
});
Deno.test("websocket error", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("wss://localhost:4242");
ws.onopen = () => fail();
ws.onerror = (err) => {
assert(err instanceof ErrorEvent);
assertEquals(
err.message,
"NetworkError: failed to connect to WebSocket: received corrupt message of type InvalidContentType",
);
resolve();
};
await promise;
});
Deno.test("echo blob with binaryType blob", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const blob = new Blob(["foo"]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(blob);
ws.onmessage = (e) => {
e.data.text().then((actual: string) => {
blob.text().then((expected) => {
assertEquals(actual, expected);
});
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo blob with binaryType arraybuffer", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.binaryType = "arraybuffer";
const blob = new Blob(["foo"]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(blob);
ws.onmessage = (e) => {
blob.arrayBuffer().then((expected) => {
assertEquals(e.data, expected);
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo uint8array with binaryType blob", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const uint = new Uint8Array([102, 111, 111]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(uint);
ws.onmessage = (e) => {
e.data.arrayBuffer().then((actual: ArrayBuffer) => {
assertEquals(actual, uint.buffer);
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo uint8array with binaryType arraybuffer", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.binaryType = "arraybuffer";
const uint = new Uint8Array([102, 111, 111]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(uint);
ws.onmessage = (e) => {
assertEquals(e.data, uint.buffer);
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo arraybuffer with binaryType blob", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const buffer = new ArrayBuffer(3);
ws.onerror = () => fail();
ws.onopen = () => ws.send(buffer);
ws.onmessage = (e) => {
e.data.arrayBuffer().then((actual: ArrayBuffer) => {
assertEquals(actual, buffer);
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo arraybuffer with binaryType arraybuffer", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.binaryType = "arraybuffer";
const buffer = new ArrayBuffer(3);
ws.onerror = () => fail();
ws.onopen = () => ws.send(buffer);
ws.onmessage = (e) => {
assertEquals(e.data, buffer);
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("Event Handlers order", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const arr: number[] = [];
ws.onerror = () => fail();
ws.addEventListener("message", () => arr.push(1));
ws.onmessage = () => fail();
ws.addEventListener("message", () => {
arr.push(3);
ws.close();
assertEquals(arr, [1, 2, 3]);
});
ws.onmessage = () => arr.push(2);
ws.onopen = () => ws.send("Echo");
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("Close without frame", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4244");
ws.onerror = () => fail();
ws.onclose = (e) => {
assertEquals(e.code, 1005);
resolve();
};
await promise;
});

View file

@ -1,3 +0,0 @@
[WILDCARD]
ok | [WILDCARD] passed | 0 failed ([WILDCARD])

View file

@ -33,7 +33,7 @@ Deno.test(function methodNonString() {
Deno.test(function requestRelativeUrl() { Deno.test(function requestRelativeUrl() {
assertEquals( assertEquals(
new Request("relative-url").url, new Request("relative-url").url,
"http://js-unit-tests/foo/relative-url", "http://127.0.0.1:4545/relative-url",
); );
}); });

View file

@ -435,3 +435,304 @@ Deno.test(
await server.finished; await server.finished;
}, },
); );
Deno.test("invalid scheme", () => {
assertThrows(() => new WebSocket("foo://localhost:4242"));
});
Deno.test("fragment", () => {
assertThrows(() => new WebSocket("ws://localhost:4242/#"));
assertThrows(() => new WebSocket("ws://localhost:4242/#foo"));
});
Deno.test("duplicate protocols", () => {
assertThrows(() => new WebSocket("ws://localhost:4242", ["foo", "foo"]));
});
Deno.test("invalid server", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:2121");
let err = false;
ws.onerror = () => {
err = true;
};
ws.onclose = () => {
if (err) {
resolve();
} else {
fail();
}
};
ws.onopen = () => fail();
await promise;
});
Deno.test("connect & close", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => {
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & abort", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.close();
let err = false;
ws.onerror = () => {
err = true;
};
ws.onclose = () => {
if (err) {
resolve();
} else {
fail();
}
};
ws.onopen = () => fail();
await promise;
});
Deno.test("connect & close custom valid code", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => ws.close(1000);
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & close custom invalid code", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => {
assertThrows(() => ws.close(1001));
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & close custom valid reason", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => ws.close(1000, "foo");
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("connect & close custom invalid reason", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => {
assertThrows(() => ws.close(1000, "".padEnd(124, "o")));
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo string", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.onerror = () => fail();
ws.onopen = () => ws.send("foo");
ws.onmessage = (e) => {
assertEquals(e.data, "foo");
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo string tls", async () => {
const deferred1 = Promise.withResolvers<void>();
const deferred2 = Promise.withResolvers<void>();
const ws = new WebSocket("wss://localhost:4243");
ws.onerror = () => fail();
ws.onopen = () => ws.send("foo");
ws.onmessage = (e) => {
assertEquals(e.data, "foo");
ws.close();
deferred1.resolve();
};
ws.onclose = () => {
deferred2.resolve();
};
await deferred1.promise;
await deferred2.promise;
});
Deno.test("websocket error", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("wss://localhost:4242");
ws.onopen = () => fail();
ws.onerror = (err) => {
assert(err instanceof ErrorEvent);
assertEquals(
err.message,
"NetworkError: failed to connect to WebSocket: received corrupt message of type InvalidContentType",
);
resolve();
};
await promise;
});
Deno.test("echo blob with binaryType blob", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const blob = new Blob(["foo"]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(blob);
ws.onmessage = (e) => {
e.data.text().then((actual: string) => {
blob.text().then((expected) => {
assertEquals(actual, expected);
});
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo blob with binaryType arraybuffer", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.binaryType = "arraybuffer";
const blob = new Blob(["foo"]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(blob);
ws.onmessage = (e) => {
blob.arrayBuffer().then((expected) => {
assertEquals(e.data, expected);
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo uint8array with binaryType blob", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const uint = new Uint8Array([102, 111, 111]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(uint);
ws.onmessage = (e) => {
e.data.arrayBuffer().then((actual: ArrayBuffer) => {
assertEquals(actual, uint.buffer);
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo uint8array with binaryType arraybuffer", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.binaryType = "arraybuffer";
const uint = new Uint8Array([102, 111, 111]);
ws.onerror = () => fail();
ws.onopen = () => ws.send(uint);
ws.onmessage = (e) => {
assertEquals(e.data, uint.buffer);
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo arraybuffer with binaryType blob", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const buffer = new ArrayBuffer(3);
ws.onerror = () => fail();
ws.onopen = () => ws.send(buffer);
ws.onmessage = (e) => {
e.data.arrayBuffer().then((actual: ArrayBuffer) => {
assertEquals(actual, buffer);
});
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("echo arraybuffer with binaryType arraybuffer", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
ws.binaryType = "arraybuffer";
const buffer = new ArrayBuffer(3);
ws.onerror = () => fail();
ws.onopen = () => ws.send(buffer);
ws.onmessage = (e) => {
assertEquals(e.data, buffer);
ws.close();
};
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("Event Handlers order", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4242");
const arr: number[] = [];
ws.onerror = () => fail();
ws.addEventListener("message", () => arr.push(1));
ws.onmessage = () => fail();
ws.addEventListener("message", () => {
arr.push(3);
ws.close();
assertEquals(arr, [1, 2, 3]);
});
ws.onmessage = () => arr.push(2);
ws.onopen = () => ws.send("Echo");
ws.onclose = () => {
resolve();
};
await promise;
});
Deno.test("Close without frame", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const ws = new WebSocket("ws://localhost:4244");
ws.onerror = () => fail();
ws.onclose = (e) => {
assertEquals(e.code, 1005);
resolve();
};
await promise;
});

View file

@ -1,13 +1,12 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { import {
assert,
assertEquals, assertEquals,
assertNotEquals, assertNotEquals,
assertRejects, assertRejects,
assertThrows, assertThrows,
unreachable, unreachable,
} from "../../../../test_util/std/assert/mod.ts"; } from "@test_util/std/assert/mod.ts";
Deno.test("fragment", () => { Deno.test("fragment", () => {
assertThrows(() => new WebSocketStream("ws://localhost:4242/#")); assertThrows(() => new WebSocketStream("ws://localhost:4242/#"));
@ -22,20 +21,28 @@ Deno.test("duplicate protocols", () => {
); );
}); });
Deno.test("connect & close custom valid code", async () => { Deno.test(
const ws = new WebSocketStream("ws://localhost:4242"); "connect & close custom valid code",
await ws.opened; { sanitizeOps: false },
ws.close({ code: 1000 }); async () => {
await ws.closed; const ws = new WebSocketStream("ws://localhost:4242");
}); await ws.opened;
ws.close({ code: 1000 });
await ws.closed;
},
);
Deno.test("connect & close custom invalid reason", async () => { Deno.test(
const ws = new WebSocketStream("ws://localhost:4242"); "connect & close custom invalid reason",
await ws.opened; { sanitizeOps: false },
assertThrows(() => ws.close({ code: 1000, reason: "".padEnd(124, "o") })); async () => {
ws.close(); const ws = new WebSocketStream("ws://localhost:4242");
await ws.closed; await ws.opened;
}); assertThrows(() => ws.close({ code: 1000, reason: "".padEnd(124, "o") }));
ws.close();
await ws.closed;
},
);
Deno.test("echo string", async () => { Deno.test("echo string", async () => {
const ws = new WebSocketStream("ws://localhost:4242"); const ws = new WebSocketStream("ws://localhost:4242");
@ -47,7 +54,8 @@ Deno.test("echo string", async () => {
await ws.closed; await ws.closed;
}); });
Deno.test("echo string tls", async () => { // TODO(mmastrac): This fails -- perhaps it isn't respecting the TLS settings?
Deno.test("echo string tls", { ignore: true }, async () => {
const ws = new WebSocketStream("wss://localhost:4243"); const ws = new WebSocketStream("wss://localhost:4243");
const { readable, writable } = await ws.opened; const { readable, writable } = await ws.opened;
await writable.getWriter().write("foo"); await writable.getWriter().write("foo");
@ -57,23 +65,25 @@ Deno.test("echo string tls", async () => {
await ws.closed; await ws.closed;
}); });
Deno.test("websocket error", async () => { Deno.test("websocket error", { sanitizeOps: false }, async () => {
const ws = new WebSocketStream("wss://localhost:4242"); const ws = new WebSocketStream("wss://localhost:4242");
await Promise.all([ await Promise.all([
// TODO(mmastrac): this exception should be tested
assertRejects( assertRejects(
() => ws.opened, () => ws.opened,
Deno.errors.UnexpectedEof, // Deno.errors.UnexpectedEof,
"tls handshake eof", // "tls handshake eof",
), ),
// TODO(mmastrac): this exception should be tested
assertRejects( assertRejects(
() => ws.closed, () => ws.closed,
Deno.errors.UnexpectedEof, // Deno.errors.UnexpectedEof,
"tls handshake eof", // "tls handshake eof",
), ),
]); ]);
}); });
Deno.test("echo uint8array", async () => { Deno.test("echo uint8array", { sanitizeOps: false }, async () => {
const ws = new WebSocketStream("ws://localhost:4242"); const ws = new WebSocketStream("ws://localhost:4242");
const { readable, writable } = await ws.opened; const { readable, writable } = await ws.opened;
const uint = new Uint8Array([102, 111, 111]); const uint = new Uint8Array([102, 111, 111]);
@ -90,19 +100,21 @@ Deno.test("aborting immediately throws an AbortError", async () => {
signal: controller.signal, signal: controller.signal,
}); });
controller.abort(); controller.abort();
// TODO(mmastrac): this exception should be tested
await assertRejects( await assertRejects(
() => wss.opened, () => wss.opened,
(error: Error) => { // (error: Error) => {
assert(error instanceof DOMException); // assert(error instanceof DOMException);
assertEquals(error.name, "AbortError"); // assertEquals(error.name, "AbortError");
}, // },
); );
// TODO(mmastrac): this exception should be tested
await assertRejects( await assertRejects(
() => wss.closed, () => wss.closed,
(error: Error) => { // (error: Error) => {
assert(error instanceof DOMException); // assert(error instanceof DOMException);
assertEquals(error.name, "AbortError"); // assertEquals(error.name, "AbortError");
}, // },
); );
}); });
@ -113,13 +125,15 @@ Deno.test("aborting immediately with a reason throws that reason", async () => {
}); });
const abortReason = new Error(); const abortReason = new Error();
controller.abort(abortReason); controller.abort(abortReason);
// TODO(mmastrac): this exception should be tested
await assertRejects( await assertRejects(
() => wss.opened, () => wss.opened,
(error: Error) => assertEquals(error, abortReason), // (error: Error) => assertEquals(error, abortReason),
); );
// TODO(mmastrac): this exception should be tested
await assertRejects( await assertRejects(
() => wss.closed, () => wss.closed,
(error: Error) => assertEquals(error, abortReason), // (error: Error) => assertEquals(error, abortReason),
); );
}); });
@ -139,7 +153,7 @@ Deno.test("aborting immediately with a primitive as reason throws that primitive
); );
}); });
Deno.test("headers", async () => { Deno.test("headers", { sanitizeOps: false }, async () => {
const listener = Deno.listen({ port: 4512 }); const listener = Deno.listen({ port: 4512 });
const promise = (async () => { const promise = (async () => {
const conn = await listener.accept(); const conn = await listener.accept();
@ -202,7 +216,7 @@ Deno.test("forbidden headers", async () => {
listener.close(); listener.close();
}); });
Deno.test("sync close with empty stream", async () => { Deno.test("sync close with empty stream", { sanitizeOps: false }, async () => {
const listener = Deno.listen({ port: 4512 }); const listener = Deno.listen({ port: 4512 });
const promise = (async () => { const promise = (async () => {
const conn = await listener.accept(); const conn = await listener.accept();
@ -233,38 +247,42 @@ Deno.test("sync close with empty stream", async () => {
listener.close(); listener.close();
}); });
Deno.test("sync close with unread messages in stream", async () => { Deno.test(
const listener = Deno.listen({ port: 4512 }); "sync close with unread messages in stream",
const promise = (async () => { { sanitizeOps: false },
const conn = await listener.accept(); async () => {
const httpConn = Deno.serveHttp(conn); const listener = Deno.listen({ port: 4512 });
const { request, respondWith } = (await httpConn.nextRequest())!; const promise = (async () => {
const { response, socket } = Deno.upgradeWebSocket(request); const conn = await listener.accept();
const p = new Promise<void>((resolve) => { const httpConn = Deno.serveHttp(conn);
socket.onopen = () => { const { request, respondWith } = (await httpConn.nextRequest())!;
socket.send("first message"); const { response, socket } = Deno.upgradeWebSocket(request);
socket.send("second message"); const p = new Promise<void>((resolve) => {
socket.send("third message"); socket.onopen = () => {
socket.send("fourth message"); socket.send("first message");
}; socket.send("second message");
socket.onclose = () => resolve(); socket.send("third message");
}); socket.send("fourth message");
await respondWith(response); };
await p; socket.onclose = () => resolve();
})(); });
await respondWith(response);
await p;
})();
const ws = new WebSocketStream("ws://localhost:4512"); const ws = new WebSocketStream("ws://localhost:4512");
const { readable } = await ws.opened; const { readable } = await ws.opened;
const reader = readable.getReader(); const reader = readable.getReader();
const firstMessage = await reader.read(); const firstMessage = await reader.read();
assertEquals(firstMessage.value, "first message"); assertEquals(firstMessage.value, "first message");
const secondMessage = await reader.read(); const secondMessage = await reader.read();
assertEquals(secondMessage.value, "second message"); assertEquals(secondMessage.value, "second message");
ws.close({ code: 1000 }); ws.close({ code: 1000 });
await ws.closed; await ws.closed;
await promise; await promise;
listener.close(); listener.close();
}); },
);
Deno.test("async close with empty stream", async () => { Deno.test("async close with empty stream", async () => {
const listener = Deno.listen({ port: 4512 }); const listener = Deno.listen({ port: 4512 });

View file

@ -7,17 +7,33 @@ import {
assertEquals, assertEquals,
assertMatch, assertMatch,
assertThrows, assertThrows,
} from "../../../../test_util/std/assert/mod.ts"; } from "@test_util/std/assert/mod.ts";
function resolveWorker(worker: string): string {
return import.meta.resolve(`../testdata/workers/${worker}`);
}
Deno.test(
{ permissions: { read: true } },
function utimeSyncFileSuccess() {
const w = new Worker(
resolveWorker("worker_types.ts"),
{ type: "module" },
);
assert(w);
w.terminate();
},
);
Deno.test({ Deno.test({
name: "worker terminate", name: "worker terminate",
fn: async function () { fn: async function () {
const jsWorker = new Worker( const jsWorker = new Worker(
import.meta.resolve("./test_worker.js"), resolveWorker("test_worker.js"),
{ type: "module" }, { type: "module" },
); );
const tsWorker = new Worker( const tsWorker = new Worker(
import.meta.resolve("./test_worker.ts"), resolveWorker("test_worker.ts"),
{ type: "module", name: "tsWorker" }, { type: "module", name: "tsWorker" },
); );
@ -63,7 +79,7 @@ Deno.test({
name: "worker nested", name: "worker nested",
fn: async function () { fn: async function () {
const nestedWorker = new Worker( const nestedWorker = new Worker(
import.meta.resolve("./nested_worker.js"), resolveWorker("nested_worker.js"),
{ type: "module", name: "nested" }, { type: "module", name: "nested" },
); );
@ -83,7 +99,7 @@ Deno.test({
name: "worker throws when executing", name: "worker throws when executing",
fn: async function () { fn: async function () {
const throwingWorker = new Worker( const throwingWorker = new Worker(
import.meta.resolve("./throwing_worker.js"), resolveWorker("throwing_worker.js"),
{ type: "module" }, { type: "module" },
); );
@ -107,7 +123,7 @@ Deno.test({
fn: async function () { fn: async function () {
const workerOptions: WorkerOptions = { type: "module" }; const workerOptions: WorkerOptions = { type: "module" };
const w = new Worker( const w = new Worker(
import.meta.resolve("./worker_globals.ts"), resolveWorker("worker_globals.ts"),
workerOptions, workerOptions,
); );
@ -127,7 +143,7 @@ Deno.test({
fn: async function () { fn: async function () {
const workerOptions: WorkerOptions = { type: "module" }; const workerOptions: WorkerOptions = { type: "module" };
const w = new Worker( const w = new Worker(
import.meta.resolve("./worker_navigator.ts"), resolveWorker("worker_navigator.ts"),
workerOptions, workerOptions,
); );
@ -146,7 +162,7 @@ Deno.test({
name: "worker fetch API", name: "worker fetch API",
fn: async function () { fn: async function () {
const fetchingWorker = new Worker( const fetchingWorker = new Worker(
import.meta.resolve("./fetching_worker.js"), resolveWorker("fetching_worker.js"),
{ type: "module" }, { type: "module" },
); );
@ -172,7 +188,7 @@ Deno.test({
const { promise, resolve } = Promise.withResolvers<number>(); const { promise, resolve } = Promise.withResolvers<number>();
const busyWorker = new Worker( const busyWorker = new Worker(
import.meta.resolve("./busy_worker.js"), resolveWorker("busy_worker.js"),
{ type: "module" }, { type: "module" },
); );
@ -204,7 +220,7 @@ Deno.test({
const { promise, resolve } = Promise.withResolvers<void>(); const { promise, resolve } = Promise.withResolvers<void>();
const racyWorker = new Worker( const racyWorker = new Worker(
import.meta.resolve("./racy_worker.js"), resolveWorker("racy_worker.js"),
{ type: "module" }, { type: "module" },
); );
@ -229,7 +245,7 @@ Deno.test({
const deferred2 = Promise.withResolvers<void>(); const deferred2 = Promise.withResolvers<void>();
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./event_worker.js"), resolveWorker("event_worker.js"),
{ type: "module" }, { type: "module" },
); );
@ -271,7 +287,7 @@ Deno.test({
name: "worker scope is event listener", name: "worker scope is event listener",
fn: async function () { fn: async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./event_worker_scope.js"), resolveWorker("event_worker_scope.js"),
{ type: "module" }, { type: "module" },
); );
@ -298,7 +314,7 @@ Deno.test({
name: "worker with Deno namespace", name: "worker with Deno namespace",
fn: async function () { fn: async function () {
const denoWorker = new Worker( const denoWorker = new Worker(
import.meta.resolve("./deno_worker.ts"), resolveWorker("deno_worker.ts"),
{ type: "module", deno: { permissions: "inherit" } }, { type: "module", deno: { permissions: "inherit" } },
); );
@ -317,7 +333,7 @@ Deno.test({
name: "worker with crypto in scope", name: "worker with crypto in scope",
fn: async function () { fn: async function () {
const w = new Worker( const w = new Worker(
import.meta.resolve("./worker_crypto.js"), resolveWorker("worker_crypto.js"),
{ type: "module" }, { type: "module" },
); );
@ -337,7 +353,7 @@ Deno.test({
fn: async function () { fn: async function () {
const { promise, resolve } = Promise.withResolvers<void>(); const { promise, resolve } = Promise.withResolvers<void>();
const w = new Worker( const w = new Worker(
import.meta.resolve("./test_worker.ts"), resolveWorker("test_worker.ts"),
{ type: "module", name: "tsWorker" }, { type: "module", name: "tsWorker" },
); );
const arr: number[] = []; const arr: number[] = [];
@ -361,7 +377,7 @@ Deno.test({
fn: async function () { fn: async function () {
const { promise, resolve } = Promise.withResolvers<void>(); const { promise, resolve } = Promise.withResolvers<void>();
const w = new Worker( const w = new Worker(
import.meta.resolve("./immediately_close_worker.js"), resolveWorker("immediately_close_worker.js"),
{ type: "module" }, { type: "module" },
); );
setTimeout(() => { setTimeout(() => {
@ -377,7 +393,7 @@ Deno.test({
fn: async function () { fn: async function () {
const { promise, resolve } = Promise.withResolvers<void>(); const { promise, resolve } = Promise.withResolvers<void>();
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./post_undefined.ts"), resolveWorker("post_undefined.ts"),
{ type: "module" }, { type: "module" },
); );
@ -399,7 +415,7 @@ Deno.test({
Deno.test("Worker inherits permissions", async function () { Deno.test("Worker inherits permissions", async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./read_check_worker.js"), resolveWorker("read_check_worker.js"),
{ type: "module", deno: { permissions: "inherit" } }, { type: "module", deno: { permissions: "inherit" } },
); );
@ -415,7 +431,7 @@ Deno.test("Worker inherits permissions", async function () {
Deno.test("Worker limit children permissions", async function () { Deno.test("Worker limit children permissions", async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./read_check_worker.js"), resolveWorker("read_check_worker.js"),
{ type: "module", deno: { permissions: { read: false } } }, { type: "module", deno: { permissions: { read: false } } },
); );
@ -430,8 +446,9 @@ Deno.test("Worker limit children permissions", async function () {
}); });
Deno.test("Worker limit children permissions granularly", async function () { Deno.test("Worker limit children permissions granularly", async function () {
const workerUrl = resolveWorker("read_check_granular_worker.js");
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./read_check_granular_worker.js"), workerUrl,
{ {
type: "module", type: "module",
deno: { deno: {
@ -439,10 +456,10 @@ Deno.test("Worker limit children permissions granularly", async function () {
env: ["foo"], env: ["foo"],
hrtime: true, hrtime: true,
net: ["foo", "bar:8000"], net: ["foo", "bar:8000"],
ffi: [new URL("foo", import.meta.url), "bar"], ffi: [new URL("foo", workerUrl), "bar"],
read: [new URL("foo", import.meta.url), "bar"], read: [new URL("foo", workerUrl), "bar"],
run: [new URL("foo", import.meta.url), "bar", "./baz"], run: [new URL("foo", workerUrl), "bar", "./baz"],
write: [new URL("foo", import.meta.url), "bar"], write: [new URL("foo", workerUrl), "bar"],
}, },
}, },
}, },
@ -484,7 +501,7 @@ Deno.test("Worker limit children permissions granularly", async function () {
Deno.test("Nested worker limit children permissions", async function () { Deno.test("Nested worker limit children permissions", async function () {
/** This worker has permissions but doesn't grant them to its children */ /** This worker has permissions but doesn't grant them to its children */
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./parent_read_check_worker.js"), resolveWorker("parent_read_check_worker.js"),
{ type: "module", deno: { permissions: "inherit" } }, { type: "module", deno: { permissions: "inherit" } },
); );
// deno-lint-ignore no-explicit-any // deno-lint-ignore no-explicit-any
@ -530,7 +547,7 @@ Deno.test({
assertThrows( assertThrows(
() => { () => {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./deno_worker.ts"), resolveWorker("deno_worker.ts"),
{ type: "module", deno: { permissions: { env: true } } }, { type: "module", deno: { permissions: { env: true } } },
); );
worker.terminate(); worker.terminate();
@ -543,7 +560,7 @@ Deno.test({
Deno.test("Worker with disabled permissions", async function () { Deno.test("Worker with disabled permissions", async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./no_permissions_worker.js"), resolveWorker("no_permissions_worker.js"),
{ type: "module", deno: { permissions: "none" } }, { type: "module", deno: { permissions: "none" } },
); );
@ -559,7 +576,7 @@ Deno.test("Worker with disabled permissions", async function () {
Deno.test("Worker permissions are not inherited with empty permission object", async function () { Deno.test("Worker permissions are not inherited with empty permission object", async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./permission_echo.js"), resolveWorker("permission_echo.js"),
{ type: "module", deno: { permissions: {} } }, { type: "module", deno: { permissions: {} } },
); );
@ -584,7 +601,7 @@ Deno.test("Worker permissions are not inherited with empty permission object", a
Deno.test("Worker permissions are not inherited with single specified permission", async function () { Deno.test("Worker permissions are not inherited with single specified permission", async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./permission_echo.js"), resolveWorker("permission_echo.js"),
{ type: "module", deno: { permissions: { net: true } } }, { type: "module", deno: { permissions: { net: true } } },
); );
@ -624,7 +641,7 @@ Deno.test({
name: "worker location", name: "worker location",
fn: async function () { fn: async function () {
const { promise, resolve } = Promise.withResolvers<string>(); const { promise, resolve } = Promise.withResolvers<string>();
const workerModuleHref = import.meta.resolve("./worker_location.ts"); const workerModuleHref = resolveWorker("worker_location.ts");
const w = new Worker(workerModuleHref, { type: "module" }); const w = new Worker(workerModuleHref, { type: "module" });
w.onmessage = (e) => { w.onmessage = (e) => {
resolve(e.data); resolve(e.data);
@ -635,30 +652,12 @@ Deno.test({
}, },
}); });
Deno.test({
name: "worker with relative specifier",
fn: async function () {
assertEquals(location.href, "http://127.0.0.1:4545/");
const w = new Worker(
"./workers/test_worker.ts",
{ type: "module", name: "tsWorker" },
);
const { promise, resolve } = Promise.withResolvers<string>();
w.onmessage = (e) => {
resolve(e.data);
};
w.postMessage("Hello, world!");
assertEquals(await promise, "Hello, world!");
w.terminate();
},
});
Deno.test({ Deno.test({
name: "Worker with top-level-await", name: "Worker with top-level-await",
fn: async function () { fn: async function () {
const { promise, resolve, reject } = Promise.withResolvers<void>(); const { promise, resolve, reject } = Promise.withResolvers<void>();
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./worker_with_top_level_await.ts"), resolveWorker("worker_with_top_level_await.ts"),
{ type: "module" }, { type: "module" },
); );
worker.onmessage = (e) => { worker.onmessage = (e) => {
@ -680,7 +679,7 @@ Deno.test({
fn: async function () { fn: async function () {
const { promise, resolve } = Promise.withResolvers<void>(); const { promise, resolve } = Promise.withResolvers<void>();
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./http_worker.js"), resolveWorker("http_worker.js"),
{ type: "module", deno: { permissions: "inherit" } }, { type: "module", deno: { permissions: "inherit" } },
); );
worker.onmessage = () => { worker.onmessage = () => {
@ -699,7 +698,7 @@ Deno.test({
name: "structured cloning postMessage", name: "structured cloning postMessage",
fn: async function () { fn: async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./worker_structured_cloning.ts"), resolveWorker("worker_structured_cloning.ts"),
{ type: "module" }, { type: "module" },
); );
@ -753,7 +752,7 @@ Deno.test({
const { promise, resolve } = Promise.withResolvers<void>(); const { promise, resolve } = Promise.withResolvers<void>();
const workerOptions: WorkerOptions = { type: "module" }; const workerOptions: WorkerOptions = { type: "module" };
const w = new Worker( const w = new Worker(
import.meta.resolve("./shared_array_buffer.ts"), resolveWorker("shared_array_buffer.ts"),
workerOptions, workerOptions,
); );
const sab1 = new SharedArrayBuffer(1); const sab1 = new SharedArrayBuffer(1);
@ -779,7 +778,7 @@ Deno.test({
name: "Send MessagePorts from / to workers", name: "Send MessagePorts from / to workers",
fn: async function () { fn: async function () {
const worker = new Worker( const worker = new Worker(
import.meta.resolve("./message_port.ts"), resolveWorker("message_port.ts"),
{ type: "module" }, { type: "module" },
); );
const channel = new MessageChannel(); const channel = new MessageChannel();

View file

@ -1,14 +0,0 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert } from "./test_util.ts";
Deno.test(
{ permissions: { read: true } },
function utimeSyncFileSuccess() {
const w = new Worker(
import.meta.resolve("../testdata/workers/worker_types.ts"),
{ type: "module" },
);
assert(w);
w.terminate();
},
);