diff --git a/bin/gstack-model-benchmark b/bin/gstack-model-benchmark index c5f5cb5b6..a198fddc9 100755 --- a/bin/gstack-model-benchmark +++ b/bin/gstack-model-benchmark @@ -88,6 +88,20 @@ function parseProviders(s: string | undefined): Array<'claude' | 'gpt' | 'gemini return seen.size ? Array.from(seen) : ['claude']; } +function parsePositiveIntegerFlag(name: string, def: string): number { + const raw = arg(name, def); + if (!raw || !/^\+?[1-9]\d*$/.test(raw)) { + console.error(`${name} requires a positive integer`); + process.exit(1); + } + const parsed = Number(raw); + if (!Number.isSafeInteger(parsed)) { + console.error(`${name} requires a positive integer`); + process.exit(1); + } + return parsed; +} + function resolvePrompt(positional: string | undefined): string { const inline = arg('--prompt'); if (inline) return inline; @@ -107,7 +121,7 @@ async function main(): Promise { const prompt = resolvePrompt(positional); const providers = parseProviders(arg('--models')); const workdir = arg('--workdir', process.cwd())!; - const timeoutMs = parseInt(arg('--timeout-ms', '300000')!, 10); + const timeoutMs = parsePositiveIntegerFlag('--timeout-ms', '300000'); const output = (arg('--output', 'table') as OutputFormat); const skipUnavailable = flag('--skip-unavailable'); const doJudge = flag('--judge'); diff --git a/test/benchmark-cli.test.ts b/test/benchmark-cli.test.ts index 8edea3b24..45392f710 100644 --- a/test/benchmark-cli.test.ts +++ b/test/benchmark-cli.test.ts @@ -73,6 +73,21 @@ describe('gstack-model-benchmark --dry-run', () => { expect(r.stdout).toContain('workdir: /tmp'); }); + test('--timeout-ms accepts plus-prefixed positive integers', () => { + const r = run(['--prompt', 'hi', '--timeout-ms', '+2500', '--dry-run']); + expect(r.status).toBe(0); + expect(r.stdout).toContain('timeout_ms: 2500'); + }); + + test('--timeout-ms rejects malformed values', () => { + for (const value of ['1abc', 'nope', '0', '-1', '1.5', '']) { + const r = run(['--prompt', 'hi', '--timeout-ms', value, '--dry-run']); + expect(r.status).toBe(1); + expect(r.stderr).toContain('--timeout-ms requires a positive integer'); + expect(r.stdout).toBe(''); + } + }); + test('--judge flag reported in dry-run output', () => { const r = run(['--prompt', 'hi', '--judge', '--dry-run']); expect(r.status).toBe(0);