Skip to content

Commit abe6bd2

Browse files
committed
fix(bench): validate memory benchmark connection counts
1 parent e31e525 commit abe6bd2

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

bench/memory/run.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, it } from 'bun:test'
2+
import { parseArgs } from './run'
3+
4+
describe('memory benchmark counts', () => {
5+
it.each(['--connections', '-c', '--runs'])('requires a positive safe integer for %s', (flag) => {
6+
for (const value of ['9007199254740992', '1.5', '0', '-1', 'Infinity', 'NaN', ''])
7+
expect(() => parseArgs([flag, value]), `${flag} ${value}`).toThrow()
8+
})
9+
10+
it('preserves defaults and accepts fractional timing windows and rates', () => {
11+
expect(parseArgs([])).toMatchObject({ connections: 64, runs: 1, loadSeconds: 60, idleSeconds: 180 })
12+
expect(parseArgs(['-c', '2', '--runs', '3', '--load', '0.5', '--idle', '0.75', '--interval', '10.5', '--settle', '0.25', '--rate', '100.5'])).toMatchObject({
13+
connections: 2, runs: 3, loadSeconds: 0.5, idleSeconds: 0.75, sampleIntervalMs: 10.5, settleSeconds: 0.25, requestRate: 100.5,
14+
})
15+
})
16+
17+
it('still caps the settling window at the idle duration', () => {
18+
expect(parseArgs(['--idle', '0.5', '--settle', '2']).settleSeconds).toBe(0.5)
19+
})
20+
})

bench/memory/run.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ function positiveNumber(flag: string, value: string): number {
5151

5252
function positiveInteger(flag: string, value: string): number {
5353
const parsed = positiveNumber(flag, value)
54-
if (!Number.isInteger(parsed)) throw new Error(`${flag} must be an integer`)
54+
if (!Number.isSafeInteger(parsed)) throw new Error(`${flag} must be a safe integer`)
5555
return parsed
5656
}
5757

58-
function parseArgs(argv: string[]): Options {
58+
export function parseArgs(argv: string[]): Options {
5959
const options: Options = {
6060
targets: BUN_141_API_PROFILE.map(target => target.targetId),
6161
scenario: 'static-json',
@@ -78,7 +78,7 @@ function parseArgs(argv: string[]): Options {
7878
case '--targets': options.targets = next().split(','); break
7979
case '--scenario': options.scenario = next(); break
8080
case '--driver': options.driver = next(); break
81-
case '--connections': case '-c': options.connections = positiveNumber(flag, next()); break
81+
case '--connections': case '-c': options.connections = positiveInteger(flag, next()); break
8282
case '--load': options.loadSeconds = positiveNumber(flag, next()); break
8383
case '--idle': options.idleSeconds = positiveNumber(flag, next()); break
8484
case '--interval': options.sampleIntervalMs = positiveNumber(flag, next()); break
@@ -103,13 +103,13 @@ const HELP = `bun bench/memory/run.ts [flags]
103103
--targets comma-separated target ids (${TARGETS.map(target => target.id).join(', ')})
104104
--scenario routing scenario to load (default static-json)
105105
--driver oha | bombardier | autocannon | builtin
106-
--connections concurrent connections (default 64)
106+
--connections concurrent connections, positive integer (default 64)
107107
--rate override the profile's fixed requests per second for every target
108108
--load sustained-load seconds (default 60)
109109
--idle quiet seconds after load (default 180)
110110
--interval RSS sample interval in milliseconds (default 100)
111111
--settle final idle window used for the median (default 10)
112-
--runs fresh-process repeats per target (default 1)
112+
--runs positive integer fresh-process repeats per target (default 1)
113113
--output explicit output directory (default results/<timestamp>)`
114114

115115
interface SelectedTarget extends MemoryProfileTarget {
@@ -313,4 +313,5 @@ async function main(): Promise<void> {
313313
console.log(report)
314314
}
315315

316-
await main()
316+
if (import.meta.main)
317+
await main()

0 commit comments

Comments
 (0)