From 1cce9da80a51d49e423223f24f94fee6a044ab10 Mon Sep 17 00:00:00 2001 From: Jarred SUmner Date: Sat, 12 Nov 2022 18:32:53 -0800 Subject: Fix memory leak in gzip pool + add test for gzip'd data --- test/bun.js/fetch-gzip.test.ts | 116 ++++ test/bun.js/filesink.test.ts | 2 +- test/bun.js/fixture.html | 1395 ++++++++++++++++++++++++++++++++++++++++ test/bun.js/fixture.html.gz | Bin 0 -> 15530 bytes test/bun.js/spawn.test.ts | 3 +- 5 files changed, 1514 insertions(+), 2 deletions(-) create mode 100644 test/bun.js/fetch-gzip.test.ts create mode 100644 test/bun.js/fixture.html create mode 100644 test/bun.js/fixture.html.gz (limited to 'test/bun.js') diff --git a/test/bun.js/fetch-gzip.test.ts b/test/bun.js/fetch-gzip.test.ts new file mode 100644 index 000000000..a75e01701 --- /dev/null +++ b/test/bun.js/fetch-gzip.test.ts @@ -0,0 +1,116 @@ +import { concatArrayBuffers } from "bun"; +import { it, describe, expect } from "bun:test"; +import fs from "fs"; +import { gc } from "./gc"; + +it("fetch() with a buffered gzip response works (one chunk)", async () => { + var server = Bun.serve({ + port: 6025, + + async fetch(req) { + return new Response( + await Bun.file(import.meta.dir + "/fixture.html.gz").arrayBuffer(), + { + headers: { + "Content-Encoding": "gzip", + "Content-Type": "text/html; charset=utf-8", + }, + }, + ); + }, + }); + + const res = await fetch( + `http://${server.hostname}:${server.port}`, + {}, + { verbose: true }, + ); + const arrayBuffer = await res.arrayBuffer(); + expect( + new Buffer(arrayBuffer).equals( + new Buffer( + await Bun.file(import.meta.dir + "/fixture.html").arrayBuffer(), + ), + ), + ).toBe(true); + server.stop(); +}); + +it("fetch() with a gzip response works (one chunk)", async () => { + var server = Bun.serve({ + port: 6023, + + fetch(req) { + return new Response(Bun.file(import.meta.dir + "/fixture.html.gz"), { + headers: { + "Content-Encoding": "gzip", + "Content-Type": "text/html; charset=utf-8", + }, + }); + }, + }); + + const res = await fetch(`http://${server.hostname}:${server.port}`); + const arrayBuffer = await res.arrayBuffer(); + expect( + new Buffer(arrayBuffer).equals( + new Buffer( + await Bun.file(import.meta.dir + "/fixture.html").arrayBuffer(), + ), + ), + ).toBe(true); + server.stop(); +}); + +it("fetch() with a gzip response works (multiple chunks)", async () => { + var server = Bun.serve({ + port: 6024, + + fetch(req) { + return new Response( + new ReadableStream({ + type: "direct", + async pull(controller) { + var chunks: ArrayBuffer[] = []; + const buffer = await Bun.file( + import.meta.dir + "/fixture.html.gz", + ).arrayBuffer(); + var remaining = buffer; + for (var i = 100; i < buffer.byteLength; i += 100) { + var chunk = remaining.slice(0, i); + remaining = remaining.slice(i); + controller.write(chunk); + chunks.push(chunk); + await controller.flush(); + } + + await controller.flush(); + // sanity check + expect( + new Buffer(concatArrayBuffers(chunks)).equals(new Buffer(buffer)), + ).toBe(true); + + controller.end(); + }, + }), + { + headers: { + "Content-Encoding": "gzip", + "Content-Type": "text/html; charset=utf-8", + "Content-Length": "1", + }, + }, + ); + }, + }); + + const res = await fetch(`http://${server.hostname}:${server.port}`, {}); + const arrayBuffer = await res.arrayBuffer(); + expect( + new Buffer(arrayBuffer).equals( + new Buffer( + await Bun.file(import.meta.dir + "/fixture.html").arrayBuffer(), + ), + ), + ).toBe(true); +}); diff --git a/test/bun.js/filesink.test.ts b/test/bun.js/filesink.test.ts index b4a178613..038e8df19 100644 --- a/test/bun.js/filesink.test.ts +++ b/test/bun.js/filesink.test.ts @@ -85,7 +85,7 @@ describe("FileSink", () => { } catch (e) {} mkfifo(path, 0o666); activeFIFO = (async function (stream: ReadableStream) { - var chunks = []; + var chunks: Uint8Array[] = []; for await (const chunk of stream) { chunks.push(chunk); } diff --git a/test/bun.js/fixture.html b/test/bun.js/fixture.html new file mode 100644 index 000000000..929b73ce4 --- /dev/null +++ b/test/bun.js/fixture.html @@ -0,0 +1,1395 @@ + + + + + + +Bun is a fast all-in-one JavaScript runtime + + + + + + + + + + + + + + +
+
+Bun + +
+
+
+
+
+

Bun is a fast all-in-one JavaScript runtime

+

+Bundle, transpile, install and run JavaScript & TypeScript +projects — all in Bun. Bun is a new JavaScript runtime with a native +bundler, transpiler, task runner and npm client built-in. +

+
+
+
+Install Bun CLI +0.2.1 +(beta) +
+
+macOS x64 & Silicon, Linux x64, Windows Subsystem for Linux +
+
+
+
+curl https://bun.sh/install | bash +
+ +
+Show script source +
+
+
+
+ +
+
+
+

Server-side rendering React

+

+HTTP requests per second (Linux x64) +

+
    +
  • +
    +bun: 69,845 requests per second +
    + +
  • +
  • +
    +node: 16,288 requests per second +
    + +
  • +
  • +
    +deno: 12,926 requests per second +
    + +
  • +
+ +
+
+

WebSocket server chat

+

+Messages sent per second (Linux x64, 16 clients) +

+
    +
  • +
    +bun: 737,280 messages sent per second +
    + +
  • +
  • +
    +node: 107,457 messages sent per second +
    + +
  • +
  • +
    +deno: 82,097 messages sent per second +
    + +
  • +
+ +
+
+

Load a huge table

+

Average queries per second

+
    +
  • +
    +bun: 70.32 queries per second +
    + +
  • +
  • +
    +deno: 36.54 queries per second +
    + +
  • +
  • +
    +better-sqlite3: 23.28 queries per second +
    + +
  • +
+ +
+
+
+
+
+
+Install Bun CLI +0.2.1 +(beta) +
+
+macOS x64 & Silicon, Linux x64, Windows Subsystem for Linux +
+
+
+
+curl https://bun.sh/install | bash +
+ +
+Show script source +
+
+
+
+
+

Tell me more about Bun

+

+Bun is a modern JavaScript runtime like Node or Deno. It was built +from scratch to focus on three main things: +

+
    +
  • Start fast (it has the edge in mind).
  • +
  • +New levels of performance (extending JavaScriptCore, the engine). +
  • +
  • +Being a great and complete tool (bundler, transpiler, package +manager). +
  • +
+

+Bun is designed as a drop-in replacement for your current JavaScript +& TypeScript apps or scripts — on your local computer, server or +on the edge. Bun natively implements hundreds of Node.js and Web APIs, +including ~90% of +Node-API +functions (native modules), fs, path, Buffer and more. +

+

+The goal of Bun is to run most of the world's JavaScript outside +of browsers, bringing performance and complexity enhancements to your +future infrastructure, as well as developer productivity through +better, simpler tooling. +

+

Batteries included

+
    +
  • +Web APIs like +fetch, +WebSocket, and +ReadableStream +are built-in +
  • +
  • +node_modules +bun implements Node.js' module resolution algorithm, so you can +use npm packages in Bun. ESM and CommonJS are supported, but Bun +internally uses ESM +
  • +
  • +In Bun, every file is transpiled. +TypeScript +& JSX just +work +
  • +
  • +Bun supports "paths", +"jsxImportSource"and more from +tsconfig.json +files +
  • +
  • +Bun.Transpiler +Bun's JSX & TypeScript transpiler is available as an API in +Bun +
  • +
  • +use the fastest system calls available with +Bun.write +to write, copy, pipe, send and clone files +
  • +
  • +Bun automatically loads environment variables from +.env +files. No more +require("dotenv").config() +
  • +
  • +Bun ships with a fast SQLite3 client built-in +bun:sqlite +
  • +
  • +Node-API +Bun implements most of +Node-API (N-API). Many Node.js native modules just work +
  • +
  • +bun:ffi call +native code from JavaScript with Bun's low-overhead foreign +function interface +
  • +
  • +node:fs +node:path Bun +natively supports a growing list of Node.js core modules along with +globals like Buffer and process +
  • +
+

How does Bun work?

+

+Bun uses the +JavaScriptCore +engine, which tends +to start +and perform a little faster than more traditional choices like +V8. Bun is written in + +Zig + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +, a low-level programming language with manual memory management.

Most +of Bun is written from scratch including the JSX/TypeScript +transpiler, npm client, bundler, SQLite client, HTTP client, WebSocket +client and more. +

+

Why is Bun fast?

+

+An enormous amount of time spent profiling, benchmarking and +optimizing things. The answer is different for every part of Bun, but +one general theme: + +Zig + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'s low-level control over memory and lack of hidden control flow +makes it much simpler to write fast software. +Sponsor the Zig Software Foundation. +

+

Getting started

+

+To install Bun, run this +install script +in your terminal. It downloads Bun from GitHub. +

+
+
curl https://bun.sh/install | bash
+
+

+Bun's HTTP server is built on web standards like +Request +and +Response +

+
+
// http.js
+export default {
+  port: 3000,
+  fetch(request) {
+    return new Response("Welcome to Bun!");
+  },
+};
+
+

Run it with Bun:

+
+
bun run http.js
+
+

+Then open +http://localhost:3000 +in your browser.

See +more examples +and check out +the docs. If +you have any questions or want help, join +Bun's Discord. +

+

Bun CLI

+
+bun run +

+The same command for running JavaScript & TypeScript files with +bun's JavaScript runtime also runs package.json +"scripts". +

+Replace npm run with +bun run and save 160ms on every +run.
+
+Bun runs package.json scripts +30x faster than npm run +
+
+
+bun install +

+bun install is an npm-compatible +package manager. You probably will be surprised by how much faster +copying files can get. +

+Replace yarn with +bun install and get 20x faster package +installs.
+
+bun install uses the fastest system calls +available to copy files. +
+
+
+bun wiptest +

+A Jest-like test runner for JavaScript & TypeScript projects +built-in to Bun. +

+ +
+

What is the license?

+

MIT License, excluding dependencies which have various licenses.

+

How do I see the source code?

+

Bun is on GitHub.

+
+
+
+ +
+Built with Bun +0.2.1 +
+ + diff --git a/test/bun.js/fixture.html.gz b/test/bun.js/fixture.html.gz new file mode 100644 index 000000000..21fa3fa1a Binary files /dev/null and b/test/bun.js/fixture.html.gz differ diff --git a/test/bun.js/spawn.test.ts b/test/bun.js/spawn.test.ts index f8694bfcc..bc00964c1 100644 --- a/test/bun.js/spawn.test.ts +++ b/test/bun.js/spawn.test.ts @@ -284,8 +284,9 @@ for (let [gcTick, label] of [ var output = ""; var reader = process.stdout!.getReader(); var done = false; + var value; while (!done) { - var { value, done } = await reader.read(); + ({ value, done } = await reader.read()); if (value) output += new TextDecoder().decode(value); } -- cgit v1.2.3