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..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 @@ -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"; @@ -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,38 @@ 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 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", 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(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, + // With a debug build the two runs take 7 to 8 minutes together. + isDebug ? 900_000 : 120_000, );