mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 13:11:40 +00:00
fix(ci): reduce slow channel test skew
This commit is contained in:
@@ -83,6 +83,7 @@ export function loadTestCatalog() {
|
||||
const isolated =
|
||||
options.unitMemoryIsolatedFiles?.includes(normalizedFile) ||
|
||||
options.extensionTimedIsolatedFiles?.includes(normalizedFile) ||
|
||||
options.channelTimedIsolatedFiles?.includes(normalizedFile) ||
|
||||
unitForkIsolatedFileSet.has(normalizedFile) ||
|
||||
extensionForkIsolatedFileSet.has(normalizedFile) ||
|
||||
channelIsolatedFileSet.has(normalizedFile);
|
||||
@@ -92,6 +93,9 @@ export function loadTestCatalog() {
|
||||
if (options.extensionTimedIsolatedFiles?.includes(normalizedFile)) {
|
||||
reasons.push("extensions-timed-heavy");
|
||||
}
|
||||
if (options.channelTimedIsolatedFiles?.includes(normalizedFile)) {
|
||||
reasons.push("channels-timed-heavy");
|
||||
}
|
||||
if (unitForkIsolatedFileSet.has(normalizedFile)) {
|
||||
reasons.push("unit-isolated-manifest");
|
||||
}
|
||||
|
||||
@@ -455,6 +455,30 @@ const resolveExtensionTimedHeavyFiles = (context) => {
|
||||
});
|
||||
};
|
||||
|
||||
const resolveChannelTimedHeavyFiles = (context) => {
|
||||
const { env, runtime, catalog, channelTimingManifest } = context;
|
||||
const timedHeavyChannelFileLimit = parseEnvNumber(
|
||||
env,
|
||||
"OPENCLAW_TEST_HEAVY_CHANNEL_FILE_LIMIT",
|
||||
runtime.isCI ? 10 : 6,
|
||||
);
|
||||
const timedHeavyChannelMinDurationMs = parseEnvNumber(
|
||||
env,
|
||||
"OPENCLAW_TEST_HEAVY_CHANNEL_MIN_MS",
|
||||
runtime.isCI ? 12_000 : 18_000,
|
||||
);
|
||||
return selectTimedHeavyFiles({
|
||||
candidates: catalog.allKnownTestFiles.filter(
|
||||
(file) =>
|
||||
catalog.channelTestPrefixes.some((prefix) => file.startsWith(prefix)) &&
|
||||
!catalog.channelIsolatedFileSet.has(file),
|
||||
),
|
||||
limit: timedHeavyChannelFileLimit,
|
||||
minDurationMs: timedHeavyChannelMinDurationMs,
|
||||
timings: channelTimingManifest,
|
||||
});
|
||||
};
|
||||
|
||||
const buildDefaultUnits = (context, request) => {
|
||||
const {
|
||||
env,
|
||||
@@ -481,6 +505,7 @@ const buildDefaultUnits = (context, request) => {
|
||||
(file) => !catalog.unitBehaviorOverrideSet.has(file),
|
||||
);
|
||||
const extensionTimedHeavyFiles = resolveExtensionTimedHeavyFiles(context);
|
||||
const channelTimedHeavyFiles = resolveChannelTimedHeavyFiles(context);
|
||||
const unitSchedulingOverrideSet = new Set([
|
||||
...catalog.unitBehaviorOverrideSet,
|
||||
...memoryHeavyUnitFiles,
|
||||
@@ -489,6 +514,10 @@ const buildDefaultUnits = (context, request) => {
|
||||
...catalog.extensionForkIsolatedFiles,
|
||||
...extensionTimedHeavyFiles,
|
||||
]);
|
||||
const channelSchedulingOverrideSet = new Set([
|
||||
...catalog.channelIsolatedFiles,
|
||||
...channelTimedHeavyFiles,
|
||||
]);
|
||||
const unitFastExcludedFiles = [
|
||||
...new Set([
|
||||
...unitSchedulingOverrideSet,
|
||||
@@ -518,7 +547,7 @@ const buildDefaultUnits = (context, request) => {
|
||||
const channelSharedCandidateFiles = catalog.allKnownTestFiles.filter(
|
||||
(file) =>
|
||||
catalog.channelTestPrefixes.some((prefix) => file.startsWith(prefix)) &&
|
||||
!catalog.channelIsolatedFileSet.has(file),
|
||||
!channelSchedulingOverrideSet.has(file),
|
||||
);
|
||||
const defaultExtensionsBatchTargetMs = executionBudget.extensionsBatchTargetMs;
|
||||
const extensionsBatchTargetMs = parseEnvNumber(
|
||||
@@ -709,6 +738,26 @@ const buildDefaultUnits = (context, request) => {
|
||||
}),
|
||||
);
|
||||
}
|
||||
for (const file of channelTimedHeavyFiles) {
|
||||
units.push(
|
||||
createExecutionUnit(context, {
|
||||
id: `channels-${path.basename(file, ".test.ts")}-isolated`,
|
||||
surface: "channels",
|
||||
isolate: true,
|
||||
estimatedDurationMs: estimateChannelDurationMs(file),
|
||||
args: [
|
||||
"vitest",
|
||||
"run",
|
||||
"--config",
|
||||
"vitest.channels.config.ts",
|
||||
"--pool=forks",
|
||||
...noIsolateArgs,
|
||||
file,
|
||||
],
|
||||
reasons: ["channels-timed-heavy"],
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedSurfaceSet.has("contracts")) {
|
||||
@@ -839,7 +888,7 @@ const buildDefaultUnits = (context, request) => {
|
||||
);
|
||||
}
|
||||
|
||||
return { units, unitMemoryIsolatedFiles };
|
||||
return { units, unitMemoryIsolatedFiles, channelTimedHeavyFiles };
|
||||
};
|
||||
|
||||
const createTargetedUnit = (context, classification, filters) => {
|
||||
@@ -961,6 +1010,7 @@ const buildTargetedUnits = (context, request) => {
|
||||
}
|
||||
const unitMemoryIsolatedFiles = request.unitMemoryIsolatedFiles ?? [];
|
||||
const extensionTimedIsolatedFiles = request.extensionTimedIsolatedFiles ?? [];
|
||||
const channelTimedIsolatedFiles = request.channelTimedIsolatedFiles ?? [];
|
||||
const estimateUnitDurationMs = (file) =>
|
||||
context.unitTimingManifest.files[file]?.durationMs ??
|
||||
context.unitTimingManifest.defaultDurationMs;
|
||||
@@ -985,6 +1035,7 @@ const buildTargetedUnits = (context, request) => {
|
||||
const classification = context.catalog.classifyTestFile(normalizeRepoPath(fileFilter), {
|
||||
unitMemoryIsolatedFiles,
|
||||
extensionTimedIsolatedFiles,
|
||||
channelTimedIsolatedFiles,
|
||||
});
|
||||
const key = `${classification.legacyBasePinned ? "base-pinned" : classification.surface}:${
|
||||
classification.isolated ? "isolated" : "default"
|
||||
@@ -998,6 +1049,7 @@ const buildTargetedUnits = (context, request) => {
|
||||
const classification = context.catalog.classifyTestFile(matchedFile, {
|
||||
unitMemoryIsolatedFiles,
|
||||
extensionTimedIsolatedFiles,
|
||||
channelTimedIsolatedFiles,
|
||||
});
|
||||
const key = `${classification.legacyBasePinned ? "base-pinned" : classification.surface}:${
|
||||
classification.isolated ? "isolated" : "default"
|
||||
@@ -1017,6 +1069,7 @@ const buildTargetedUnits = (context, request) => {
|
||||
context.catalog.classifyTestFile(file, {
|
||||
unitMemoryIsolatedFiles,
|
||||
extensionTimedIsolatedFiles,
|
||||
channelTimedIsolatedFiles,
|
||||
}),
|
||||
[file],
|
||||
),
|
||||
@@ -1154,10 +1207,18 @@ const estimateTopLevelEntryDurationMs = (unit, context) => {
|
||||
);
|
||||
}
|
||||
if (context.catalog.channelTestPrefixes.some((prefix) => file.startsWith(prefix))) {
|
||||
return totalMs + 3_000;
|
||||
return (
|
||||
totalMs +
|
||||
(context.channelTimingManifest.files[file]?.durationMs ??
|
||||
context.channelTimingManifest.defaultDurationMs)
|
||||
);
|
||||
}
|
||||
if (file.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
|
||||
return totalMs + 2_000;
|
||||
return (
|
||||
totalMs +
|
||||
(context.extensionTimingManifest.files[file]?.durationMs ??
|
||||
context.extensionTimingManifest.defaultDurationMs)
|
||||
);
|
||||
}
|
||||
return totalMs + 1_000;
|
||||
}, 0);
|
||||
@@ -1497,9 +1558,11 @@ export function explainExecutionTarget(request, options = {}) {
|
||||
(file) => !context.catalog.unitBehaviorOverrideSet.has(file),
|
||||
);
|
||||
const extensionTimedIsolatedFiles = resolveExtensionTimedHeavyFiles(context);
|
||||
const channelTimedIsolatedFiles = resolveChannelTimedHeavyFiles(context);
|
||||
const classification = context.catalog.classifyTestFile(normalizedTarget, {
|
||||
unitMemoryIsolatedFiles,
|
||||
extensionTimedIsolatedFiles,
|
||||
channelTimedIsolatedFiles,
|
||||
});
|
||||
const targetedUnit = createTargetedUnit(context, classification, [normalizedTarget]);
|
||||
return {
|
||||
@@ -1584,12 +1647,14 @@ export function buildExecutionPlan(request, options = {}) {
|
||||
|
||||
const defaultPlanning = buildDefaultUnits(context, { ...request, fileFilters });
|
||||
const extensionTimedIsolatedFiles = resolveExtensionTimedHeavyFiles(context);
|
||||
const channelTimedIsolatedFiles = resolveChannelTimedHeavyFiles(context);
|
||||
let units = defaultPlanning.units;
|
||||
const targetedUnits = buildTargetedUnits(context, {
|
||||
...request,
|
||||
fileFilters,
|
||||
unitMemoryIsolatedFiles: defaultPlanning.unitMemoryIsolatedFiles,
|
||||
extensionTimedIsolatedFiles,
|
||||
channelTimedIsolatedFiles,
|
||||
});
|
||||
if (context.configuredShardCount !== null && context.shardCount > 1) {
|
||||
units = expandUnitsAcrossTopLevelShards(context, units);
|
||||
|
||||
Reference in New Issue
Block a user