agentic-qe 2.6.4 → 2.6.6
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/CHANGELOG.md +95 -0
- package/README.md +26 -1
- package/dist/agents/CoverageAnalyzerAgent.d.ts +31 -0
- package/dist/agents/CoverageAnalyzerAgent.d.ts.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.js +159 -0
- package/dist/agents/CoverageAnalyzerAgent.js.map +1 -1
- package/dist/agents/FleetCommanderAgent.d.ts +36 -0
- package/dist/agents/FleetCommanderAgent.d.ts.map +1 -1
- package/dist/agents/FleetCommanderAgent.js +226 -0
- package/dist/agents/FleetCommanderAgent.js.map +1 -1
- package/dist/cli/commands/kg/mincut.d.ts +50 -0
- package/dist/cli/commands/kg/mincut.d.ts.map +1 -0
- package/dist/cli/commands/kg/mincut.js +372 -0
- package/dist/cli/commands/kg/mincut.js.map +1 -0
- package/dist/cli/commands/providers/index.d.ts +20 -0
- package/dist/cli/commands/providers/index.d.ts.map +1 -0
- package/dist/cli/commands/providers/index.js +143 -0
- package/dist/cli/commands/providers/index.js.map +1 -0
- package/dist/cli/commands/providers/status.d.ts +117 -0
- package/dist/cli/commands/providers/status.d.ts.map +1 -0
- package/dist/cli/commands/providers/status.js +368 -0
- package/dist/cli/commands/providers/status.js.map +1 -0
- package/dist/cli/index.js +99 -62
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/claude-config.js +2 -2
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.d.ts +148 -0
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.js +393 -0
- package/dist/code-intelligence/analysis/mincut/CircularDependencyDetector.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.d.ts +169 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.js +335 -0
- package/dist/code-intelligence/analysis/mincut/GraphAdapter.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.d.ts +55 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.js +265 -0
- package/dist/code-intelligence/analysis/mincut/JsMinCut.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.d.ts +92 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.js +200 -0
- package/dist/code-intelligence/analysis/mincut/MinCutAnalyzer.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.d.ts +157 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.js +434 -0
- package/dist/code-intelligence/analysis/mincut/ModuleCouplingAnalyzer.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/index.d.ts +12 -0
- package/dist/code-intelligence/analysis/mincut/index.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/index.js +20 -0
- package/dist/code-intelligence/analysis/mincut/index.js.map +1 -0
- package/dist/code-intelligence/analysis/mincut/types.d.ts +145 -0
- package/dist/code-intelligence/analysis/mincut/types.d.ts.map +1 -0
- package/dist/code-intelligence/analysis/mincut/types.js +16 -0
- package/dist/code-intelligence/analysis/mincut/types.js.map +1 -0
- package/dist/code-intelligence/chunking/ASTChunker.d.ts +1 -1
- package/dist/code-intelligence/chunking/ASTChunker.d.ts.map +1 -1
- package/dist/code-intelligence/chunking/ASTChunker.js +4 -4
- package/dist/code-intelligence/chunking/ASTChunker.js.map +1 -1
- package/dist/code-intelligence/graph/GraphBuilder.d.ts +120 -0
- package/dist/code-intelligence/graph/GraphBuilder.d.ts.map +1 -1
- package/dist/code-intelligence/graph/GraphBuilder.js +517 -0
- package/dist/code-intelligence/graph/GraphBuilder.js.map +1 -1
- package/dist/code-intelligence/orchestrator/CodeIntelligenceOrchestrator.d.ts.map +1 -1
- package/dist/code-intelligence/orchestrator/CodeIntelligenceOrchestrator.js +3 -3
- package/dist/code-intelligence/orchestrator/CodeIntelligenceOrchestrator.js.map +1 -1
- package/dist/code-intelligence/parser/{TreeSitterParser.d.ts → WebTreeSitterParser.d.ts} +45 -10
- package/dist/code-intelligence/parser/WebTreeSitterParser.d.ts.map +1 -0
- package/dist/code-intelligence/parser/{TreeSitterParser.js → WebTreeSitterParser.js} +147 -54
- package/dist/code-intelligence/parser/WebTreeSitterParser.js.map +1 -0
- package/dist/code-intelligence/parser/extractors/BaseExtractor.d.ts +12 -10
- package/dist/code-intelligence/parser/extractors/BaseExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/BaseExtractor.js +7 -3
- package/dist/code-intelligence/parser/extractors/BaseExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/GoExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/GoExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/GoExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/GoExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/JavaScriptExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/PythonExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/PythonExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/PythonExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/PythonExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/RustExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/RustExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/RustExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/RustExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.d.ts +7 -5
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.d.ts.map +1 -1
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.js +2 -2
- package/dist/code-intelligence/parser/extractors/TypeScriptExtractor.js.map +1 -1
- package/dist/code-intelligence/parser/index.d.ts +7 -1
- package/dist/code-intelligence/parser/index.d.ts.map +1 -1
- package/dist/code-intelligence/parser/index.js +11 -3
- package/dist/code-intelligence/parser/index.js.map +1 -1
- package/dist/code-intelligence/service/CodeIntelligenceService.d.ts.map +1 -1
- package/dist/code-intelligence/service/CodeIntelligenceService.js +7 -5
- package/dist/code-intelligence/service/CodeIntelligenceService.js.map +1 -1
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/coverage/CriticalPathDetector.d.ts +240 -0
- package/dist/coverage/CriticalPathDetector.d.ts.map +1 -0
- package/dist/coverage/CriticalPathDetector.js +388 -0
- package/dist/coverage/CriticalPathDetector.js.map +1 -0
- package/dist/coverage/index.d.ts +13 -0
- package/dist/coverage/index.d.ts.map +1 -0
- package/dist/coverage/index.js +16 -0
- package/dist/coverage/index.js.map +1 -0
- package/dist/fleet/topology/SPOFMonitor.d.ts +181 -0
- package/dist/fleet/topology/SPOFMonitor.d.ts.map +1 -0
- package/dist/fleet/topology/SPOFMonitor.js +286 -0
- package/dist/fleet/topology/SPOFMonitor.js.map +1 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.d.ts +87 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.d.ts.map +1 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.js +472 -0
- package/dist/fleet/topology/TopologyMinCutAnalyzer.js.map +1 -0
- package/dist/fleet/topology/index.d.ts +13 -0
- package/dist/fleet/topology/index.d.ts.map +1 -0
- package/dist/fleet/topology/index.js +20 -0
- package/dist/fleet/topology/index.js.map +1 -0
- package/dist/fleet/topology/types.d.ts +139 -0
- package/dist/fleet/topology/types.d.ts.map +1 -0
- package/dist/fleet/topology/types.js +19 -0
- package/dist/fleet/topology/types.js.map +1 -0
- package/dist/mcp/handlers/test/test-execute-parallel.d.ts +34 -3
- package/dist/mcp/handlers/test/test-execute-parallel.d.ts.map +1 -1
- package/dist/mcp/handlers/test/test-execute-parallel.js +120 -5
- package/dist/mcp/handlers/test/test-execute-parallel.js.map +1 -1
- package/dist/mcp/server-instructions.d.ts +2 -2
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +2 -2
- package/dist/monitoring/ProviderHealthMonitor.d.ts +195 -0
- package/dist/monitoring/ProviderHealthMonitor.d.ts.map +1 -0
- package/dist/monitoring/ProviderHealthMonitor.js +431 -0
- package/dist/monitoring/ProviderHealthMonitor.js.map +1 -0
- package/dist/monitoring/QuotaManager.d.ts +122 -0
- package/dist/monitoring/QuotaManager.d.ts.map +1 -0
- package/dist/monitoring/QuotaManager.js +351 -0
- package/dist/monitoring/QuotaManager.js.map +1 -0
- package/dist/providers/GitHubModelsProvider.d.ts +117 -0
- package/dist/providers/GitHubModelsProvider.d.ts.map +1 -0
- package/dist/providers/GitHubModelsProvider.js +464 -0
- package/dist/providers/GitHubModelsProvider.js.map +1 -0
- package/dist/providers/GroqProvider.d.ts +115 -0
- package/dist/providers/GroqProvider.d.ts.map +1 -0
- package/dist/providers/GroqProvider.js +443 -0
- package/dist/providers/GroqProvider.js.map +1 -0
- package/dist/providers/HybridRouterHealthIntegration.d.ts +191 -0
- package/dist/providers/HybridRouterHealthIntegration.d.ts.map +1 -0
- package/dist/providers/HybridRouterHealthIntegration.js +439 -0
- package/dist/providers/HybridRouterHealthIntegration.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +12 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/test/partition/MinCutPartitioner.d.ts +97 -0
- package/dist/test/partition/MinCutPartitioner.d.ts.map +1 -0
- package/dist/test/partition/MinCutPartitioner.js +459 -0
- package/dist/test/partition/MinCutPartitioner.js.map +1 -0
- package/dist/test/partition/RealTestExecutor.d.ts +86 -0
- package/dist/test/partition/RealTestExecutor.d.ts.map +1 -0
- package/dist/test/partition/RealTestExecutor.js +279 -0
- package/dist/test/partition/RealTestExecutor.js.map +1 -0
- package/dist/test/partition/TestDependencyAnalyzer.d.ts +75 -0
- package/dist/test/partition/TestDependencyAnalyzer.d.ts.map +1 -0
- package/dist/test/partition/TestDependencyAnalyzer.js +297 -0
- package/dist/test/partition/TestDependencyAnalyzer.js.map +1 -0
- package/dist/test/partition/index.d.ts +10 -0
- package/dist/test/partition/index.d.ts.map +1 -0
- package/dist/test/partition/index.js +26 -0
- package/dist/test/partition/index.js.map +1 -0
- package/dist/test/partition/types.d.ts +120 -0
- package/dist/test/partition/types.d.ts.map +1 -0
- package/dist/test/partition/types.js +21 -0
- package/dist/test/partition/types.js.map +1 -0
- package/package.json +5 -8
- package/dist/cli/commands/providers.d.ts +0 -50
- package/dist/cli/commands/providers.d.ts.map +0 -1
- package/dist/cli/commands/providers.js +0 -403
- package/dist/cli/commands/providers.js.map +0 -1
- package/dist/code-intelligence/parser/TreeSitterParser.d.ts.map +0 -1
- package/dist/code-intelligence/parser/TreeSitterParser.js.map +0 -1
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MinCut-Based Test Suite Partitioner
|
|
4
|
+
*
|
|
5
|
+
* Uses the Stoer-Wagner minimum cut algorithm to optimally partition
|
|
6
|
+
* test suites for parallel execution, minimizing cross-partition
|
|
7
|
+
* dependencies and balancing execution time across workers.
|
|
8
|
+
*
|
|
9
|
+
* Expected improvement: 30-50% faster parallel execution compared
|
|
10
|
+
* to naive round-robin or random distribution.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.MinCutPartitioner = void 0;
|
|
14
|
+
exports.partitionTests = partitionTests;
|
|
15
|
+
const types_js_1 = require("./types.js");
|
|
16
|
+
const MinCutAnalyzer_js_1 = require("../../code-intelligence/analysis/mincut/MinCutAnalyzer.js");
|
|
17
|
+
const Logger_js_1 = require("../../utils/Logger.js");
|
|
18
|
+
const logger = Logger_js_1.Logger.getInstance();
|
|
19
|
+
/**
|
|
20
|
+
* Partitions test suites using MinCut algorithm to minimize
|
|
21
|
+
* cross-partition dependencies and balance execution time.
|
|
22
|
+
*/
|
|
23
|
+
class MinCutPartitioner {
|
|
24
|
+
constructor(config = {}) {
|
|
25
|
+
this.config = { ...types_js_1.DEFAULT_PARTITION_CONFIG, ...config };
|
|
26
|
+
this.minCutAnalyzer = new MinCutAnalyzer_js_1.MinCutAnalyzer({
|
|
27
|
+
timeout: this.config.timeout,
|
|
28
|
+
maxNodes: 10000,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Partition test files for optimal parallel execution
|
|
33
|
+
*
|
|
34
|
+
* @param tests - Array of test files with metadata
|
|
35
|
+
* @returns PartitionResult with optimized test distribution
|
|
36
|
+
*/
|
|
37
|
+
async partition(tests) {
|
|
38
|
+
const startTime = performance.now();
|
|
39
|
+
// Handle edge cases
|
|
40
|
+
if (tests.length === 0) {
|
|
41
|
+
return this.emptyResult(startTime);
|
|
42
|
+
}
|
|
43
|
+
if (tests.length <= this.config.partitionCount) {
|
|
44
|
+
return this.trivialPartition(tests, startTime);
|
|
45
|
+
}
|
|
46
|
+
// Build dependency graph
|
|
47
|
+
const { nodes, edges } = this.buildTestGraph(tests);
|
|
48
|
+
// If no dependencies, use duration-balanced partitioning
|
|
49
|
+
if (edges.length === 0) {
|
|
50
|
+
return this.durationBalancedPartition(tests, startTime);
|
|
51
|
+
}
|
|
52
|
+
// Use MinCut to find optimal partition boundaries
|
|
53
|
+
const graph = {
|
|
54
|
+
nodes: nodes.map(n => ({
|
|
55
|
+
id: n.id,
|
|
56
|
+
label: n.id,
|
|
57
|
+
properties: { weight: n.weight },
|
|
58
|
+
})),
|
|
59
|
+
edges: edges.map(e => ({
|
|
60
|
+
source: e.source,
|
|
61
|
+
target: e.target,
|
|
62
|
+
weight: e.weight,
|
|
63
|
+
})),
|
|
64
|
+
directed: false,
|
|
65
|
+
};
|
|
66
|
+
try {
|
|
67
|
+
// For 2 partitions, use single MinCut
|
|
68
|
+
if (this.config.partitionCount === 2) {
|
|
69
|
+
const result = await this.minCutAnalyzer.computeMinCut(graph);
|
|
70
|
+
return this.buildResult(tests, [result], startTime);
|
|
71
|
+
}
|
|
72
|
+
// For k partitions, use recursive bisection
|
|
73
|
+
const partitions = await this.recursiveBisection(tests, graph);
|
|
74
|
+
return this.buildResultFromPartitions(tests, partitions, startTime);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
logger.warn('MinCut partitioning failed, falling back to duration-balanced', { error });
|
|
78
|
+
return this.durationBalancedPartition(tests, startTime);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build a dependency graph from test files
|
|
83
|
+
*/
|
|
84
|
+
buildTestGraph(tests) {
|
|
85
|
+
const testMap = new Map(tests.map(t => [t.path, t]));
|
|
86
|
+
const nodes = [];
|
|
87
|
+
const edges = [];
|
|
88
|
+
const edgeSet = new Set();
|
|
89
|
+
for (const test of tests) {
|
|
90
|
+
// Node weight based on duration (normalized)
|
|
91
|
+
const maxDuration = Math.max(...tests.map(t => t.estimatedDuration));
|
|
92
|
+
const normalizedWeight = maxDuration > 0 ? test.estimatedDuration / maxDuration : 1;
|
|
93
|
+
nodes.push({
|
|
94
|
+
id: test.path,
|
|
95
|
+
testFile: test,
|
|
96
|
+
weight: normalizedWeight,
|
|
97
|
+
});
|
|
98
|
+
// Add edges for dependencies
|
|
99
|
+
for (const dep of test.dependencies) {
|
|
100
|
+
if (testMap.has(dep)) {
|
|
101
|
+
const edgeKey = [test.path, dep].sort().join('->');
|
|
102
|
+
if (!edgeSet.has(edgeKey)) {
|
|
103
|
+
edgeSet.add(edgeKey);
|
|
104
|
+
edges.push({
|
|
105
|
+
source: test.path,
|
|
106
|
+
target: dep,
|
|
107
|
+
weight: this.calculateEdgeWeight(test, testMap.get(dep)),
|
|
108
|
+
type: 'import',
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Add edges for dependents (reverse dependencies)
|
|
114
|
+
for (const dependent of test.dependents) {
|
|
115
|
+
if (testMap.has(dependent)) {
|
|
116
|
+
const edgeKey = [test.path, dependent].sort().join('->');
|
|
117
|
+
if (!edgeSet.has(edgeKey)) {
|
|
118
|
+
edgeSet.add(edgeKey);
|
|
119
|
+
edges.push({
|
|
120
|
+
source: test.path,
|
|
121
|
+
target: dependent,
|
|
122
|
+
weight: this.calculateEdgeWeight(test, testMap.get(dependent)),
|
|
123
|
+
type: 'fixture',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return { nodes, edges };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Calculate edge weight based on dependency characteristics
|
|
133
|
+
* Higher weight = stronger coupling = should stay together
|
|
134
|
+
*/
|
|
135
|
+
calculateEdgeWeight(test1, test2) {
|
|
136
|
+
let weight = 1.0;
|
|
137
|
+
// Shared tags increase weight
|
|
138
|
+
const sharedTags = test1.tags?.filter(t => test2.tags?.includes(t)) || [];
|
|
139
|
+
weight += sharedTags.length * 0.5;
|
|
140
|
+
// Same priority increases weight
|
|
141
|
+
if (test1.priority === test2.priority) {
|
|
142
|
+
weight += 0.3;
|
|
143
|
+
}
|
|
144
|
+
// Critical tests should stay with their dependencies
|
|
145
|
+
if (test1.priority === 'critical' || test2.priority === 'critical') {
|
|
146
|
+
weight += 1.0;
|
|
147
|
+
}
|
|
148
|
+
// Flaky tests should stay together (for isolation)
|
|
149
|
+
if (test1.flakinessScore > 0.3 && test2.flakinessScore > 0.3) {
|
|
150
|
+
weight += 0.5;
|
|
151
|
+
}
|
|
152
|
+
return weight;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Recursively bisect graph to create k partitions
|
|
156
|
+
*/
|
|
157
|
+
async recursiveBisection(tests, graph) {
|
|
158
|
+
const partitions = [];
|
|
159
|
+
const queue = [{ tests, graph }];
|
|
160
|
+
while (queue.length < this.config.partitionCount && queue.length > 0) {
|
|
161
|
+
// Find the largest partition to split
|
|
162
|
+
queue.sort((a, b) => b.tests.length - a.tests.length);
|
|
163
|
+
const { tests: currentTests, graph: currentGraph } = queue.shift();
|
|
164
|
+
if (currentTests.length <= 2) {
|
|
165
|
+
// Too small to split, add as final partition
|
|
166
|
+
partitions.push(currentTests);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const result = await this.minCutAnalyzer.computeMinCut(currentGraph);
|
|
171
|
+
// Create two sub-partitions
|
|
172
|
+
const partition1Tests = currentTests.filter(t => result.partition1.includes(t.path));
|
|
173
|
+
const partition2Tests = currentTests.filter(t => result.partition2.includes(t.path));
|
|
174
|
+
// Create sub-graphs
|
|
175
|
+
const subGraph1 = this.createSubgraph(currentGraph, result.partition1);
|
|
176
|
+
const subGraph2 = this.createSubgraph(currentGraph, result.partition2);
|
|
177
|
+
if (partition1Tests.length > 0) {
|
|
178
|
+
queue.push({ tests: partition1Tests, graph: subGraph1 });
|
|
179
|
+
}
|
|
180
|
+
if (partition2Tests.length > 0) {
|
|
181
|
+
queue.push({ tests: partition2Tests, graph: subGraph2 });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
// If MinCut fails, add as final partition
|
|
186
|
+
partitions.push(currentTests);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Add remaining queue items as partitions
|
|
190
|
+
for (const item of queue) {
|
|
191
|
+
partitions.push(item.tests);
|
|
192
|
+
}
|
|
193
|
+
// Ensure we have exactly partitionCount partitions
|
|
194
|
+
return this.balancePartitions(partitions);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Create a subgraph containing only specified nodes
|
|
198
|
+
*/
|
|
199
|
+
createSubgraph(graph, nodeIds) {
|
|
200
|
+
const nodeSet = new Set(nodeIds);
|
|
201
|
+
return {
|
|
202
|
+
nodes: graph.nodes.filter(n => nodeSet.has(n.id)),
|
|
203
|
+
edges: graph.edges.filter(e => nodeSet.has(e.source) && nodeSet.has(e.target)),
|
|
204
|
+
directed: graph.directed,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Balance partitions to ensure exactly k partitions
|
|
209
|
+
*/
|
|
210
|
+
balancePartitions(partitions) {
|
|
211
|
+
const k = this.config.partitionCount;
|
|
212
|
+
// If we have too few partitions, split the largest ones
|
|
213
|
+
while (partitions.length < k) {
|
|
214
|
+
partitions.sort((a, b) => b.length - a.length);
|
|
215
|
+
const largest = partitions.shift();
|
|
216
|
+
if (largest.length <= 1) {
|
|
217
|
+
partitions.push(largest);
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
const mid = Math.ceil(largest.length / 2);
|
|
221
|
+
partitions.push(largest.slice(0, mid));
|
|
222
|
+
partitions.push(largest.slice(mid));
|
|
223
|
+
}
|
|
224
|
+
// If we have too many partitions, merge the smallest ones
|
|
225
|
+
while (partitions.length > k) {
|
|
226
|
+
partitions.sort((a, b) => a.length - b.length);
|
|
227
|
+
const smallest1 = partitions.shift();
|
|
228
|
+
const smallest2 = partitions.shift();
|
|
229
|
+
partitions.push([...smallest1, ...smallest2]);
|
|
230
|
+
}
|
|
231
|
+
return partitions;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Simple duration-balanced partitioning (fallback)
|
|
235
|
+
*/
|
|
236
|
+
durationBalancedPartition(tests, startTime) {
|
|
237
|
+
// Sort by duration descending (longest first)
|
|
238
|
+
const sortedTests = [...tests].sort((a, b) => b.estimatedDuration - a.estimatedDuration);
|
|
239
|
+
// Initialize partition buckets
|
|
240
|
+
const buckets = [];
|
|
241
|
+
for (let i = 0; i < this.config.partitionCount; i++) {
|
|
242
|
+
buckets.push({ tests: [], duration: 0 });
|
|
243
|
+
}
|
|
244
|
+
// Greedy assignment: add each test to the bucket with least total duration
|
|
245
|
+
for (const test of sortedTests) {
|
|
246
|
+
buckets.sort((a, b) => a.duration - b.duration);
|
|
247
|
+
buckets[0].tests.push(test);
|
|
248
|
+
buckets[0].duration += test.estimatedDuration;
|
|
249
|
+
}
|
|
250
|
+
const partitions = buckets.map((bucket, i) => ({
|
|
251
|
+
id: `partition-${i}`,
|
|
252
|
+
tests: bucket.tests,
|
|
253
|
+
estimatedDuration: bucket.duration,
|
|
254
|
+
crossPartitionDeps: this.countCrossPartitionDeps(bucket.tests, tests, buckets),
|
|
255
|
+
workerIndex: i,
|
|
256
|
+
}));
|
|
257
|
+
const computationTimeMs = performance.now() - startTime;
|
|
258
|
+
const stats = this.calculateStats(partitions, tests);
|
|
259
|
+
return {
|
|
260
|
+
partitions,
|
|
261
|
+
algorithm: 'duration-balanced',
|
|
262
|
+
totalCrossPartitionDeps: partitions.reduce((sum, p) => sum + p.crossPartitionDeps, 0),
|
|
263
|
+
loadBalanceScore: stats.parallelEfficiency,
|
|
264
|
+
computationTimeMs,
|
|
265
|
+
estimatedSpeedup: this.estimateSpeedup(partitions, tests),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Build result from MinCut output (2 partitions)
|
|
270
|
+
*/
|
|
271
|
+
buildResult(tests, cuts, startTime) {
|
|
272
|
+
const testMap = new Map(tests.map(t => [t.path, t]));
|
|
273
|
+
const cut = cuts[0];
|
|
274
|
+
const partition1Tests = tests.filter(t => cut.partition1.includes(t.path));
|
|
275
|
+
const partition2Tests = tests.filter(t => cut.partition2.includes(t.path));
|
|
276
|
+
const partitions = [
|
|
277
|
+
{
|
|
278
|
+
id: 'partition-0',
|
|
279
|
+
tests: partition1Tests,
|
|
280
|
+
estimatedDuration: partition1Tests.reduce((sum, t) => sum + t.estimatedDuration, 0),
|
|
281
|
+
crossPartitionDeps: cut.cutEdges.length,
|
|
282
|
+
workerIndex: 0,
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
id: 'partition-1',
|
|
286
|
+
tests: partition2Tests,
|
|
287
|
+
estimatedDuration: partition2Tests.reduce((sum, t) => sum + t.estimatedDuration, 0),
|
|
288
|
+
crossPartitionDeps: cut.cutEdges.length,
|
|
289
|
+
workerIndex: 1,
|
|
290
|
+
},
|
|
291
|
+
];
|
|
292
|
+
const computationTimeMs = performance.now() - startTime;
|
|
293
|
+
const stats = this.calculateStats(partitions, tests);
|
|
294
|
+
return {
|
|
295
|
+
partitions,
|
|
296
|
+
algorithm: 'mincut',
|
|
297
|
+
totalCrossPartitionDeps: cut.cutEdges.length,
|
|
298
|
+
loadBalanceScore: stats.parallelEfficiency,
|
|
299
|
+
computationTimeMs,
|
|
300
|
+
minCutValue: cut.cutValue,
|
|
301
|
+
estimatedSpeedup: this.estimateSpeedup(partitions, tests),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Build result from recursive bisection partitions
|
|
306
|
+
*/
|
|
307
|
+
buildResultFromPartitions(tests, testPartitions, startTime) {
|
|
308
|
+
const partitions = testPartitions.map((partition, i) => ({
|
|
309
|
+
id: `partition-${i}`,
|
|
310
|
+
tests: partition,
|
|
311
|
+
estimatedDuration: partition.reduce((sum, t) => sum + t.estimatedDuration, 0),
|
|
312
|
+
crossPartitionDeps: this.countCrossPartitionDepsForPartition(partition, tests, testPartitions),
|
|
313
|
+
workerIndex: i,
|
|
314
|
+
}));
|
|
315
|
+
const computationTimeMs = performance.now() - startTime;
|
|
316
|
+
const stats = this.calculateStats(partitions, tests);
|
|
317
|
+
const totalCrossPartitionDeps = partitions.reduce((sum, p) => sum + p.crossPartitionDeps, 0) / 2; // Divide by 2 to avoid double counting
|
|
318
|
+
return {
|
|
319
|
+
partitions,
|
|
320
|
+
algorithm: 'mincut',
|
|
321
|
+
totalCrossPartitionDeps,
|
|
322
|
+
loadBalanceScore: stats.parallelEfficiency,
|
|
323
|
+
computationTimeMs,
|
|
324
|
+
estimatedSpeedup: this.estimateSpeedup(partitions, tests),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Count cross-partition dependencies for a single partition
|
|
329
|
+
*/
|
|
330
|
+
countCrossPartitionDepsForPartition(partition, allTests, allPartitions) {
|
|
331
|
+
const partitionPaths = new Set(partition.map(t => t.path));
|
|
332
|
+
let count = 0;
|
|
333
|
+
for (const test of partition) {
|
|
334
|
+
for (const dep of [...test.dependencies, ...test.dependents]) {
|
|
335
|
+
if (!partitionPaths.has(dep) && allTests.some(t => t.path === dep)) {
|
|
336
|
+
count++;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return count;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Count cross-partition dependencies
|
|
344
|
+
*/
|
|
345
|
+
countCrossPartitionDeps(partitionTests, allTests, buckets) {
|
|
346
|
+
const partitionPaths = new Set(partitionTests.map(t => t.path));
|
|
347
|
+
let count = 0;
|
|
348
|
+
for (const test of partitionTests) {
|
|
349
|
+
for (const dep of [...test.dependencies, ...test.dependents]) {
|
|
350
|
+
if (!partitionPaths.has(dep) && allTests.some(t => t.path === dep)) {
|
|
351
|
+
count++;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return count;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Calculate partition quality statistics
|
|
359
|
+
*/
|
|
360
|
+
calculateStats(partitions, tests) {
|
|
361
|
+
const durations = partitions.map(p => p.estimatedDuration);
|
|
362
|
+
const avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
363
|
+
const variance = durations.reduce((sum, d) => sum + Math.pow(d - avgDuration, 2), 0) / durations.length;
|
|
364
|
+
const stdDev = Math.sqrt(variance);
|
|
365
|
+
const sizes = partitions.map(p => p.tests.length);
|
|
366
|
+
const avgSize = sizes.reduce((a, b) => a + b, 0) / sizes.length;
|
|
367
|
+
const sizeVariance = sizes.reduce((sum, s) => sum + Math.pow(s - avgSize, 2), 0) / sizes.length;
|
|
368
|
+
const sizeStdDev = Math.sqrt(sizeVariance);
|
|
369
|
+
const totalDeps = tests.reduce((sum, t) => sum + t.dependencies.length + t.dependents.length, 0);
|
|
370
|
+
const crossDeps = partitions.reduce((sum, p) => sum + p.crossPartitionDeps, 0);
|
|
371
|
+
const crossDepPercentage = totalDeps > 0 ? crossDeps / totalDeps : 0;
|
|
372
|
+
// Parallel efficiency: ratio of avg duration to max duration
|
|
373
|
+
const maxDuration = Math.max(...durations);
|
|
374
|
+
const parallelEfficiency = maxDuration > 0 ? avgDuration / maxDuration : 1;
|
|
375
|
+
// Compare with naive round-robin (would have higher variance)
|
|
376
|
+
const naiveVariance = this.estimateNaiveVariance(tests);
|
|
377
|
+
const vsNaiveImprovement = naiveVariance > 0 ? 1 - (variance / naiveVariance) : 0;
|
|
378
|
+
return {
|
|
379
|
+
durationVariance: variance,
|
|
380
|
+
sizeStdDev,
|
|
381
|
+
crossDepPercentage,
|
|
382
|
+
parallelEfficiency,
|
|
383
|
+
vsNaiveImprovement: Math.max(0, vsNaiveImprovement),
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Estimate variance for naive round-robin
|
|
388
|
+
*/
|
|
389
|
+
estimateNaiveVariance(tests) {
|
|
390
|
+
const k = this.config.partitionCount;
|
|
391
|
+
const naiveBuckets = Array(k).fill(0);
|
|
392
|
+
tests.forEach((test, i) => {
|
|
393
|
+
naiveBuckets[i % k] += test.estimatedDuration;
|
|
394
|
+
});
|
|
395
|
+
const avg = naiveBuckets.reduce((a, b) => a + b, 0) / k;
|
|
396
|
+
return naiveBuckets.reduce((sum, d) => sum + Math.pow(d - avg, 2), 0) / k;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Estimate speedup compared to sequential execution
|
|
400
|
+
*/
|
|
401
|
+
estimateSpeedup(partitions, tests) {
|
|
402
|
+
const totalDuration = tests.reduce((sum, t) => sum + t.estimatedDuration, 0);
|
|
403
|
+
const maxPartitionDuration = Math.max(...partitions.map(p => p.estimatedDuration));
|
|
404
|
+
if (maxPartitionDuration === 0)
|
|
405
|
+
return 1;
|
|
406
|
+
// Account for cross-partition dependency overhead (10% per dependency)
|
|
407
|
+
const crossDepOverhead = partitions.reduce((sum, p) => sum + p.crossPartitionDeps, 0) * 0.1;
|
|
408
|
+
const effectiveParallelDuration = maxPartitionDuration * (1 + crossDepOverhead / 100);
|
|
409
|
+
return totalDuration / effectiveParallelDuration;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Empty result for no tests
|
|
413
|
+
*/
|
|
414
|
+
emptyResult(startTime) {
|
|
415
|
+
return {
|
|
416
|
+
partitions: [],
|
|
417
|
+
algorithm: 'mincut',
|
|
418
|
+
totalCrossPartitionDeps: 0,
|
|
419
|
+
loadBalanceScore: 1,
|
|
420
|
+
computationTimeMs: performance.now() - startTime,
|
|
421
|
+
estimatedSpeedup: 1,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Trivial partition when tests <= partition count
|
|
426
|
+
*/
|
|
427
|
+
trivialPartition(tests, startTime) {
|
|
428
|
+
const partitions = tests.map((test, i) => ({
|
|
429
|
+
id: `partition-${i}`,
|
|
430
|
+
tests: [test],
|
|
431
|
+
estimatedDuration: test.estimatedDuration,
|
|
432
|
+
crossPartitionDeps: 0,
|
|
433
|
+
workerIndex: i,
|
|
434
|
+
}));
|
|
435
|
+
return {
|
|
436
|
+
partitions,
|
|
437
|
+
algorithm: 'mincut',
|
|
438
|
+
totalCrossPartitionDeps: 0,
|
|
439
|
+
loadBalanceScore: 1,
|
|
440
|
+
computationTimeMs: performance.now() - startTime,
|
|
441
|
+
estimatedSpeedup: tests.length,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Get current configuration
|
|
446
|
+
*/
|
|
447
|
+
getConfig() {
|
|
448
|
+
return { ...this.config };
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
exports.MinCutPartitioner = MinCutPartitioner;
|
|
452
|
+
/**
|
|
453
|
+
* Convenience function for one-off partitioning
|
|
454
|
+
*/
|
|
455
|
+
async function partitionTests(tests, config) {
|
|
456
|
+
const partitioner = new MinCutPartitioner(config);
|
|
457
|
+
return partitioner.partition(tests);
|
|
458
|
+
}
|
|
459
|
+
//# sourceMappingURL=MinCutPartitioner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MinCutPartitioner.js","sourceRoot":"","sources":["../../../src/test/partition/MinCutPartitioner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real Test Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes tests using actual Jest/Vitest via child_process.spawn.
|
|
5
|
+
* This replaces the fake "setTimeout + random pass/fail" mock
|
|
6
|
+
* with real test execution.
|
|
7
|
+
*/
|
|
8
|
+
export interface TestExecutionResult {
|
|
9
|
+
testFile: string;
|
|
10
|
+
passed: boolean;
|
|
11
|
+
failed: number;
|
|
12
|
+
total: number;
|
|
13
|
+
duration: number;
|
|
14
|
+
error?: string;
|
|
15
|
+
output?: string;
|
|
16
|
+
workerIndex: number;
|
|
17
|
+
}
|
|
18
|
+
export interface BatchExecutionResult {
|
|
19
|
+
results: TestExecutionResult[];
|
|
20
|
+
totalDuration: number;
|
|
21
|
+
passed: number;
|
|
22
|
+
failed: number;
|
|
23
|
+
}
|
|
24
|
+
export interface ExecutorConfig {
|
|
25
|
+
/** Test runner command (default: 'npx') */
|
|
26
|
+
command: string;
|
|
27
|
+
/** Test runner args (default: ['jest']) */
|
|
28
|
+
runnerArgs: string[];
|
|
29
|
+
/** Timeout per test file in ms (default: 30000) */
|
|
30
|
+
timeout: number;
|
|
31
|
+
/** Working directory */
|
|
32
|
+
cwd: string;
|
|
33
|
+
/** Environment variables */
|
|
34
|
+
env?: Record<string, string>;
|
|
35
|
+
/** Whether to collect coverage */
|
|
36
|
+
collectCoverage: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Executes real tests using Jest via child_process
|
|
40
|
+
*/
|
|
41
|
+
export declare class RealTestExecutor {
|
|
42
|
+
private config;
|
|
43
|
+
private runningProcesses;
|
|
44
|
+
constructor(config?: Partial<ExecutorConfig>);
|
|
45
|
+
/**
|
|
46
|
+
* Execute a single test file
|
|
47
|
+
*/
|
|
48
|
+
executeTest(testFile: string, workerIndex?: number): Promise<TestExecutionResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Execute a batch of test files sequentially on a single worker
|
|
51
|
+
*/
|
|
52
|
+
executeBatch(testFiles: string[], workerIndex?: number): Promise<BatchExecutionResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Execute multiple batches in parallel (one per worker)
|
|
55
|
+
*/
|
|
56
|
+
executeParallel(batches: string[][], onProgress?: (workerIndex: number, result: TestExecutionResult) => void): Promise<BatchExecutionResult[]>;
|
|
57
|
+
/**
|
|
58
|
+
* Execute batch with progress callback
|
|
59
|
+
*/
|
|
60
|
+
private executeBatchWithProgress;
|
|
61
|
+
/**
|
|
62
|
+
* Parse Jest JSON output to extract test results
|
|
63
|
+
*/
|
|
64
|
+
private parseJestOutput;
|
|
65
|
+
/**
|
|
66
|
+
* Kill all running test processes
|
|
67
|
+
*/
|
|
68
|
+
killAll(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get number of currently running tests
|
|
71
|
+
*/
|
|
72
|
+
getRunningCount(): number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Aggregate results from multiple batch executions
|
|
76
|
+
*/
|
|
77
|
+
export declare function aggregateBatchResults(batches: BatchExecutionResult[]): {
|
|
78
|
+
allResults: TestExecutionResult[];
|
|
79
|
+
totalDuration: number;
|
|
80
|
+
maxWorkerDuration: number;
|
|
81
|
+
passed: number;
|
|
82
|
+
failed: number;
|
|
83
|
+
total: number;
|
|
84
|
+
parallelSpeedup: number;
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=RealTestExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealTestExecutor.d.ts","sourceRoot":"","sources":["../../../src/test/partition/RealTestExecutor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,kCAAkC;IAClC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAUD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,gBAAgB,CAAwC;gBAEpD,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM;IAIhD;;OAEG;IACU,WAAW,CACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAU,GACtB,OAAO,CAAC,mBAAmB,CAAC;IAqG/B;;OAEG;IACU,YAAY,CACvB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,GAAE,MAAU,GACtB,OAAO,CAAC,oBAAoB,CAAC;IA2BhC;;OAEG;IACU,eAAe,CAC1B,OAAO,EAAE,MAAM,EAAE,EAAE,EACnB,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,KAAK,IAAI,GACtE,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAQlC;;OAEG;YACW,wBAAwB;IAiCtC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgCvB;;OAEG;IACI,OAAO,IAAI,IAAI;IAQtB;;OAEG;IACI,eAAe,IAAI,MAAM;CAGjC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG;IACtE,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB,CAgBA"}
|