From 67f14ff684ad968fbb6ce7800a964d5844c88d47 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Fri, 30 Oct 2026 11:47:32 +0000 Subject: [PATCH 1/3] test(builtins-table): run the same-ids test's generators without simulated-throw traces and tighten its assertions The two generator runs get bunEnv without BUN_JSC_dumpSimulatedThrows. The ASAN lane sets that variable, and it takes 20 s of the 45 s of one run there. BUN_JSC_validateExceptionChecks stays. The test asserts the stderr lines, the exit code and the signal of both runs in one toEqual. It compares the two id files with toBe, which prints the lines that differ. It also requires that the two builds number different lists of native calls, so a generator that ignores --types-only fails the test. --- ...e-ids-in-every-build-configuration.test.ts | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts b/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts index 80cea7e48059..a9b85a1e87f5 100644 --- a/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts +++ b/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts @@ -10,8 +10,9 @@ const bunRoot = resolve(import.meta.dir, "..", "..", ".."); const schemas = globAllSources().bindgen; const testSchemas = schemas.filter(schema => schema.endsWith("_test.bind.ts")).map(schema => basename(schema)); -async function idsFor(typesOnly: readonly string[]): Promise { - using directory = tempDir("builtins-table", {}); +type Build = "withoutAssertions" | "withAssertions"; + +async function generateInto(directory: string, typesOnly: readonly string[]) { await using generator = Bun.spawn({ cmd: [ bunExe(), @@ -24,19 +25,37 @@ async function idsFor(typesOnly: readonly string[]): Promise { `--types-only=${typesOnly.join(",")}`, ], cwd: bunRoot, - env: bunEnv, + // The ASAN lane sets BUN_JSC_dumpSimulatedThrows, which nearly doubles a run's time. The exception checks stay on. + env: { ...bunEnv, BUN_JSC_dumpSimulatedThrows: undefined }, stdout: "ignore", - stderr: "inherit", + stderr: "pipe", }); - expect(await generator.exited).toBe(0); - return readFileSync(join(String(directory), "aot_builtin_ids.rs"), "utf8"); + const [stderr, exitCode] = await Promise.all([generator.stderr.text(), generator.exited]); + // Every run prints summaries that begin with "builtins table:". Any other line says what went wrong. + const errors = stderr.split("\n").filter(line => line !== "" && !line.startsWith("builtins table:")); + return { errors, exitCode, signalCode: generator.signalCode }; } +// BunAOTHostBindings.cpp names the list of native calls that its build numbers: generate-js2native.ts stamps each list. +const nativeCallListOf = (hostBindings: string) => hostBindings.match(/\bBun__js2nativeList_[0-9a-f]{8}\b/)?.[0]; + test.skipIf(generated === undefined)( "one prebuilt engine serves a build with and a build without assertions", async () => { - const [withoutAssertions, withAssertions] = await Promise.all([idsFor(testSchemas), idsFor([])]); - expect(withAssertions === withoutAssertions).toBe(true); + using directory = tempDir("builtins-table", { withoutAssertions: {}, withAssertions: {} }); + const written = (build: Build, file: string) => readFileSync(join(String(directory), build, file), "utf8"); + const [withoutAssertions, withAssertions] = await Promise.all([ + generateInto(join(String(directory), "withoutAssertions"), testSchemas), + generateInto(join(String(directory), "withAssertions"), []), + ]); + const accepted = { errors: [], exitCode: 0, signalCode: null }; + expect({ withoutAssertions, withAssertions }).toEqual({ withoutAssertions: accepted, withAssertions: accepted }); + + // The two are not one build: only with assertions does Bun number the native calls of the *_test.bind.ts schemas. + expect(nativeCallListOf(written("withAssertions", "BunAOTHostBindings.cpp"))).not.toBe( + nativeCallListOf(written("withoutAssertions", "BunAOTHostBindings.cpp")), + ); + expect(written("withAssertions", "aot_builtin_ids.rs")).toBe(written("withoutAssertions", "aot_builtin_ids.rs")); }, 120_000, ); From d1c78e1913c305bf56c5795185475d4b6615a958 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Fri, 30 Oct 2026 12:31:56 +0000 Subject: [PATCH 2/3] test(builtins-table): give the same-ids test 30 minutes on a debug build and compare every native-call list name One run of the generator takes about 7 minutes with a debug build, so the test could not pass there within 120 s. A debug build has 30 minutes now. Every other build keeps 120 s. The check that the two builds number different lists of native calls compares every Bun__js2nativeList_ name of each BunAOTHostBindings.cpp as a Set, not only the first one. --- .../same-ids-in-every-build-configuration.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts b/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts index a9b85a1e87f5..9f98804e1670 100644 --- a/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts +++ b/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "bun:test"; -import { bunEnv, bunExe, tempDir } from "harness"; +import { bunEnv, bunExe, isDebug, tempDir } from "harness"; import { readFileSync } from "node:fs"; import { basename, join, resolve } from "node:path"; import { crateOf } from "../../../scripts/build/codegen.ts"; @@ -37,7 +37,7 @@ async function generateInto(directory: string, typesOnly: readonly string[]) { } // BunAOTHostBindings.cpp names the list of native calls that its build numbers: generate-js2native.ts stamps each list. -const nativeCallListOf = (hostBindings: string) => hostBindings.match(/\bBun__js2nativeList_[0-9a-f]{8}\b/)?.[0]; +const nativeCallListsOf = (hostBindings: string) => new Set(hostBindings.match(/\bBun__js2nativeList_[0-9a-f]{8}\b/g)); test.skipIf(generated === undefined)( "one prebuilt engine serves a build with and a build without assertions", @@ -52,10 +52,11 @@ test.skipIf(generated === undefined)( expect({ withoutAssertions, withAssertions }).toEqual({ withoutAssertions: accepted, withAssertions: accepted }); // The two are not one build: only with assertions does Bun number the native calls of the *_test.bind.ts schemas. - expect(nativeCallListOf(written("withAssertions", "BunAOTHostBindings.cpp"))).not.toBe( - nativeCallListOf(written("withoutAssertions", "BunAOTHostBindings.cpp")), + expect(nativeCallListsOf(written("withAssertions", "BunAOTHostBindings.cpp"))).not.toEqual( + nativeCallListsOf(written("withoutAssertions", "BunAOTHostBindings.cpp")), ); expect(written("withAssertions", "aot_builtin_ids.rs")).toBe(written("withoutAssertions", "aot_builtin_ids.rs")); }, - 120_000, + // One run of the generator takes about 7 minutes with a debug build. + isDebug ? 1_800_000 : 120_000, ); From 6a91d04bdd98eaa085990b8e8fe29819590c4a70 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Fri, 30 Oct 2026 12:46:06 +0000 Subject: [PATCH 3/3] test(builtins-table): size the same-ids test's debug limit to its measured time With a debug build the two generator runs took 397, 403 and 491 s together. The limit for a debug build is 15 minutes, not 30. --- .../same-ids-in-every-build-configuration.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts b/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts index 9f98804e1670..199555bad701 100644 --- a/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts +++ b/test/internal/builtins-table/same-ids-in-every-build-configuration.test.ts @@ -57,6 +57,6 @@ test.skipIf(generated === undefined)( ); expect(written("withAssertions", "aot_builtin_ids.rs")).toBe(written("withoutAssertions", "aot_builtin_ids.rs")); }, - // One run of the generator takes about 7 minutes with a debug build. - isDebug ? 1_800_000 : 120_000, + // With a debug build the two runs take 7 to 8 minutes together. + isDebug ? 900_000 : 120_000, );