diff options
Diffstat (limited to 'test/js')
| -rw-r--r-- | test/js/web/fetch/fetch-leak-test-fixture-2.js | 26 | ||||
| -rw-r--r-- | test/js/web/fetch/fetch-leak-test-fixture.js | 34 | ||||
| -rw-r--r-- | test/js/web/fetch/fetch-leak.test.js | 55 |
3 files changed, 115 insertions, 0 deletions
diff --git a/test/js/web/fetch/fetch-leak-test-fixture-2.js b/test/js/web/fetch/fetch-leak-test-fixture-2.js new file mode 100644 index 000000000..7379b1b7b --- /dev/null +++ b/test/js/web/fetch/fetch-leak-test-fixture-2.js @@ -0,0 +1,26 @@ +import { heapStats } from "bun:jsc"; + +const { SERVER } = process.env; + +if (typeof SERVER === "undefined" || !SERVER?.length) { + throw new Error("SERVER environment variable is not set"); +} + +const COUNT = parseInt(process.env.COUNT || "20", 10); +var oks = 0; +await (async function runAll() { + for (let j = 0; j < COUNT; j++) { + oks += (await fetch(SERVER)).ok; + } +})(); + +if (oks !== COUNT) { + throw new Error("Not all requests succeeded"); +} + +await Bun.sleep(10); +Bun.gc(true); + +if ((heapStats().objectTypeCounts.Response ?? 0) > 5) { + throw new Error("Too many Response objects: " + heapStats().objectTypeCounts.Response); +} diff --git a/test/js/web/fetch/fetch-leak-test-fixture.js b/test/js/web/fetch/fetch-leak-test-fixture.js new file mode 100644 index 000000000..07275a425 --- /dev/null +++ b/test/js/web/fetch/fetch-leak-test-fixture.js @@ -0,0 +1,34 @@ +import { heapStats } from "bun:jsc"; + +const { SERVER } = process.env; + +if (typeof SERVER === "undefined" || !SERVER?.length) { + throw new Error("SERVER environment variable is not set"); +} + +const COUNT = parseInt(process.env.COUNT || "50", 10); +await (async function runAll() { + var fetches = new Array(COUNT); + let i = 0; + while (i < Math.max(COUNT - 32, 0)) { + for (let j = 0; j < 32; j++) { + fetches.push(fetch(SERVER)); + } + await Promise.all(fetches.slice(i, i + 32)); + i += 32; + } + + while (i++ < COUNT) { + fetches.push(fetch(SERVER)); + } + + await Promise.all(fetches); + fetches.length = 0; + fetches = []; +})(); +await Bun.sleep(10); +Bun.gc(true); + +if ((heapStats().objectTypeCounts.Response ?? 0) > 10) { + throw new Error("Too many Response objects: " + heapStats().objectTypeCounts.Response); +} diff --git a/test/js/web/fetch/fetch-leak.test.js b/test/js/web/fetch/fetch-leak.test.js new file mode 100644 index 000000000..fa8b225bd --- /dev/null +++ b/test/js/web/fetch/fetch-leak.test.js @@ -0,0 +1,55 @@ +import { test, expect, describe } from "bun:test"; +import { join } from "node:path"; +import { bunEnv, bunExe } from "harness"; + +describe("fetch doesn't leak", () => { + test("fixture #1", async () => { + const body = new Blob(["some body in here!".repeat(100)]); + const server = Bun.serve({ + port: 0, + + fetch(req) { + return new Response(body); + }, + }); + + const proc = Bun.spawn({ + env: { + ...bunEnv, + SERVER: `http://${server.hostname}:${server.port}`, + }, + stderr: "inherit", + stdout: "inherit", + cmd: [bunExe(), join(import.meta.dir, "fetch-leak-test-fixture.js")], + }); + + const exitCode = await proc.exited; + server.stop(true); + expect(exitCode).toBe(0); + }); + + test("fixture #2", async () => { + const body = new Blob(["some body in here!".repeat(100)]); + const server = Bun.serve({ + port: 0, + + fetch(req) { + return new Response(body); + }, + }); + + const proc = Bun.spawn({ + env: { + ...bunEnv, + SERVER: `http://${server.hostname}:${server.port}`, + }, + stderr: "inherit", + stdout: "inherit", + cmd: [bunExe(), join(import.meta.dir, "fetch-leak-test-fixture-2.js")], + }); + + const exitCode = await proc.exited; + server.stop(true); + expect(exitCode).toBe(0); + }); +}); |
