Files
2026-05-28 18:37:07 +08:00

161 lines
5.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* 批量压测统一入口:按 target 路由到 `targets/*.mjs`。
*
* 用法(在 monorepo 根):
* pnpm run test:stress # 执行全部用例 + 套件总报告
* pnpm run test:stress -- list
* pnpm run test:stress -- text -- --count 10 -c 2
* pnpm run test:stress -- all -- --count 5 -c 2
* pnpm run test:stress -- video-edit --reuse-fixtures --setup-only
*/
import { dirname, join } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { runStressSuite } from "./lib/run-suite.mjs";
const __dirname = dirname(fileURLToPath(import.meta.url));
/**
* @param {string[]} argv
*/
function partitionStressArgv(argv) {
/** @type {{ reuseFixtures?: boolean, setupOnly?: boolean, fixturesDir?: string, stressConfigPath?: string }} */
const globals = {};
const filtered = [];
for (let i = 2; i < argv.length; i++) {
const a = argv[i];
if (a === "--reuse-fixtures") {
globals.reuseFixtures = true;
continue;
}
if (a === "--setup-only") {
globals.setupOnly = true;
continue;
}
if (a === "--fixtures-dir") {
globals.fixturesDir = argv[++i];
continue;
}
if (a.startsWith("--fixtures-dir=")) {
globals.fixturesDir = a.slice("--fixtures-dir=".length);
continue;
}
if (a === "--stress-config") {
globals.stressConfigPath = argv[++i];
continue;
}
if (a.startsWith("--stress-config=")) {
globals.stressConfigPath = a.slice("--stress-config=".length);
continue;
}
filtered.push(a);
}
const cleaned = filtered.filter((a) => a !== "--");
const rawTarget = cleaned.shift();
return { globals, target: rawTarget, forwarded: cleaned };
}
/** @type {Record<string, { file: string, canonical: string }>} */
const ROUTES = {
all: { file: "__suite__", canonical: "all" },
"run-all": { file: "__suite__", canonical: "all" },
// 文本
text: { file: "text-chat.mjs", canonical: "text" },
"text-chat": { file: "text-chat.mjs", canonical: "text" },
// 语音
"speech-tts": { file: "speech-synthesize.mjs", canonical: "speech-tts" },
"speech-synthesize": { file: "speech-synthesize.mjs", canonical: "speech-tts" },
"speech-asr": { file: "speech-recognize.mjs", canonical: "speech-asr" },
"speech-recognize": { file: "speech-recognize.mjs", canonical: "speech-asr" },
// 图像
"image-generate": { file: "image-generate.mjs", canonical: "image-generate" },
"image-edit": { file: "image-edit.mjs", canonical: "image-edit" },
// 视频
"video-t2v": { file: "video-t2v.mjs", canonical: "video-t2v" },
"video-generate": { file: "video-t2v.mjs", canonical: "video-t2v" },
"video-i2v": { file: "video-i2v.mjs", canonical: "video-i2v" },
"video-ref": { file: "video-ref.mjs", canonical: "video-ref" },
"video-edit": { file: "video-edit.mjs", canonical: "video-edit" },
};
function printTargets() {
console.log(`
压测目标(第一参数,省略或 all 表示跑全部用例并生成套件总报告)
-------------------------- ----------------------------------------
(无 / all 顺序执行全部 9 个用例 → SUITE_REPORT.md
text bl text chat
speech-tts bl speech synthesize
speech-asr bl speech recognize需前置音频
image-generate bl image generate
image-edit bl image edit需前置图
video-t2v / video-generate bl video generate 文生视频
video-i2v bl video generate --image需前置图
video-ref bl video ref需前置图
video-edit bl video edit需前置短视频
全局选项(可出现在任意顺序,会与 target 参数分离):
--reuse-fixtures 若当前批次 fixtures/prerequisites.json 已存在则跳过生成
--setup-only 仅生成前置资源(适用于带 fixtures 的目标;套件模式不可用)
--fixtures-dir <path> 使用已有目录下的 prerequisites.json不复制
--stress-config <path> 压测 count/concurrency 配置文件(默认 stress.defaults.json
示例:
pnpm run test:stress
pnpm run test:stress -- list
pnpm run test:stress -- all -- --count 5 -c 2
pnpm run test:stress -- image-generate -- --count 5 -c 1
pnpm run test:stress -- video-edit --setup-only
`);
}
async function main() {
const { globals, target, forwarded } = partitionStressArgv(process.argv);
const t = target?.trim();
if (t === "list" || t === "--help" || t === "-h") {
printTargets();
process.exit(0);
}
if (!t || t === "all" || t === "run-all") {
await runStressSuite({ globals, forwarded });
return;
}
const route = ROUTES[t];
if (!route) {
console.error(`未知 target: "${t}". 运行 pnpm run test:stress -- list 查看列表。`);
process.exit(1);
}
if (route.file === "__suite__") {
await runStressSuite({ globals, forwarded });
return;
}
const modHref = pathToFileURL(join(__dirname, "targets", route.file)).href;
const mod = await import(modHref);
/** @type {(a: string[], c: object) => Promise<void>} */
const runStress = mod.runStress;
if (typeof runStress !== "function") {
console.error(`${route.file} 未导出 runStress`);
process.exit(1);
}
await runStress(forwarded, {
canonicalTarget: route.canonical,
globals,
alias: t,
});
}
main().catch((e) => {
console.error(e);
process.exit(1);
});