Skip to content

Commit 833a42c

Browse files
committed
test(gateway): split full-suite gateway-server shard
1 parent 3ad0ad9 commit 833a42c

2 files changed

Lines changed: 118 additions & 15 deletions

File tree

scripts/test-projects.test-support.mjs

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,19 @@ const BROAD_CHANGED_ENV_KEY = "OPENCLAW_TEST_CHANGED_BROAD";
404404
const VITEST_NO_OUTPUT_TIMEOUT_ENV_KEY = "OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS";
405405
const VITEST_NO_OUTPUT_RETRY_ENV_KEY = "OPENCLAW_VITEST_NO_OUTPUT_RETRY";
406406
export 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+
]);
407420
const VITEST_CONFIG_TARGET_KIND_BY_PATH = new Map(
408421
Object.entries(VITEST_CONFIG_BY_KIND).map(([kind, config]) => [config, kind]),
409422
);
@@ -455,6 +468,62 @@ function normalizePathPattern(value) {
455468
return value.replaceAll("\\", "/");
456469
}
457470

471+
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+
458527
function isExistingPathTarget(arg, cwd) {
459528
return fs.existsSync(path.resolve(cwd, arg));
460529
}
@@ -1299,7 +1368,7 @@ export function buildVitestRunPlans(
12991368
}
13001369

13011370
export function buildFullSuiteVitestRunPlans(args, cwd = process.cwd()) {
1302-
const { forwardedArgs, watchMode } = parseTestProjectsArgs(args, cwd);
1371+
const { forwardedArgs, targetArgs, watchMode } = parseTestProjectsArgs(args, cwd);
13031372
if (watchMode) {
13041373
return [
13051374
{
@@ -1324,12 +1393,30 @@ export function buildFullSuiteVitestRunPlans(args, cwd = process.cwd()) {
13241393
}
13251394
const expandShard = expandToProjectConfigs;
13261395
const 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

test/scripts/test-projects.test.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,7 @@ describe("scripts/test-projects full-suite sharding", () => {
11421142

11431143
it("can expand full-suite shards to project configs for perf experiments", () => {
11441144
const previous = process.env.OPENCLAW_TEST_PROJECTS_LEAF_SHARDS;
1145+
const gatewayServerConfig = "test/vitest/vitest.gateway-server.config.ts";
11451146
process.env.OPENCLAW_TEST_PROJECTS_LEAF_SHARDS = "1";
11461147
let plans: ReturnType<typeof buildFullSuiteVitestRunPlans>;
11471148
try {
@@ -1187,7 +1188,10 @@ describe("scripts/test-projects full-suite sharding", () => {
11871188
"test/vitest/vitest.gateway-core.config.ts",
11881189
"test/vitest/vitest.gateway-client.config.ts",
11891190
"test/vitest/vitest.gateway-methods.config.ts",
1190-
"test/vitest/vitest.gateway-server.config.ts",
1191+
gatewayServerConfig,
1192+
gatewayServerConfig,
1193+
gatewayServerConfig,
1194+
gatewayServerConfig,
11911195
"test/vitest/vitest.cli.config.ts",
11921196
"test/vitest/vitest.commands-light.config.ts",
11931197
"test/vitest/vitest.commands.config.ts",
@@ -1230,13 +1234,25 @@ describe("scripts/test-projects full-suite sharding", () => {
12301234
"test/vitest/vitest.extensions.config.ts",
12311235
"test/vitest/vitest.extension-misc.config.ts",
12321236
]);
1233-
expect(plans).toEqual(
1234-
plans.map((plan) => ({
1235-
config: plan.config,
1236-
forwardedArgs: [],
1237-
includePatterns: null,
1238-
watchMode: false,
1239-
})),
1237+
1238+
const gatewayPlans = plans.filter((plan) => plan.config === gatewayServerConfig);
1239+
const gatewayTargets = gatewayPlans.flatMap((plan) => plan.forwardedArgs);
1240+
const gatewayChunkSizes = gatewayPlans.map((plan) => plan.forwardedArgs.length);
1241+
expect(gatewayPlans).toHaveLength(4);
1242+
expect(gatewayTargets.length).toBeGreaterThan(90);
1243+
expect(new Set(gatewayTargets).size).toBe(gatewayTargets.length);
1244+
expect(gatewayTargets).toContain("src/gateway/server-network-runtime.e2e.test.ts");
1245+
expect(gatewayTargets).not.toContain("src/gateway/gateway.test.ts");
1246+
expect(Math.max(...gatewayChunkSizes) - Math.min(...gatewayChunkSizes)).toBeLessThanOrEqual(1);
1247+
expect(plans.filter((plan) => plan.config !== gatewayServerConfig)).toEqual(
1248+
plans
1249+
.filter((plan) => plan.config !== gatewayServerConfig)
1250+
.map((plan) => ({
1251+
config: plan.config,
1252+
forwardedArgs: [],
1253+
includePatterns: null,
1254+
watchMode: false,
1255+
})),
12401256
);
12411257
});
12421258

0 commit comments

Comments
 (0)