ppef 1.1.0 → 1.2.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 +76 -125
- package/dist/__tests__/cli/evaluate-command.integration.test.d.ts +8 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.d.ts.map +1 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.js +308 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.js.map +1 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.d.ts +8 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.js +405 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.js.map +1 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.d.ts +8 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.js +424 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.js.map +1 -0
- package/dist/__tests__/evaluators/registry.unit.test.d.ts +7 -0
- package/dist/__tests__/evaluators/registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/registry.unit.test.js +173 -0
- package/dist/__tests__/evaluators/registry.unit.test.js.map +1 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.d.ts +8 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.js +260 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.js.map +1 -0
- package/dist/__tests__/framework-pipeline.integration.test.js +36 -9
- package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -1
- package/dist/__tests__/index-exports.unit.test.js +9 -12
- package/dist/__tests__/index-exports.unit.test.js.map +1 -1
- package/dist/aggregation/pipeline.d.ts.map +1 -1
- package/dist/aggregation/pipeline.js +40 -3
- package/dist/aggregation/pipeline.js.map +1 -1
- package/dist/claims/index.d.ts +6 -3
- package/dist/claims/index.d.ts.map +1 -1
- package/dist/claims/index.js +6 -3
- package/dist/claims/index.js.map +1 -1
- package/dist/cli/__tests__/aggregate.command.unit.test.js +3 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js.map +1 -1
- package/dist/cli/__tests__/binary-sut.integration.test.d.ts +8 -0
- package/dist/cli/__tests__/binary-sut.integration.test.d.ts.map +1 -0
- package/dist/cli/__tests__/binary-sut.integration.test.js +165 -0
- package/dist/cli/__tests__/binary-sut.integration.test.js.map +1 -0
- package/dist/cli/__tests__/config-loader.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/config-loader.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/config-loader.unit.test.js +611 -0
- package/dist/cli/__tests__/config-loader.unit.test.js.map +1 -0
- package/dist/cli/command-deps.d.ts +13 -1
- package/dist/cli/command-deps.d.ts.map +1 -1
- package/dist/cli/commands/aggregate.d.ts.map +1 -1
- package/dist/cli/commands/aggregate.js +3 -0
- package/dist/cli/commands/aggregate.js.map +1 -1
- package/dist/cli/commands/evaluate.d.ts +41 -0
- package/dist/cli/commands/evaluate.d.ts.map +1 -0
- package/dist/cli/commands/evaluate.js +287 -0
- package/dist/cli/commands/evaluate.js.map +1 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +93 -1
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.d.ts +2 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/module-loader.d.ts +23 -1
- package/dist/cli/module-loader.d.ts.map +1 -1
- package/dist/cli/module-loader.js +19 -1
- package/dist/cli/module-loader.js.map +1 -1
- package/dist/cli/types.d.ts +19 -0
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/evaluators/claims-evaluator.d.ts +87 -0
- package/dist/evaluators/claims-evaluator.d.ts.map +1 -0
- package/dist/evaluators/claims-evaluator.js +289 -0
- package/dist/evaluators/claims-evaluator.js.map +1 -0
- package/dist/evaluators/exploratory-evaluator.d.ts +136 -0
- package/dist/evaluators/exploratory-evaluator.d.ts.map +1 -0
- package/dist/evaluators/exploratory-evaluator.js +545 -0
- package/dist/evaluators/exploratory-evaluator.js.map +1 -0
- package/dist/evaluators/index.d.ts +13 -0
- package/dist/evaluators/index.d.ts.map +1 -0
- package/dist/evaluators/index.js +14 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/metrics-evaluator.d.ts +114 -0
- package/dist/evaluators/metrics-evaluator.d.ts.map +1 -0
- package/dist/evaluators/metrics-evaluator.js +433 -0
- package/dist/evaluators/metrics-evaluator.js.map +1 -0
- package/dist/evaluators/registry.d.ts +106 -0
- package/dist/evaluators/registry.d.ts.map +1 -0
- package/dist/evaluators/registry.js +148 -0
- package/dist/evaluators/registry.js.map +1 -0
- package/dist/evaluators/robustness-evaluator.d.ts +57 -0
- package/dist/evaluators/robustness-evaluator.d.ts.map +1 -0
- package/dist/evaluators/robustness-evaluator.js +186 -0
- package/dist/evaluators/robustness-evaluator.js.map +1 -0
- package/dist/executor/__tests__/binary-sut.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/binary-sut.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/binary-sut.unit.test.js +313 -0
- package/dist/executor/__tests__/binary-sut.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js +43 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -1
- package/dist/executor/__tests__/executor.unit.test.js +56 -9
- package/dist/executor/__tests__/executor.unit.test.js.map +1 -1
- package/dist/executor/__tests__/resource-calculator.unit.test.d.ts +10 -0
- package/dist/executor/__tests__/resource-calculator.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/resource-calculator.unit.test.js +104 -0
- package/dist/executor/__tests__/resource-calculator.unit.test.js.map +1 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.js +276 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.js.map +1 -0
- package/dist/executor/binary-sut.d.ts +105 -0
- package/dist/executor/binary-sut.d.ts.map +1 -0
- package/dist/executor/binary-sut.js +174 -0
- package/dist/executor/binary-sut.js.map +1 -0
- package/dist/executor/checkpoint-storage.d.ts.map +1 -1
- package/dist/executor/checkpoint-storage.js +6 -4
- package/dist/executor/checkpoint-storage.js.map +1 -1
- package/dist/executor/executor.d.ts +28 -0
- package/dist/executor/executor.d.ts.map +1 -1
- package/dist/executor/executor.js +85 -24
- package/dist/executor/executor.js.map +1 -1
- package/dist/executor/index.d.ts +4 -0
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +4 -0
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/resource-calculator.d.ts +49 -0
- package/dist/executor/resource-calculator.d.ts.map +1 -0
- package/dist/executor/resource-calculator.js +129 -0
- package/dist/executor/resource-calculator.js.map +1 -0
- package/dist/executor/worker-entry.js +26 -10
- package/dist/executor/worker-entry.js.map +1 -1
- package/dist/executor/worker-executor.d.ts +104 -3
- package/dist/executor/worker-executor.d.ts.map +1 -1
- package/dist/executor/worker-executor.js +224 -4
- package/dist/executor/worker-executor.js.map +1 -1
- package/dist/executor/worker-threads-executor.d.ts +245 -0
- package/dist/executor/worker-threads-executor.d.ts.map +1 -0
- package/dist/executor/worker-threads-executor.js +332 -0
- package/dist/executor/worker-threads-executor.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/renderers/latex-renderer.d.ts +60 -0
- package/dist/renderers/latex-renderer.d.ts.map +1 -1
- package/dist/renderers/latex-renderer.js +299 -0
- package/dist/renderers/latex-renderer.js.map +1 -1
- package/dist/renderers/types.d.ts +9 -0
- package/dist/renderers/types.d.ts.map +1 -1
- package/dist/renderers/types.js.map +1 -1
- package/dist/robustness/index.d.ts +5 -2
- package/dist/robustness/index.d.ts.map +1 -1
- package/dist/robustness/index.js +4 -2
- package/dist/robustness/index.js.map +1 -1
- package/dist/types/evaluator.d.ts +449 -0
- package/dist/types/evaluator.d.ts.map +1 -0
- package/dist/types/evaluator.js +9 -0
- package/dist/types/evaluator.js.map +1 -0
- package/dist/types/result.d.ts +2 -0
- package/dist/types/result.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/claims/__tests__/evaluator.unit.test.d.ts +0 -12
- package/dist/claims/__tests__/evaluator.unit.test.d.ts.map +0 -1
- package/dist/claims/__tests__/evaluator.unit.test.js +0 -801
- package/dist/claims/__tests__/evaluator.unit.test.js.map +0 -1
- package/dist/claims/evaluator.d.ts +0 -33
- package/dist/claims/evaluator.d.ts.map +0 -1
- package/dist/claims/evaluator.js +0 -174
- package/dist/claims/evaluator.js.map +0 -1
- package/dist/robustness/__tests__/analyzer.unit.test.d.ts +0 -11
- package/dist/robustness/__tests__/analyzer.unit.test.d.ts.map +0 -1
- package/dist/robustness/__tests__/analyzer.unit.test.js +0 -455
- package/dist/robustness/__tests__/analyzer.unit.test.js.map +0 -1
- package/dist/robustness/analyzer.d.ts +0 -61
- package/dist/robustness/analyzer.d.ts.map +0 -1
- package/dist/robustness/analyzer.js +0 -191
- package/dist/robustness/analyzer.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-calculator.d.ts","sourceRoot":"","sources":["../../src/executor/resource-calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;CACxB;AA6ED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACvC,cAAc,SAAO,EACrB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,SAAO,GAAG,cAAc,CAgB5E"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Calculator
|
|
3
|
+
*
|
|
4
|
+
* Automatically calculates optimal resource limits for parallel execution
|
|
5
|
+
* using the "75% rule" - reserves 75% of available resources for workers,
|
|
6
|
+
* leaving 25% for system stability and other processes.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - CPU-based worker count (75% of available cores)
|
|
10
|
+
* - Memory per worker calculation (total memory / worker count)
|
|
11
|
+
* - Dynamic disk I/O ceiling measurement (detects throughput plateau)
|
|
12
|
+
* - Caching to avoid repeated measurements
|
|
13
|
+
*
|
|
14
|
+
* Disk I/O Measurement Algorithm:
|
|
15
|
+
* 1. Test concurrent write+read operations at increasing levels (1, 6, 11, 16, ...)
|
|
16
|
+
* 2. Measure throughput (MB/s) for each concurrency level
|
|
17
|
+
* 3. Detect when throughput plateaus (<5% improvement)
|
|
18
|
+
* 4. Return 75% of the detected ceiling
|
|
19
|
+
* 5. Cache result to avoid re-measuring
|
|
20
|
+
*/
|
|
21
|
+
import { cpus, totalmem } from "node:os";
|
|
22
|
+
import { mkdtemp, readFile, writeFile, unlink } from "node:fs/promises";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
/**
|
|
26
|
+
* Measure disk I/O ceiling by testing throughput at increasing concurrency levels.
|
|
27
|
+
* Returns the concurrency level where throughput stops improving (the ceiling).
|
|
28
|
+
*
|
|
29
|
+
* @param sampleSizeMb - Size of test data in MB (default: 10)
|
|
30
|
+
* @param maxConcurrency - Maximum concurrency to test (default: 100)
|
|
31
|
+
* @param timeoutMs - Timeout per test in milliseconds (default: 5000)
|
|
32
|
+
* @returns The detected concurrency ceiling
|
|
33
|
+
*/
|
|
34
|
+
async function measureDiskIoCeiling(sampleSizeMb = 10, maxConcurrency = 100, timeoutMs = 5000) {
|
|
35
|
+
const testData = Buffer.alloc(sampleSizeMb * 1024 * 1024, "x");
|
|
36
|
+
// Test at increasing concurrency levels
|
|
37
|
+
let lastThroughput = 0;
|
|
38
|
+
let ceiling = 10; // Default fallback
|
|
39
|
+
for (let concurrency = 1; concurrency <= maxConcurrency; concurrency += 5) {
|
|
40
|
+
const tempDir = await mkdtemp(join(tmpdir(), "io-test-"));
|
|
41
|
+
const startTime = performance.now();
|
|
42
|
+
try {
|
|
43
|
+
// Run concurrent write+read operations
|
|
44
|
+
const operations = Array.from({ length: concurrency }, async () => {
|
|
45
|
+
const filePath = join(tempDir, `test-${Math.random().toString(36).slice(2)}.dat`);
|
|
46
|
+
await writeFile(filePath, testData);
|
|
47
|
+
await readFile(filePath);
|
|
48
|
+
return filePath;
|
|
49
|
+
});
|
|
50
|
+
await Promise.race([
|
|
51
|
+
Promise.all(operations),
|
|
52
|
+
new Promise((_resolve, reject) => setTimeout(() => {
|
|
53
|
+
reject(new Error("timeout"));
|
|
54
|
+
}, timeoutMs)),
|
|
55
|
+
]);
|
|
56
|
+
const elapsedMs = performance.now() - startTime;
|
|
57
|
+
const throughput = (concurrency * sampleSizeMb) / (elapsedMs / 1000);
|
|
58
|
+
// Check if we've hit the ceiling (throughput not improving)
|
|
59
|
+
if (throughput > lastThroughput * 1.05) {
|
|
60
|
+
// Still improving
|
|
61
|
+
lastThroughput = throughput;
|
|
62
|
+
ceiling = concurrency;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Throughput plateaued - we found the ceiling
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Timeout or error - previous level was the ceiling
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
// Cleanup
|
|
75
|
+
try {
|
|
76
|
+
const { readdir } = await import("node:fs/promises");
|
|
77
|
+
const files = await readdir(tempDir);
|
|
78
|
+
await Promise.all(files.map((f) => unlink(join(tempDir, f))));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Ignore cleanup errors
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return ceiling;
|
|
86
|
+
}
|
|
87
|
+
/** Cached disk I/O ceiling measurement */
|
|
88
|
+
let cachedCeiling = null;
|
|
89
|
+
/**
|
|
90
|
+
* Calculate resource limits using the 75% rule.
|
|
91
|
+
*
|
|
92
|
+
* @param reservePercent - Percentage of resources to reserve (default: 0.75 for 75%)
|
|
93
|
+
* @param options - Options for resource calculation
|
|
94
|
+
* @returns Resource limits for parallel execution
|
|
95
|
+
*/
|
|
96
|
+
export async function calculateResources(reservePercent = 0.75, options = {}) {
|
|
97
|
+
const cpuCount = cpus().length;
|
|
98
|
+
const totalMemory = totalmem();
|
|
99
|
+
// Clamp reservePercent to [0, 1] range
|
|
100
|
+
const clampedReserve = Math.max(0, Math.min(1, reservePercent));
|
|
101
|
+
const maxWorkers = Math.floor(cpuCount * clampedReserve);
|
|
102
|
+
// Avoid division by zero when maxWorkers is 0
|
|
103
|
+
const maxMemoryMb = maxWorkers > 0 ? Math.floor((totalMemory * clampedReserve) / maxWorkers / (1024 * 1024)) : 0;
|
|
104
|
+
// Measure disk I/O ceiling once, then cache
|
|
105
|
+
let maxConcurrentIo = Math.floor(100 * clampedReserve);
|
|
106
|
+
if (options.measureDisk !== false && maxWorkers > 0) {
|
|
107
|
+
cachedCeiling ??= await measureDiskIoCeiling();
|
|
108
|
+
maxConcurrentIo = Math.floor(cachedCeiling * clampedReserve);
|
|
109
|
+
}
|
|
110
|
+
return { maxWorkers, maxMemoryMb, maxConcurrentIo };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Synchronous version that skips disk measurement (for quick startup).
|
|
114
|
+
*
|
|
115
|
+
* @param reservePercent - Percentage of resources to reserve (default: 0.75 for 75%)
|
|
116
|
+
* @returns Resource limits for parallel execution (with estimated I/O)
|
|
117
|
+
*/
|
|
118
|
+
export function calculateResourcesSync(reservePercent = 0.75) {
|
|
119
|
+
const cpuCount = cpus().length;
|
|
120
|
+
const totalMemory = totalmem();
|
|
121
|
+
// Clamp reservePercent to [0, 1] range
|
|
122
|
+
const clampedReserve = Math.max(0, Math.min(1, reservePercent));
|
|
123
|
+
const maxWorkers = Math.floor(cpuCount * clampedReserve);
|
|
124
|
+
// Avoid division by zero when maxWorkers is 0
|
|
125
|
+
const maxMemoryMb = maxWorkers > 0 ? Math.floor((totalMemory * clampedReserve) / maxWorkers / (1024 * 1024)) : 0;
|
|
126
|
+
const maxConcurrentIo = Math.floor(100 * clampedReserve);
|
|
127
|
+
return { maxWorkers, maxMemoryMb, maxConcurrentIo };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=resource-calculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-calculator.js","sourceRoot":"","sources":["../../src/executor/resource-calculator.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,25 +12,41 @@ import { parentPort } from "node:worker_threads";
|
|
|
12
12
|
import { WorkerExecutor, } from "./worker-executor.js";
|
|
13
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
14
|
const __dirname = dirname(__filename);
|
|
15
|
-
|
|
15
|
+
// From dist/executor/, go up 2 levels to reach the package root
|
|
16
|
+
const projectRoot = resolve(__dirname, "../../");
|
|
16
17
|
/**
|
|
17
18
|
* Real module loader implementation for production use.
|
|
19
|
+
*
|
|
20
|
+
* Module paths reference the ppef structure:
|
|
21
|
+
* - executor: src/executor/executor.ts -> dist/executor/executor.js
|
|
22
|
+
* - evaluate: Not used in worker mode (SUTs/cases loaded via serialization)
|
|
23
|
+
* - registry: Not used in worker mode (not needed for isolated execution)
|
|
24
|
+
* - suts: Not used in worker mode (SUTs passed via serialization)
|
|
25
|
+
* - datasets: Not used in worker mode (not needed for isolated execution)
|
|
26
|
+
*
|
|
27
|
+
* NOTE: For worker threads, SUT and case definitions are passed via
|
|
28
|
+
* WorkerMessage serialization instead of dynamic imports, providing
|
|
29
|
+
* better isolation and avoiding hardcoded module paths.
|
|
18
30
|
*/
|
|
19
31
|
class RealModuleLoader {
|
|
20
32
|
async loadExecutor() {
|
|
21
|
-
return (await import(`${projectRoot}/dist/
|
|
33
|
+
return (await import(`${projectRoot}/dist/executor/executor.js`));
|
|
22
34
|
}
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
loadEvaluate() {
|
|
36
|
+
// Not used in worker threads mode - SUTs/cases passed via serialization
|
|
37
|
+
return Promise.reject(new Error("loadEvaluate not supported in worker threads mode"));
|
|
25
38
|
}
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
loadRegistry() {
|
|
40
|
+
// Not used in worker threads mode
|
|
41
|
+
return Promise.reject(new Error("loadRegistry not supported in worker threads mode"));
|
|
28
42
|
}
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
loadSuts() {
|
|
44
|
+
// Not used in worker threads mode - SUTs passed via serialization
|
|
45
|
+
return Promise.reject(new Error("loadSuts not supported in worker threads mode"));
|
|
31
46
|
}
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
loadDatasets() {
|
|
48
|
+
// Not used in worker threads mode
|
|
49
|
+
return Promise.reject(new Error("loadDatasets not supported in worker threads mode"));
|
|
34
50
|
}
|
|
35
51
|
}
|
|
36
52
|
// Create executor with real dependencies and start listening
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAON,cAAc,GACd,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAON,cAAc,GACd,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,gEAAgE;AAChE,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AACH,MAAM,gBAAgB;IACd,KAAK,CAAC,YAAY;QACxB,OAAO,CAAC,MAAM,MAAM,CAAC,GAAG,WAAW,4BAA4B,CAAC,CAA+B,CAAC;IACjG,CAAC;IAEM,YAAY;QAClB,wEAAwE;QACxE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;IACvF,CAAC;IAEM,YAAY;QAClB,kCAAkC;QAClC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;IACvF,CAAC;IAEM,QAAQ;QACd,kEAAkE;QAClE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC;IACnF,CAAC;IAEM,YAAY;QAClB,kCAAkC;QAClC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;IACvF,CAAC;CACD;AAED,6DAA6D;AAC7D,IAAI,UAAU,EAAE,CAAC;IAChB,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC3E,QAAQ,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This class can be tested by injecting mock dependencies,
|
|
5
5
|
* while worker-entry.ts provides real implementations.
|
|
6
|
+
*
|
|
7
|
+
* Two execution modes:
|
|
8
|
+
* 1. Legacy mode: Uses module loader to dynamically load SUTs/cases (for backward compatibility)
|
|
9
|
+
* 2. Serialized mode: SUTs/cases passed via WorkerMessage (for worker threads isolation)
|
|
6
10
|
*/
|
|
7
11
|
import type { EvaluationResult } from "../types/result.js";
|
|
8
12
|
/**
|
|
@@ -26,11 +30,77 @@ export interface ExecutorConfig {
|
|
|
26
30
|
collectProvenance: boolean;
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
|
-
*
|
|
33
|
+
* Serialized SUT definition for passing via WorkerMessage.
|
|
34
|
+
*/
|
|
35
|
+
export interface SerializedSut {
|
|
36
|
+
id: string;
|
|
37
|
+
module: string;
|
|
38
|
+
exportName: string;
|
|
39
|
+
registration: {
|
|
40
|
+
name: string;
|
|
41
|
+
version: string;
|
|
42
|
+
role: string;
|
|
43
|
+
};
|
|
44
|
+
/** Binary SUT configuration (if type="binary") */
|
|
45
|
+
binary?: {
|
|
46
|
+
command: string;
|
|
47
|
+
args?: string[];
|
|
48
|
+
inputFormat?: "json" | "raw" | "lines";
|
|
49
|
+
outputFormat?: "json" | "raw" | "lines";
|
|
50
|
+
timeout?: number;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Serialized case definition for passing via WorkerMessage.
|
|
55
|
+
*/
|
|
56
|
+
export interface SerializedCase {
|
|
57
|
+
caseId: string;
|
|
58
|
+
module: string;
|
|
59
|
+
exportName: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Registry manifest for passing pre-registered SUTs/cases via WorkerMessage.
|
|
63
|
+
* Allows worker threads to reconstruct registries without dynamic module loading.
|
|
64
|
+
*
|
|
65
|
+
* This enables registry-based SUTs (like GraphBox's wrapper classes) to work
|
|
66
|
+
* with worker thread isolation without requiring standalone createSut() files.
|
|
67
|
+
*/
|
|
68
|
+
export interface RegistryManifest {
|
|
69
|
+
/** Pre-registered SUT metadata */
|
|
70
|
+
suts: {
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
version: string;
|
|
74
|
+
role: string;
|
|
75
|
+
config: Record<string, unknown>;
|
|
76
|
+
tags: string[];
|
|
77
|
+
}[];
|
|
78
|
+
/** Shared code bundle (registry functions) */
|
|
79
|
+
sharedCode: string;
|
|
80
|
+
/** Map of SUT IDs to their module paths */
|
|
81
|
+
sutModules: Record<string, string>;
|
|
82
|
+
/** Export name for createSut function */
|
|
83
|
+
exportName: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Type definition for message sent to worker.
|
|
87
|
+
*
|
|
88
|
+
* Supports three modes:
|
|
89
|
+
* - Legacy: Only `runs` and `config` provided (uses module loader)
|
|
90
|
+
* - Serialized: `suts` and `cases` arrays provided (direct instantiation)
|
|
91
|
+
* - Registry: `registryManifest` provided (reconstructs registry from manifest)
|
|
30
92
|
*/
|
|
31
93
|
export interface WorkerMessage {
|
|
32
94
|
runs: RunConfig[];
|
|
33
95
|
config: ExecutorConfig;
|
|
96
|
+
/** Base directory for resolving module paths (required for serialized mode) */
|
|
97
|
+
baseDir?: string;
|
|
98
|
+
/** Serialized SUT definitions (optional, for serialized mode) */
|
|
99
|
+
suts?: SerializedSut[];
|
|
100
|
+
/** Serialized case definitions (optional, for serialized mode) */
|
|
101
|
+
cases?: SerializedCase[];
|
|
102
|
+
/** Registry manifest (optional, for registry mode) */
|
|
103
|
+
registryManifest?: RegistryManifest;
|
|
34
104
|
}
|
|
35
105
|
/**
|
|
36
106
|
* Type definition for worker response
|
|
@@ -129,15 +199,20 @@ export interface IModuleLoader {
|
|
|
129
199
|
}
|
|
130
200
|
/**
|
|
131
201
|
* WorkerExecutor - Core worker execution logic with injected dependencies.
|
|
202
|
+
*
|
|
203
|
+
* Supports two execution modes:
|
|
204
|
+
* 1. Legacy mode: Uses module loader for dynamic imports (backward compatible)
|
|
205
|
+
* 2. Serialized mode: SUTs/cases passed via WorkerMessage (worker threads isolation)
|
|
132
206
|
*/
|
|
133
207
|
export declare class WorkerExecutor {
|
|
134
208
|
private readonly parentPort;
|
|
135
209
|
private readonly moduleLoader;
|
|
210
|
+
private readonly projectRoot;
|
|
136
211
|
/**
|
|
137
212
|
* Create a new WorkerExecutor with injected dependencies.
|
|
138
213
|
* @param parentPort - Communication port to parent thread
|
|
139
|
-
* @param moduleLoader - Module loader for dynamic imports
|
|
140
|
-
* @param projectRoot - Root directory for the project (
|
|
214
|
+
* @param moduleLoader - Module loader for dynamic imports (legacy mode)
|
|
215
|
+
* @param projectRoot - Root directory for the project (used for module resolution)
|
|
141
216
|
*/
|
|
142
217
|
constructor(parentPort: IParentPort, moduleLoader: IModuleLoader, projectRoot: string);
|
|
143
218
|
/**
|
|
@@ -150,7 +225,33 @@ export declare class WorkerExecutor {
|
|
|
150
225
|
handleMessage(data: unknown): Promise<void>;
|
|
151
226
|
/**
|
|
152
227
|
* Execute a batch of runs.
|
|
228
|
+
*
|
|
229
|
+
* Three execution modes:
|
|
230
|
+
* 1. Legacy mode: Uses module loader to dynamically load SUTs/cases
|
|
231
|
+
* 2. Serialized mode: SUTs/cases passed via WorkerMessage (for worker threads)
|
|
232
|
+
* 3. Registry mode: Reconstructs registry from manifest (for registry-based SUTs)
|
|
153
233
|
*/
|
|
154
234
|
executeBatch(message: WorkerMessage): Promise<WorkerResponse>;
|
|
235
|
+
/**
|
|
236
|
+
* Execute using legacy mode with dynamic module loading.
|
|
237
|
+
* Used for backward compatibility with existing tests.
|
|
238
|
+
*/
|
|
239
|
+
private executeBatchLegacy;
|
|
240
|
+
/**
|
|
241
|
+
* Execute using serialized mode (SUTs/cases passed via WorkerMessage).
|
|
242
|
+
* This mode is used for worker threads isolation.
|
|
243
|
+
*
|
|
244
|
+
* Dynamically imports SUT and case modules based on provided definitions,
|
|
245
|
+
* creates an Executor instance, and executes the planned runs.
|
|
246
|
+
*/
|
|
247
|
+
private executeBatchSerialized;
|
|
248
|
+
/**
|
|
249
|
+
* Execute using registry manifest mode.
|
|
250
|
+
* Reconstructs SUT registry from manifest and executes runs.
|
|
251
|
+
*
|
|
252
|
+
* This mode enables registry-based SUTs (like GraphBox wrapper classes)
|
|
253
|
+
* to work with worker thread isolation without requiring standalone files.
|
|
254
|
+
*/
|
|
255
|
+
private executeBatchRegistry;
|
|
155
256
|
}
|
|
156
257
|
//# sourceMappingURL=worker-executor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-executor.d.ts","sourceRoot":"","sources":["../../src/executor/worker-executor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker-executor.d.ts","sourceRoot":"","sources":["../../src/executor/worker-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,24 +3,40 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This class can be tested by injecting mock dependencies,
|
|
5
5
|
* while worker-entry.ts provides real implementations.
|
|
6
|
+
*
|
|
7
|
+
* Two execution modes:
|
|
8
|
+
* 1. Legacy mode: Uses module loader to dynamically load SUTs/cases (for backward compatibility)
|
|
9
|
+
* 2. Serialized mode: SUTs/cases passed via WorkerMessage (for worker threads isolation)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Type-safe dynamic import helper.
|
|
13
|
+
* TypeScript's import() returns `any`, so we use a type assertion function
|
|
14
|
+
* to satisfy ESLint's no-unsafe-assignment rule.
|
|
6
15
|
*/
|
|
16
|
+
async function dynamicImport(modulePath) {
|
|
17
|
+
return import(modulePath);
|
|
18
|
+
}
|
|
7
19
|
/**
|
|
8
20
|
* WorkerExecutor - Core worker execution logic with injected dependencies.
|
|
21
|
+
*
|
|
22
|
+
* Supports two execution modes:
|
|
23
|
+
* 1. Legacy mode: Uses module loader for dynamic imports (backward compatible)
|
|
24
|
+
* 2. Serialized mode: SUTs/cases passed via WorkerMessage (worker threads isolation)
|
|
9
25
|
*/
|
|
10
26
|
export class WorkerExecutor {
|
|
11
27
|
parentPort;
|
|
12
28
|
moduleLoader;
|
|
29
|
+
projectRoot;
|
|
13
30
|
/**
|
|
14
31
|
* Create a new WorkerExecutor with injected dependencies.
|
|
15
32
|
* @param parentPort - Communication port to parent thread
|
|
16
|
-
* @param moduleLoader - Module loader for dynamic imports
|
|
17
|
-
* @param projectRoot - Root directory for the project (
|
|
33
|
+
* @param moduleLoader - Module loader for dynamic imports (legacy mode)
|
|
34
|
+
* @param projectRoot - Root directory for the project (used for module resolution)
|
|
18
35
|
*/
|
|
19
36
|
constructor(parentPort, moduleLoader, projectRoot) {
|
|
20
37
|
this.parentPort = parentPort;
|
|
21
38
|
this.moduleLoader = moduleLoader;
|
|
22
|
-
|
|
23
|
-
void projectRoot;
|
|
39
|
+
this.projectRoot = projectRoot;
|
|
24
40
|
}
|
|
25
41
|
/**
|
|
26
42
|
* Start listening for messages from parent thread.
|
|
@@ -48,8 +64,29 @@ export class WorkerExecutor {
|
|
|
48
64
|
}
|
|
49
65
|
/**
|
|
50
66
|
* Execute a batch of runs.
|
|
67
|
+
*
|
|
68
|
+
* Three execution modes:
|
|
69
|
+
* 1. Legacy mode: Uses module loader to dynamically load SUTs/cases
|
|
70
|
+
* 2. Serialized mode: SUTs/cases passed via WorkerMessage (for worker threads)
|
|
71
|
+
* 3. Registry mode: Reconstructs registry from manifest (for registry-based SUTs)
|
|
51
72
|
*/
|
|
52
73
|
async executeBatch(message) {
|
|
74
|
+
// Check for registry manifest mode
|
|
75
|
+
if (message.registryManifest && message.baseDir) {
|
|
76
|
+
return this.executeBatchRegistry(message);
|
|
77
|
+
}
|
|
78
|
+
// Check if serialized mode (SUTs/cases provided in message)
|
|
79
|
+
if (message.suts && message.cases && message.baseDir) {
|
|
80
|
+
return this.executeBatchSerialized(message);
|
|
81
|
+
}
|
|
82
|
+
// Legacy mode: Use module loader
|
|
83
|
+
return this.executeBatchLegacy(message);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Execute using legacy mode with dynamic module loading.
|
|
87
|
+
* Used for backward compatibility with existing tests.
|
|
88
|
+
*/
|
|
89
|
+
async executeBatchLegacy(message) {
|
|
53
90
|
// Import the executor and other dependencies
|
|
54
91
|
const executorModule = await this.moduleLoader.loadExecutor();
|
|
55
92
|
const evaluateModule = await this.moduleLoader.loadEvaluate();
|
|
@@ -84,5 +121,188 @@ export class WorkerExecutor {
|
|
|
84
121
|
errors: results.errors,
|
|
85
122
|
};
|
|
86
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Execute using serialized mode (SUTs/cases passed via WorkerMessage).
|
|
126
|
+
* This mode is used for worker threads isolation.
|
|
127
|
+
*
|
|
128
|
+
* Dynamically imports SUT and case modules based on provided definitions,
|
|
129
|
+
* creates an Executor instance, and executes the planned runs.
|
|
130
|
+
*/
|
|
131
|
+
async executeBatchSerialized(message) {
|
|
132
|
+
if (!message.baseDir || !message.suts || !message.cases) {
|
|
133
|
+
throw new Error("Serialized mode requires baseDir, suts, and cases in WorkerMessage");
|
|
134
|
+
}
|
|
135
|
+
// Load executor module
|
|
136
|
+
const executorModule = await this.moduleLoader.loadExecutor();
|
|
137
|
+
// Load SUTs dynamically
|
|
138
|
+
const suts = [];
|
|
139
|
+
const sutMap = new Map();
|
|
140
|
+
for (const serializedSut of message.suts) {
|
|
141
|
+
try {
|
|
142
|
+
// Handle binary SUTs
|
|
143
|
+
if (serializedSut.binary) {
|
|
144
|
+
const binarySutModule = await dynamicImport(`${this.projectRoot}/dist/executor/binary-sut.js`);
|
|
145
|
+
const BinarySutClass = binarySutModule.BinarySut;
|
|
146
|
+
const sut = new BinarySutClass(serializedSut.id, serializedSut.binary);
|
|
147
|
+
const sutDefinition = {
|
|
148
|
+
factory: () => sut,
|
|
149
|
+
registration: {
|
|
150
|
+
...serializedSut.registration,
|
|
151
|
+
id: serializedSut.id,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
suts.push(sutDefinition);
|
|
155
|
+
sutMap.set(serializedSut.id, sutDefinition);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
// Resolve module path (baseDir is already absolute)
|
|
159
|
+
const modulePath = `${this.projectRoot}/${serializedSut.module}`;
|
|
160
|
+
// Dynamic import from the module path
|
|
161
|
+
const module = await dynamicImport(modulePath);
|
|
162
|
+
const factory = module[serializedSut.exportName];
|
|
163
|
+
if (typeof factory !== "function") {
|
|
164
|
+
throw new Error(`Export ${serializedSut.exportName} in ${modulePath} is not a function`);
|
|
165
|
+
}
|
|
166
|
+
// Build SutDefinition object
|
|
167
|
+
const sutDefinition = {
|
|
168
|
+
factory,
|
|
169
|
+
registration: {
|
|
170
|
+
...serializedSut.registration,
|
|
171
|
+
id: serializedSut.id,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
suts.push(sutDefinition);
|
|
175
|
+
sutMap.set(serializedSut.id, sutDefinition);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
throw new Error(`Failed to load SUT "${serializedSut.id}": ${error instanceof Error ? error.message : String(error)}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Load cases dynamically
|
|
182
|
+
const cases = [];
|
|
183
|
+
const caseMap = new Map();
|
|
184
|
+
for (const serializedCase of message.cases) {
|
|
185
|
+
// Resolve module path (baseDir is already absolute)
|
|
186
|
+
const modulePath = `${this.projectRoot}/${serializedCase.module}`;
|
|
187
|
+
try {
|
|
188
|
+
// Dynamic import from the module path
|
|
189
|
+
const module = await dynamicImport(modulePath);
|
|
190
|
+
const caseDefinitionFn = module[serializedCase.exportName];
|
|
191
|
+
if (typeof caseDefinitionFn !== "function") {
|
|
192
|
+
throw new Error(`Export ${serializedCase.exportName} in ${modulePath} is not a function`);
|
|
193
|
+
}
|
|
194
|
+
// Call the function to get the case definition
|
|
195
|
+
const caseDefinition = caseDefinitionFn();
|
|
196
|
+
// Validate that we got a proper CaseDefinition
|
|
197
|
+
if (typeof caseDefinition.getInput !== "function" ||
|
|
198
|
+
typeof caseDefinition.getInputs !== "function") {
|
|
199
|
+
throw new Error(`Export ${serializedCase.exportName} in ${modulePath} did not return a valid CaseDefinition`);
|
|
200
|
+
}
|
|
201
|
+
cases.push(caseDefinition);
|
|
202
|
+
caseMap.set(serializedCase.caseId, caseDefinition);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
throw new Error(`Failed to load case "${serializedCase.caseId}" from ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Create executor with config
|
|
209
|
+
const executor = new executorModule.Executor({
|
|
210
|
+
repetitions: message.config.repetitions,
|
|
211
|
+
seedBase: message.config.seedBase,
|
|
212
|
+
continueOnError: message.config.continueOnError,
|
|
213
|
+
timeoutMs: message.config.timeoutMs,
|
|
214
|
+
collectProvenance: message.config.collectProvenance,
|
|
215
|
+
});
|
|
216
|
+
// Execute the runs (pass no-op callback - workers don't save checkpoints)
|
|
217
|
+
const results = await executor.execute(suts, cases, () => ({}));
|
|
218
|
+
return {
|
|
219
|
+
results: results.results,
|
|
220
|
+
errors: results.errors,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Execute using registry manifest mode.
|
|
225
|
+
* Reconstructs SUT registry from manifest and executes runs.
|
|
226
|
+
*
|
|
227
|
+
* This mode enables registry-based SUTs (like GraphBox wrapper classes)
|
|
228
|
+
* to work with worker thread isolation without requiring standalone files.
|
|
229
|
+
*/
|
|
230
|
+
async executeBatchRegistry(message) {
|
|
231
|
+
if (!message.baseDir || !message.registryManifest) {
|
|
232
|
+
throw new Error("Registry mode requires baseDir and registryManifest in WorkerMessage");
|
|
233
|
+
}
|
|
234
|
+
const { registryManifest } = message;
|
|
235
|
+
// Load executor module
|
|
236
|
+
const executorModule = await this.moduleLoader.loadExecutor();
|
|
237
|
+
// Reconstruct SUTs from registry manifest
|
|
238
|
+
const suts = [];
|
|
239
|
+
const sutMap = new Map();
|
|
240
|
+
for (const sutMeta of registryManifest.suts) {
|
|
241
|
+
try {
|
|
242
|
+
// Resolve module path from sutModules map
|
|
243
|
+
const modulePath = `${this.projectRoot}/${registryManifest.sutModules[sutMeta.id]}`;
|
|
244
|
+
// Dynamic import the SUT module
|
|
245
|
+
const module = await dynamicImport(modulePath);
|
|
246
|
+
const factory = module[registryManifest.exportName];
|
|
247
|
+
if (typeof factory !== "function") {
|
|
248
|
+
throw new Error(`Export ${registryManifest.exportName} in ${modulePath} is not a function`);
|
|
249
|
+
}
|
|
250
|
+
// Build SutDefinition object with registry metadata
|
|
251
|
+
const sutDefinition = {
|
|
252
|
+
factory,
|
|
253
|
+
registration: {
|
|
254
|
+
...sutMeta,
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
suts.push(sutDefinition);
|
|
258
|
+
sutMap.set(sutMeta.id, sutDefinition);
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
throw new Error(`Failed to load SUT "${sutMeta.id}" from registry: ${error instanceof Error ? error.message : String(error)}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// For registry mode, cases must still be provided separately
|
|
265
|
+
// This is a design limitation - full registry support would require case manifests too
|
|
266
|
+
if (!message.cases || message.cases.length === 0) {
|
|
267
|
+
throw new Error("Registry mode requires cases array in WorkerMessage");
|
|
268
|
+
}
|
|
269
|
+
// Load cases using the same logic as serialized mode
|
|
270
|
+
const cases = [];
|
|
271
|
+
const caseMap = new Map();
|
|
272
|
+
for (const serializedCase of message.cases) {
|
|
273
|
+
const modulePath = `${this.projectRoot}/${serializedCase.module}`;
|
|
274
|
+
try {
|
|
275
|
+
const module = await dynamicImport(modulePath);
|
|
276
|
+
const caseDefinitionFn = module[serializedCase.exportName];
|
|
277
|
+
if (typeof caseDefinitionFn !== "function") {
|
|
278
|
+
throw new Error(`Export ${serializedCase.exportName} in ${modulePath} is not a function`);
|
|
279
|
+
}
|
|
280
|
+
const caseDefinition = caseDefinitionFn();
|
|
281
|
+
if (typeof caseDefinition.getInput !== "function" ||
|
|
282
|
+
typeof caseDefinition.getInputs !== "function") {
|
|
283
|
+
throw new Error(`Export ${serializedCase.exportName} in ${modulePath} did not return a valid CaseDefinition`);
|
|
284
|
+
}
|
|
285
|
+
cases.push(caseDefinition);
|
|
286
|
+
caseMap.set(serializedCase.caseId, caseDefinition);
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
throw new Error(`Failed to load case "${serializedCase.caseId}" from ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Create executor with config
|
|
293
|
+
const executor = new executorModule.Executor({
|
|
294
|
+
repetitions: message.config.repetitions,
|
|
295
|
+
seedBase: message.config.seedBase,
|
|
296
|
+
continueOnError: message.config.continueOnError,
|
|
297
|
+
timeoutMs: message.config.timeoutMs,
|
|
298
|
+
collectProvenance: message.config.collectProvenance,
|
|
299
|
+
});
|
|
300
|
+
// Execute the runs
|
|
301
|
+
const results = await executor.execute(suts, cases, () => ({}));
|
|
302
|
+
return {
|
|
303
|
+
results: results.results,
|
|
304
|
+
errors: results.errors,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
87
307
|
}
|
|
88
308
|
//# sourceMappingURL=worker-executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-executor.js","sourceRoot":"","sources":["../../src/executor/worker-executor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker-executor.js","sourceRoot":"","sources":["../../src/executor/worker-executor.ts"],"names":[],"mappings":"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"}
|