mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-13 18:36:04 +00:00
fix(test): guard model resolution profiler args
This commit is contained in:
@@ -26,6 +26,23 @@ type Options = {
|
||||
warmup: number;
|
||||
};
|
||||
|
||||
const BOOLEAN_FLAGS = new Set(["--help", "-h", "--json", "--keep-temp", "--runtime-hooks"]);
|
||||
const VALUE_FLAGS = new Set([
|
||||
"--agents",
|
||||
"--cpu-prof-dir",
|
||||
"--cpu-prof-output",
|
||||
"--lookups",
|
||||
"--models-per-provider",
|
||||
"--output",
|
||||
"--providers",
|
||||
"--runs",
|
||||
"--warmup",
|
||||
]);
|
||||
|
||||
class CliArgumentError extends Error {
|
||||
override name = "CliArgumentError";
|
||||
}
|
||||
|
||||
type PhaseSample = {
|
||||
ensureMs: number;
|
||||
resolveMs: number;
|
||||
@@ -73,7 +90,11 @@ function parseFlagValue(flag: string): string | undefined {
|
||||
if (index === -1) {
|
||||
return undefined;
|
||||
}
|
||||
return process.argv[index + 1];
|
||||
const value = process.argv[index + 1];
|
||||
if (!value || value.startsWith("--")) {
|
||||
throw new CliArgumentError(`${flag} requires a value`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function hasFlag(flag: string): boolean {
|
||||
@@ -85,9 +106,12 @@ function parsePositiveInt(flag: string, fallback: number): number {
|
||||
if (!raw) {
|
||||
return fallback;
|
||||
}
|
||||
const value = Number.parseInt(raw, 10);
|
||||
const value = Number(raw);
|
||||
if (!Number.isFinite(value) || value <= 0) {
|
||||
throw new Error(`${flag} must be a positive integer`);
|
||||
throw new CliArgumentError(`${flag} must be a positive integer`);
|
||||
}
|
||||
if (!Number.isInteger(value)) {
|
||||
throw new CliArgumentError(`${flag} must be a positive integer`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -97,14 +121,32 @@ function parseNonNegativeInt(flag: string, fallback: number): number {
|
||||
if (!raw) {
|
||||
return fallback;
|
||||
}
|
||||
const value = Number.parseInt(raw, 10);
|
||||
const value = Number(raw);
|
||||
if (!Number.isFinite(value) || value < 0) {
|
||||
throw new Error(`${flag} must be a non-negative integer`);
|
||||
throw new CliArgumentError(`${flag} must be a non-negative integer`);
|
||||
}
|
||||
if (!Number.isInteger(value)) {
|
||||
throw new CliArgumentError(`${flag} must be a non-negative integer`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function validateCliArgs(args = process.argv.slice(2)): void {
|
||||
for (let index = 0; index < args.length; index += 1) {
|
||||
const arg = args[index] ?? "";
|
||||
if (BOOLEAN_FLAGS.has(arg)) {
|
||||
continue;
|
||||
}
|
||||
if (VALUE_FLAGS.has(arg)) {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
throw new CliArgumentError(`Unknown argument: ${arg}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseOptions(): Options {
|
||||
validateCliArgs();
|
||||
return {
|
||||
agentCount: parsePositiveInt("--agents", 8),
|
||||
cpuProfDir: parseFlagValue("--cpu-prof-dir"),
|
||||
@@ -494,6 +536,10 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
main().catch((error: unknown) => {
|
||||
if (error instanceof CliArgumentError) {
|
||||
process.stderr.write(`${error.message}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
||||
process.stderr.write(`${message}\n`);
|
||||
process.exit(1);
|
||||
|
||||
43
test/scripts/issue-78851-model-resolution.test.ts
Normal file
43
test/scripts/issue-78851-model-resolution.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
// Issue 78851 profiler CLI tests cover argument handling before work starts.
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
function runProfiler(...args: string[]) {
|
||||
return spawnSync(
|
||||
process.execPath,
|
||||
["--import", "tsx", "scripts/perf/issue-78851-model-resolution.ts", ...args],
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf8",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
describe("issue 78851 model resolution profiler CLI", () => {
|
||||
it("prints help without starting the profiler", () => {
|
||||
const result = runProfiler("--help");
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain("OpenClaw issue #78851 model-resolution profiler");
|
||||
expect(result.stdout).toContain(
|
||||
"node --import tsx scripts/perf/issue-78851-model-resolution.ts [options]",
|
||||
);
|
||||
expect(result.stderr).toBe("");
|
||||
});
|
||||
|
||||
it("rejects unknown arguments before starting the profiler", () => {
|
||||
const result = runProfiler("--wat");
|
||||
|
||||
expect(result.status).toBe(1);
|
||||
expect(result.stdout).toBe("");
|
||||
expect(result.stderr.trim()).toBe("Unknown argument: --wat");
|
||||
});
|
||||
|
||||
it("rejects partial numeric arguments before starting the profiler", () => {
|
||||
const result = runProfiler("--providers", "48junk");
|
||||
|
||||
expect(result.status).toBe(1);
|
||||
expect(result.stdout).toBe("");
|
||||
expect(result.stderr.trim()).toBe("--providers must be a positive integer");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user