



























@@ -404,6 +404,19 @@ const BROAD_CHANGED_ENV_KEY = "OPENCLAW_TEST_CHANGED_BROAD";
404404const VITEST_NO_OUTPUT_TIMEOUT_ENV_KEY = "OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS";
405405const VITEST_NO_OUTPUT_RETRY_ENV_KEY = "OPENCLAW_VITEST_NO_OUTPUT_RETRY";
406406export const DEFAULT_TEST_PROJECTS_VITEST_NO_OUTPUT_TIMEOUT_MS = "300000";
407+const GATEWAY_SERVER_FULL_SUITE_TARGET_CHUNK_COUNT = 4;
408+const GATEWAY_SERVER_BACKED_HTTP_TEST_TARGETS = [
409+"src/gateway/embeddings-http.test.ts",
410+"src/gateway/models-http.test.ts",
411+"src/gateway/openai-http.test.ts",
412+"src/gateway/openresponses-http.test.ts",
413+"src/gateway/probe.auth.integration.test.ts",
414+];
415+const GATEWAY_SERVER_EXCLUDED_TEST_TARGETS = new Set([
416+"src/gateway/gateway.test.ts",
417+"src/gateway/server.startup-matrix-migration.integration.test.ts",
418+"src/gateway/sessions-history-http.test.ts",
419+]);
407420const VITEST_CONFIG_TARGET_KIND_BY_PATH = new Map(
408421Object.entries(VITEST_CONFIG_BY_KIND).map(([kind, config]) => [config, kind]),
409422);
@@ -455,6 +468,62 @@ function normalizePathPattern(value) {
455468return value.replaceAll("\\", "/");
456469}
457470471+function listRepoFilesRecursive(root, cwd) {
472+const entries = fs.readdirSync(root, { withFileTypes: true });
473+return entries.flatMap((entry) => {
474+const absolute = path.join(root, entry.name);
475+if (entry.isDirectory()) {
476+return listRepoFilesRecursive(absolute, cwd);
477+}
478+if (!entry.isFile()) {
479+return [];
480+}
481+return [normalizePathPattern(path.relative(cwd, absolute))];
482+});
483+}
484+485+function isGatewayServerFullSuiteTarget(relative) {
486+if (
487+GATEWAY_SERVER_EXCLUDED_TEST_TARGETS.has(relative) ||
488+relative.startsWith("src/gateway/server-methods/")
489+) {
490+return false;
491+}
492+return (
493+GATEWAY_SERVER_BACKED_HTTP_TEST_TARGETS.includes(relative) ||
494+(relative.startsWith("src/gateway/") &&
495+path.posix.basename(relative).includes("server") &&
496+relative.endsWith(".test.ts"))
497+);
498+}
499+500+function resolveGatewayServerFullSuiteTargets(cwd) {
501+const gatewayDir = path.join(cwd, "src/gateway");
502+if (!fs.existsSync(gatewayDir)) {
503+return [];
504+}
505+return listRepoFilesRecursive(gatewayDir, cwd)
506+.filter(isGatewayServerFullSuiteTarget)
507+.sort((a, b) => a.localeCompare(b));
508+}
509+510+function splitTargetChunks(targets, chunkCount) {
511+if (targets.length === 0) {
512+return [];
513+}
514+const normalizedChunkCount = Math.min(chunkCount, targets.length);
515+const baseSize = Math.floor(targets.length / normalizedChunkCount);
516+const remainder = targets.length % normalizedChunkCount;
517+const chunks = [];
518+let offset = 0;
519+for (let index = 0; index < normalizedChunkCount; index += 1) {
520+const chunkSize = baseSize + (index < remainder ? 1 : 0);
521+chunks.push(targets.slice(offset, offset + chunkSize));
522+offset += chunkSize;
523+}
524+return chunks;
525+}
526+458527function isExistingPathTarget(arg, cwd) {
459528return fs.existsSync(path.resolve(cwd, arg));
460529}
@@ -1299,7 +1368,7 @@ export function buildVitestRunPlans(
12991368}
1300136913011370export function buildFullSuiteVitestRunPlans(args, cwd = process.cwd()) {
1302-const { forwardedArgs, watchMode } = parseTestProjectsArgs(args, cwd);
1371+const { forwardedArgs, targetArgs, watchMode } = parseTestProjectsArgs(args, cwd);
13031372if (watchMode) {
13041373return [
13051374{
@@ -1324,12 +1393,30 @@ export function buildFullSuiteVitestRunPlans(args, cwd = process.cwd()) {
13241393}
13251394const expandShard = expandToProjectConfigs;
13261395const configs = expandShard ? shard.projects : [shard.config];
1327-return configs.map((config) => ({
1328- config,
1329- forwardedArgs,
1330-includePatterns: null,
1331-watchMode: false,
1332-}));
1396+return configs.flatMap((config) => {
1397+if (expandShard && targetArgs.length === 0 && config === GATEWAY_SERVER_VITEST_CONFIG) {
1398+const chunks = splitTargetChunks(
1399+resolveGatewayServerFullSuiteTargets(cwd),
1400+GATEWAY_SERVER_FULL_SUITE_TARGET_CHUNK_COUNT,
1401+);
1402+if (chunks.length > 0) {
1403+return chunks.map((targets) => ({
1404+ config,
1405+forwardedArgs: [...forwardedArgs, ...targets],
1406+includePatterns: null,
1407+watchMode: false,
1408+}));
1409+}
1410+}
1411+return [
1412+{
1413+ config,
1414+ forwardedArgs,
1415+includePatterns: null,
1416+watchMode: false,
1417+},
1418+];
1419+});
13331420});
13341421}
13351422此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。