Files
bun.sh/test/cli/run/run-crash-handler.test.ts
Jarred Sumner 2e02d9de28 Use ReadableStream.prototype.* in tests instead of new Response(...).* (#20937)
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Alistair Smith <hi@alistair.sh>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-14 00:47:53 -07:00

94 lines
2.9 KiB
TypeScript

import { crash_handler } from "bun:internal-for-testing";
import { describe, expect, test } from "bun:test";
import { bunEnv, bunExe, mergeWindowEnvs } from "harness";
import path from "path";
const { getMachOImageZeroOffset } = crash_handler;
test.if(process.platform === "darwin")("macOS has the assumed image offset", () => {
// If this fails, then https://bun.report will be incorrect and the stack
// trace remappings will stop working.
expect(getMachOImageZeroOffset()).toBe(0x100000000);
});
test("raise ignoring panic handler does not trigger the panic handler", async () => {
let sent = false;
const resolve_handler = Promise.withResolvers();
using server = Bun.serve({
port: 0,
fetch(request, server) {
sent = true;
resolve_handler.resolve();
return new Response("OK");
},
});
const proc = Bun.spawn({
cmd: [bunExe(), path.join(import.meta.dir, "fixture-crash.js"), "raiseIgnoringPanicHandler"],
env: mergeWindowEnvs([
bunEnv,
{
BUN_CRASH_REPORT_URL: server.url.toString(),
BUN_ENABLE_CRASH_REPORTING: "1",
},
]),
});
await proc.exited;
/// Wait two seconds for a slow http request, or continue immediately once the request is heard.
await Promise.race([resolve_handler.promise, Bun.sleep(2000)]);
expect(proc.exited).resolves.not.toBe(0);
expect(sent).toBe(false);
});
describe("automatic crash reporter", () => {
for (const approach of ["panic", "segfault", "outOfMemory"]) {
test(`${approach} should report`, async () => {
let sent = false;
const resolve_handler = Promise.withResolvers();
// Self host the crash report backend.
using server = Bun.serve({
port: 0,
fetch(request, server) {
expect(request.url).toEndWith("/ack");
sent = true;
resolve_handler.resolve();
return new Response("OK");
},
});
const proc = Bun.spawn({
cmd: [bunExe(), path.join(import.meta.dir, "fixture-crash.js"), approach],
env: mergeWindowEnvs([
bunEnv,
{
BUN_CRASH_REPORT_URL: server.url.toString(),
BUN_ENABLE_CRASH_REPORTING: "1",
GITHUB_ACTIONS: undefined,
CI: undefined,
},
]),
stdio: ["ignore", "pipe", "pipe"],
});
const exitCode = await proc.exited;
const stderr = await proc.stderr.text();
console.log(stderr);
await resolve_handler.promise;
expect(exitCode).not.toBe(0);
expect(stderr).toContain(server.url.toString());
if (approach !== "outOfMemory") {
expect(stderr).toContain("oh no: Bun has crashed. This indicates a bug in Bun, not your code");
} else {
expect(stderr.toLowerCase()).toContain("out of memory");
expect(stderr.toLowerCase()).not.toContain("panic");
}
expect(sent).toBe(true);
});
}
});