summaryrefslogtreecommitdiff
path: root/cli/tests/unit/net_test.ts
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2024-02-10 13:22:13 -0700
committerGitHub <noreply@github.com>2024-02-10 20:22:13 +0000
commitf5e46c9bf2f50d66a953fa133161fc829cecff06 (patch)
tree8faf2f5831c1c7b11d842cd9908d141082c869a5 /cli/tests/unit/net_test.ts
parentd2477f780630a812bfd65e3987b70c0d309385bb (diff)
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests -> tests, and updates of relative paths for files. This is the first step towards aggregate all of the integration test files under tests/, which will lead to a set of integration tests that can run without the CLI binary being built. While we could leave these tests under `cli`, it would require us to keep a more complex directory structure for the various test runners. In addition, we have a lot of complexity to ignore various test files in the `cli` project itself (cargo publish exclusion rules, autotests = false, etc). And finally, the `tests/` folder will eventually house the `test_ffi`, `test_napi` and other testing code, reducing the size of the root repo directory. For easier review, the extremely large and noisy "move" is in the first commit (with no changes -- just a move), while the remainder of the changes to actual files is in the second commit.
Diffstat (limited to 'cli/tests/unit/net_test.ts')
-rw-r--r--cli/tests/unit/net_test.ts1274
1 files changed, 0 insertions, 1274 deletions
diff --git a/cli/tests/unit/net_test.ts b/cli/tests/unit/net_test.ts
deleted file mode 100644
index fa9790a76..000000000
--- a/cli/tests/unit/net_test.ts
+++ /dev/null
@@ -1,1274 +0,0 @@
-// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-import {
- assert,
- assertEquals,
- assertNotEquals,
- assertRejects,
- assertThrows,
- delay,
- execCode,
- execCode2,
- tmpUnixSocketPath,
-} from "./test_util.ts";
-
-// Since these tests may run in parallel, ensure this port is unique to this file
-const listenPort = 4503;
-const listenPort2 = 4504;
-
-let isCI: boolean;
-try {
- isCI = Deno.env.get("CI") !== undefined;
-} catch {
- isCI = true;
-}
-
-Deno.test({ permissions: { net: true } }, function netTcpListenClose() {
- const listener = Deno.listen({ hostname: "127.0.0.1", port: listenPort });
- assert(listener.addr.transport === "tcp");
- assertEquals(listener.addr.hostname, "127.0.0.1");
- assertEquals(listener.addr.port, listenPort);
- assertNotEquals(listener.rid, 0);
- listener.close();
-});
-
-Deno.test(
- {
- permissions: { net: true },
- },
- function netUdpListenClose() {
- const socket = Deno.listenDatagram({
- hostname: "127.0.0.1",
- port: listenPort,
- transport: "udp",
- });
- assert(socket.addr.transport === "udp");
- assertEquals(socket.addr.hostname, "127.0.0.1");
- assertEquals(socket.addr.port, listenPort);
- socket.close();
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- function netUnixListenClose() {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listen({
- path: filePath,
- transport: "unix",
- });
- assert(socket.addr.transport === "unix");
- assertEquals(socket.addr.path, filePath);
- socket.close();
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- function netUnixPacketListenClose() {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listenDatagram({
- path: filePath,
- transport: "unixpacket",
- });
- assert(socket.addr.transport === "unixpacket");
- assertEquals(socket.addr.path, filePath);
- socket.close();
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: false },
- },
- function netUnixListenWritePermission() {
- assertThrows(() => {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listen({
- path: filePath,
- transport: "unix",
- });
- assert(socket.addr.transport === "unix");
- assertEquals(socket.addr.path, filePath);
- socket.close();
- }, Deno.errors.PermissionDenied);
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: false },
- },
- function netUnixPacketListenWritePermission() {
- assertThrows(() => {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listenDatagram({
- path: filePath,
- transport: "unixpacket",
- });
- assert(socket.addr.transport === "unixpacket");
- assertEquals(socket.addr.path, filePath);
- socket.close();
- }, Deno.errors.PermissionDenied);
- },
-);
-
-Deno.test(
- {
- permissions: { net: true },
- },
- async function netTcpCloseWhileAccept() {
- const listener = Deno.listen({ port: listenPort });
- const p = listener.accept();
- listener.close();
- // TODO(piscisaureus): the error type should be `Interrupted` here, which
- // gets thrown, but then ext/net catches it and rethrows `BadResource`.
- await assertRejects(
- () => p,
- Deno.errors.BadResource,
- "Listener has been closed",
- );
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- async function netUnixCloseWhileAccept() {
- const filePath = tmpUnixSocketPath();
- const listener = Deno.listen({
- path: filePath,
- transport: "unix",
- });
- const p = listener.accept();
- listener.close();
- await assertRejects(
- () => p,
- Deno.errors.BadResource,
- "Listener has been closed",
- );
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netTcpConcurrentAccept() {
- const listener = Deno.listen({ port: 4510 });
- let acceptErrCount = 0;
- const checkErr = (e: Error) => {
- if (e.message === "Listener has been closed") {
- assertEquals(acceptErrCount, 1);
- } else if (e.message === "Another accept task is ongoing") {
- acceptErrCount++;
- } else {
- throw new Error("Unexpected error message");
- }
- };
- const p = listener.accept().catch(checkErr);
- const p1 = listener.accept().catch(checkErr);
- await Promise.race([p, p1]);
- listener.close();
- await Promise.all([p, p1]);
- assertEquals(acceptErrCount, 1);
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- async function netUnixConcurrentAccept() {
- const filePath = tmpUnixSocketPath();
- const listener = Deno.listen({ transport: "unix", path: filePath });
- let acceptErrCount = 0;
- const checkErr = (e: Error) => {
- if (e.message === "Listener has been closed") {
- assertEquals(acceptErrCount, 1);
- } else if (e instanceof Deno.errors.Busy) { // "Listener already in use"
- acceptErrCount++;
- } else {
- throw e;
- }
- };
- const p = listener.accept().catch(checkErr);
- const p1 = listener.accept().catch(checkErr);
- await Promise.race([p, p1]);
- listener.close();
- await Promise.all([p, p1]);
- assertEquals(acceptErrCount, 1);
- },
-);
-
-Deno.test({ permissions: { net: true } }, async function netTcpDialListen() {
- const listener = Deno.listen({ port: listenPort });
- listener.accept().then(
- async (conn) => {
- assert(conn.remoteAddr != null);
- assert(conn.localAddr.transport === "tcp");
- assertEquals(conn.localAddr.hostname, "127.0.0.1");
- assertEquals(conn.localAddr.port, listenPort);
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- },
- );
-
- const conn = await Deno.connect({ hostname: "127.0.0.1", port: listenPort });
- assert(conn.remoteAddr.transport === "tcp");
- assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
- assertEquals(conn.remoteAddr.port, listenPort);
- assert(conn.localAddr != null);
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== null);
-
- const readResult2 = await conn.read(buf);
- assertEquals(readResult2, null);
-
- listener.close();
- conn.close();
-});
-
-Deno.test({ permissions: { net: true } }, async function netTcpSetNoDelay() {
- const listener = Deno.listen({ port: listenPort });
- listener.accept().then(
- async (conn) => {
- assert(conn.remoteAddr != null);
- assert(conn.localAddr.transport === "tcp");
- assertEquals(conn.localAddr.hostname, "127.0.0.1");
- assertEquals(conn.localAddr.port, listenPort);
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- },
- );
-
- const conn = await Deno.connect({ hostname: "127.0.0.1", port: listenPort });
- conn.setNoDelay(true);
- assert(conn.remoteAddr.transport === "tcp");
- assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
- assertEquals(conn.remoteAddr.port, listenPort);
- assert(conn.localAddr != null);
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== null);
-
- const readResult2 = await conn.read(buf);
- assertEquals(readResult2, null);
-
- listener.close();
- conn.close();
-});
-
-Deno.test({ permissions: { net: true } }, async function netTcpSetKeepAlive() {
- const listener = Deno.listen({ port: listenPort });
- listener.accept().then(
- async (conn) => {
- assert(conn.remoteAddr != null);
- assert(conn.localAddr.transport === "tcp");
- assertEquals(conn.localAddr.hostname, "127.0.0.1");
- assertEquals(conn.localAddr.port, listenPort);
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- },
- );
-
- const conn = await Deno.connect({ hostname: "127.0.0.1", port: listenPort });
- conn.setKeepAlive(true);
- assert(conn.remoteAddr.transport === "tcp");
- assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
- assertEquals(conn.remoteAddr.port, listenPort);
- assert(conn.localAddr != null);
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== null);
-
- const readResult2 = await conn.read(buf);
- assertEquals(readResult2, null);
-
- listener.close();
- conn.close();
-});
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- async function netUnixDialListen() {
- const filePath = tmpUnixSocketPath();
- const listener = Deno.listen({ path: filePath, transport: "unix" });
- listener.accept().then(
- async (conn) => {
- assert(conn.remoteAddr != null);
- assert(conn.localAddr.transport === "unix");
- assertEquals(conn.localAddr.path, filePath);
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- },
- );
- const conn = await Deno.connect({ path: filePath, transport: "unix" });
- assert(conn.remoteAddr.transport === "unix");
- assertEquals(conn.remoteAddr.path, filePath);
- assert(conn.remoteAddr != null);
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== null);
-
- const readResult2 = await conn.read(buf);
- assertEquals(readResult2, null);
-
- listener.close();
- conn.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netUdpSendReceive() {
- const alice = Deno.listenDatagram({ port: listenPort, transport: "udp" });
- assert(alice.addr.transport === "udp");
- assertEquals(alice.addr.port, listenPort);
- assertEquals(alice.addr.hostname, "127.0.0.1");
-
- const bob = Deno.listenDatagram({ port: listenPort2, transport: "udp" });
- assert(bob.addr.transport === "udp");
- assertEquals(bob.addr.port, listenPort2);
- assertEquals(bob.addr.hostname, "127.0.0.1");
-
- const sent = new Uint8Array([1, 2, 3]);
- const byteLength = await alice.send(sent, bob.addr);
-
- assertEquals(byteLength, 3);
-
- const [recvd, remote] = await bob.receive();
- assert(remote.transport === "udp");
- assertEquals(remote.port, listenPort);
- assertEquals(recvd.length, 3);
- assertEquals(1, recvd[0]);
- assertEquals(2, recvd[1]);
- assertEquals(3, recvd[2]);
- alice.close();
- bob.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true }, ignore: true },
- async function netUdpSendReceiveBroadcast() {
- // Must bind sender to an address that can send to the broadcast address on MacOS.
- // Macos will give us error 49 when sending the broadcast packet if we omit hostname here.
- const alice = Deno.listenDatagram({
- port: listenPort,
- transport: "udp",
- hostname: "0.0.0.0",
- });
-
- const bob = Deno.listenDatagram({
- port: listenPort,
- transport: "udp",
- hostname: "0.0.0.0",
- });
- assert(bob.addr.transport === "udp");
- assertEquals(bob.addr.port, listenPort);
- assertEquals(bob.addr.hostname, "0.0.0.0");
-
- const broadcastAddr = { ...bob.addr, hostname: "255.255.255.255" };
-
- const sent = new Uint8Array([1, 2, 3]);
- const byteLength = await alice.send(sent, broadcastAddr);
-
- assertEquals(byteLength, 3);
- const [recvd, remote] = await bob.receive();
- assert(remote.transport === "udp");
- assertEquals(remote.port, listenPort);
- assertEquals(recvd.length, 3);
- assertEquals(1, recvd[0]);
- assertEquals(2, recvd[1]);
- assertEquals(3, recvd[2]);
- alice.close();
- bob.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true }, ignore: true },
- async function netUdpMulticastV4() {
- const listener = Deno.listenDatagram({
- hostname: "0.0.0.0",
- port: 5353,
- transport: "udp",
- reuseAddress: true,
- });
-
- const membership = await listener.joinMulticastV4(
- "224.0.0.251",
- "127.0.0.1",
- );
-
- membership.setLoopback(true);
- membership.setLoopback(false);
- membership.setTTL(50);
- membership.leave();
- listener.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true }, ignore: true },
- async function netUdpMulticastV6() {
- const listener = Deno.listenDatagram({
- hostname: "::",
- port: 5353,
- transport: "udp",
- reuseAddress: true,
- });
-
- const membership = await listener.joinMulticastV6(
- "ff02::fb",
- 1,
- );
-
- membership.setLoopback(true);
- membership.setLoopback(false);
- membership.leave();
- listener.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true }, ignore: true },
- async function netUdpSendReceiveMulticastv4() {
- const alice = Deno.listenDatagram({
- hostname: "0.0.0.0",
- port: 5353,
- transport: "udp",
- reuseAddress: true,
- loopback: true,
- });
-
- const bob = Deno.listenDatagram({
- hostname: "0.0.0.0",
- port: 5353,
- transport: "udp",
- reuseAddress: true,
- });
-
- const aliceMembership = await alice.joinMulticastV4(
- "224.0.0.1",
- "0.0.0.0",
- );
-
- const bobMembership = await bob.joinMulticastV4("224.0.0.1", "0.0.0.0");
-
- const sent = new Uint8Array([1, 2, 3]);
-
- await alice.send(sent, {
- hostname: "224.0.0.1",
- port: 5353,
- transport: "udp",
- });
-
- const [recvd, remote] = await bob.receive();
-
- assert(remote.transport === "udp");
- assertEquals(remote.port, 5353);
- assertEquals(recvd.length, 3);
- assertEquals(1, recvd[0]);
- assertEquals(2, recvd[1]);
- assertEquals(3, recvd[2]);
-
- aliceMembership.leave();
- bobMembership.leave();
-
- alice.close();
- bob.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true }, ignore: true },
- async function netUdpMulticastLoopbackOption() {
- // Must bind sender to an address that can send to the broadcast address on MacOS.
- // Macos will give us error 49 when sending the broadcast packet if we omit hostname here.
- const listener = Deno.listenDatagram({
- port: 5353,
- transport: "udp",
- hostname: "0.0.0.0",
- loopback: true,
- reuseAddress: true,
- });
-
- const membership = await listener.joinMulticastV4(
- "224.0.0.1",
- "0.0.0.0",
- );
-
- // await membership.setLoopback(true);
-
- const sent = new Uint8Array([1, 2, 3]);
- const byteLength = await listener.send(sent, {
- hostname: "224.0.0.1",
- port: 5353,
- transport: "udp",
- });
-
- assertEquals(byteLength, 3);
- const [recvd, remote] = await listener.receive();
- assert(remote.transport === "udp");
- assertEquals(remote.port, 5353);
- assertEquals(recvd.length, 3);
- assertEquals(1, recvd[0]);
- assertEquals(2, recvd[1]);
- assertEquals(3, recvd[2]);
- membership.leave();
- listener.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netUdpConcurrentSendReceive() {
- const socket = Deno.listenDatagram({ port: listenPort, transport: "udp" });
- assert(socket.addr.transport === "udp");
- assertEquals(socket.addr.port, listenPort);
- assertEquals(socket.addr.hostname, "127.0.0.1");
-
- const recvPromise = socket.receive();
-
- const sendBuf = new Uint8Array([1, 2, 3]);
- const sendLen = await socket.send(sendBuf, socket.addr);
- assertEquals(sendLen, 3);
-
- const [recvBuf, _recvAddr] = await recvPromise;
- assertEquals(recvBuf.length, 3);
- assertEquals(1, recvBuf[0]);
- assertEquals(2, recvBuf[1]);
- assertEquals(3, recvBuf[2]);
-
- socket.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netUdpBorrowMutError() {
- const socket = Deno.listenDatagram({
- port: listenPort,
- transport: "udp",
- });
- // Panic happened on second send: BorrowMutError
- const a = socket.send(new Uint8Array(), socket.addr);
- const b = socket.send(new Uint8Array(), socket.addr);
- await Promise.all([a, b]);
- socket.close();
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- async function netUnixPacketSendReceive() {
- const aliceFilePath = tmpUnixSocketPath();
- const alice = Deno.listenDatagram({
- path: aliceFilePath,
- transport: "unixpacket",
- });
- assert(alice.addr.transport === "unixpacket");
- assertEquals(alice.addr.path, aliceFilePath);
-
- const bobFilePath = tmpUnixSocketPath();
- const bob = Deno.listenDatagram({
- path: bobFilePath,
- transport: "unixpacket",
- });
- assert(bob.addr.transport === "unixpacket");
- assertEquals(bob.addr.path, bobFilePath);
-
- const sent = new Uint8Array([1, 2, 3]);
- const byteLength = await alice.send(sent, bob.addr);
- assertEquals(byteLength, 3);
-
- const [recvd, remote] = await bob.receive();
- assert(remote.transport === "unixpacket");
- assertEquals(remote.path, aliceFilePath);
- assertEquals(recvd.length, 3);
- assertEquals(1, recvd[0]);
- assertEquals(2, recvd[1]);
- assertEquals(3, recvd[2]);
- alice.close();
- bob.close();
- },
-);
-
-// TODO(lucacasonato): support concurrent reads and writes on unixpacket sockets
-Deno.test(
- { ignore: true, permissions: { read: true, write: true } },
- async function netUnixPacketConcurrentSendReceive() {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listenDatagram({
- path: filePath,
- transport: "unixpacket",
- });
- assert(socket.addr.transport === "unixpacket");
- assertEquals(socket.addr.path, filePath);
-
- const recvPromise = socket.receive();
-
- const sendBuf = new Uint8Array([1, 2, 3]);
- const sendLen = await socket.send(sendBuf, socket.addr);
- assertEquals(sendLen, 3);
-
- const [recvBuf, _recvAddr] = await recvPromise;
- assertEquals(recvBuf.length, 3);
- assertEquals(1, recvBuf[0]);
- assertEquals(2, recvBuf[1]);
- assertEquals(3, recvBuf[2]);
-
- socket.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netTcpListenIteratorBreakClosesResource() {
- async function iterate(listener: Deno.Listener) {
- let i = 0;
-
- for await (const conn of listener) {
- conn.close();
- i++;
-
- if (i > 1) {
- break;
- }
- }
- }
-
- const addr = { hostname: "127.0.0.1", port: 8888 };
- const listener = Deno.listen(addr);
- const iteratePromise = iterate(listener);
-
- await delay(100);
- const conn1 = await Deno.connect(addr);
- conn1.close();
- const conn2 = await Deno.connect(addr);
- conn2.close();
-
- await iteratePromise;
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netTcpListenCloseWhileIterating() {
- const listener = Deno.listen({ port: 8001 });
- const nextWhileClosing = listener[Symbol.asyncIterator]().next();
- listener.close();
- assertEquals(await nextWhileClosing, { value: undefined, done: true });
-
- const nextAfterClosing = listener[Symbol.asyncIterator]().next();
- assertEquals(await nextAfterClosing, { value: undefined, done: true });
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netUdpListenCloseWhileIterating() {
- const socket = Deno.listenDatagram({ port: 8000, transport: "udp" });
- const nextWhileClosing = socket[Symbol.asyncIterator]().next();
- socket.close();
- assertEquals(await nextWhileClosing, { value: undefined, done: true });
-
- const nextAfterClosing = socket[Symbol.asyncIterator]().next();
- assertEquals(await nextAfterClosing, { value: undefined, done: true });
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- async function netUnixListenCloseWhileIterating() {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listen({ path: filePath, transport: "unix" });
- const nextWhileClosing = socket[Symbol.asyncIterator]().next();
- socket.close();
- assertEquals(await nextWhileClosing, { value: undefined, done: true });
-
- const nextAfterClosing = socket[Symbol.asyncIterator]().next();
- assertEquals(await nextAfterClosing, { value: undefined, done: true });
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
- },
- async function netUnixPacketListenCloseWhileIterating() {
- const filePath = tmpUnixSocketPath();
- const socket = Deno.listenDatagram({
- path: filePath,
- transport: "unixpacket",
- });
- const nextWhileClosing = socket[Symbol.asyncIterator]().next();
- socket.close();
- assertEquals(await nextWhileClosing, { value: undefined, done: true });
-
- const nextAfterClosing = socket[Symbol.asyncIterator]().next();
- assertEquals(await nextAfterClosing, { value: undefined, done: true });
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netListenAsyncIterator() {
- const addr = { hostname: "127.0.0.1", port: listenPort };
- const listener = Deno.listen(addr);
- const runAsyncIterator = async () => {
- for await (const conn of listener) {
- await conn.write(new Uint8Array([1, 2, 3]));
- conn.close();
- }
- };
- runAsyncIterator();
- const conn = await Deno.connect(addr);
- const buf = new Uint8Array(1024);
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- assert(conn.rid > 0);
-
- assert(readResult !== null);
-
- const readResult2 = await conn.read(buf);
- assertEquals(readResult2, null);
-
- listener.close();
- conn.close();
- },
-);
-
-Deno.test(
- {
- permissions: { net: true },
- },
- async function netCloseWriteSuccess() {
- const addr = { hostname: "127.0.0.1", port: listenPort };
- const listener = Deno.listen(addr);
- const { promise: closePromise, resolve } = Promise.withResolvers<void>();
- listener.accept().then(async (conn) => {
- await conn.write(new Uint8Array([1, 2, 3]));
- await closePromise;
- conn.close();
- });
- const conn = await Deno.connect(addr);
- conn.closeWrite(); // closing write
- const buf = new Uint8Array(1024);
- // Check read not impacted
- const readResult = await conn.read(buf);
- assertEquals(3, readResult);
- assertEquals(1, buf[0]);
- assertEquals(2, buf[1]);
- assertEquals(3, buf[2]);
- // Verify that the write end of the socket is closed.
- // TODO(piscisaureus): assert that thrown error is of a specific type.
- await assertRejects(async () => {
- await conn.write(new Uint8Array([1, 2, 3]));
- });
- resolve();
- listener.close();
- conn.close();
- },
-);
-
-Deno.test(
- {
- // https://github.com/denoland/deno/issues/11580
- ignore: Deno.build.os === "darwin" && isCI,
- permissions: { net: true },
- },
- async function netHangsOnClose() {
- let acceptedConn: Deno.Conn;
-
- async function iteratorReq(listener: Deno.Listener) {
- const p = new Uint8Array(10);
- const conn = await listener.accept();
- acceptedConn = conn;
-
- try {
- while (true) {
- const nread = await conn.read(p);
- if (nread === null) {
- break;
- }
- await conn.write(new Uint8Array([1, 2, 3]));
- }
- } catch (err) {
- assert(err);
- assert(err instanceof Deno.errors.Interrupted);
- }
- }
-
- const addr = { hostname: "127.0.0.1", port: listenPort };
- const listener = Deno.listen(addr);
- const listenerPromise = iteratorReq(listener);
- const connectionPromise = (async () => {
- const conn = await Deno.connect(addr);
- await conn.write(new Uint8Array([1, 2, 3, 4]));
- const buf = new Uint8Array(10);
- await conn.read(buf);
- conn!.close();
- acceptedConn!.close();
- listener.close();
- })();
-
- await Promise.all([
- listenerPromise,
- connectionPromise,
- ]);
- },
-);
-
-Deno.test(
- {
- permissions: { net: true },
- },
- function netExplicitUndefinedHostname() {
- const listener = Deno.listen({ hostname: undefined, port: 8080 });
- assertEquals((listener.addr as Deno.NetAddr).hostname, "0.0.0.0");
- listener.close();
- },
-);
-
-Deno.test(
- {
- ignore: Deno.build.os !== "linux",
- permissions: { read: true, write: true },
- },
- function netUnixAbstractPathShouldNotPanic() {
- const listener = Deno.listen({
- path: "\0aaa",
- transport: "unix",
- });
- assert("not panic");
- listener.close();
- },
-);
-
-Deno.test({ permissions: { net: true } }, async function whatwgStreams() {
- const server = (async () => {
- const listener = Deno.listen({ hostname: "127.0.0.1", port: listenPort });
- const conn = await listener.accept();
- await conn.readable.pipeTo(conn.writable);
- listener.close();
- })();
-
- const conn = await Deno.connect({ hostname: "127.0.0.1", port: listenPort });
- const reader = conn.readable.getReader();
- const writer = conn.writable.getWriter();
- const encoder = new TextEncoder();
- const decoder = new TextDecoder();
- const data = encoder.encode("Hello World");
-
- await writer.write(data);
- const { value, done } = await reader.read();
- assert(!done);
- assertEquals(decoder.decode(value), "Hello World");
- await reader.cancel();
- await server;
-});
-
-Deno.test(
- { permissions: { read: true } },
- async function readableStreamTextEncoderPipe() {
- const filename = "cli/tests/testdata/assets/hello.txt";
- const file = await Deno.open(filename);
- const readable = file.readable.pipeThrough(new TextDecoderStream());
- const chunks = [];
- for await (const chunk of readable) {
- chunks.push(chunk);
- }
- assertEquals(chunks.length, 1);
- assertEquals(chunks[0].length, 12);
- },
-);
-
-Deno.test(
- { permissions: { read: true, write: true } },
- async function writableStream() {
- const path = await Deno.makeTempFile();
- const file = await Deno.open(path, { write: true });
- assert(file.writable instanceof WritableStream);
- const readable = new ReadableStream({
- start(controller) {
- controller.enqueue(new TextEncoder().encode("hello "));
- controller.enqueue(new TextEncoder().encode("world!"));
- controller.close();
- },
- });
- await readable.pipeTo(file.writable);
- const res = await Deno.readTextFile(path);
- assertEquals(res, "hello world!");
- },
-);
-
-Deno.test(
- { permissions: { read: true, run: true } },
- async function netListenUnref() {
- const [statusCode, _output] = await execCode(`
- async function main() {
- const listener = Deno.listen({ port: ${listenPort} });
- listener.unref();
- await listener.accept(); // This doesn't block the program from exiting
- }
- main();
- `);
- assertEquals(statusCode, 0);
- },
-);
-
-Deno.test(
- { permissions: { read: true, run: true } },
- async function netListenUnref2() {
- const [statusCode, _output] = await execCode(`
- async function main() {
- const listener = Deno.listen({ port: ${listenPort} });
- await listener.accept();
- listener.unref();
- await listener.accept(); // The program exits here
- throw new Error(); // The program doesn't reach here
- }
- main();
- const conn = await Deno.connect({ port: ${listenPort} });
- conn.close();
- `);
- assertEquals(statusCode, 0);
- },
-);
-
-Deno.test(
- { permissions: { read: true, run: true, net: true } },
- async function netListenUnrefAndRef() {
- const p = execCode2(`
- async function main() {
- const listener = Deno.listen({ port: ${listenPort} });
- listener.unref();
- listener.ref(); // This restores 'ref' state of listener
- console.log("started");
- await listener.accept();
- console.log("accepted")
- }
- main();
- `);
- await p.waitStdoutText("started");
- const conn = await Deno.connect({ port: listenPort });
- conn.close();
- const [statusCode, output] = await p.finished();
- assertEquals(statusCode, 0);
- assertEquals(output.trim(), "started\naccepted");
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function netListenUnrefConcurrentAccept() {
- const timer = setTimeout(() => {}, 1000);
- const listener = Deno.listen({ port: listenPort });
- listener.accept().catch(() => {});
- listener.unref();
- // Unref'd listener still causes Busy error
- // on concurrent accept calls.
- await assertRejects(async () => {
- await listener.accept(); // The program exits here
- }, Deno.errors.Busy);
- listener.close();
- clearTimeout(timer);
- },
-);
-
-Deno.test({
- ignore: Deno.build.os === "windows",
- permissions: { read: true, write: true },
-}, function netUnixListenAddrAlreadyInUse() {
- const filePath = tmpUnixSocketPath();
- const listener = Deno.listen({ path: filePath, transport: "unix" });
- assertThrows(
- () => {
- Deno.listen({ path: filePath, transport: "unix" });
- },
- Deno.errors.AddrInUse,
- );
- listener.close();
-});
-
-Deno.test(
- { permissions: { net: true, read: true, run: true } },
- async function netConnUnref() {
- const listener = Deno.listen({ port: listenPort });
- const intervalId = setInterval(() => {}); // This keeps event loop alive.
-
- const program = execCode(`
- async function main() {
- const conn = await Deno.connect({ port: ${listenPort} });
- conn.unref();
- await conn.read(new Uint8Array(10)); // The program exits here
- throw new Error(); // The program doesn't reach here
- }
- main();
- `);
- const conn = await listener.accept();
- const [statusCode, _output] = await program;
- conn.close();
- listener.close();
- clearInterval(intervalId);
- assertEquals(statusCode, 0);
- },
-);
-
-Deno.test(
- { permissions: { net: true, read: true, run: true } },
- async function netConnUnrefReadable() {
- const listener = Deno.listen({ port: listenPort });
- const intervalId = setInterval(() => {}); // This keeps event loop alive.
-
- const program = execCode(`
- async function main() {
- const conn = await Deno.connect({ port: ${listenPort} });
- conn.unref();
- const reader = conn.readable.getReader();
- await reader.read(); // The program exits here
- throw new Error(); // The program doesn't reach here
- }
- main();
- `);
- const conn = await listener.accept();
- const [statusCode, _output] = await program;
- conn.close();
- listener.close();
- clearInterval(intervalId);
- assertEquals(statusCode, 0);
- },
-);
-
-Deno.test({ permissions: { net: true } }, async function netTcpReuseAddr() {
- const listener1 = Deno.listen({
- hostname: "127.0.0.1",
- port: listenPort,
- });
- listener1.accept().then(
- (conn) => {
- conn.close();
- },
- );
-
- const conn1 = await Deno.connect({ hostname: "127.0.0.1", port: listenPort });
- const buf1 = new Uint8Array(1024);
- await conn1.read(buf1);
- listener1.close();
- conn1.close();
-
- const listener2 = Deno.listen({
- hostname: "127.0.0.1",
- port: listenPort,
- });
-
- listener2.accept().then(
- (conn) => {
- conn.close();
- },
- );
-
- const conn2 = await Deno.connect({ hostname: "127.0.0.1", port: listenPort });
- const buf2 = new Uint8Array(1024);
- await conn2.read(buf2);
-
- listener2.close();
- conn2.close();
-});
-
-Deno.test(
- { permissions: { net: true } },
- async function netUdpReuseAddr() {
- const sender = Deno.listenDatagram({
- port: 4002,
- transport: "udp",
- });
- const listener1 = Deno.listenDatagram({
- port: 4000,
- transport: "udp",
- reuseAddress: true,
- });
- const listener2 = Deno.listenDatagram({
- port: 4000,
- transport: "udp",
- reuseAddress: true,
- });
-
- const sent = new Uint8Array([1, 2, 3]);
- await sender.send(sent, listener1.addr);
- await Promise.any([listener1.receive(), listener2.receive()]).then(
- ([recvd, remote]) => {
- assert(remote.transport === "udp");
- assertEquals(recvd.length, 3);
- assertEquals(1, recvd[0]);
- assertEquals(2, recvd[1]);
- assertEquals(3, recvd[2]);
- },
- );
- sender.close();
- listener1.close();
- listener2.close();
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- function netUdpNoReuseAddr() {
- let listener1;
- try {
- listener1 = Deno.listenDatagram({
- port: 4001,
- transport: "udp",
- reuseAddress: false,
- });
- } catch (err) {
- assert(err);
- assert(err instanceof Deno.errors.AddrInUse); // AddrInUse from previous test
- }
-
- assertThrows(() => {
- Deno.listenDatagram({
- port: 4001,
- transport: "udp",
- reuseAddress: false,
- });
- }, Deno.errors.AddrInUse);
- if (typeof listener1 !== "undefined") {
- listener1.close();
- }
- },
-);
-
-Deno.test({
- ignore: Deno.build.os !== "linux",
- permissions: { net: true },
-}, async function netTcpListenReusePort() {
- const port = 4003;
- const listener1 = Deno.listen({ port, reusePort: true });
- const listener2 = Deno.listen({ port, reusePort: true });
- let p1;
- let p2;
- let listener1Recv = false;
- let listener2Recv = false;
- while (!listener1Recv || !listener2Recv) {
- if (!p1) {
- p1 = listener1.accept().then((conn) => {
- conn.close();
- listener1Recv = true;
- p1 = undefined;
- }).catch(() => {});
- }
- if (!p2) {
- p2 = listener2.accept().then((conn) => {
- conn.close();
- listener2Recv = true;
- p2 = undefined;
- }).catch(() => {});
- }
- const conn = await Deno.connect({ port });
- conn.close();
- await Promise.race([p1, p2]);
- }
- listener1.close();
- listener2.close();
-});
-
-Deno.test({
- ignore: Deno.build.os === "linux",
- permissions: { net: true },
-}, function netTcpListenReusePortDoesNothing() {
- const listener1 = Deno.listen({ port: 4003, reusePort: true });
- assertThrows(() => {
- Deno.listen({ port: 4003, reusePort: true });
- }, Deno.errors.AddrInUse);
- listener1.close();
-});
-
-Deno.test({
- permissions: { net: true },
-}, function netTcpListenDoesNotThrowOnStringPort() {
- // @ts-ignore String port is not allowed by typing, but it shouldn't throw
- // for backwards compatibility.
- const listener = Deno.listen({ hostname: "localhost", port: "0" });
- listener.close();
-});
-
-Deno.test(
- { permissions: { net: true } },
- async function listenerExplicitResourceManagement() {
- let done: Promise<Deno.errors.BadResource>;
-
- {
- using listener = Deno.listen({ port: listenPort });
-
- done = assertRejects(
- () => listener.accept(),
- Deno.errors.BadResource,
- );
- }
-
- await done;
- },
-);
-
-Deno.test(
- { permissions: { net: true } },
- async function listenerExplicitResourceManagementManualClose() {
- using listener = Deno.listen({ port: listenPort });
- listener.close();
- await assertRejects( // definitely closed
- () => listener.accept(),
- Deno.errors.BadResource,
- );
- // calling [Symbol.dispose] after manual close is a no-op
- },
-);