Tests: cap CI extension batch concurrency

This commit is contained in:
Gustavo Madeira Santana
2026-03-28 18:58:47 -04:00
parent 81432d6b7e
commit 0b8bc0e1b4
2 changed files with 57 additions and 1 deletions

View File

@@ -1359,6 +1359,24 @@ export const formatExecutionUnitSummary = (unit) =>
unit.maxWorkers ?? "default",
)} surface=${unit.surface} isolate=${unit.isolate ? "yes" : "no"} pool=${unit.pool}`;
function resolveSurfaceAwareTopLevelParallelLimit(context, units, defaultLimit) {
if (!context.runtime.isCI || context.noIsolateArgs.length === 0) {
return defaultLimit;
}
const sharedExtensionUnits = units.filter(
(unit) => unit.surface === "extensions" && !unit.isolate,
);
if (sharedExtensionUnits.length <= 1) {
return defaultLimit;
}
// Shared extension batches can each retain multiple GiB in CI. Limit that
// phase to two concurrent lanes so provider-contract checks are not starved
// behind unrelated memory-heavy extension suites.
return Math.min(defaultLimit, 2);
}
export function explainExecutionTarget(request, options = {}) {
const context = createPlannerContext(request, options);
context.noIsolateArgs =
@@ -1492,7 +1510,11 @@ export function buildExecutionPlan(request, options = {}) {
context.noIsolateArgs.length > 0
? context.executionBudget.topLevelParallelLimitNoIsolate
: context.executionBudget.topLevelParallelLimitIsolated;
const defaultTopLevelParallelLimit = baseTopLevelParallelLimit;
const defaultTopLevelParallelLimit = resolveSurfaceAwareTopLevelParallelLimit(
context,
selectedUnits,
baseTopLevelParallelLimit,
);
const topLevelParallelLimit = Math.max(
1,
parseEnvNumber(env, "OPENCLAW_TEST_TOP_LEVEL_CONCURRENCY", defaultTopLevelParallelLimit),

View File

@@ -83,6 +83,40 @@ describe("test planner", () => {
artifacts.cleanupTempArtifacts();
});
it("caps CI extension batch concurrency when multiple shared batches are scheduled", () => {
const env = {
CI: "true",
GITHUB_ACTIONS: "true",
RUNNER_OS: "Linux",
OPENCLAW_TEST_HOST_CPU_COUNT: "4",
OPENCLAW_TEST_HOST_MEMORY_GIB: "16",
};
const artifacts = createExecutionArtifacts(env);
const plan = buildExecutionPlan(
{
profile: null,
mode: "ci",
surfaces: ["extensions"],
passthroughArgs: [],
},
{
env,
platform: "linux",
writeTempJsonArtifact: artifacts.writeTempJsonArtifact,
},
);
const sharedExtensionBatches = plan.selectedUnits.filter(
(unit) => unit.surface === "extensions" && !unit.isolate,
);
expect(plan.runtimeCapabilities.runtimeProfileName).toBe("ci-linux");
expect(plan.executionBudget.topLevelParallelLimitNoIsolate).toBe(4);
expect(sharedExtensionBatches.length).toBeGreaterThan(1);
expect(plan.topLevelParallelLimit).toBe(2);
artifacts.cleanupTempArtifacts();
});
it("scales down mid-tier local concurrency under saturated load", () => {
const artifacts = createExecutionArtifacts({
RUNNER_OS: "Linux",