From eb393986d68b6714cb897bdcc27254923e9bec59 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Fri, 16 Oct 2026 12:25:47 +0000 Subject: [PATCH 1/3] verify-baseline: pass a per-test timeout to the emulated test run [skip tests] Also adds a temporary measurement of the slow tests under the emulators. The next commit removes it. --- scripts/verify-baseline.ts | 88 +++++++++- .../fixtures/simd-baseline-probe.test.ts | 161 ++++++++++++++++++ 2 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts diff --git a/scripts/verify-baseline.ts b/scripts/verify-baseline.ts index 4c10c15e1485..349a55d240e2 100644 --- a/scripts/verify-baseline.ts +++ b/scripts/verify-baseline.ts @@ -118,6 +118,80 @@ async function teeStream(stream: ReadableStream, output: NodeJS.Writ return Buffer.concat(chunks).toString(); } +// ---- TEMPORARY MEASUREMENT: symbolize the trace of a crash report printed by the last run ---- +let lastOutput = ""; +const base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +function readVlq(text: string, at: number): [number, number] { + let value = 0; + let scale = 1; + for (;;) { + const digit = base64Alphabet.indexOf(text[at++]); + if (digit < 0) throw new Error(`bad VLQ digit at ${at - 1}`); + value += (digit & 31) * scale; + scale *= 32; + if (!(digit & 32)) break; + } + const negative = value % 2 === 1; + value = Math.floor(value / 2); + return [negative ? -value : value, at]; +} +async function symbolizeCrash() { + const match = /https:\/\/bun\.report\/[^/\s]+\/(\S+)/.exec(lastOutput); + if (!match) { + console.log(" (no crash report in the output of this run)"); + return; + } + try { + const trace = match[1]; + let at = 10; // platform, command, version, 7 hex of the commit + [, at] = readVlq(trace, at); + [, at] = readVlq(trace, at); + const frames: { module: string; address: number }[] = []; + for (;;) { + if (trace[at] === "_") { + frames.push({ module: "?", address: 0 }); + at++; + continue; + } + let value: number; + [value, at] = readVlq(trace, at); + if (value === 0) break; + if (value === 1) { + let length: number; + [length, at] = readVlq(trace, at); + const module = trace.slice(at, at + length); + at += length; + let address: number; + [address, at] = readVlq(trace, at); + frames.push({ module, address }); + } else { + frames.push({ module: "bun", address: value }); + } + } + console.log(`+++ crash trace of the run above (${frames.length} frames, reason ${trace.slice(at)})`); + frames.forEach((frame, index) => console.log(` #${index} ${frame.module} 0x${frame.address.toString(16)}`)); + const pdb = binary.replace(/\.exe$/i, ".pdb"); + const symbolizer = Bun.which("pdb-addr2line"); + console.log(` pdb: ${pdb} (exists: ${await Bun.file(pdb).exists()}), pdb-addr2line: ${symbolizer}`); + console.log(` files next to the binary: ${readdirSync(dirname(binary)).join(", ")}`); + if (!isWindows || !symbolizer) return; + const addresses = frames.filter(f => f.module === "bun").map(f => `0x${f.address.toString(16).toUpperCase()}`); + for (const flags of [["-a", "-f", "-i", "-p"], []]) { + const result = Bun.spawnSync([symbolizer, "--exe", pdb, ...flags, ...addresses], { + stdout: "pipe", + stderr: "pipe", + }); + console.log(` pdb-addr2line ${flags.join(" ")} exit ${result.exitCode}`); + console.log(result.stdout.toString()); + console.log(result.stderr.toString()); + if (result.exitCode === 0) break; + } + } catch (error) { + console.log(" failed to decode the crash trace:", error); + } +} +// ---- END TEMPORARY MEASUREMENT ---- + async function runTest(label: string, binaryArgs: string[], options?: RunTestOptions): Promise { console.log(`+++ ${label}`); @@ -150,6 +224,7 @@ async function runTest(label: string, binaryArgs: string[], options?: RunTestOpt const signalCode = proc.signalCode; const elapsed = ((performance.now() - start) / 1000).toFixed(1); const output = stdout + "\n" + stderr; + lastOutput = output; if (exitCode === 0) { if (!live && stdout.trim()) console.log(stdout.trim()); @@ -235,7 +310,18 @@ if (values["skip-emulation"]) { } else { // Phase 1: SIMD code path verification const simdTestPath = join(repoRoot, "test", "js", "bun", "jsc-stress", "fixtures", "simd-baseline.test.ts"); - await runTest("SIMD baseline tests", ["test", simdTestPath], { live: true }); + await runTest("SIMD baseline tests", ["test", "--timeout=90000", simdTestPath], { live: true }); + + // ---- TEMPORARY MEASUREMENT ---- + await symbolizeCrash(); + const probePath = join(fixturesDir, "simd-baseline-probe.test.ts"); + await runTest("probe: phases #1", ["test", "--timeout=300000", probePath], { live: true }); + await symbolizeCrash(); + await runTest("probe: SIMD baseline tests #2", ["test", "--timeout=90000", simdTestPath], { live: true }); + await runTest("probe: phases #2", ["test", "--timeout=300000", probePath], { live: true }); + await runTest("probe: bun -e", ["-e", "console.log(1)"], { live: true }); + await symbolizeCrash(); + // ---- END TEMPORARY MEASUREMENT ---- } // Phase 2: JIT stress fixtures (only with --jit-stress, e.g. on WebKit changes) diff --git a/test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts b/test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts new file mode 100644 index 000000000000..c00ab1c23b03 --- /dev/null +++ b/test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts @@ -0,0 +1,161 @@ +// Temporary measurement for the verify-baseline step: prints how long each +// phase of the three slow simd-baseline tests takes under the emulator, cold +// (round 1) and warm (rounds 2 and 3). + +import { expect, test } from "bun:test"; +import { promisify } from "node:util"; +import { deflate, deflateSync } from "node:zlib"; + +const deflateAsync = promisify(deflate); + +let last = performance.now(); +let lastCpu = process.cpuUsage(); +function mark(label: string) { + const now = performance.now(); + const cpu = process.cpuUsage(lastCpu); + const rss = (process.memoryUsage.rss() / 1048576).toFixed(0); + console.log( + `PROBE ${label} ${(now - last).toFixed(1)}ms (user ${(cpu.user / 1000).toFixed(0)}ms sys ${(cpu.system / 1000).toFixed(0)}ms rss ${rss}MB)`, + ); + lastCpu = process.cpuUsage(); + last = performance.now(); +} + +const width = 72; +const height = 40; + +function crc32(bytes: Uint8Array): number { + let crc = ~0 >>> 0; + for (const byte of bytes) { + crc ^= byte; + for (let bit = 0; bit < 8; bit++) crc = (crc >>> 1) ^ (0xedb88320 & -(crc & 1)); + } + return ~crc >>> 0; +} + +function pngChunk(type: string, data: Uint8Array): Uint8Array { + const chunk = new Uint8Array(12 + data.length); + const view = new DataView(chunk.buffer); + view.setUint32(0, data.length); + chunk.set(Buffer.from(type, "latin1"), 4); + chunk.set(data, 8); + view.setUint32(8 + data.length, crc32(chunk.subarray(4, 8 + data.length))); + return chunk; +} + +function png(tag: string, rgb: (x: number, y: number) => [number, number, number]): Uint8Array { + const stride = 1 + width * 3; + const raw = new Uint8Array(height * stride); + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) raw.set(rgb(x, y), y * stride + 1 + x * 3); + } + mark(`${tag} png.pixels`); + const ihdr = new Uint8Array(13); + const view = new DataView(ihdr.buffer); + view.setUint32(0, width); + view.setUint32(4, height); + ihdr.set([8, 2, 0, 0, 0], 8); + const idat = deflateSync(raw); + mark(`${tag} png.deflateSync`); + const out = Buffer.concat([ + Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), + pngChunk("IHDR", ihdr), + pngChunk("IDAT", idat), + pngChunk("IEND", new Uint8Array(0)), + ]); + mark(`${tag} png.crc32+concat`); + return out; +} + +async function pool(tag: string) { + const small = Buffer.alloc(4096, "a"); + deflateSync(small); + mark(`${tag} pool.deflateSync(4k)`); + await deflateAsync(small); + mark(`${tag} pool.deflateAsync(4k) a`); + await deflateAsync(small); + mark(`${tag} pool.deflateAsync(4k) b`); + await Promise.all(Array.from({ length: 16 }, () => deflateAsync(small))); + mark(`${tag} pool.deflateAsync(4k) x16 a`); + await Promise.all(Array.from({ length: 16 }, () => deflateAsync(small))); + mark(`${tag} pool.deflateAsync(4k) x16 b`); +} + +async function grey(tag: string) { + const source = png(tag, () => [77, 77, 77]); + const image = new Bun.Image(source); + mark(`${tag} new Bun.Image`); + const pending = image.jpeg({ quality: 100 }).bytes(); + mark(`${tag} jpeg().bytes() call`); + const first = await pending; + mark(`${tag} await png->jpeg`); + const second = await new Bun.Image(first).jpeg({ quality: 100 }).bytes(); + mark(`${tag} await jpeg->jpeg`); + expect(first.subarray(0, 2)).toEqual(new Uint8Array([0xff, 0xd8])); + expect(second).toEqual(first); + mark(`${tag} expect`); +} + +async function gradient(tag: string) { + const source = png(tag, (x, y) => [x * 3, y * 6, (x + y) & 0xff]); + for (const progressive of [false, true]) { + const p = progressive ? "progressive" : "baseline"; + const jpeg = await new Bun.Image(source).jpeg({ quality: 90, progressive }).bytes(); + mark(`${tag} ${p} await png->jpeg`); + expect(await new Bun.Image(jpeg).metadata()).toEqual({ width, height, format: "jpeg" }); + mark(`${tag} ${p} await jpeg metadata`); + const decoded = await new Bun.Image(jpeg).png().bytes(); + mark(`${tag} ${p} await jpeg->png`); + expect(await new Bun.Image(decoded).metadata()).toEqual({ width, height, format: "png" }); + mark(`${tag} ${p} await png metadata`); + } +} + +async function http(tag: string, host: string) { + const longHeaderValue = Buffer.alloc(512, "v").toString(); + const server = Bun.serve({ + port: 0, + fetch(req) { + return new Response(req.headers.get("X-Test-Header") || "missing"); + }, + }); + mark(`${tag} Bun.serve`); + const pending = fetch(`http://${host}:${server.port}/` + "path/".repeat(20), { + headers: { + "X-Test-Header": longHeaderValue, + "X-Header-A": Buffer.alloc(64, "a").toString(), + "X-Header-B": Buffer.alloc(64, "b").toString(), + "X-Header-C": Buffer.alloc(64, "c").toString(), + "Accept": "application/json", + "Accept-Language": "en-US,en;q=0.9,fr;q=0.8,de;q=0.7", + }, + }); + mark(`${tag} fetch() call`); + const resp = await pending; + mark(`${tag} await fetch`); + expect(await resp.text()).toBe(longHeaderValue); + mark(`${tag} await text`); + await server.stop(true); + mark(`${tag} server.stop`); +} + +function steady(tag: string) { + let sum = 0; + for (let i = 0; i < 2_000_000; i++) sum = (sum + i * 3) | 0; + mark(`${tag} steady js loop 2M (${sum})`); + const hex = Buffer.alloc(4 << 20, 0xab).toString("hex"); + mark(`${tag} steady native hex 4MB (${hex.length})`); +} + +test("probe", async () => { + console.log(`PROBE cpus=${navigator.hardwareConcurrency} revision=${Bun.revision.slice(0, 9)}`); + mark("start"); + for (const round of [1, 2, 3]) { + await pool(`r${round} pool:`); + await http(`r${round} http(localhost):`, "localhost"); + await http(`r${round} http(127.0.0.1):`, "127.0.0.1"); + await grey(`r${round} grey:`); + await gradient(`r${round} gradient:`); + steady(`r${round}`); + } +}, 240_000); From 63a3b270e11dd4f47c979d81dafe10916bf3cfee Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Sat, 17 Oct 2026 09:40:11 +0000 Subject: [PATCH 2/3] verify-baseline: remove the temporary measurement The per-test timeout for the emulated test run stays. --- scripts/verify-baseline.ts | 88 +--------- .../fixtures/simd-baseline-probe.test.ts | 161 ------------------ 2 files changed, 2 insertions(+), 247 deletions(-) delete mode 100644 test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts diff --git a/scripts/verify-baseline.ts b/scripts/verify-baseline.ts index 349a55d240e2..74edff63782f 100644 --- a/scripts/verify-baseline.ts +++ b/scripts/verify-baseline.ts @@ -118,80 +118,6 @@ async function teeStream(stream: ReadableStream, output: NodeJS.Writ return Buffer.concat(chunks).toString(); } -// ---- TEMPORARY MEASUREMENT: symbolize the trace of a crash report printed by the last run ---- -let lastOutput = ""; -const base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -function readVlq(text: string, at: number): [number, number] { - let value = 0; - let scale = 1; - for (;;) { - const digit = base64Alphabet.indexOf(text[at++]); - if (digit < 0) throw new Error(`bad VLQ digit at ${at - 1}`); - value += (digit & 31) * scale; - scale *= 32; - if (!(digit & 32)) break; - } - const negative = value % 2 === 1; - value = Math.floor(value / 2); - return [negative ? -value : value, at]; -} -async function symbolizeCrash() { - const match = /https:\/\/bun\.report\/[^/\s]+\/(\S+)/.exec(lastOutput); - if (!match) { - console.log(" (no crash report in the output of this run)"); - return; - } - try { - const trace = match[1]; - let at = 10; // platform, command, version, 7 hex of the commit - [, at] = readVlq(trace, at); - [, at] = readVlq(trace, at); - const frames: { module: string; address: number }[] = []; - for (;;) { - if (trace[at] === "_") { - frames.push({ module: "?", address: 0 }); - at++; - continue; - } - let value: number; - [value, at] = readVlq(trace, at); - if (value === 0) break; - if (value === 1) { - let length: number; - [length, at] = readVlq(trace, at); - const module = trace.slice(at, at + length); - at += length; - let address: number; - [address, at] = readVlq(trace, at); - frames.push({ module, address }); - } else { - frames.push({ module: "bun", address: value }); - } - } - console.log(`+++ crash trace of the run above (${frames.length} frames, reason ${trace.slice(at)})`); - frames.forEach((frame, index) => console.log(` #${index} ${frame.module} 0x${frame.address.toString(16)}`)); - const pdb = binary.replace(/\.exe$/i, ".pdb"); - const symbolizer = Bun.which("pdb-addr2line"); - console.log(` pdb: ${pdb} (exists: ${await Bun.file(pdb).exists()}), pdb-addr2line: ${symbolizer}`); - console.log(` files next to the binary: ${readdirSync(dirname(binary)).join(", ")}`); - if (!isWindows || !symbolizer) return; - const addresses = frames.filter(f => f.module === "bun").map(f => `0x${f.address.toString(16).toUpperCase()}`); - for (const flags of [["-a", "-f", "-i", "-p"], []]) { - const result = Bun.spawnSync([symbolizer, "--exe", pdb, ...flags, ...addresses], { - stdout: "pipe", - stderr: "pipe", - }); - console.log(` pdb-addr2line ${flags.join(" ")} exit ${result.exitCode}`); - console.log(result.stdout.toString()); - console.log(result.stderr.toString()); - if (result.exitCode === 0) break; - } - } catch (error) { - console.log(" failed to decode the crash trace:", error); - } -} -// ---- END TEMPORARY MEASUREMENT ---- - async function runTest(label: string, binaryArgs: string[], options?: RunTestOptions): Promise { console.log(`+++ ${label}`); @@ -224,7 +150,6 @@ async function runTest(label: string, binaryArgs: string[], options?: RunTestOpt const signalCode = proc.signalCode; const elapsed = ((performance.now() - start) / 1000).toFixed(1); const output = stdout + "\n" + stderr; - lastOutput = output; if (exitCode === 0) { if (!live && stdout.trim()) console.log(stdout.trim()); @@ -310,18 +235,9 @@ if (values["skip-emulation"]) { } else { // Phase 1: SIMD code path verification const simdTestPath = join(repoRoot, "test", "js", "bun", "jsc-stress", "fixtures", "simd-baseline.test.ts"); + // The default per-test timeout (5 s) assumes native speed. Intel SDE runs this file hundreds of + // times slower, so use the per-test timeout that runner.node.ts gives every native run in CI. await runTest("SIMD baseline tests", ["test", "--timeout=90000", simdTestPath], { live: true }); - - // ---- TEMPORARY MEASUREMENT ---- - await symbolizeCrash(); - const probePath = join(fixturesDir, "simd-baseline-probe.test.ts"); - await runTest("probe: phases #1", ["test", "--timeout=300000", probePath], { live: true }); - await symbolizeCrash(); - await runTest("probe: SIMD baseline tests #2", ["test", "--timeout=90000", simdTestPath], { live: true }); - await runTest("probe: phases #2", ["test", "--timeout=300000", probePath], { live: true }); - await runTest("probe: bun -e", ["-e", "console.log(1)"], { live: true }); - await symbolizeCrash(); - // ---- END TEMPORARY MEASUREMENT ---- } // Phase 2: JIT stress fixtures (only with --jit-stress, e.g. on WebKit changes) diff --git a/test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts b/test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts deleted file mode 100644 index c00ab1c23b03..000000000000 --- a/test/js/bun/jsc-stress/fixtures/simd-baseline-probe.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -// Temporary measurement for the verify-baseline step: prints how long each -// phase of the three slow simd-baseline tests takes under the emulator, cold -// (round 1) and warm (rounds 2 and 3). - -import { expect, test } from "bun:test"; -import { promisify } from "node:util"; -import { deflate, deflateSync } from "node:zlib"; - -const deflateAsync = promisify(deflate); - -let last = performance.now(); -let lastCpu = process.cpuUsage(); -function mark(label: string) { - const now = performance.now(); - const cpu = process.cpuUsage(lastCpu); - const rss = (process.memoryUsage.rss() / 1048576).toFixed(0); - console.log( - `PROBE ${label} ${(now - last).toFixed(1)}ms (user ${(cpu.user / 1000).toFixed(0)}ms sys ${(cpu.system / 1000).toFixed(0)}ms rss ${rss}MB)`, - ); - lastCpu = process.cpuUsage(); - last = performance.now(); -} - -const width = 72; -const height = 40; - -function crc32(bytes: Uint8Array): number { - let crc = ~0 >>> 0; - for (const byte of bytes) { - crc ^= byte; - for (let bit = 0; bit < 8; bit++) crc = (crc >>> 1) ^ (0xedb88320 & -(crc & 1)); - } - return ~crc >>> 0; -} - -function pngChunk(type: string, data: Uint8Array): Uint8Array { - const chunk = new Uint8Array(12 + data.length); - const view = new DataView(chunk.buffer); - view.setUint32(0, data.length); - chunk.set(Buffer.from(type, "latin1"), 4); - chunk.set(data, 8); - view.setUint32(8 + data.length, crc32(chunk.subarray(4, 8 + data.length))); - return chunk; -} - -function png(tag: string, rgb: (x: number, y: number) => [number, number, number]): Uint8Array { - const stride = 1 + width * 3; - const raw = new Uint8Array(height * stride); - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) raw.set(rgb(x, y), y * stride + 1 + x * 3); - } - mark(`${tag} png.pixels`); - const ihdr = new Uint8Array(13); - const view = new DataView(ihdr.buffer); - view.setUint32(0, width); - view.setUint32(4, height); - ihdr.set([8, 2, 0, 0, 0], 8); - const idat = deflateSync(raw); - mark(`${tag} png.deflateSync`); - const out = Buffer.concat([ - Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), - pngChunk("IHDR", ihdr), - pngChunk("IDAT", idat), - pngChunk("IEND", new Uint8Array(0)), - ]); - mark(`${tag} png.crc32+concat`); - return out; -} - -async function pool(tag: string) { - const small = Buffer.alloc(4096, "a"); - deflateSync(small); - mark(`${tag} pool.deflateSync(4k)`); - await deflateAsync(small); - mark(`${tag} pool.deflateAsync(4k) a`); - await deflateAsync(small); - mark(`${tag} pool.deflateAsync(4k) b`); - await Promise.all(Array.from({ length: 16 }, () => deflateAsync(small))); - mark(`${tag} pool.deflateAsync(4k) x16 a`); - await Promise.all(Array.from({ length: 16 }, () => deflateAsync(small))); - mark(`${tag} pool.deflateAsync(4k) x16 b`); -} - -async function grey(tag: string) { - const source = png(tag, () => [77, 77, 77]); - const image = new Bun.Image(source); - mark(`${tag} new Bun.Image`); - const pending = image.jpeg({ quality: 100 }).bytes(); - mark(`${tag} jpeg().bytes() call`); - const first = await pending; - mark(`${tag} await png->jpeg`); - const second = await new Bun.Image(first).jpeg({ quality: 100 }).bytes(); - mark(`${tag} await jpeg->jpeg`); - expect(first.subarray(0, 2)).toEqual(new Uint8Array([0xff, 0xd8])); - expect(second).toEqual(first); - mark(`${tag} expect`); -} - -async function gradient(tag: string) { - const source = png(tag, (x, y) => [x * 3, y * 6, (x + y) & 0xff]); - for (const progressive of [false, true]) { - const p = progressive ? "progressive" : "baseline"; - const jpeg = await new Bun.Image(source).jpeg({ quality: 90, progressive }).bytes(); - mark(`${tag} ${p} await png->jpeg`); - expect(await new Bun.Image(jpeg).metadata()).toEqual({ width, height, format: "jpeg" }); - mark(`${tag} ${p} await jpeg metadata`); - const decoded = await new Bun.Image(jpeg).png().bytes(); - mark(`${tag} ${p} await jpeg->png`); - expect(await new Bun.Image(decoded).metadata()).toEqual({ width, height, format: "png" }); - mark(`${tag} ${p} await png metadata`); - } -} - -async function http(tag: string, host: string) { - const longHeaderValue = Buffer.alloc(512, "v").toString(); - const server = Bun.serve({ - port: 0, - fetch(req) { - return new Response(req.headers.get("X-Test-Header") || "missing"); - }, - }); - mark(`${tag} Bun.serve`); - const pending = fetch(`http://${host}:${server.port}/` + "path/".repeat(20), { - headers: { - "X-Test-Header": longHeaderValue, - "X-Header-A": Buffer.alloc(64, "a").toString(), - "X-Header-B": Buffer.alloc(64, "b").toString(), - "X-Header-C": Buffer.alloc(64, "c").toString(), - "Accept": "application/json", - "Accept-Language": "en-US,en;q=0.9,fr;q=0.8,de;q=0.7", - }, - }); - mark(`${tag} fetch() call`); - const resp = await pending; - mark(`${tag} await fetch`); - expect(await resp.text()).toBe(longHeaderValue); - mark(`${tag} await text`); - await server.stop(true); - mark(`${tag} server.stop`); -} - -function steady(tag: string) { - let sum = 0; - for (let i = 0; i < 2_000_000; i++) sum = (sum + i * 3) | 0; - mark(`${tag} steady js loop 2M (${sum})`); - const hex = Buffer.alloc(4 << 20, 0xab).toString("hex"); - mark(`${tag} steady native hex 4MB (${hex.length})`); -} - -test("probe", async () => { - console.log(`PROBE cpus=${navigator.hardwareConcurrency} revision=${Bun.revision.slice(0, 9)}`); - mark("start"); - for (const round of [1, 2, 3]) { - await pool(`r${round} pool:`); - await http(`r${round} http(localhost):`, "localhost"); - await http(`r${round} http(127.0.0.1):`, "127.0.0.1"); - await grey(`r${round} grey:`); - await gradient(`r${round} gradient:`); - steady(`r${round}`); - } -}, 240_000); From 1817eea91b414d0adcfddc2045d831d47bb2b070 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Sat, 17 Oct 2026 17:04:48 +0000 Subject: [PATCH 3/3] verify-baseline: name the per-test timeout of the emulated run The value no longer refers to the timeout of the CI test runner. The two are equal now, but the emulated run needs its own value. --- scripts/verify-baseline.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/verify-baseline.ts b/scripts/verify-baseline.ts index 74edff63782f..4e88770adfbe 100644 --- a/scripts/verify-baseline.ts +++ b/scripts/verify-baseline.ts @@ -236,8 +236,9 @@ if (values["skip-emulation"]) { // Phase 1: SIMD code path verification const simdTestPath = join(repoRoot, "test", "js", "bun", "jsc-stress", "fixtures", "simd-baseline.test.ts"); // The default per-test timeout (5 s) assumes native speed. Intel SDE runs this file hundreds of - // times slower, so use the per-test timeout that runner.node.ts gives every native run in CI. - await runTest("SIMD baseline tests", ["test", "--timeout=90000", simdTestPath], { live: true }); + // times slower, so the emulated run gets a per-test timeout of its own. + const emulatedTestTimeoutMs = 90_000; + await runTest("SIMD baseline tests", ["test", `--timeout=${emulatedTestTimeoutMs}`, simdTestPath], { live: true }); } // Phase 2: JIT stress fixtures (only with --jit-stress, e.g. on WebKit changes)