MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / planCiShards

Function planCiShards

e2e/scripts/ci-shard.ts:163–218  ·  view source on GitHub ↗
(
  files: readonly WeightedTestFile[],
  shardCount: number,
)

Source from the content-addressed store, hash-verified

161 * or more shards than files. External CLI values must be parsed first.
162 */
163export const planCiShards = (
164 files: readonly WeightedTestFile[],
165 shardCount: number,
166): readonly CiShardAssignment[] => {
167 if (!Number.isSafeInteger(shardCount) || shardCount <= 0) {
168 throw new Error("shard count must be a positive safe integer");
169 }
170 if (files.length < shardCount) {
171 throw new Error("every configured shard must receive at least one test file");
172 }
173
174 const paths = files.map((file) => file.path);
175 if (new Set(paths).size !== paths.length) {
176 throw new Error("test file paths must be unique");
177 }
178 for (const file of files) {
179 if (file.path.length === 0 || !Number.isFinite(file.durationMs) || file.durationMs <= 0) {
180 throw new Error("test files must have a path and positive finite duration");
181 }
182 }
183
184 const bins = Array.from({ length: shardCount }, (_, index) => ({
185 index: index + 1,
186 estimatedDurationMs: 0,
187 files: [] as string[],
188 isolated: false,
189 }));
190 const longestFirst = [...files].sort(
191 (left, right) => right.durationMs - left.durationMs || comparePaths(left.path, right.path),
192 );
193
194 for (const file of longestFirst) {
195 const mustIsolate = file.durationMs >= ISOLATED_TEST_DURATION_MS;
196 const candidates = bins.filter((bin) => (mustIsolate ? bin.files.length === 0 : !bin.isolated));
197 const firstCandidate = candidates[0];
198 if (firstCandidate === undefined) {
199 throw new Error("configured shard count cannot isolate every long-running test file");
200 }
201
202 let lightest = firstCandidate;
203 for (const candidate of candidates.slice(1)) {
204 if (candidate.estimatedDurationMs < lightest.estimatedDurationMs) {
205 lightest = candidate;
206 }
207 }
208 lightest.files.push(file.path);
209 lightest.estimatedDurationMs += file.durationMs;
210 lightest.isolated = mustIsolate;
211 }
212
213 return bins.map((bin) => ({
214 index: bin.index,
215 estimatedDurationMs: bin.estimatedDurationMs,
216 files: [...bin.files].sort(comparePaths),
217 }));
218};
219
220/** Discovers and plans all shards for one configured target. */

Callers 2

ci-shard.test.tsFile · 0.90
planTargetShardsFunction · 0.85

Calls 2

comparePathsFunction · 0.85
pushMethod · 0.80

Tested by

no test coverage detected