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,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for ResourceCalculator
|
|
3
|
+
*
|
|
4
|
+
* Tests automatic 75% resource calculation including:
|
|
5
|
+
* - CPU-based worker count
|
|
6
|
+
* - Memory per worker calculation
|
|
7
|
+
* - Disk I/O throttling (dynamic measurement)
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=resource-calculator.unit.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-calculator.unit.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/resource-calculator.unit.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for ResourceCalculator
|
|
3
|
+
*
|
|
4
|
+
* Tests automatic 75% resource calculation including:
|
|
5
|
+
* - CPU-based worker count
|
|
6
|
+
* - Memory per worker calculation
|
|
7
|
+
* - Disk I/O throttling (dynamic measurement)
|
|
8
|
+
*/
|
|
9
|
+
import { describe, it } from "node:test";
|
|
10
|
+
import { strict as assert } from "node:assert";
|
|
11
|
+
import { calculateResources, calculateResourcesSync, } from "../resource-calculator.js";
|
|
12
|
+
import { cpus } from "node:os";
|
|
13
|
+
describe("ResourceCalculator", () => {
|
|
14
|
+
describe("calculateResourcesSync", () => {
|
|
15
|
+
it("should calculate 75% of CPU cores as max workers", () => {
|
|
16
|
+
const result = calculateResourcesSync(0.75);
|
|
17
|
+
assert.ok(result.maxWorkers >= 1);
|
|
18
|
+
assert.ok(Number.isInteger(result.maxWorkers));
|
|
19
|
+
// Should be at least 1 worker
|
|
20
|
+
assert.strictEqual(result.maxWorkers, Math.max(1, Math.floor(cpus().length * 0.75)));
|
|
21
|
+
});
|
|
22
|
+
it("should calculate memory per worker", () => {
|
|
23
|
+
const result = calculateResourcesSync(0.75);
|
|
24
|
+
assert.ok(result.maxMemoryMb > 0);
|
|
25
|
+
assert.ok(Number.isInteger(result.maxMemoryMb));
|
|
26
|
+
// Memory should be reasonable (> 100MB)
|
|
27
|
+
assert.ok(result.maxMemoryMb > 100);
|
|
28
|
+
});
|
|
29
|
+
it("should calculate I/O concurrency estimate", () => {
|
|
30
|
+
const result = calculateResourcesSync(0.75);
|
|
31
|
+
assert.ok(result.maxConcurrentIo > 0);
|
|
32
|
+
assert.ok(Number.isInteger(result.maxConcurrentIo));
|
|
33
|
+
// Default estimate should be 75% of 100
|
|
34
|
+
assert.strictEqual(result.maxConcurrentIo, Math.floor(100 * 0.75));
|
|
35
|
+
});
|
|
36
|
+
it("should return 1 worker minimum for very low CPU counts", () => {
|
|
37
|
+
// Create a mock result by testing with actual hardware
|
|
38
|
+
const result = calculateResourcesSync(0.75);
|
|
39
|
+
// Should always return at least 1 worker
|
|
40
|
+
assert.ok(result.maxWorkers >= 1);
|
|
41
|
+
});
|
|
42
|
+
it("should use 50% reserve when specified", () => {
|
|
43
|
+
const result75 = calculateResourcesSync(0.75);
|
|
44
|
+
const result50 = calculateResourcesSync(0.5);
|
|
45
|
+
assert.ok(result50.maxWorkers <= result75.maxWorkers);
|
|
46
|
+
assert.ok(result50.maxMemoryMb > 0);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe("calculateResources", () => {
|
|
50
|
+
it("should match synchronous results when disk measurement is disabled", async () => {
|
|
51
|
+
const syncResult = calculateResourcesSync(0.75);
|
|
52
|
+
const asyncResult = await calculateResources(0.75, { measureDisk: false });
|
|
53
|
+
assert.strictEqual(asyncResult.maxWorkers, syncResult.maxWorkers);
|
|
54
|
+
assert.strictEqual(asyncResult.maxMemoryMb, syncResult.maxMemoryMb);
|
|
55
|
+
assert.strictEqual(asyncResult.maxConcurrentIo, syncResult.maxConcurrentIo);
|
|
56
|
+
});
|
|
57
|
+
it("should perform disk I/O measurement when enabled", async () => {
|
|
58
|
+
const result = await calculateResources(0.75, { measureDisk: true });
|
|
59
|
+
assert.ok(result.maxWorkers >= 1);
|
|
60
|
+
assert.ok(result.maxMemoryMb > 0);
|
|
61
|
+
// maxConcurrentIo should be based on measurement or estimate
|
|
62
|
+
assert.ok(result.maxConcurrentIo > 0);
|
|
63
|
+
});
|
|
64
|
+
it("should cache disk measurement result", async () => {
|
|
65
|
+
// First call should measure
|
|
66
|
+
const result1 = await calculateResources(0.75, { measureDisk: true });
|
|
67
|
+
// Second call should use cached value
|
|
68
|
+
const result2 = await calculateResources(0.75, { measureDisk: true });
|
|
69
|
+
// Results should be identical (cached)
|
|
70
|
+
assert.deepStrictEqual(result1, result2);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe("ResourceLimits type", () => {
|
|
74
|
+
it("should have correct structure", () => {
|
|
75
|
+
const result = calculateResourcesSync();
|
|
76
|
+
assert.ok(typeof result.maxWorkers === "number");
|
|
77
|
+
assert.ok(typeof result.maxMemoryMb === "number");
|
|
78
|
+
assert.ok(typeof result.maxConcurrentIo === "number");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("edge cases", () => {
|
|
82
|
+
it("should handle 0% reserve (100% usage)", () => {
|
|
83
|
+
const result = calculateResourcesSync(0);
|
|
84
|
+
assert.strictEqual(result.maxWorkers, 0);
|
|
85
|
+
assert.strictEqual(result.maxMemoryMb, 0);
|
|
86
|
+
assert.strictEqual(result.maxConcurrentIo, 0);
|
|
87
|
+
});
|
|
88
|
+
it("should handle 100% reserve (all resources)", () => {
|
|
89
|
+
const result = calculateResourcesSync(1);
|
|
90
|
+
assert.ok(result.maxWorkers >= 1);
|
|
91
|
+
assert.ok(result.maxMemoryMb > 0);
|
|
92
|
+
assert.ok(result.maxConcurrentIo > 0);
|
|
93
|
+
});
|
|
94
|
+
it("should handle invalid reserve values gracefully", () => {
|
|
95
|
+
// Negative reserve should be treated as 0
|
|
96
|
+
const result1 = calculateResourcesSync(-0.5);
|
|
97
|
+
assert.strictEqual(result1.maxWorkers, 0);
|
|
98
|
+
// Reserve > 1 should be clamped
|
|
99
|
+
const result2 = calculateResourcesSync(1.5);
|
|
100
|
+
assert.ok(result2.maxWorkers >= 1);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=resource-calculator.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-calculator.unit.test.js","sourceRoot":"","sources":["../../../src/executor/__tests__/resource-calculator.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-threads-executor.unit.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/worker-threads-executor.unit.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for WorkerThreadsExecutor
|
|
3
|
+
*
|
|
4
|
+
* Tests worker thread spawning, message passing, batch distribution,
|
|
5
|
+
* and the new DI-enabled WorkerThreadsExecutor class.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, beforeEach } from "node:test";
|
|
8
|
+
import { strict as assert } from "node:assert";
|
|
9
|
+
import { WorkerThreadsExecutor, ConsoleLogger, } from "../worker-threads-executor.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create a minimal ExecutorConfig for testing.
|
|
12
|
+
*/
|
|
13
|
+
function createTestConfig(timeoutMs = 0) {
|
|
14
|
+
return {
|
|
15
|
+
continueOnError: false,
|
|
16
|
+
repetitions: 1,
|
|
17
|
+
seedBase: 42,
|
|
18
|
+
timeoutMs,
|
|
19
|
+
collectProvenance: false,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a minimal PlannedRun for testing.
|
|
24
|
+
*/
|
|
25
|
+
function createTestRun(override) {
|
|
26
|
+
return {
|
|
27
|
+
sutId: "test-sut",
|
|
28
|
+
caseId: "test-case",
|
|
29
|
+
repetition: 0,
|
|
30
|
+
seed: 42,
|
|
31
|
+
...override,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Mock logger for testing.
|
|
36
|
+
*/
|
|
37
|
+
class MockLogger {
|
|
38
|
+
logs = [];
|
|
39
|
+
log(message) {
|
|
40
|
+
this.logs.push(message);
|
|
41
|
+
}
|
|
42
|
+
debug(message) {
|
|
43
|
+
this.logs.push(message);
|
|
44
|
+
}
|
|
45
|
+
info(message) {
|
|
46
|
+
this.logs.push(message);
|
|
47
|
+
}
|
|
48
|
+
warn(message) {
|
|
49
|
+
this.logs.push(message);
|
|
50
|
+
}
|
|
51
|
+
clear() {
|
|
52
|
+
this.logs = [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Mock worker for testing.
|
|
57
|
+
*/
|
|
58
|
+
class MockWorker {
|
|
59
|
+
messageListener = null;
|
|
60
|
+
errorListener = null;
|
|
61
|
+
postMessage(_message) {
|
|
62
|
+
// Simulate async response
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
if (this.messageListener) {
|
|
65
|
+
const response = {
|
|
66
|
+
type: "done",
|
|
67
|
+
results: [],
|
|
68
|
+
errors: [],
|
|
69
|
+
};
|
|
70
|
+
this.messageListener(response);
|
|
71
|
+
}
|
|
72
|
+
}, 10);
|
|
73
|
+
}
|
|
74
|
+
on(event, listener) {
|
|
75
|
+
if (event === "message") {
|
|
76
|
+
this.messageListener = listener;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this.errorListener = listener;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async terminate() {
|
|
83
|
+
// Mock terminate - return exit code
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Mock worker factory for testing.
|
|
89
|
+
*/
|
|
90
|
+
class MockWorkerFactory {
|
|
91
|
+
createdWorkers = [];
|
|
92
|
+
create(_workerPath) {
|
|
93
|
+
const worker = new MockWorker();
|
|
94
|
+
this.createdWorkers.push(worker);
|
|
95
|
+
return worker;
|
|
96
|
+
}
|
|
97
|
+
clear() {
|
|
98
|
+
this.createdWorkers = [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Mock worker entry path for testing.
|
|
103
|
+
*/
|
|
104
|
+
class MockWorkerEntryPath {
|
|
105
|
+
getWorkerEntryPath() {
|
|
106
|
+
return "/mock/worker-entry.js";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
describe("WorkerThreadsExecutor", () => {
|
|
110
|
+
let mockLogger;
|
|
111
|
+
let mockWorkerFactory;
|
|
112
|
+
let mockWorkerEntryPath;
|
|
113
|
+
beforeEach(() => {
|
|
114
|
+
mockLogger = new MockLogger();
|
|
115
|
+
mockWorkerFactory = new MockWorkerFactory();
|
|
116
|
+
mockWorkerEntryPath = new MockWorkerEntryPath();
|
|
117
|
+
});
|
|
118
|
+
describe("constructor", () => {
|
|
119
|
+
it("should use default dependencies when none provided", () => {
|
|
120
|
+
const executor = new WorkerThreadsExecutor();
|
|
121
|
+
assert.ok(executor);
|
|
122
|
+
});
|
|
123
|
+
it("should use provided dependencies", () => {
|
|
124
|
+
const executor = new WorkerThreadsExecutor({
|
|
125
|
+
logger: mockLogger,
|
|
126
|
+
workerFactory: mockWorkerFactory,
|
|
127
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
128
|
+
});
|
|
129
|
+
assert.ok(executor);
|
|
130
|
+
});
|
|
131
|
+
it("should use partial dependencies", () => {
|
|
132
|
+
const executor = new WorkerThreadsExecutor({
|
|
133
|
+
logger: mockLogger,
|
|
134
|
+
});
|
|
135
|
+
assert.ok(executor);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe("_createBatches", () => {
|
|
139
|
+
it("should distribute runs evenly across workers", () => {
|
|
140
|
+
const executor = new WorkerThreadsExecutor({
|
|
141
|
+
logger: mockLogger,
|
|
142
|
+
workerFactory: mockWorkerFactory,
|
|
143
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
144
|
+
});
|
|
145
|
+
const runs = [
|
|
146
|
+
createTestRun({ runId: "run1", caseId: "case1" }),
|
|
147
|
+
createTestRun({ runId: "run2", caseId: "case2" }),
|
|
148
|
+
createTestRun({ runId: "run3", caseId: "case3" }),
|
|
149
|
+
createTestRun({ runId: "run4", caseId: "case4" }),
|
|
150
|
+
];
|
|
151
|
+
// Access private method via testing
|
|
152
|
+
const batches = executor._createBatches(runs, 2);
|
|
153
|
+
assert.strictEqual(batches.length, 2);
|
|
154
|
+
assert.strictEqual(batches[0].runIds.length, 2);
|
|
155
|
+
assert.strictEqual(batches[1].runIds.length, 2);
|
|
156
|
+
assert.deepStrictEqual(batches[0].runIds, ["run1", "run2"]);
|
|
157
|
+
assert.deepStrictEqual(batches[1].runIds, ["run3", "run4"]);
|
|
158
|
+
});
|
|
159
|
+
it("should handle uneven distribution", () => {
|
|
160
|
+
const executor = new WorkerThreadsExecutor({
|
|
161
|
+
logger: mockLogger,
|
|
162
|
+
workerFactory: mockWorkerFactory,
|
|
163
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
164
|
+
});
|
|
165
|
+
const runs = [
|
|
166
|
+
createTestRun({ runId: "run1", caseId: "case1" }),
|
|
167
|
+
createTestRun({ runId: "run2", caseId: "case2" }),
|
|
168
|
+
createTestRun({ runId: "run3", caseId: "case3" }),
|
|
169
|
+
];
|
|
170
|
+
const batches = executor._createBatches(runs, 2);
|
|
171
|
+
assert.strictEqual(batches.length, 2);
|
|
172
|
+
assert.strictEqual(batches[0].runIds.length, 2);
|
|
173
|
+
assert.strictEqual(batches[1].runIds.length, 1);
|
|
174
|
+
});
|
|
175
|
+
it("should handle more workers than runs", () => {
|
|
176
|
+
const executor = new WorkerThreadsExecutor({
|
|
177
|
+
logger: mockLogger,
|
|
178
|
+
workerFactory: mockWorkerFactory,
|
|
179
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
180
|
+
});
|
|
181
|
+
const runs = [createTestRun({ runId: "run1", caseId: "case1" })];
|
|
182
|
+
const batches = executor._createBatches(runs, 4);
|
|
183
|
+
assert.strictEqual(batches.length, 1);
|
|
184
|
+
assert.strictEqual(batches[0].runIds.length, 1);
|
|
185
|
+
});
|
|
186
|
+
it("should handle empty runs", () => {
|
|
187
|
+
const executor = new WorkerThreadsExecutor({
|
|
188
|
+
logger: mockLogger,
|
|
189
|
+
workerFactory: mockWorkerFactory,
|
|
190
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
191
|
+
});
|
|
192
|
+
const runs = [];
|
|
193
|
+
const batches = executor._createBatches(runs, 2);
|
|
194
|
+
assert.strictEqual(batches.length, 0);
|
|
195
|
+
});
|
|
196
|
+
it("should create proper batch metadata", () => {
|
|
197
|
+
const executor = new WorkerThreadsExecutor({
|
|
198
|
+
logger: mockLogger,
|
|
199
|
+
workerFactory: mockWorkerFactory,
|
|
200
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
201
|
+
});
|
|
202
|
+
const runs = [
|
|
203
|
+
createTestRun({ runId: "run1", caseId: "case1" }),
|
|
204
|
+
createTestRun({ runId: "run2", caseId: "case2" }),
|
|
205
|
+
];
|
|
206
|
+
const batches = executor._createBatches(runs, 2);
|
|
207
|
+
assert.strictEqual(batches[0].index, 0);
|
|
208
|
+
assert.strictEqual(batches[0].firstRunId, "run1");
|
|
209
|
+
assert.strictEqual(batches[0].lastRunId, "run1");
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe("WorkerThreadsExecutorOptions", () => {
|
|
213
|
+
describe("defaults", () => {
|
|
214
|
+
it("should use default workers when not specified", () => {
|
|
215
|
+
const options = {};
|
|
216
|
+
const executor = new WorkerThreadsExecutor(options);
|
|
217
|
+
assert.ok(executor);
|
|
218
|
+
});
|
|
219
|
+
it("should use custom workers when specified", () => {
|
|
220
|
+
const options = { workers: 4 };
|
|
221
|
+
const executor = new WorkerThreadsExecutor(options);
|
|
222
|
+
assert.ok(executor);
|
|
223
|
+
});
|
|
224
|
+
it("should accept resource limits", () => {
|
|
225
|
+
const options = {
|
|
226
|
+
workers: 2,
|
|
227
|
+
maxMemoryMb: 2048,
|
|
228
|
+
maxConcurrentIo: 50,
|
|
229
|
+
};
|
|
230
|
+
const executor = new WorkerThreadsExecutor(options);
|
|
231
|
+
assert.ok(executor);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
describe("ConsoleLogger", () => {
|
|
236
|
+
it("should provide console-based logging", () => {
|
|
237
|
+
const logger = new ConsoleLogger();
|
|
238
|
+
// These should not throw
|
|
239
|
+
logger.log("test log");
|
|
240
|
+
logger.debug("test debug");
|
|
241
|
+
logger.info("test info");
|
|
242
|
+
logger.warn("test warn");
|
|
243
|
+
assert.ok(true);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
describe("WorkerEntryPath", () => {
|
|
247
|
+
it("should return path to worker entry", () => {
|
|
248
|
+
const pathResolver = new MockWorkerEntryPath();
|
|
249
|
+
const path = pathResolver.getWorkerEntryPath();
|
|
250
|
+
assert.strictEqual(path, "/mock/worker-entry.js");
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
describe("WorkerThreadsExecutor integration", () => {
|
|
255
|
+
it("should spawn workers for each batch", async () => {
|
|
256
|
+
const mockLogger = new MockLogger();
|
|
257
|
+
const mockWorkerFactory = new MockWorkerFactory();
|
|
258
|
+
const mockWorkerEntryPath = new MockWorkerEntryPath();
|
|
259
|
+
const executor = new WorkerThreadsExecutor({
|
|
260
|
+
logger: mockLogger,
|
|
261
|
+
workerFactory: mockWorkerFactory,
|
|
262
|
+
workerEntryPath: mockWorkerEntryPath,
|
|
263
|
+
});
|
|
264
|
+
const runs = [
|
|
265
|
+
createTestRun({ runId: "run1", caseId: "case1" }),
|
|
266
|
+
createTestRun({ runId: "run2", caseId: "case2" }),
|
|
267
|
+
];
|
|
268
|
+
const config = createTestConfig(0);
|
|
269
|
+
const result = await executor.execute(runs, [], [], config, { workers: 2 });
|
|
270
|
+
// Should have spawned 2 workers
|
|
271
|
+
assert.strictEqual(mockWorkerFactory.createdWorkers.length, 2);
|
|
272
|
+
assert.strictEqual(result.results.length, 0);
|
|
273
|
+
assert.strictEqual(result.errors.length, 0);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
//# sourceMappingURL=worker-threads-executor.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-threads-executor.unit.test.js","sourceRoot":"","sources":["../../../src/executor/__tests__/worker-threads-executor.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary SUT Wrapper
|
|
3
|
+
*
|
|
4
|
+
* Enables arbitrary binaries (Python scripts, compiled executables, etc.)
|
|
5
|
+
* to be used as System Under Test in ppef experiments.
|
|
6
|
+
*
|
|
7
|
+
* The BinarySut class implements the SUT interface and bridges to external
|
|
8
|
+
* processes via stdin/stdout IPC, with proper timeout handling and error isolation.
|
|
9
|
+
*
|
|
10
|
+
* Supported I/O formats:
|
|
11
|
+
* - json: Structured data serialization (default)
|
|
12
|
+
* - raw: Plain text passthrough
|
|
13
|
+
* - lines: Line-separated values
|
|
14
|
+
*/
|
|
15
|
+
import type { SUT } from "../types/sut.js";
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for binary SUT execution.
|
|
18
|
+
*/
|
|
19
|
+
export interface BinarySutConfig {
|
|
20
|
+
/** Command to execute (e.g., "python3", "./my-script", "node") */
|
|
21
|
+
command: string;
|
|
22
|
+
/** Arguments to pass to the command */
|
|
23
|
+
args?: string[];
|
|
24
|
+
/** Working directory (defaults to current directory) */
|
|
25
|
+
cwd?: string;
|
|
26
|
+
/** Environment variables (merged with process.env) */
|
|
27
|
+
env?: Record<string, string>;
|
|
28
|
+
/** How to serialize inputs to stdin */
|
|
29
|
+
inputFormat?: "json" | "raw" | "lines";
|
|
30
|
+
/** How to deserialize stdout */
|
|
31
|
+
outputFormat?: "json" | "raw" | "lines";
|
|
32
|
+
/** Timeout per run in milliseconds (0 = no timeout, default: 30000) */
|
|
33
|
+
timeout?: number;
|
|
34
|
+
/** Exit code that indicates success (default: 0) */
|
|
35
|
+
successExitCode?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Binary SUT wrapper implementing the SUT interface.
|
|
39
|
+
*
|
|
40
|
+
* Spawns external processes, communicates via stdin/stdout,
|
|
41
|
+
* and provides timeout handling and error isolation.
|
|
42
|
+
*/
|
|
43
|
+
export declare class BinarySut implements SUT<unknown, unknown> {
|
|
44
|
+
readonly id: string;
|
|
45
|
+
readonly config: Readonly<BinarySutConfig>;
|
|
46
|
+
constructor(id: string, config: BinarySutConfig);
|
|
47
|
+
/**
|
|
48
|
+
* Execute the binary with the given inputs.
|
|
49
|
+
*
|
|
50
|
+
* @param inputs - Algorithm inputs (will be serialized based on inputFormat)
|
|
51
|
+
* @returns Promise resolving to deserialized output
|
|
52
|
+
* @throws Error on timeout, non-zero exit code, or spawn failure
|
|
53
|
+
*/
|
|
54
|
+
run(inputs: unknown): Promise<unknown>;
|
|
55
|
+
/**
|
|
56
|
+
* Serialize inputs to stdin format.
|
|
57
|
+
*/
|
|
58
|
+
private _serializeInputs;
|
|
59
|
+
/**
|
|
60
|
+
* Collect stdout/stderr from process with timeout handling.
|
|
61
|
+
*/
|
|
62
|
+
private _collectOutput;
|
|
63
|
+
/**
|
|
64
|
+
* Deserialize stdout to output format.
|
|
65
|
+
*/
|
|
66
|
+
private _deserializeOutput;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Options for creating a binary SUT factory.
|
|
70
|
+
*/
|
|
71
|
+
export interface CreateBinarySutOptions extends BinarySutConfig {
|
|
72
|
+
/** SUT ID (defaults to command name) */
|
|
73
|
+
id?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* SUT factory type for binary SUTs.
|
|
77
|
+
*
|
|
78
|
+
* Matches the expected SutFactory signature from the SUT interface.
|
|
79
|
+
*/
|
|
80
|
+
export type BinarySutFactory = (config?: Record<string, unknown>) => SUT<unknown, unknown>;
|
|
81
|
+
/**
|
|
82
|
+
* Create a binary SUT factory function.
|
|
83
|
+
*
|
|
84
|
+
* The returned factory matches the SutFactory signature and can be used
|
|
85
|
+
* interchangeably with other SUT factories in the ppef framework.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* import { createBinarySut } from "ppef";
|
|
90
|
+
*
|
|
91
|
+
* const pythonSutFactory = createBinarySut({
|
|
92
|
+
* id: "python-classifier",
|
|
93
|
+
* command: "python3",
|
|
94
|
+
* args: ["classifier.py"],
|
|
95
|
+
* inputFormat: "json",
|
|
96
|
+
* outputFormat: "json",
|
|
97
|
+
* timeout: 30000,
|
|
98
|
+
* });
|
|
99
|
+
*
|
|
100
|
+
* const sut = pythonSutFactory({ modelPath: "./model.pkl" });
|
|
101
|
+
* const result = await sut.run({ features: [1, 2, 3] });
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare function createBinarySut(options: CreateBinarySutOptions): BinarySutFactory;
|
|
105
|
+
//# sourceMappingURL=binary-sut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-sut.d.ts","sourceRoot":"","sources":["../../src/executor/binary-sut.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAEhB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;IAEvC,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;IAExC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAWD;;;;;GAKG;AACH,qBAAa,SAAU,YAAW,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;gBAE/B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAU/C;;;;;;OAMG;IACG,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB5C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;OAEG;YACW,cAAc;IAyC5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAoB1B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC9D,wCAAwC;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAE3F;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,gBAAgB,CAiBjF"}
|