aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/js/bun/net/echo.js8
-rw-r--r--test/js/node/net/node-net.test.ts4
-rw-r--r--test/js/web/fetch/body-stream.test.ts474
-rw-r--r--test/js/web/fetch/fetch-gzip.test.ts10
-rw-r--r--test/js/web/fetch/fetch_headers.test.js8
-rw-r--r--test/js/web/websocket/websocket.test.js11
6 files changed, 269 insertions, 246 deletions
diff --git a/test/js/bun/net/echo.js b/test/js/bun/net/echo.js
index f02637739..28ded3658 100644
--- a/test/js/bun/net/echo.js
+++ b/test/js/bun/net/echo.js
@@ -36,7 +36,7 @@ function createOptions(type, message, closeOnDone) {
return {
hostname: "localhost",
- port: 12345,
+ port: 0,
socket: {
close() {
report();
@@ -73,4 +73,8 @@ const server = Bun.listen(
socket.end();
}),
);
-Bun.connect(createOptions("[Client]", "request"));
+
+await Bun.connect({
+ ...createOptions("[Client]", "request"),
+ port: server.port,
+});
diff --git a/test/js/node/net/node-net.test.ts b/test/js/node/net/node-net.test.ts
index fae1a50f7..02348487f 100644
--- a/test/js/node/net/node-net.test.ts
+++ b/test/js/node/net/node-net.test.ts
@@ -70,7 +70,7 @@ describe("net.Socket read", () => {
}
: {
hostname: "localhost",
- port: port++,
+ port: 0,
socket: {
open(socket) {
socket.data.message = message;
@@ -249,7 +249,7 @@ describe("net.Socket write", () => {
var leaky;
server = Bun.listen({
hostname: "0.0.0.0",
- port: port++,
+ port: 0,
socket: {
close,
data(socket, buffer) {
diff --git a/test/js/web/fetch/body-stream.test.ts b/test/js/web/fetch/body-stream.test.ts
index ecfa3e7be..55a7570b3 100644
--- a/test/js/web/fetch/body-stream.test.ts
+++ b/test/js/web/fetch/body-stream.test.ts
@@ -143,7 +143,7 @@ async function runInServer(opts: ServeOptions, cb: (url: string) => void | Promi
var server;
const handler = {
...opts,
- port: port++,
+ port: 0,
fetch(req) {
try {
return opts.fetch(req);
@@ -197,256 +197,276 @@ function gc() {
}
describe("reader", function () {
- try {
- // - 1 byte
- // - less than the InlineBlob limit
- // - multiple chunks
- // - backpressure
- for (let inputLength of [1, 2, 12, 95, 1024, 1024 * 1024, 1024 * 1024 * 2]) {
- var bytes = new Uint8Array(inputLength);
- {
- const chunk = Math.min(bytes.length, 256);
- for (var i = 0; i < chunk; i++) {
- bytes[i] = 255 - i;
+ for (let withDelay of [false, true]) {
+ try {
+ // - 1 byte
+ // - less than the InlineBlob limit
+ // - multiple chunks
+ // - backpressure
+
+ for (let inputLength of [1, 2, 12, 95, 1024, 1024 * 1024, 1024 * 1024 * 2]) {
+ var bytes = new Uint8Array(inputLength);
+ {
+ const chunk = Math.min(bytes.length, 256);
+ for (var i = 0; i < chunk; i++) {
+ bytes[i] = 255 - i;
+ }
}
- }
- if (bytes.length > 255) fillRepeating(bytes, 0, bytes.length);
-
- for (const huge_ of [
- bytes,
- bytes.buffer,
- new DataView(bytes.buffer),
- new Int8Array(bytes),
- new Blob([bytes]),
-
- new Uint16Array(bytes),
- new Uint32Array(bytes),
- new Float64Array(bytes),
-
- new Int16Array(bytes),
- new Int32Array(bytes),
- new Float32Array(bytes),
-
- // make sure we handle subarray() as expected when reading
- // typed arrays from native code
- new Int16Array(bytes).subarray(1),
- new Int16Array(bytes).subarray(0, new Int16Array(bytes).byteLength - 1),
- new Int32Array(bytes).subarray(1),
- new Int32Array(bytes).subarray(0, new Int32Array(bytes).byteLength - 1),
- new Float32Array(bytes).subarray(1),
- new Float32Array(bytes).subarray(0, new Float32Array(bytes).byteLength - 1),
- new Int16Array(bytes).subarray(0, 1),
- new Int32Array(bytes).subarray(0, 1),
- new Float32Array(bytes).subarray(0, 1),
- ]) {
- gc();
- const thisArray = huge_;
- if (Number(thisArray.byteLength ?? thisArray.size) === 0) continue;
-
- it(`works with ${thisArray.constructor.name}(${
- thisArray.byteLength ?? thisArray.size
- }:${inputLength}) via req.body.getReader() in chunks`, async () => {
- var huge = thisArray;
- var called = false;
+ if (bytes.length > 255) fillRepeating(bytes, 0, bytes.length);
+
+ for (const huge_ of [
+ bytes,
+ bytes.buffer,
+ new DataView(bytes.buffer),
+ new Int8Array(bytes),
+ new Blob([bytes]),
+
+ new Uint16Array(bytes),
+ new Uint32Array(bytes),
+ new Float64Array(bytes),
+
+ new Int16Array(bytes),
+ new Int32Array(bytes),
+ new Float32Array(bytes),
+
+ // make sure we handle subarray() as expected when reading
+ // typed arrays from native code
+ new Int16Array(bytes).subarray(1),
+ new Int16Array(bytes).subarray(0, new Int16Array(bytes).byteLength - 1),
+ new Int32Array(bytes).subarray(1),
+ new Int32Array(bytes).subarray(0, new Int32Array(bytes).byteLength - 1),
+ new Float32Array(bytes).subarray(1),
+ new Float32Array(bytes).subarray(0, new Float32Array(bytes).byteLength - 1),
+ new Int16Array(bytes).subarray(0, 1),
+ new Int32Array(bytes).subarray(0, 1),
+ new Float32Array(bytes).subarray(0, 1),
+ ]) {
gc();
+ const thisArray = huge_;
+ if (Number(thisArray.byteLength ?? thisArray.size) === 0) continue;
+
+ it(
+ `works with ${thisArray.constructor.name}(${
+ thisArray.byteLength ?? thisArray.size
+ }:${inputLength}) via req.body.getReader() in chunks` + (withDelay ? " with delay" : ""),
+ async () => {
+ var huge = thisArray;
+ var called = false;
+ gc();
- const expectedHash =
- huge instanceof Blob
- ? Bun.SHA1.hash(new Uint8Array(await huge.arrayBuffer()), "base64")
- : Bun.SHA1.hash(huge, "base64");
- const expectedSize = huge instanceof Blob ? huge.size : huge.byteLength;
-
- const out = await runInServer(
- {
- async fetch(req) {
- try {
- expect(req.headers.get("x-custom")).toBe("hello");
- expect(req.headers.get("content-type")).toBe("text/plain");
- expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
-
+ const expectedHash =
+ huge instanceof Blob
+ ? Bun.SHA1.hash(new Uint8Array(await huge.arrayBuffer()), "base64")
+ : Bun.SHA1.hash(huge, "base64");
+ const expectedSize = huge instanceof Blob ? huge.size : huge.byteLength;
+
+ const out = await runInServer(
+ {
+ async fetch(req) {
+ try {
+ if (withDelay) await 1;
+
+ expect(req.headers.get("x-custom")).toBe("hello");
+ expect(req.headers.get("content-type")).toBe("text/plain");
+ expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
+
+ gc();
+ expect(req.headers.get("x-custom")).toBe("hello");
+ expect(req.headers.get("content-type")).toBe("text/plain");
+ expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
+
+ var reader = req.body.getReader();
+ called = true;
+ var buffers = [];
+ while (true) {
+ var { done, value } = await reader.read();
+ if (done) break;
+ buffers.push(value);
+ }
+ const out = new Blob(buffers);
+ gc();
+ expect(out.size).toBe(expectedSize);
+ expect(Bun.SHA1.hash(await out.arrayBuffer(), "base64")).toBe(expectedHash);
+ expect(req.headers.get("x-custom")).toBe("hello");
+ expect(req.headers.get("content-type")).toBe("text/plain");
+ expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
+ gc();
+ return new Response(out, {
+ headers: req.headers,
+ });
+ } catch (e) {
+ console.error(e);
+ throw e;
+ }
+ },
+ },
+ async url => {
gc();
- expect(req.headers.get("x-custom")).toBe("hello");
- expect(req.headers.get("content-type")).toBe("text/plain");
- expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
-
- var reader = req.body.getReader();
- called = true;
- var buffers = [];
- while (true) {
- var { done, value } = await reader.read();
- if (done) break;
- buffers.push(value);
+ if (withDelay) await 1;
+ const pendingResponse = await fetch(url, {
+ body: huge,
+ method: "POST",
+ headers: {
+ "content-type": "text/plain",
+ "x-custom": "hello",
+ "x-typed-array": thisArray.constructor.name,
+ },
+ });
+ if (withDelay) {
+ await 1;
}
- const out = new Blob(buffers);
+ const response = await pendingResponse;
+ huge = undefined;
+ expect(response.status).toBe(200);
+ const response_body = new Uint8Array(await response.arrayBuffer());
+
+ expect(response_body.byteLength).toBe(expectedSize);
+ expect(Bun.SHA1.hash(response_body, "base64")).toBe(expectedHash);
+
gc();
- expect(out.size).toBe(expectedSize);
- expect(Bun.SHA1.hash(await out.arrayBuffer(), "base64")).toBe(expectedHash);
- expect(req.headers.get("x-custom")).toBe("hello");
- expect(req.headers.get("content-type")).toBe("text/plain");
- expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
+ expect(response.headers.get("content-type")).toBe("text/plain");
gc();
- return new Response(out, {
- headers: req.headers,
- });
- } catch (e) {
- console.error(e);
- throw e;
- }
- },
- },
- async url => {
- gc();
- const response = await fetch(url, {
- body: huge,
- method: "POST",
- headers: {
- "content-type": "text/plain",
- "x-custom": "hello",
- "x-typed-array": thisArray.constructor.name,
},
- });
- huge = undefined;
- expect(response.status).toBe(200);
- const response_body = new Uint8Array(await response.arrayBuffer());
-
- expect(response_body.byteLength).toBe(expectedSize);
- expect(Bun.SHA1.hash(response_body, "base64")).toBe(expectedHash);
-
- gc();
- expect(response.headers.get("content-type")).toBe("text/plain");
+ );
+ expect(called).toBe(true);
gc();
+ return out;
},
);
- expect(called).toBe(true);
- gc();
- return out;
- });
-
- for (let isDirectStream of [true, false]) {
- const positions = ["begin", "end"];
- const inner = thisArray => {
- for (let position of positions) {
- it(`streaming back ${thisArray.constructor.name}(${
- thisArray.byteLength ?? thisArray.size
- }:${inputLength}) starting request.body.getReader() at ${position}`, async () => {
- var huge = thisArray;
- var called = false;
- gc();
-
- const expectedHash =
- huge instanceof Blob
- ? Bun.SHA1.hash(new Uint8Array(await huge.arrayBuffer()), "base64")
- : Bun.SHA1.hash(huge, "base64");
- const expectedSize = huge instanceof Blob ? huge.size : huge.byteLength;
-
- const out = await runInServer(
- {
- async fetch(req) {
- try {
- var reader;
-
- if (position === "begin") {
- reader = req.body.getReader();
- }
- if (position === "end") {
- await 1;
- reader = req.body.getReader();
- }
+ for (let isDirectStream of [true, false]) {
+ const positions = ["begin", "end"];
+ const inner = thisArray => {
+ for (let position of positions) {
+ it(`streaming back ${thisArray.constructor.name}(${
+ thisArray.byteLength ?? thisArray.size
+ }:${inputLength}) starting request.body.getReader() at ${position}`, async () => {
+ var huge = thisArray;
+ var called = false;
+ gc();
- expect(req.headers.get("x-custom")).toBe("hello");
- expect(req.headers.get("content-type")).toBe("text/plain");
- expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
-
- gc();
- expect(req.headers.get("x-custom")).toBe("hello");
- expect(req.headers.get("content-type")).toBe("text/plain");
- expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
-
- const direct = {
- type: "direct",
- async pull(controller) {
- while (true) {
- const { done, value } = await reader.read();
- if (done) {
- called = true;
- controller.end();
-
- return;
+ const expectedHash =
+ huge instanceof Blob
+ ? Bun.SHA1.hash(new Uint8Array(await huge.arrayBuffer()), "base64")
+ : Bun.SHA1.hash(huge, "base64");
+ const expectedSize = huge instanceof Blob ? huge.size : huge.byteLength;
+
+ const out = await runInServer(
+ {
+ async fetch(req) {
+ try {
+ var reader;
+
+ if (withDelay) await 1;
+
+ if (position === "begin") {
+ reader = req.body.getReader();
+ }
+
+ if (position === "end") {
+ await 1;
+ reader = req.body.getReader();
+ }
+
+ expect(req.headers.get("x-custom")).toBe("hello");
+ expect(req.headers.get("content-type")).toBe("text/plain");
+ expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
+
+ gc();
+ expect(req.headers.get("x-custom")).toBe("hello");
+ expect(req.headers.get("content-type")).toBe("text/plain");
+ expect(req.headers.get("user-agent")).toBe(navigator.userAgent);
+
+ const direct = {
+ type: "direct",
+ async pull(controller) {
+ if (withDelay) await 1;
+
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) {
+ called = true;
+ controller.end();
+
+ return;
+ }
+ controller.write(value);
}
- controller.write(value);
- }
- },
- };
-
- const web = {
- async pull(controller) {
- while (true) {
- const { done, value } = await reader.read();
- if (done) {
- called = true;
- controller.close();
- return;
+ },
+ };
+
+ const web = {
+ async start() {
+ if (withDelay) await 1;
+ },
+ async pull(controller) {
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) {
+ called = true;
+ controller.close();
+ return;
+ }
+ controller.enqueue(value);
}
- controller.enqueue(value);
- }
- },
- };
-
- return new Response(new ReadableStream(isDirectStream ? direct : web), {
- headers: req.headers,
- });
- } catch (e) {
- console.error(e);
- throw e;
- }
- },
- },
- async url => {
- gc();
- const response = await fetch(url, {
- body: huge,
- method: "POST",
- headers: {
- "content-type": "text/plain",
- "x-custom": "hello",
- "x-typed-array": thisArray.constructor.name,
+ },
+ };
+
+ return new Response(new ReadableStream(isDirectStream ? direct : web), {
+ headers: req.headers,
+ });
+ } catch (e) {
+ console.error(e);
+ throw e;
+ }
},
- });
- huge = undefined;
- expect(response.status).toBe(200);
- const response_body = new Uint8Array(await response.arrayBuffer());
+ },
+ async url => {
+ gc();
+ const response = await fetch(url, {
+ body: huge,
+ method: "POST",
+ headers: {
+ "content-type": "text/plain",
+ "x-custom": "hello",
+ "x-typed-array": thisArray.constructor.name,
+ },
+ });
+ huge = undefined;
+ expect(response.status).toBe(200);
+ const response_body = new Uint8Array(await response.arrayBuffer());
- expect(response_body.byteLength).toBe(expectedSize);
- expect(Bun.SHA1.hash(response_body, "base64")).toBe(expectedHash);
+ expect(response_body.byteLength).toBe(expectedSize);
+ expect(Bun.SHA1.hash(response_body, "base64")).toBe(expectedHash);
- gc();
- if (!response.headers.has("content-type")) {
- console.error(Object.fromEntries(response.headers.entries()));
- }
+ gc();
+ if (!response.headers.has("content-type")) {
+ console.error(Object.fromEntries(response.headers.entries()));
+ }
- expect(response.headers.get("content-type")).toBe("text/plain");
- gc();
- },
- );
- expect(called).toBe(true);
- gc();
- return out;
- });
+ expect(response.headers.get("content-type")).toBe("text/plain");
+ gc();
+ },
+ );
+ expect(called).toBe(true);
+ gc();
+ return out;
+ });
+ }
+ };
+
+ if (isDirectStream) {
+ describe(" direct stream", () => inner(thisArray));
+ } else {
+ describe("default stream", () => inner(thisArray));
}
- };
-
- if (isDirectStream) {
- describe(" direct stream", () => inner(thisArray));
- } else {
- describe("default stream", () => inner(thisArray));
}
}
}
+ } catch (e) {
+ console.error(e);
+ throw e;
}
- } catch (e) {
- console.error(e);
- throw e;
}
});
diff --git a/test/js/web/fetch/fetch-gzip.test.ts b/test/js/web/fetch/fetch-gzip.test.ts
index 01eedc54a..91ea8de9f 100644
--- a/test/js/web/fetch/fetch-gzip.test.ts
+++ b/test/js/web/fetch/fetch-gzip.test.ts
@@ -5,7 +5,7 @@ import { gc, gcTick } from "harness";
it("fetch() with a buffered gzip response works (one chunk)", async () => {
var server = Bun.serve({
- port: 6025,
+ port: 0,
async fetch(req) {
gcTick(true);
@@ -35,7 +35,7 @@ it("fetch() with a buffered gzip response works (one chunk)", async () => {
it("fetch() with a redirect that returns a buffered gzip response works (one chunk)", async () => {
var server = Bun.serve({
- port: 6020,
+ port: 0,
async fetch(req) {
if (req.url.endsWith("/redirect"))
@@ -60,7 +60,7 @@ it("fetch() with a redirect that returns a buffered gzip response works (one chu
it("fetch() with a protocol-relative redirect that returns a buffered gzip response works (one chunk)", async () => {
const server = Bun.serve({
- port: 5018,
+ port: 0,
async fetch(req, server) {
if (req.url.endsWith("/redirect"))
@@ -89,7 +89,7 @@ it("fetch() with a protocol-relative redirect that returns a buffered gzip respo
it("fetch() with a gzip response works (one chunk, streamed, with a delay", async () => {
var server = Bun.serve({
- port: 6081,
+ port: 0,
fetch(req) {
return new Response(
@@ -126,7 +126,7 @@ it("fetch() with a gzip response works (multiple chunks, TCP server", async done
const compressed = await Bun.file(import.meta.dir + "/fixture.html.gz").arrayBuffer();
var socketToClose;
const server = Bun.listen({
- port: 4024,
+ port: 0,
hostname: "0.0.0.0",
socket: {
async open(socket) {
diff --git a/test/js/web/fetch/fetch_headers.test.js b/test/js/web/fetch/fetch_headers.test.js
index cd2786c08..7ee851bb0 100644
--- a/test/js/web/fetch/fetch_headers.test.js
+++ b/test/js/web/fetch/fetch_headers.test.js
@@ -1,6 +1,5 @@
import { describe, it, expect, beforeAll, afterAll } from "bun:test";
-const port = 3009;
-const url = `http://localhost:${port}`;
+let url = `http://localhost:0`;
let server;
describe("Headers", async () => {
@@ -11,11 +10,12 @@ describe("Headers", async () => {
const hdr = req.headers.get("x-test");
return new Response(hdr);
},
- port: port,
+ port: 0,
});
+ url = `http://${server.hostname}:${server.port}`;
});
afterAll(() => {
- server.stop();
+ server.stop(true);
});
it("Headers should work", async () => {
diff --git a/test/js/web/websocket/websocket.test.js b/test/js/web/websocket/websocket.test.js
index f0f29c1c3..99d60f292 100644
--- a/test/js/web/websocket/websocket.test.js
+++ b/test/js/web/websocket/websocket.test.js
@@ -33,7 +33,7 @@ describe("WebSocket", () => {
it("supports headers", done => {
const server = Bun.serve({
- port: 8024,
+ port: 0,
fetch(req, server) {
expect(req.headers.get("X-Hello")).toBe("World");
expect(req.headers.get("content-type")).toBe("lolwut");
@@ -57,7 +57,7 @@ describe("WebSocket", () => {
it("should connect over http", done => {
const server = Bun.serve({
- port: 8025,
+ port: 0,
fetch(req, server) {
server.stop();
done();
@@ -132,11 +132,10 @@ describe("WebSocket", () => {
});
describe("websocket in subprocess", () => {
- var port = 8765;
it("should exit", async () => {
let messageReceived = false;
const server = Bun.serve({
- port: port++,
+ port: 0,
fetch(req, server) {
if (server.upgrade(req)) {
return;
@@ -198,7 +197,7 @@ describe("websocket in subprocess", () => {
let messageReceived = false;
let start = 0;
const server = Bun.serve({
- port: port++,
+ port: 0,
fetch(req, server) {
if (server.upgrade(req)) {
return;
@@ -234,7 +233,7 @@ describe("websocket in subprocess", () => {
it("should exit after server stop and 0 messages", async () => {
const server = Bun.serve({
- port: port++,
+ port: 0,
fetch(req, server) {
if (server.upgrade(req)) {
return;