@nsxbet/playwright-orchestrator 0.8.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -7
- package/dist/commands/assign.d.ts +3 -10
- package/dist/commands/assign.d.ts.map +1 -1
- package/dist/commands/assign.js +32 -187
- package/dist/commands/assign.js.map +1 -1
- package/dist/commands/extract-timing.d.ts +1 -0
- package/dist/commands/extract-timing.d.ts.map +1 -1
- package/dist/commands/extract-timing.js +31 -1
- package/dist/commands/extract-timing.js.map +1 -1
- package/dist/commands/filter-report.d.ts +24 -0
- package/dist/commands/filter-report.d.ts.map +1 -0
- package/dist/commands/filter-report.js +123 -0
- package/dist/commands/filter-report.js.map +1 -0
- package/dist/core/ckk-algorithm.d.ts +1 -1
- package/dist/core/ckk-algorithm.d.ts.map +1 -1
- package/dist/core/ckk-algorithm.js +130 -36
- package/dist/core/ckk-algorithm.js.map +1 -1
- package/dist/core/estimate.d.ts +11 -0
- package/dist/core/estimate.d.ts.map +1 -1
- package/dist/core/estimate.js +43 -0
- package/dist/core/estimate.js.map +1 -1
- package/dist/fixture.d.ts +0 -10
- package/dist/fixture.d.ts.map +1 -1
- package/dist/fixture.js +0 -36
- package/dist/fixture.js.map +1 -1
- package/dist/reporter.d.ts +26 -0
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +120 -0
- package/dist/reporter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { Command, Flags } from '@oclif/core';
|
|
4
|
+
export default class FilterReport extends Command {
|
|
5
|
+
static description = 'Remove orchestrator-skipped tests from a Playwright JSON report';
|
|
6
|
+
static examples = [
|
|
7
|
+
'<%= config.bin %> filter-report --report-file ./results.json',
|
|
8
|
+
'<%= config.bin %> filter-report --report-file ./merged.json --output-file ./filtered.json',
|
|
9
|
+
];
|
|
10
|
+
static flags = {
|
|
11
|
+
'report-file': Flags.string({
|
|
12
|
+
char: 'r',
|
|
13
|
+
description: 'Path to Playwright JSON report file',
|
|
14
|
+
required: true,
|
|
15
|
+
}),
|
|
16
|
+
'output-file': Flags.string({
|
|
17
|
+
char: 'o',
|
|
18
|
+
description: 'Path to write filtered report (defaults to overwriting input)',
|
|
19
|
+
}),
|
|
20
|
+
verbose: Flags.boolean({
|
|
21
|
+
char: 'v',
|
|
22
|
+
description: 'Show verbose output',
|
|
23
|
+
default: false,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { flags } = await this.parse(FilterReport);
|
|
28
|
+
const reportPath = path.resolve(flags['report-file']);
|
|
29
|
+
if (!fs.existsSync(reportPath)) {
|
|
30
|
+
this.warn(`Report file not found: ${reportPath}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let report;
|
|
34
|
+
try {
|
|
35
|
+
report = JSON.parse(fs.readFileSync(reportPath, 'utf-8'));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
this.error(`Failed to parse report: ${reportPath}`);
|
|
39
|
+
}
|
|
40
|
+
if (!report.suites) {
|
|
41
|
+
this.warn('Report has no suites, nothing to filter');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const suites = report.suites;
|
|
45
|
+
const beforeCount = this.countSpecs(suites);
|
|
46
|
+
this.filterSuites(suites);
|
|
47
|
+
const afterCount = this.countSpecs(suites);
|
|
48
|
+
const removed = beforeCount - afterCount;
|
|
49
|
+
const outputPath = flags['output-file']
|
|
50
|
+
? path.resolve(flags['output-file'])
|
|
51
|
+
: reportPath;
|
|
52
|
+
fs.writeFileSync(outputPath, JSON.stringify(report));
|
|
53
|
+
if (flags.verbose || removed > 0) {
|
|
54
|
+
this.log(`Filtered report: ${beforeCount} → ${afterCount} specs (removed ${removed} orchestrator-skipped)`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if a test has an orchestrator-skip annotation ("Not in shard").
|
|
59
|
+
*/
|
|
60
|
+
isOrchestratorSkipped(test) {
|
|
61
|
+
const annotations = test.annotations;
|
|
62
|
+
return (annotations?.some((a) => a.type === 'skip' && a.description === 'Not in shard') ?? false);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Remove orchestrator-skipped entries at three levels:
|
|
66
|
+
* 1. Results: strip skipped results from tests with "Not in shard" annotation
|
|
67
|
+
* 2. Tests: remove tests with no remaining results
|
|
68
|
+
* 3. Specs/Suites: remove empty specs and prune empty suites
|
|
69
|
+
*/
|
|
70
|
+
filterSuites(suites) {
|
|
71
|
+
for (let i = suites.length - 1; i >= 0; i--) {
|
|
72
|
+
const suite = suites[i];
|
|
73
|
+
if (!suite)
|
|
74
|
+
continue;
|
|
75
|
+
if (Array.isArray(suite.specs)) {
|
|
76
|
+
const specs = suite.specs;
|
|
77
|
+
for (const spec of specs) {
|
|
78
|
+
const tests = spec.tests;
|
|
79
|
+
if (!tests)
|
|
80
|
+
continue;
|
|
81
|
+
// Result-level: strip skipped results from orchestrator-skipped tests
|
|
82
|
+
for (const test of tests) {
|
|
83
|
+
if (!this.isOrchestratorSkipped(test))
|
|
84
|
+
continue;
|
|
85
|
+
const results = test.results;
|
|
86
|
+
if (!results)
|
|
87
|
+
continue;
|
|
88
|
+
test.results = results.filter((r) => r.status !== 'skipped');
|
|
89
|
+
}
|
|
90
|
+
// Test-level: remove tests with no remaining results
|
|
91
|
+
spec.tests = tests.filter((test) => {
|
|
92
|
+
const results = test.results;
|
|
93
|
+
return results && results.length > 0;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// Spec-level: remove specs with no remaining tests
|
|
97
|
+
suite.specs = specs.filter((spec) => {
|
|
98
|
+
const tests = spec.tests;
|
|
99
|
+
return tests && tests.length > 0;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (Array.isArray(suite.suites)) {
|
|
103
|
+
this.filterSuites(suite.suites);
|
|
104
|
+
}
|
|
105
|
+
const hasSpecs = Array.isArray(suite.specs) && suite.specs.length > 0;
|
|
106
|
+
const hasSubSuites = Array.isArray(suite.suites) && suite.suites.length > 0;
|
|
107
|
+
if (!hasSpecs && !hasSubSuites) {
|
|
108
|
+
suites.splice(i, 1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
countSpecs(suites) {
|
|
113
|
+
let count = 0;
|
|
114
|
+
for (const suite of suites) {
|
|
115
|
+
if (Array.isArray(suite.specs))
|
|
116
|
+
count += suite.specs.length;
|
|
117
|
+
if (Array.isArray(suite.suites))
|
|
118
|
+
count += this.countSpecs(suite.suites);
|
|
119
|
+
}
|
|
120
|
+
return count;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=filter-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-report.js","sourceRoot":"","sources":["../../src/commands/filter-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,7 +29,7 @@ export interface CKKResult {
|
|
|
29
29
|
* @param timeoutMs - Maximum time to search for optimal solution
|
|
30
30
|
* @returns Optimal (or near-optimal) shard assignments
|
|
31
31
|
*/
|
|
32
|
-
export declare function assignWithCKK(tests: TestWithDuration[], numShards: number, timeoutMs?: number): CKKResult;
|
|
32
|
+
export declare function assignWithCKK(tests: TestWithDuration[], numShards: number, timeoutMs?: number, fileAffinityPenalty?: number): CKKResult;
|
|
33
33
|
/**
|
|
34
34
|
* Calculate theoretical lower bound for makespan
|
|
35
35
|
* This is the best possible makespan if we could partition perfectly
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ckk-algorithm.d.ts","sourceRoot":"","sources":["../../src/core/ckk-algorithm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE;;GAEG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,gBAAgB,EAAE,EACzB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAA4B,
|
|
1
|
+
{"version":3,"file":"ckk-algorithm.d.ts","sourceRoot":"","sources":["../../src/core/ckk-algorithm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE;;GAEG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,gBAAgB,EAAE,EACzB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAA4B,EACvC,mBAAmB,SAAI,GACtB,SAAS,CA8MX;AAmHD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,gBAAgB,EAAE,EACzB,SAAS,EAAE,MAAM,GAChB,MAAM,CAQR"}
|
|
@@ -17,7 +17,7 @@ export const DEFAULT_CKK_TIMEOUT = 500;
|
|
|
17
17
|
* @param timeoutMs - Maximum time to search for optimal solution
|
|
18
18
|
* @returns Optimal (or near-optimal) shard assignments
|
|
19
19
|
*/
|
|
20
|
-
export function assignWithCKK(tests, numShards, timeoutMs = DEFAULT_CKK_TIMEOUT) {
|
|
20
|
+
export function assignWithCKK(tests, numShards, timeoutMs = DEFAULT_CKK_TIMEOUT, fileAffinityPenalty = 0) {
|
|
21
21
|
if (tests.length === 0) {
|
|
22
22
|
return {
|
|
23
23
|
assignments: createEmptyAssignments(numShards),
|
|
@@ -32,18 +32,36 @@ export function assignWithCKK(tests, numShards, timeoutMs = DEFAULT_CKK_TIMEOUT)
|
|
|
32
32
|
// More shards than tests - each test gets its own shard
|
|
33
33
|
return assignOnePerShard(tests, numShards);
|
|
34
34
|
}
|
|
35
|
-
// Sort tests by duration descending for better
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
// Sort tests by duration descending, then by file ascending for better
|
|
36
|
+
// file-affinity convergence (same-file tests appear adjacent)
|
|
37
|
+
const sortedTests = [...tests].sort((a, b) => b.duration - a.duration || a.file.localeCompare(b.file));
|
|
38
|
+
// Precompute per-file test counts for penalty amortization
|
|
39
|
+
const fileTestCounts = new Map();
|
|
40
|
+
for (const test of sortedTests) {
|
|
41
|
+
fileTestCounts.set(test.file, (fileTestCounts.get(test.file) ?? 0) + 1);
|
|
42
|
+
}
|
|
43
|
+
// Get LPT solution as upper bound (uses its own copy of fileRemaining)
|
|
44
|
+
const lptResult = assignWithLPTInternal(sortedTests, numShards, fileAffinityPenalty, fileTestCounts, new Map(fileTestCounts));
|
|
39
45
|
let bestMakespan = lptResult.makespan;
|
|
40
46
|
let bestAssignment = lptResult.assignments;
|
|
41
47
|
let isOptimal = false;
|
|
48
|
+
// Track remaining unassigned tests per file for CKK search
|
|
49
|
+
const fileRemaining = new Map(fileTestCounts);
|
|
42
50
|
// For small inputs, try to find optimal solution
|
|
43
51
|
const startTime = Date.now();
|
|
44
52
|
// Branch and bound search
|
|
45
|
-
|
|
53
|
+
// effectiveLoads include penalty; actualLoads are real durations for output
|
|
54
|
+
const effectiveLoads = new Array(numShards).fill(0);
|
|
55
|
+
const actualLoads = new Array(numShards).fill(0);
|
|
46
56
|
const shardTests = Array.from({ length: numShards }, () => []);
|
|
57
|
+
const shardFiles = Array.from({ length: numShards }, () => new Set());
|
|
58
|
+
function computePenalty(shardIdx, file) {
|
|
59
|
+
if (fileAffinityPenalty <= 0 || shardFiles[shardIdx]?.has(file))
|
|
60
|
+
return 0;
|
|
61
|
+
const total = fileTestCounts.get(file) ?? 1;
|
|
62
|
+
const remaining = fileRemaining.get(file) ?? 1;
|
|
63
|
+
return Math.round(fileAffinityPenalty * (remaining / total));
|
|
64
|
+
}
|
|
47
65
|
function search(testIndex) {
|
|
48
66
|
// Check timeout
|
|
49
67
|
if (Date.now() - startTime > timeoutMs) {
|
|
@@ -51,10 +69,10 @@ export function assignWithCKK(tests, numShards, timeoutMs = DEFAULT_CKK_TIMEOUT)
|
|
|
51
69
|
}
|
|
52
70
|
// All tests assigned
|
|
53
71
|
if (testIndex >= sortedTests.length) {
|
|
54
|
-
const currentMakespan = Math.max(...
|
|
72
|
+
const currentMakespan = Math.max(...effectiveLoads);
|
|
55
73
|
if (currentMakespan < bestMakespan) {
|
|
56
74
|
bestMakespan = currentMakespan;
|
|
57
|
-
bestAssignment =
|
|
75
|
+
bestAssignment = actualLoads.map((load, i) => ({
|
|
58
76
|
shardIndex: i + 1,
|
|
59
77
|
tests: [...(shardTests[i] ?? [])],
|
|
60
78
|
expectedDuration: load,
|
|
@@ -67,49 +85,91 @@ export function assignWithCKK(tests, numShards, timeoutMs = DEFAULT_CKK_TIMEOUT)
|
|
|
67
85
|
if (!test)
|
|
68
86
|
return true;
|
|
69
87
|
// Calculate lower bound: current max + remaining items distributed perfectly
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
88
|
+
const remainingTests = sortedTests.slice(testIndex);
|
|
89
|
+
let remainingDuration = 0;
|
|
90
|
+
for (const t of remainingTests) {
|
|
91
|
+
remainingDuration += t.duration;
|
|
92
|
+
}
|
|
93
|
+
// Account for minimum penalties: each unique file among remaining tests
|
|
94
|
+
// that isn't on ANY shard yet will require at least one penalty payment
|
|
95
|
+
let minPenaltyCost = 0;
|
|
96
|
+
if (fileAffinityPenalty > 0) {
|
|
97
|
+
const allShardFiles = new Set();
|
|
98
|
+
for (const files of shardFiles) {
|
|
99
|
+
for (const f of files)
|
|
100
|
+
allShardFiles.add(f);
|
|
101
|
+
}
|
|
102
|
+
const newFiles = new Set();
|
|
103
|
+
for (const t of remainingTests) {
|
|
104
|
+
if (!allShardFiles.has(t.file))
|
|
105
|
+
newFiles.add(t.file);
|
|
106
|
+
}
|
|
107
|
+
// Each new file incurs at least one amortized penalty
|
|
108
|
+
for (const file of newFiles) {
|
|
109
|
+
const total = fileTestCounts.get(file) ?? 1;
|
|
110
|
+
const remaining = fileRemaining.get(file) ?? 1;
|
|
111
|
+
minPenaltyCost += Math.round(fileAffinityPenalty * (remaining / total));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const currentMax = Math.max(...effectiveLoads);
|
|
115
|
+
const totalAfter = effectiveLoads.reduce((sum, l) => sum + l, 0) +
|
|
116
|
+
remainingDuration +
|
|
117
|
+
minPenaltyCost;
|
|
75
118
|
const lowerBound = Math.max(currentMax, Math.ceil(totalAfter / numShards));
|
|
76
119
|
// Prune if lower bound exceeds best
|
|
77
120
|
if (lowerBound >= bestMakespan) {
|
|
78
121
|
return true;
|
|
79
122
|
}
|
|
80
123
|
// Try assigning to each shard, starting with least loaded
|
|
81
|
-
const shardOrder =
|
|
124
|
+
const shardOrder = effectiveLoads
|
|
82
125
|
.map((load, i) => ({ load, index: i }))
|
|
83
126
|
.sort((a, b) => a.load - b.load)
|
|
84
127
|
.map((s) => s.index);
|
|
85
|
-
// Skip duplicate
|
|
86
|
-
|
|
128
|
+
// Skip duplicate states to avoid redundant exploration.
|
|
129
|
+
// When penalty > 0, key on load + whether shard has the file,
|
|
130
|
+
// since two shards with the same load but different file sets are NOT equivalent.
|
|
131
|
+
const seenStates = new Set();
|
|
87
132
|
for (const shardIdx of shardOrder) {
|
|
88
|
-
const load =
|
|
133
|
+
const load = effectiveLoads[shardIdx];
|
|
89
134
|
if (load === undefined)
|
|
90
135
|
continue;
|
|
91
|
-
|
|
92
|
-
|
|
136
|
+
const hasFile = shardFiles[shardIdx]?.has(test.file) ?? false;
|
|
137
|
+
const dedupKey = fileAffinityPenalty > 0 ? `${load}:${hasFile}` : `${load}`;
|
|
138
|
+
if (seenStates.has(dedupKey)) {
|
|
93
139
|
continue;
|
|
94
140
|
}
|
|
95
|
-
|
|
141
|
+
seenStates.add(dedupKey);
|
|
142
|
+
const penalty = computePenalty(shardIdx, test.file);
|
|
143
|
+
const effectiveCost = test.duration + penalty;
|
|
96
144
|
// Prune: if adding to this shard exceeds best makespan, skip
|
|
97
|
-
if (load +
|
|
145
|
+
if (load + effectiveCost >= bestMakespan) {
|
|
98
146
|
continue;
|
|
99
147
|
}
|
|
100
148
|
// Assign test to shard
|
|
101
|
-
|
|
149
|
+
effectiveLoads[shardIdx] = load + effectiveCost;
|
|
150
|
+
actualLoads[shardIdx] = (actualLoads[shardIdx] ?? 0) + test.duration;
|
|
151
|
+
const isNewFile = !shardFiles[shardIdx]?.has(test.file);
|
|
152
|
+
shardFiles[shardIdx]?.add(test.file);
|
|
102
153
|
shardTests[shardIdx]?.push(test.testId);
|
|
154
|
+
fileRemaining.set(test.file, (fileRemaining.get(test.file) ?? 1) - 1);
|
|
103
155
|
const completed = search(testIndex + 1);
|
|
104
156
|
if (!completed) {
|
|
105
157
|
// Timeout - restore and return
|
|
106
|
-
|
|
158
|
+
effectiveLoads[shardIdx] = load;
|
|
159
|
+
actualLoads[shardIdx] = (actualLoads[shardIdx] ?? 0) - test.duration;
|
|
160
|
+
if (isNewFile)
|
|
161
|
+
shardFiles[shardIdx]?.delete(test.file);
|
|
107
162
|
shardTests[shardIdx]?.pop();
|
|
163
|
+
fileRemaining.set(test.file, (fileRemaining.get(test.file) ?? 0) + 1);
|
|
108
164
|
return false;
|
|
109
165
|
}
|
|
110
166
|
// Restore state for backtracking
|
|
111
|
-
|
|
167
|
+
effectiveLoads[shardIdx] = load;
|
|
168
|
+
actualLoads[shardIdx] = (actualLoads[shardIdx] ?? 0) - test.duration;
|
|
169
|
+
if (isNewFile)
|
|
170
|
+
shardFiles[shardIdx]?.delete(test.file);
|
|
112
171
|
shardTests[shardIdx]?.pop();
|
|
172
|
+
fileRemaining.set(test.file, (fileRemaining.get(test.file) ?? 0) + 1);
|
|
113
173
|
}
|
|
114
174
|
return true;
|
|
115
175
|
}
|
|
@@ -117,35 +177,69 @@ export function assignWithCKK(tests, numShards, timeoutMs = DEFAULT_CKK_TIMEOUT)
|
|
|
117
177
|
if (tests.length <= 50) {
|
|
118
178
|
search(0);
|
|
119
179
|
}
|
|
180
|
+
// Return actual makespan (without penalties) for user-facing output
|
|
181
|
+
const actualMakespan = bestAssignment.length > 0
|
|
182
|
+
? Math.max(...bestAssignment.map((a) => a.expectedDuration))
|
|
183
|
+
: 0;
|
|
120
184
|
return {
|
|
121
185
|
assignments: bestAssignment,
|
|
122
|
-
makespan:
|
|
186
|
+
makespan: actualMakespan,
|
|
123
187
|
isOptimal,
|
|
124
188
|
};
|
|
125
189
|
}
|
|
126
190
|
/**
|
|
127
|
-
* Simple LPT algorithm for internal use
|
|
191
|
+
* Simple LPT algorithm for internal use, with optional file affinity penalty.
|
|
192
|
+
*
|
|
193
|
+
* When fileAffinityPenalty > 0, effective loads include the penalty for each
|
|
194
|
+
* new file introduced to a shard. The returned expectedDuration and makespan
|
|
195
|
+
* reflect effective loads so the CKK search can use them as an upper bound.
|
|
128
196
|
*/
|
|
129
|
-
function assignWithLPTInternal(sortedTests, numShards) {
|
|
197
|
+
function assignWithLPTInternal(sortedTests, numShards, fileAffinityPenalty = 0, fileTestCounts = new Map(), fileRemaining = new Map()) {
|
|
130
198
|
const shards = Array.from({ length: numShards }, (_, i) => ({
|
|
131
199
|
shardIndex: i + 1,
|
|
132
200
|
tests: [],
|
|
133
201
|
expectedDuration: 0,
|
|
134
202
|
}));
|
|
203
|
+
// Track effective loads (with penalty) separately from actual durations
|
|
204
|
+
const effectiveLoads = new Array(numShards).fill(0);
|
|
205
|
+
const actualLoads = new Array(numShards).fill(0);
|
|
206
|
+
const shardFiles = Array.from({ length: numShards }, () => new Set());
|
|
135
207
|
for (const test of sortedTests) {
|
|
136
|
-
// Find shard with minimum load
|
|
137
|
-
let
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
208
|
+
// Find shard with minimum effective load after assignment (including penalty)
|
|
209
|
+
let minIdx = 0;
|
|
210
|
+
let minCost = Infinity;
|
|
211
|
+
for (let i = 0; i < numShards; i++) {
|
|
212
|
+
let penalty = 0;
|
|
213
|
+
if (fileAffinityPenalty > 0 && !shardFiles[i]?.has(test.file)) {
|
|
214
|
+
const total = fileTestCounts.get(test.file) ?? 1;
|
|
215
|
+
const remaining = fileRemaining.get(test.file) ?? 1;
|
|
216
|
+
penalty = Math.round(fileAffinityPenalty * (remaining / total));
|
|
141
217
|
}
|
|
218
|
+
const cost = (effectiveLoads[i] ?? 0) + test.duration + penalty;
|
|
219
|
+
if (cost < minCost) {
|
|
220
|
+
minCost = cost;
|
|
221
|
+
minIdx = i;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
let penalty = 0;
|
|
225
|
+
if (fileAffinityPenalty > 0 && !shardFiles[minIdx]?.has(test.file)) {
|
|
226
|
+
const total = fileTestCounts.get(test.file) ?? 1;
|
|
227
|
+
const remaining = fileRemaining.get(test.file) ?? 1;
|
|
228
|
+
penalty = Math.round(fileAffinityPenalty * (remaining / total));
|
|
142
229
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
230
|
+
const shard = shards[minIdx];
|
|
231
|
+
if (shard) {
|
|
232
|
+
shard.tests.push(test.testId);
|
|
233
|
+
effectiveLoads[minIdx] =
|
|
234
|
+
(effectiveLoads[minIdx] ?? 0) + test.duration + penalty;
|
|
235
|
+
actualLoads[minIdx] = (actualLoads[minIdx] ?? 0) + test.duration;
|
|
236
|
+
shard.expectedDuration = actualLoads[minIdx] ?? 0;
|
|
237
|
+
shardFiles[minIdx]?.add(test.file);
|
|
238
|
+
fileRemaining.set(test.file, (fileRemaining.get(test.file) ?? 1) - 1);
|
|
146
239
|
}
|
|
147
240
|
}
|
|
148
|
-
|
|
241
|
+
// Makespan uses effective loads so CKK can prune against it
|
|
242
|
+
const makespan = effectiveLoads.length > 0 ? Math.max(...effectiveLoads) : 0;
|
|
149
243
|
return { assignments: shards, makespan };
|
|
150
244
|
}
|
|
151
245
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ckk-algorithm.js","sourceRoot":"","sources":["../../src/core/ckk-algorithm.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ckk-algorithm.js","sourceRoot":"","sources":["../../src/core/ckk-algorithm.ts"],"names":[],"mappings":"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"}
|
package/dist/core/estimate.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { DiscoveredTest, TimingData } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default file affinity penalty when no timing data exists (30 seconds)
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_FILE_AFFINITY_PENALTY = 30000;
|
|
2
6
|
/**
|
|
3
7
|
* Default milliseconds per line for duration estimation
|
|
4
8
|
*/
|
|
@@ -61,6 +65,13 @@ export declare function getTestDurations(tests: DiscoveredTest[], timingData: Ti
|
|
|
61
65
|
* @returns Average duration in milliseconds, or DEFAULT_TEST_DURATION if no data
|
|
62
66
|
*/
|
|
63
67
|
export declare function calculateAverageTestDuration(timingData: TimingData | null): number;
|
|
68
|
+
/**
|
|
69
|
+
* Calculate file affinity penalty from timing data.
|
|
70
|
+
*
|
|
71
|
+
* Computes the P25 (25th percentile) of per-file average durations.
|
|
72
|
+
* Falls back to DEFAULT_FILE_AFFINITY_PENALTY when no timing data exists.
|
|
73
|
+
*/
|
|
74
|
+
export declare function calculateFileAffinityPenalty(timingData: TimingData | null): number;
|
|
64
75
|
/**
|
|
65
76
|
* Calculate average test duration for tests in a specific file
|
|
66
77
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../../src/core/estimate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7D;;GAEG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAA4B,GACtC,MAAM,CAGR;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,GAAE,MAA4B,GACtC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CASrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,CA0BR;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EAAE,EACvB,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,KAAK,CAAC;IACP,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAoBD;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,CAQR;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI,CAef"}
|
|
1
|
+
{"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../../src/core/estimate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7D;;GAEG;AACH,eAAO,MAAM,6BAA6B,QAAQ,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAA4B,GACtC,MAAM,CAGR;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,GAAE,MAA4B,GACtC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CASrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,CA0BR;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EAAE,EACvB,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,KAAK,CAAC;IACP,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAoBD;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,CAQR;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,CAoCR;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI,CAef"}
|
package/dist/core/estimate.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { parseTestId } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Default file affinity penalty when no timing data exists (30 seconds)
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_FILE_AFFINITY_PENALTY = 30000;
|
|
4
8
|
/**
|
|
5
9
|
* Default milliseconds per line for duration estimation
|
|
6
10
|
*/
|
|
@@ -121,6 +125,45 @@ export function calculateAverageTestDuration(timingData) {
|
|
|
121
125
|
const sum = durations.reduce((acc, d) => acc + d, 0);
|
|
122
126
|
return Math.round(sum / durations.length);
|
|
123
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Calculate file affinity penalty from timing data.
|
|
130
|
+
*
|
|
131
|
+
* Computes the P25 (25th percentile) of per-file average durations.
|
|
132
|
+
* Falls back to DEFAULT_FILE_AFFINITY_PENALTY when no timing data exists.
|
|
133
|
+
*/
|
|
134
|
+
export function calculateFileAffinityPenalty(timingData) {
|
|
135
|
+
if (!timingData || Object.keys(timingData.tests).length === 0) {
|
|
136
|
+
return DEFAULT_FILE_AFFINITY_PENALTY;
|
|
137
|
+
}
|
|
138
|
+
// Group tests by file and compute average duration per file
|
|
139
|
+
const fileTests = new Map();
|
|
140
|
+
for (const test of Object.values(timingData.tests)) {
|
|
141
|
+
const durations = fileTests.get(test.file);
|
|
142
|
+
if (durations) {
|
|
143
|
+
durations.push(test.duration);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
fileTests.set(test.file, [test.duration]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const fileAverages = [];
|
|
150
|
+
for (const durations of fileTests.values()) {
|
|
151
|
+
const sum = durations.reduce((acc, d) => acc + d, 0);
|
|
152
|
+
fileAverages.push(sum / durations.length);
|
|
153
|
+
}
|
|
154
|
+
if (fileAverages.length === 0) {
|
|
155
|
+
return DEFAULT_FILE_AFFINITY_PENALTY;
|
|
156
|
+
}
|
|
157
|
+
// P25 of per-file averages
|
|
158
|
+
fileAverages.sort((a, b) => a - b);
|
|
159
|
+
const index = (fileAverages.length - 1) * 0.25;
|
|
160
|
+
const lower = Math.floor(index);
|
|
161
|
+
const upper = Math.ceil(index);
|
|
162
|
+
const lowerVal = fileAverages[lower] ?? 0;
|
|
163
|
+
const upperVal = fileAverages[upper] ?? lowerVal;
|
|
164
|
+
const penalty = lowerVal + (upperVal - lowerVal) * (index - lower);
|
|
165
|
+
return Math.round(penalty);
|
|
166
|
+
}
|
|
124
167
|
/**
|
|
125
168
|
* Calculate average test duration for tests in a specific file
|
|
126
169
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimate.js","sourceRoot":"","sources":["../../src/core/estimate.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"estimate.js","sourceRoot":"","sources":["../../src/core/estimate.ts"],"names":[],"mappings":"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"}
|
package/dist/fixture.d.ts
CHANGED
|
@@ -56,16 +56,6 @@ import type { TestType } from '@playwright/test';
|
|
|
56
56
|
export declare function withOrchestratorFilter<T extends object, W extends object>(test: TestType<T, W>): TestType<T & {
|
|
57
57
|
_orchestratorFilter: undefined;
|
|
58
58
|
}, W>;
|
|
59
|
-
/**
|
|
60
|
-
* @deprecated Use `withOrchestratorFilter` instead. This function uses beforeEach
|
|
61
|
-
* which only works for the first test file processed, not subsequent files.
|
|
62
|
-
*
|
|
63
|
-
* Sets up the orchestrator filter as a beforeEach hook.
|
|
64
|
-
* This will skip tests that are not in the current shard.
|
|
65
|
-
*
|
|
66
|
-
* @param test - The test object from @playwright/test
|
|
67
|
-
*/
|
|
68
|
-
export declare function setupOrchestratorFilter<T extends object, W extends object>(test: TestType<T, W>): void;
|
|
69
59
|
/**
|
|
70
60
|
* Check if a test should run based on the shard file.
|
|
71
61
|
* Can be called manually in individual tests.
|
package/dist/fixture.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixture.d.ts","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAuDjD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EACvE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,QAAQ,CAAC,CAAC,GAAG;IAAE,mBAAmB,EAAE,SAAS,CAAA;CAAE,EAAE,CAAC,CAAC,CAwDrD;AAED
|
|
1
|
+
{"version":3,"file":"fixture.d.ts","sourceRoot":"","sources":["../src/fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAuDjD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EACvE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,QAAQ,CAAC,CAAC,GAAG;IAAE,mBAAmB,EAAE,SAAS,CAAA;CAAE,EAAE,CAAC,CAAC,CAwDrD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C,GAAG,OAAO,CAUV"}
|
package/dist/fixture.js
CHANGED
|
@@ -127,42 +127,6 @@ export function withOrchestratorFilter(test) {
|
|
|
127
127
|
],
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
|
-
/**
|
|
131
|
-
* @deprecated Use `withOrchestratorFilter` instead. This function uses beforeEach
|
|
132
|
-
* which only works for the first test file processed, not subsequent files.
|
|
133
|
-
*
|
|
134
|
-
* Sets up the orchestrator filter as a beforeEach hook.
|
|
135
|
-
* This will skip tests that are not in the current shard.
|
|
136
|
-
*
|
|
137
|
-
* @param test - The test object from @playwright/test
|
|
138
|
-
*/
|
|
139
|
-
export function setupOrchestratorFilter(test) {
|
|
140
|
-
// biome-ignore lint/correctness/noEmptyPattern: Playwright requires empty destructuring for fixtures
|
|
141
|
-
test.beforeEach(async ({}, testInfo) => {
|
|
142
|
-
const allowedTestIds = loadShardFile();
|
|
143
|
-
if (allowedTestIds) {
|
|
144
|
-
// CRITICAL: Use project.testDir for consistent path resolution with test-discovery
|
|
145
|
-
// No fallback to process.cwd() - this causes path mismatch bugs
|
|
146
|
-
const testDir = testInfo.project.testDir;
|
|
147
|
-
if (!testDir) {
|
|
148
|
-
throw new Error('[Orchestrator Fixture] Could not determine project testDir. ' +
|
|
149
|
-
'Ensure your playwright.config.ts has projects configured with testDir.');
|
|
150
|
-
}
|
|
151
|
-
const testId = buildTestIdFromRuntime(testInfo.file, testInfo.titlePath, {
|
|
152
|
-
projectName: testInfo.project.name,
|
|
153
|
-
baseDir: testDir,
|
|
154
|
-
});
|
|
155
|
-
const isAllowed = allowedTestIds.has(testId);
|
|
156
|
-
// Debug: Write to stderr for visibility in CI logs
|
|
157
|
-
if (process.env.ORCHESTRATOR_DEBUG === '1') {
|
|
158
|
-
process.stderr.write(`[Fixture] testDir=${testInfo.project.testDir} | testId=${testId} | allowed=${isAllowed}\n`);
|
|
159
|
-
}
|
|
160
|
-
if (!isAllowed) {
|
|
161
|
-
test.skip(true, 'Not in shard');
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
130
|
/**
|
|
167
131
|
* Check if a test should run based on the shard file.
|
|
168
132
|
* Can be called manually in individual tests.
|