Reduce avoidable setup costs in slow opencode tests while preserving reviewed coverage and recording the benchmark evidence for follow-up test-suite work.
43 lines
1.8 KiB
TypeScript
43 lines
1.8 KiB
TypeScript
// Per-file profiler for finding candidate test-speed work; see ../../perf/test-suite.md
|
|
// for the benchmark notes, kept wins, and discarded experiments.
|
|
// Example: TEST_PROFILE_GLOB='test/server/**/*.test.ts' TEST_PROFILE_TOP=15 bun run profile:test
|
|
const pattern = Bun.env.TEST_PROFILE_GLOB ?? "test/**/*.test.{ts,tsx}"
|
|
const limit = Number(Bun.env.TEST_PROFILE_LIMIT ?? 0)
|
|
const timeout = Bun.env.TEST_PROFILE_TIMEOUT ?? "30000"
|
|
const files = Array.fromAsync(new Bun.Glob(pattern).scan({ cwd: import.meta.dir + "/..", onlyFiles: true }))
|
|
.then((files) => files.toSorted())
|
|
.then((files) => (limit > 0 ? files.slice(0, limit) : files))
|
|
|
|
const results = []
|
|
for (const file of await files) {
|
|
const start = performance.now()
|
|
const proc = Bun.spawn(["bun", "test", "--timeout", timeout, file], {
|
|
cwd: import.meta.dir + "/..",
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
env: Bun.env,
|
|
})
|
|
const [output, error, exitCode] = await Promise.all([
|
|
new Response(proc.stdout).text(),
|
|
new Response(proc.stderr).text(),
|
|
proc.exited,
|
|
])
|
|
const seconds = (performance.now() - start) / 1000
|
|
results.push({ file, seconds, exitCode })
|
|
console.log(`${exitCode === 0 ? "PASS" : "FAIL"} ${seconds.toFixed(3)}s ${file}`)
|
|
if (exitCode !== 0) console.log((output + error).trim())
|
|
}
|
|
|
|
const sorted = results.toSorted((a, b) => b.seconds - a.seconds)
|
|
console.log("\nSlowest test files:")
|
|
for (const result of sorted.slice(0, Number(Bun.env.TEST_PROFILE_TOP ?? 20))) {
|
|
console.log(`${result.seconds.toFixed(3)}s ${result.exitCode === 0 ? "PASS" : "FAIL"} ${result.file}`)
|
|
}
|
|
|
|
if (sorted[0]) {
|
|
console.log(`METRIC slowest_test_file_seconds=${sorted[0].seconds.toFixed(3)}`)
|
|
console.log(`METRIC profiled_test_files=${results.length}`)
|
|
}
|
|
|
|
if (results.some((result) => result.exitCode !== 0)) process.exit(1)
|