mirror of https://github.com/openclaw/openclaw.git
fix: avoid over-sharding single include-file test batches
This commit is contained in:
parent
c22edbb8ee
commit
aff6883f93
|
|
@ -15,6 +15,17 @@ import {
|
|||
} from "../test-parallel-utils.mjs";
|
||||
import { countExplicitEntryFilters, getExplicitEntryFilters } from "./vitest-args.mjs";
|
||||
|
||||
const countUnitEntryFilters = (unit) => {
|
||||
const explicitFilterCount = countExplicitEntryFilters(unit.args);
|
||||
if (explicitFilterCount !== null) {
|
||||
return explicitFilterCount;
|
||||
}
|
||||
if (Array.isArray(unit.includeFiles) && unit.includeFiles.length > 0) {
|
||||
return unit.includeFiles.length;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export function resolvePnpmCommandInvocation(options = {}) {
|
||||
const npmExecPath = typeof options.npmExecPath === "string" ? options.npmExecPath.trim() : "";
|
||||
if (npmExecPath && path.isAbsolute(npmExecPath)) {
|
||||
|
|
@ -253,7 +264,7 @@ export function formatPlanOutput(plan) {
|
|||
`runtime=${plan.runtimeCapabilities.runtimeProfileName} mode=${plan.runtimeCapabilities.mode} intent=${plan.runtimeCapabilities.intentProfile} memoryBand=${plan.runtimeCapabilities.memoryBand} loadBand=${plan.runtimeCapabilities.loadBand} failurePolicy=${plan.failurePolicy} vitestMaxWorkers=${String(plan.executionBudget.vitestMaxWorkers ?? "default")} topLevelParallel=${plan.topLevelParallelEnabled ? String(plan.topLevelParallelLimit) : "off"}`,
|
||||
...plan.selectedUnits.map(
|
||||
(unit) =>
|
||||
`${unit.id} filters=${String(countExplicitEntryFilters(unit.args) ?? "all")} maxWorkers=${String(
|
||||
`${unit.id} filters=${String(countUnitEntryFilters(unit) ?? "all")} maxWorkers=${String(
|
||||
unit.maxWorkers ?? "default",
|
||||
)} surface=${unit.surface} isolate=${unit.isolate ? "yes" : "no"} pool=${unit.pool}`,
|
||||
),
|
||||
|
|
@ -810,7 +821,7 @@ export async function executePlan(plan, options = {}) {
|
|||
results.push(await runOnce(unit, extraArgs));
|
||||
return results;
|
||||
}
|
||||
const explicitFilterCount = countExplicitEntryFilters(unit.args);
|
||||
const explicitFilterCount = countUnitEntryFilters(unit);
|
||||
const topLevelAssignedShard = plan.topLevelSingleShardAssignments.get(unit);
|
||||
if (topLevelAssignedShard !== undefined) {
|
||||
if (plan.shardIndexOverride !== null && plan.shardIndexOverride !== topLevelAssignedShard) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,17 @@ import {
|
|||
SINGLE_RUN_ONLY_FLAGS,
|
||||
} from "./vitest-args.mjs";
|
||||
|
||||
const countUnitEntryFilters = (unit) => {
|
||||
const explicitFilterCount = countExplicitEntryFilters(unit.args);
|
||||
if (explicitFilterCount !== null) {
|
||||
return explicitFilterCount;
|
||||
}
|
||||
if (Array.isArray(unit.includeFiles) && unit.includeFiles.length > 0) {
|
||||
return unit.includeFiles.length;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const parseEnvNumber = (env, name, fallback) => {
|
||||
const parsed = Number.parseInt(env[name] ?? "", 10);
|
||||
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
||||
|
|
@ -1116,7 +1127,7 @@ const buildTopLevelSingleShardAssignments = (context, units) => {
|
|||
if (unit.fixedShardIndex !== undefined) {
|
||||
return false;
|
||||
}
|
||||
const explicitFilterCount = countExplicitEntryFilters(unit.args);
|
||||
const explicitFilterCount = countUnitEntryFilters(unit);
|
||||
if (explicitFilterCount === null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1364,7 +1375,7 @@ export function buildCIExecutionManifest(scopeInput = {}, options = {}) {
|
|||
}
|
||||
|
||||
export const formatExecutionUnitSummary = (unit) =>
|
||||
`${unit.id} filters=${String(countExplicitEntryFilters(unit.args) || "all")} maxWorkers=${String(
|
||||
`${unit.id} filters=${String(countUnitEntryFilters(unit) || "all")} maxWorkers=${String(
|
||||
unit.maxWorkers ?? "default",
|
||||
)} surface=${unit.surface} isolate=${unit.isolate ? "yes" : "no"} pool=${unit.pool}`;
|
||||
|
||||
|
|
|
|||
|
|
@ -277,8 +277,8 @@ describe("scripts/test-parallel lane planning", () => {
|
|||
);
|
||||
|
||||
expect(output).toContain("mode=local intent=normal memoryBand=mid");
|
||||
expect(output).toContain("unit-fast filters=all maxWorkers=");
|
||||
expect(output).toMatch(/extensions(?:-batch-1)? filters=all maxWorkers=/);
|
||||
expect(output).toMatch(/unit-fast(?:-batch-\d+)? filters=\d+ maxWorkers=/);
|
||||
expect(output).toMatch(/extensions(?:-batch-\d+)? filters=\d+ maxWorkers=/);
|
||||
});
|
||||
|
||||
it("uses higher shared extension worker counts on high-memory local hosts", () => {
|
||||
|
|
@ -304,8 +304,8 @@ describe("scripts/test-parallel lane planning", () => {
|
|||
|
||||
expect(midSharedBatches.length).toBeGreaterThan(0);
|
||||
expect(highSharedBatches.length).toBeGreaterThan(0);
|
||||
expect(midSharedBatches.every((line) => line.includes("filters=all maxWorkers=3"))).toBe(true);
|
||||
expect(highSharedBatches.every((line) => line.includes("filters=all maxWorkers=5"))).toBe(true);
|
||||
expect(midSharedBatches.every((line) => /filters=\d+ maxWorkers=3/.test(line))).toBe(true);
|
||||
expect(highSharedBatches.every((line) => /filters=\d+ maxWorkers=5/.test(line))).toBe(true);
|
||||
expect(highSharedBatches.length).toBeLessThanOrEqual(midSharedBatches.length);
|
||||
});
|
||||
|
||||
|
|
@ -320,7 +320,7 @@ describe("scripts/test-parallel lane planning", () => {
|
|||
expect(firstChannelIsolated).toBeGreaterThanOrEqual(0);
|
||||
expect(firstExtensionBatch).toBeGreaterThan(firstChannelIsolated);
|
||||
expect(firstChannelBatch).toBeGreaterThan(firstExtensionBatch);
|
||||
expect(output).toContain("channels-batch-1 filters=all maxWorkers=5");
|
||||
expect(output).toMatch(/channels-batch-1 filters=\d+ maxWorkers=5/);
|
||||
});
|
||||
|
||||
it("uses coarser unit-fast batching for high-memory local multi-surface runs", () => {
|
||||
|
|
|
|||
|
|
@ -400,6 +400,41 @@ describe("test planner", () => {
|
|||
artifacts.cleanupTempArtifacts();
|
||||
});
|
||||
|
||||
it("assigns single include-file CI batches to one shard instead of over-sharding them", () => {
|
||||
const env = {
|
||||
CI: "true",
|
||||
GITHUB_ACTIONS: "true",
|
||||
OPENCLAW_TEST_SHARDS: "4",
|
||||
OPENCLAW_TEST_SHARD_INDEX: "1",
|
||||
OPENCLAW_TEST_LOAD_AWARE: "0",
|
||||
};
|
||||
const artifacts = createExecutionArtifacts(env);
|
||||
const plan = buildExecutionPlan(
|
||||
{
|
||||
mode: "ci",
|
||||
passthroughArgs: [],
|
||||
},
|
||||
{
|
||||
env,
|
||||
platform: "linux",
|
||||
writeTempJsonArtifact: artifacts.writeTempJsonArtifact,
|
||||
},
|
||||
);
|
||||
|
||||
const singleFileBatch = plan.parallelUnits.find(
|
||||
(unit) =>
|
||||
unit.id.startsWith("unit-fast-") &&
|
||||
unit.fixedShardIndex === undefined &&
|
||||
Array.isArray(unit.includeFiles) &&
|
||||
unit.includeFiles.length === 1,
|
||||
);
|
||||
|
||||
expect(singleFileBatch).toBeTruthy();
|
||||
expect(plan.topLevelSingleShardAssignments.get(singleFileBatch)).toBeTypeOf("number");
|
||||
|
||||
artifacts.cleanupTempArtifacts();
|
||||
});
|
||||
|
||||
it("removes planner temp artifacts when cleanup runs after planning", () => {
|
||||
const artifacts = createExecutionArtifacts({});
|
||||
buildExecutionPlan(
|
||||
|
|
|
|||
Loading…
Reference in New Issue