mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
test(ci): rebalance compact Node shards (#121834)
* test(ci): rebalance compact node shards Amp-Thread-ID: https://ampcode.com/threads/T-019fee8d-665d-707b-a380-23f2a6a1ce03 Co-authored-by: Peter Steinberger <steipete@gmail.com> * test(ci): guard compact planner coverage Amp-Thread-ID: https://ampcode.com/threads/T-019fee8d-665d-707b-a380-23f2a6a1ce03 Co-authored-by: Peter Steinberger <steipete@gmail.com> * test(ci): drop obsolete shard isolation check Amp-Thread-ID: https://ampcode.com/threads/T-019fee8d-665d-707b-a380-23f2a6a1ce03 Co-authored-by: Peter Steinberger <steipete@gmail.com> * test(ci): stop freezing compact shard placement Amp-Thread-ID: https://ampcode.com/threads/T-019fee8d-665d-707b-a380-23f2a6a1ce03 Co-authored-by: Peter Steinberger <steipete@gmail.com> --------- Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
committed by
GitHub
parent
73a9eed95b
commit
19ed7feee1
@@ -98,10 +98,10 @@ const COMPACT_EMBEDDED_GROUP_NAMES = [
|
||||
const MAX_BUNDLED_NODE_TEST_PATTERNS = 64;
|
||||
// PR-only bundles trade a little serial work for fewer ephemeral runner registrations.
|
||||
// Keep runner classes and subprocess isolation intact while bounding each combined job.
|
||||
// The group hints below are loaded-fleet CI walls. The 220s cap keeps the
|
||||
// established 24-worker compact matrix after refreshing underestimated groups;
|
||||
// expanded composite groups are then striped evenly across those jobs.
|
||||
const COMPACT_NODE_TEST_JOB_SECONDS = 220;
|
||||
// The group hints below are loaded-fleet CI walls. The 310s admission cap
|
||||
// reduces the compact matrix from 24 to 23 workers; expanded composite groups
|
||||
// are then striped evenly across those jobs.
|
||||
const COMPACT_NODE_TEST_JOB_SECONDS = 310;
|
||||
const COMPACT_NODE_TEST_JOB_GROUPS = 10;
|
||||
const COMPACT_TOOLING_NODE_TEST_GROUPS = 4;
|
||||
const COMPACT_WHOLE_NODE_TEST_TIMEOUT_MINUTES = 120;
|
||||
@@ -115,13 +115,14 @@ const UNIT_FAST_NODE_TEST_STRIPES = 2;
|
||||
// dropping cache-warm/contention outliers outside [median/1.5, median*1.5].
|
||||
// Packing only: a stale entry skews job balance but never correctness.
|
||||
// Unknown shards fall back to a per-file estimate.
|
||||
// Four outlier hints were refreshed from child-process walls in run 31450296338.
|
||||
// Outlier hints were refreshed from child-process walls in runs 31453973052
|
||||
// and 31455822921.
|
||||
const COMPACT_GROUP_SECONDS_HINTS = new Map<string, number>([
|
||||
["agentic-agents-core-auth", 27],
|
||||
["agentic-agents-core-isolated", 9],
|
||||
// Model catalog and full UI both cold-load broad graphs. Keep their combined
|
||||
// hint above the compact-bin cap so model visibility cannot starve for 120s.
|
||||
["agentic-agents-core-models", 70],
|
||||
// Model catalog and full UI both cold-load broad graphs; preserve their
|
||||
// measured separation when striping the expanded groups.
|
||||
["agentic-agents-core-models", 37],
|
||||
// Reliability's runtime-free provider check dropped its wall time from
|
||||
// ~245s to ~5s; the narrow anthropic cli-api artifact removes the same
|
||||
// full-barrel evaluation for the remaining facade importers (spawn).
|
||||
@@ -133,74 +134,93 @@ const COMPACT_GROUP_SECONDS_HINTS = new Map<string, number>([
|
||||
["agentic-agents-core-runner-commands", 27],
|
||||
["agentic-agents-core-runner-embedded", 20],
|
||||
["agentic-agents-core-runner-sessions", 13],
|
||||
["agentic-agents-core-runtime", 130],
|
||||
["agentic-agents-core-subagents", 32],
|
||||
["agentic-agents-core-runtime", 104],
|
||||
["agentic-agents-core-subagents", 10],
|
||||
["agentic-agents-core-tools", 52],
|
||||
// The composite hint sets the existing job count before its independent
|
||||
// configs are striped across those jobs. Split hints are medians from four
|
||||
// recent 2-core runs
|
||||
// (30532132189, 30532967046, 30534273298, 30536274496).
|
||||
["agentic-agents-embedded", 430],
|
||||
["agentic-agents-embedded-base", 363],
|
||||
["agentic-agents-embedded-incomplete-turn", 146],
|
||||
["agentic-agents-embedded-overflow-compaction", 150],
|
||||
// The composite hint sets the job count before its independent configs are
|
||||
// striped across those jobs. Split hints use the same loaded-fleet run as
|
||||
// the rest of this map rather than older 2-core measurements.
|
||||
["agentic-agents-embedded", 150],
|
||||
["agentic-agents-embedded-base", 88],
|
||||
["agentic-agents-embedded-incomplete-turn", 14],
|
||||
["agentic-agents-embedded-overflow-compaction", 12],
|
||||
["agentic-agents-embedded-run", 30],
|
||||
["agentic-agents-support", 110],
|
||||
["agentic-agents-support", 201],
|
||||
["agentic-agents-tools", 42],
|
||||
["agentic-cli", 72],
|
||||
["agentic-command-support", 41],
|
||||
["agentic-commands-agent-channel", 51],
|
||||
["agentic-cli", 145],
|
||||
["agentic-command-support", 65],
|
||||
["agentic-commands-agent-channel", 74],
|
||||
["agentic-commands-doctor", 19],
|
||||
["agentic-commands-doctor-auth", 11],
|
||||
["agentic-commands-doctor-config-state", 42],
|
||||
["agentic-commands-doctor-config-state", 112],
|
||||
["agentic-commands-doctor-device", 2],
|
||||
["agentic-commands-doctor-gateway", 4],
|
||||
["agentic-commands-doctor-platform", 3],
|
||||
["agentic-commands-doctor-plugins-tools", 11],
|
||||
["agentic-commands-doctor-sessions-cron", 24],
|
||||
["agentic-commands-doctor-shared", 16],
|
||||
["agentic-commands-doctor-whatsapp", 1],
|
||||
["agentic-commands-doctor-workspace", 1],
|
||||
["agentic-commands-models", 16],
|
||||
["agentic-commands-onboard-config", 11],
|
||||
["agentic-commands-status-tools", 21],
|
||||
["agentic-control-plane-agent-chat", 74],
|
||||
["agentic-control-plane-auth-node", 89],
|
||||
["agentic-control-plane-agent-chat", 123],
|
||||
["agentic-control-plane-auth-node", 128],
|
||||
["agentic-control-plane-http-models", 33],
|
||||
["agentic-control-plane-http-plugin-ws", 39],
|
||||
["agentic-control-plane-runtime-config", 14],
|
||||
["agentic-control-plane-runtime-cron", 15],
|
||||
["agentic-control-plane-runtime-network", 1],
|
||||
["agentic-control-plane-runtime-server", 29],
|
||||
["agentic-control-plane-runtime-shared-token", 22],
|
||||
["agentic-control-plane-runtime-state", 13],
|
||||
["agentic-control-plane-runtime-ui-tools", 11],
|
||||
["agentic-control-plane-startup-core", 156],
|
||||
["agentic-control-plane-startup-core", 28],
|
||||
["agentic-control-plane-startup-health-runtime", 22],
|
||||
["agentic-control-plane-startup-restart-close", 8],
|
||||
["agentic-gateway-core", 124],
|
||||
["agentic-gateway-methods", 69],
|
||||
["agentic-gateway-core", 197],
|
||||
["agentic-gateway-methods", 136],
|
||||
["agentic-plugin-sdk", 47],
|
||||
["auto-reply-core-top-level", 30],
|
||||
["auto-reply-reply-agent-runner", 40],
|
||||
["auto-reply-reply-commands-1", 24],
|
||||
["auto-reply-reply-commands-1", 44],
|
||||
["auto-reply-reply-commands-2", 18],
|
||||
["auto-reply-reply-commands-3", 12],
|
||||
["auto-reply-reply-dispatch", 40],
|
||||
["auto-reply-reply-commands-3", 36],
|
||||
["auto-reply-reply-dispatch", 64],
|
||||
["auto-reply-reply-session", 19],
|
||||
["auto-reply-reply-state-routing", 18],
|
||||
["auto-reply-reply-state-routing", 54],
|
||||
["core-runtime-cron-core", 16],
|
||||
["core-runtime-cron-isolated-agent", 59],
|
||||
["core-runtime-cron-service", 23],
|
||||
["core-runtime-cron-isolated-agent", 94],
|
||||
["core-runtime-cron-service", 49],
|
||||
["core-runtime-hooks", 9],
|
||||
["core-runtime-infra-approval-exec", 30],
|
||||
["core-runtime-infra-channel-plugin", 17],
|
||||
["core-runtime-infra-cli-ui", 1],
|
||||
["core-runtime-infra-core-utils", 3],
|
||||
["core-runtime-infra-diagnostics-state", 19],
|
||||
["core-runtime-infra-heartbeat-runner", 53],
|
||||
["core-runtime-infra-events-runtime", 4],
|
||||
["core-runtime-infra-file-safety", 2],
|
||||
["core-runtime-infra-files-commands", 5],
|
||||
["core-runtime-infra-gateway-lock-argv", 2],
|
||||
["core-runtime-infra-gateway-processes", 1],
|
||||
["core-runtime-infra-gateway-watch", 1],
|
||||
["core-runtime-infra-heartbeat-core", 4],
|
||||
["core-runtime-infra-heartbeat-runner", 123],
|
||||
["core-runtime-infra-misc", 9],
|
||||
["core-runtime-infra-misc-dedupe-disk", 1],
|
||||
["core-runtime-infra-misc-os", 1],
|
||||
["core-runtime-infra-misc-values", 1],
|
||||
["core-runtime-infra-net-install", 13],
|
||||
["core-runtime-infra-network-node", 2],
|
||||
["core-runtime-infra-network-platform", 4],
|
||||
["core-runtime-infra-outbound-actions", 19],
|
||||
["core-runtime-infra-outbound-core", 45],
|
||||
["core-runtime-infra-process", 91],
|
||||
["core-runtime-infra-process", 118],
|
||||
["core-runtime-infra-provider-push", 17],
|
||||
["core-runtime-infra-storage-state", 70],
|
||||
["core-runtime-infra-repo-tooling", 4],
|
||||
["core-runtime-infra-storage-state", 96],
|
||||
["core-runtime-infra-system-runtime", 40],
|
||||
["core-runtime-media-ui", 124],
|
||||
["core-runtime-media-ui", 174],
|
||||
["core-runtime-secrets", 37],
|
||||
["core-runtime-shared", 48],
|
||||
// PTY timing suites still need a lightly packed lane; the exclusive-bin cap
|
||||
@@ -211,12 +231,12 @@ const COMPACT_GROUP_SECONDS_HINTS = new Map<string, number>([
|
||||
["core-tooling-3", 108],
|
||||
["core-tooling-4", 125],
|
||||
["core-tooling-isolated", 49],
|
||||
["core-unit-fast-1", 41],
|
||||
["core-unit-fast-1", 89],
|
||||
["core-unit-fast-2", 92],
|
||||
// Fork-per-file isolation parallelizes poorly on 4 vCPU; keep it on the
|
||||
// 8 vCPU class, where it still runs a measured ~90s under fleet load.
|
||||
["core-unit-fast-isolated", 90],
|
||||
["core-unit-src-security", 95],
|
||||
["core-unit-src-security", 205],
|
||||
["core-unit-support", 17],
|
||||
]);
|
||||
// Advisory per-file wall-clock hints (seconds) for stripe balancing, measured
|
||||
@@ -1620,29 +1640,31 @@ function createCompactNodeTestShardBundles(
|
||||
}
|
||||
}
|
||||
|
||||
// First-fit above determines the bounded worker count. Stripe every regular
|
||||
// group across those workers afterward; only re-striping the expanded
|
||||
// embedded group left the 4-vCPU matrix with full early bins and nearly
|
||||
// empty tail bins despite accurate timing hints.
|
||||
const expandedGroups = groups.flatMap(expandCompactGroup);
|
||||
if (expandedGroups.length !== groups.length) {
|
||||
const regularGroups = expandedGroups
|
||||
.filter((group) => !isExclusiveCompactGroup(group))
|
||||
.toSorted((a, b) => a.shard_name.localeCompare(b.shard_name));
|
||||
const regularBinCount = bins.filter((bin) => !bin.exclusive).length;
|
||||
const regularBatches = createStripedBatches(
|
||||
regularGroups,
|
||||
regularBinCount,
|
||||
estimateCompactGroupSeconds,
|
||||
);
|
||||
if (regularBatches.some((batch) => batch.length > COMPACT_NODE_TEST_JOB_GROUPS)) {
|
||||
throw new Error("striped compact job exceeds its group capacity");
|
||||
}
|
||||
const regularBins = regularBatches.map((batch) => ({
|
||||
exclusive: false,
|
||||
groups: batch,
|
||||
hasWholeConfigGroup: batch.some((group) => !group.includePatterns),
|
||||
weight: batch.reduce((sum, group) => sum + estimateCompactGroupSeconds(group), 0),
|
||||
}));
|
||||
const exclusiveBins = bins.filter((bin) => bin.exclusive);
|
||||
bins.splice(0, bins.length, ...regularBins, ...exclusiveBins);
|
||||
const regularGroups = expandedGroups
|
||||
.filter((group) => !isExclusiveCompactGroup(group))
|
||||
.toSorted((a, b) => a.shard_name.localeCompare(b.shard_name));
|
||||
const regularBinCount = bins.filter((bin) => !bin.exclusive).length;
|
||||
const regularBatches = createStripedBatches(
|
||||
regularGroups,
|
||||
regularBinCount,
|
||||
estimateCompactGroupSeconds,
|
||||
);
|
||||
if (regularBatches.some((batch) => batch.length > COMPACT_NODE_TEST_JOB_GROUPS)) {
|
||||
throw new Error("striped compact job exceeds its group capacity");
|
||||
}
|
||||
const regularBins = regularBatches.map((batch) => ({
|
||||
exclusive: false,
|
||||
groups: batch,
|
||||
hasWholeConfigGroup: batch.some((group) => !group.includePatterns),
|
||||
weight: batch.reduce((sum, group) => sum + estimateCompactGroupSeconds(group), 0),
|
||||
}));
|
||||
const exclusiveBins = bins.filter((bin) => bin.exclusive);
|
||||
bins.splice(0, bins.length, ...regularBins, ...exclusiveBins);
|
||||
|
||||
for (const [index, bin] of bins.entries()) {
|
||||
const [firstGroup] = bin.groups;
|
||||
|
||||
Reference in New Issue
Block a user