ppef 1.0.0 → 1.0.1

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.
Files changed (199) hide show
  1. package/README.md +172 -0
  2. package/dist/__tests__/framework-pipeline.integration.test.d.ts +7 -0
  3. package/dist/__tests__/framework-pipeline.integration.test.d.ts.map +1 -0
  4. package/dist/__tests__/framework-pipeline.integration.test.js +413 -0
  5. package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -0
  6. package/dist/__tests__/registry-executor.integration.test.d.ts +5 -0
  7. package/dist/__tests__/registry-executor.integration.test.d.ts.map +1 -0
  8. package/dist/__tests__/registry-executor.integration.test.js +349 -0
  9. package/dist/__tests__/registry-executor.integration.test.js.map +1 -0
  10. package/dist/__tests__/test-helpers.d.ts +94 -0
  11. package/dist/__tests__/test-helpers.d.ts.map +1 -0
  12. package/dist/__tests__/test-helpers.js +271 -0
  13. package/dist/__tests__/test-helpers.js.map +1 -0
  14. package/dist/aggregation/aggregators.d.ts +54 -0
  15. package/dist/aggregation/aggregators.d.ts.map +1 -0
  16. package/dist/aggregation/aggregators.js +228 -0
  17. package/dist/aggregation/aggregators.js.map +1 -0
  18. package/dist/aggregation/index.d.ts +8 -0
  19. package/dist/aggregation/index.d.ts.map +1 -0
  20. package/dist/aggregation/index.js +8 -0
  21. package/dist/aggregation/index.js.map +1 -0
  22. package/dist/aggregation/pipeline.d.ts +38 -0
  23. package/dist/aggregation/pipeline.d.ts.map +1 -0
  24. package/dist/aggregation/pipeline.js +198 -0
  25. package/dist/aggregation/pipeline.js.map +1 -0
  26. package/dist/claims/evaluator.d.ts +33 -0
  27. package/dist/claims/evaluator.d.ts.map +1 -0
  28. package/dist/claims/evaluator.js +174 -0
  29. package/dist/claims/evaluator.js.map +1 -0
  30. package/dist/claims/index.d.ts +7 -0
  31. package/dist/claims/index.d.ts.map +1 -0
  32. package/dist/claims/index.js +7 -0
  33. package/dist/claims/index.js.map +1 -0
  34. package/dist/collector/index.d.ts +8 -0
  35. package/dist/collector/index.d.ts.map +1 -0
  36. package/dist/collector/index.js +8 -0
  37. package/dist/collector/index.js.map +1 -0
  38. package/dist/collector/result-collector.d.ts +159 -0
  39. package/dist/collector/result-collector.d.ts.map +1 -0
  40. package/dist/collector/result-collector.js +213 -0
  41. package/dist/collector/result-collector.js.map +1 -0
  42. package/dist/collector/schema.d.ts +34 -0
  43. package/dist/collector/schema.d.ts.map +1 -0
  44. package/dist/collector/schema.js +145 -0
  45. package/dist/collector/schema.js.map +1 -0
  46. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts +10 -0
  47. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts.map +1 -0
  48. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js +122 -0
  49. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js.map +1 -0
  50. package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts +7 -0
  51. package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts.map +1 -0
  52. package/dist/executor/__tests__/checkpoint-manager.integration.test.js +330 -0
  53. package/dist/executor/__tests__/checkpoint-manager.integration.test.js.map +1 -0
  54. package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts +7 -0
  55. package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts.map +1 -0
  56. package/dist/executor/__tests__/checkpoint-manager.unit.test.js +449 -0
  57. package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -0
  58. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +11 -0
  59. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -0
  60. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +224 -0
  61. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -0
  62. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts +8 -0
  63. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts.map +1 -0
  64. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js +164 -0
  65. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js.map +1 -0
  66. package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts +7 -0
  67. package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts.map +1 -0
  68. package/dist/executor/__tests__/checkpoint-storage.unit.test.js +386 -0
  69. package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -0
  70. package/dist/executor/__tests__/executor.unit.test.d.ts +7 -0
  71. package/dist/executor/__tests__/executor.unit.test.d.ts.map +1 -0
  72. package/dist/executor/__tests__/executor.unit.test.js +134 -0
  73. package/dist/executor/__tests__/executor.unit.test.js.map +1 -0
  74. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts +12 -0
  75. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts.map +1 -0
  76. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js +196 -0
  77. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js.map +1 -0
  78. package/dist/executor/__tests__/parallel-executor.integration.test.d.ts +7 -0
  79. package/dist/executor/__tests__/parallel-executor.integration.test.d.ts.map +1 -0
  80. package/dist/executor/__tests__/parallel-executor.integration.test.js +249 -0
  81. package/dist/executor/__tests__/parallel-executor.integration.test.js.map +1 -0
  82. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +7 -0
  83. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -0
  84. package/dist/executor/__tests__/parallel-executor.unit.test.js +203 -0
  85. package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -0
  86. package/dist/executor/checkpoint-manager.d.ts +231 -0
  87. package/dist/executor/checkpoint-manager.d.ts.map +1 -0
  88. package/dist/executor/checkpoint-manager.js +395 -0
  89. package/dist/executor/checkpoint-manager.js.map +1 -0
  90. package/dist/executor/checkpoint-storage.d.ts +230 -0
  91. package/dist/executor/checkpoint-storage.d.ts.map +1 -0
  92. package/dist/executor/checkpoint-storage.js +370 -0
  93. package/dist/executor/checkpoint-storage.js.map +1 -0
  94. package/dist/executor/checkpoint-types.d.ts +48 -0
  95. package/dist/executor/checkpoint-types.d.ts.map +1 -0
  96. package/dist/executor/checkpoint-types.js +8 -0
  97. package/dist/executor/checkpoint-types.js.map +1 -0
  98. package/dist/executor/executor.d.ts +164 -0
  99. package/dist/executor/executor.d.ts.map +1 -0
  100. package/dist/executor/executor.js +408 -0
  101. package/dist/executor/executor.js.map +1 -0
  102. package/dist/executor/index.d.ts +11 -0
  103. package/dist/executor/index.d.ts.map +1 -0
  104. package/dist/executor/index.js +11 -0
  105. package/dist/executor/index.js.map +1 -0
  106. package/dist/executor/memory-monitor.d.ts +115 -0
  107. package/dist/executor/memory-monitor.d.ts.map +1 -0
  108. package/dist/executor/memory-monitor.js +168 -0
  109. package/dist/executor/memory-monitor.js.map +1 -0
  110. package/dist/executor/parallel-executor.d.ts +53 -0
  111. package/dist/executor/parallel-executor.d.ts.map +1 -0
  112. package/dist/executor/parallel-executor.js +194 -0
  113. package/dist/executor/parallel-executor.js.map +1 -0
  114. package/dist/executor/run-id.d.ts +71 -0
  115. package/dist/executor/run-id.d.ts.map +1 -0
  116. package/dist/executor/run-id.js +67 -0
  117. package/dist/executor/run-id.js.map +1 -0
  118. package/dist/executor/worker-entry.d.ts +8 -0
  119. package/dist/executor/worker-entry.d.ts.map +1 -0
  120. package/dist/executor/worker-entry.js +67 -0
  121. package/dist/executor/worker-entry.js.map +1 -0
  122. package/dist/index.cjs +11 -0
  123. package/dist/index.d.ts +15 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +24 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/registry/case-registry.d.ts +113 -0
  128. package/dist/registry/case-registry.d.ts.map +1 -0
  129. package/dist/registry/case-registry.js +160 -0
  130. package/dist/registry/case-registry.js.map +1 -0
  131. package/dist/registry/index.d.ts +8 -0
  132. package/dist/registry/index.d.ts.map +1 -0
  133. package/dist/registry/index.js +8 -0
  134. package/dist/registry/index.js.map +1 -0
  135. package/dist/registry/sut-registry.d.ts +96 -0
  136. package/dist/registry/sut-registry.d.ts.map +1 -0
  137. package/dist/registry/sut-registry.js +126 -0
  138. package/dist/registry/sut-registry.js.map +1 -0
  139. package/dist/renderers/index.d.ts +10 -0
  140. package/dist/renderers/index.d.ts.map +1 -0
  141. package/dist/renderers/index.js +9 -0
  142. package/dist/renderers/index.js.map +1 -0
  143. package/dist/renderers/latex-renderer.d.ts +84 -0
  144. package/dist/renderers/latex-renderer.d.ts.map +1 -0
  145. package/dist/renderers/latex-renderer.js +208 -0
  146. package/dist/renderers/latex-renderer.js.map +1 -0
  147. package/dist/renderers/types.d.ts +106 -0
  148. package/dist/renderers/types.d.ts.map +1 -0
  149. package/dist/renderers/types.js +23 -0
  150. package/dist/renderers/types.js.map +1 -0
  151. package/dist/robustness/analyzer.d.ts +61 -0
  152. package/dist/robustness/analyzer.d.ts.map +1 -0
  153. package/dist/robustness/analyzer.js +191 -0
  154. package/dist/robustness/analyzer.js.map +1 -0
  155. package/dist/robustness/index.d.ts +8 -0
  156. package/dist/robustness/index.d.ts.map +1 -0
  157. package/dist/robustness/index.js +8 -0
  158. package/dist/robustness/index.js.map +1 -0
  159. package/dist/robustness/perturbations.d.ts +46 -0
  160. package/dist/robustness/perturbations.d.ts.map +1 -0
  161. package/dist/robustness/perturbations.js +184 -0
  162. package/dist/robustness/perturbations.js.map +1 -0
  163. package/dist/statistical/index.d.ts +8 -0
  164. package/dist/statistical/index.d.ts.map +1 -0
  165. package/dist/statistical/index.js +8 -0
  166. package/dist/statistical/index.js.map +1 -0
  167. package/dist/statistical/mann-whitney-u.d.ts +62 -0
  168. package/dist/statistical/mann-whitney-u.d.ts.map +1 -0
  169. package/dist/statistical/mann-whitney-u.js +127 -0
  170. package/dist/statistical/mann-whitney-u.js.map +1 -0
  171. package/dist/types/aggregate.d.ts +124 -0
  172. package/dist/types/aggregate.d.ts.map +1 -0
  173. package/dist/types/aggregate.js +9 -0
  174. package/dist/types/aggregate.js.map +1 -0
  175. package/dist/types/case.d.ts +105 -0
  176. package/dist/types/case.d.ts.map +1 -0
  177. package/dist/types/case.js +10 -0
  178. package/dist/types/case.js.map +1 -0
  179. package/dist/types/claims.d.ts +122 -0
  180. package/dist/types/claims.d.ts.map +1 -0
  181. package/dist/types/claims.js +14 -0
  182. package/dist/types/claims.js.map +1 -0
  183. package/dist/types/index.d.ts +12 -0
  184. package/dist/types/index.d.ts.map +1 -0
  185. package/dist/types/index.js +7 -0
  186. package/dist/types/index.js.map +1 -0
  187. package/dist/types/perturbation.d.ts +105 -0
  188. package/dist/types/perturbation.d.ts.map +1 -0
  189. package/dist/types/perturbation.js +9 -0
  190. package/dist/types/perturbation.js.map +1 -0
  191. package/dist/types/result.d.ts +150 -0
  192. package/dist/types/result.d.ts.map +1 -0
  193. package/dist/types/result.js +12 -0
  194. package/dist/types/result.js.map +1 -0
  195. package/dist/types/sut.d.ts +128 -0
  196. package/dist/types/sut.d.ts.map +1 -0
  197. package/dist/types/sut.js +12 -0
  198. package/dist/types/sut.js.map +1 -0
  199. package/package.json +283 -7
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Integration Tests for Parallel Checkpoint Merge Bug
3
+ *
4
+ * Simulates the actual parallel execution scenario that caused data loss:
5
+ * 1. Main process has 123 completed runs
6
+ * 2. Workers spawn and create sharded checkpoints
7
+ * 3. Workers complete additional runs
8
+ * 4. mergeShards() is called
9
+ * 5. Main checkpoint should have all runs, but gets overwritten
10
+ */
11
+ import { randomBytes } from "node:crypto";
12
+ import { mkdirSync, readFileSync, rmSync } from "node:fs";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { afterEach, beforeEach, describe, it } from "node:test";
16
+ import * as assert from "node:assert/strict";
17
+ import { CheckpointManager } from "../checkpoint-manager.js";
18
+ import { FileStorage } from "../checkpoint-storage.js";
19
+ describe("Parallel Checkpoint Merge Integration Tests", () => {
20
+ let testDir;
21
+ let mainCheckpoint;
22
+ let mainPath;
23
+ beforeEach(() => {
24
+ testDir = join(tmpdir(), `parallel-merge-test-${randomBytes(8).toString("hex")}`);
25
+ mkdirSync(testDir, { recursive: true });
26
+ mainPath = join(testDir, "checkpoint.json");
27
+ mainCheckpoint = new CheckpointManager({ storage: new FileStorage(mainPath) });
28
+ });
29
+ /**
30
+ * Helper to read checkpoint data directly from file
31
+ * @param path
32
+ */
33
+ const readCheckpointFile = (path) => {
34
+ const data = JSON.parse(readFileSync(path, "utf-8"));
35
+ return data;
36
+ };
37
+ afterEach(() => {
38
+ rmSync(testDir, { recursive: true, force: true });
39
+ });
40
+ it("integration-1: simulates real data loss scenario - 123 main + 2 shards = only 3 remain", async () => {
41
+ console.log("\n=== Simulating Real Data Loss Scenario ===\n");
42
+ // Step 1: Populate main checkpoint with 123 runs (simulating completed experiments)
43
+ console.log("Step 1: Creating main checkpoint with 123 runs...");
44
+ const mainRuns = createMockRunBatch(123);
45
+ for (const run of mainRuns) {
46
+ await mainCheckpoint.saveIncremental(run);
47
+ }
48
+ console.log(" Main checkpoint created:", readCheckpointFile(mainPath).completedRunIds.length, "runs");
49
+ // Step 2: Simulate workers creating sharded checkpoints
50
+ console.log("\nStep 2: Workers create sharded checkpoints...");
51
+ const shard1Path = join(testDir, "checkpoint-worker-01.json");
52
+ const shard1Storage = new FileStorage(shard1Path);
53
+ const shard1Runs = [createMockResult("worker1-run-001", "sut-1", "case-100")];
54
+ await shard1Storage.save({
55
+ configHash: "test-hash",
56
+ createdAt: new Date().toISOString(),
57
+ updatedAt: new Date().toISOString(),
58
+ completedRunIds: ["worker1-run-001"],
59
+ results: { "worker1-run-001": shard1Runs[0] },
60
+ totalPlanned: 132,
61
+ });
62
+ console.log(" Worker 1 shard: 1 run");
63
+ const shard2Path = join(testDir, "checkpoint-worker-02.json");
64
+ const shard2Storage = new FileStorage(shard2Path);
65
+ const shard2Runs = [createMockResult("worker2-run-001", "sut-2", "case-200")];
66
+ await shard2Storage.save({
67
+ configHash: "test-hash",
68
+ createdAt: new Date().toISOString(),
69
+ updatedAt: new Date().toISOString(),
70
+ completedRunIds: ["worker2-run-001"],
71
+ results: { "worker2-run-001": shard2Runs[0] },
72
+ totalPlanned: 132,
73
+ });
74
+ console.log(" Worker 2 shard: 1 run");
75
+ // Step 3: Main process loads checkpoint and calls mergeShards
76
+ console.log("\nStep 3: Main process merges shards...");
77
+ await mainCheckpoint.load();
78
+ const beforeMerge = readCheckpointFile(mainPath);
79
+ console.log(" Before merge: main checkpoint has", beforeMerge.completedRunIds.length, "runs");
80
+ // This is where the bug happens!
81
+ const merged = await mainCheckpoint.mergeShards([shard1Path, shard2Path]);
82
+ const afterMerge = readCheckpointFile(mainPath);
83
+ console.log(" After merge: main checkpoint has", afterMerge.completedRunIds.length, "runs");
84
+ console.log(" Merged data has:", merged.completedRunIds.length, "runs");
85
+ // BUG: We expect 125 runs (123 main + 2 shards), but we only get 2!
86
+ console.log("\n Expected: 125 runs (123 + 2)");
87
+ console.log(" Actual:", afterMerge.completedRunIds.length, "runs");
88
+ console.log(" Data loss:", 123 - afterMerge.completedRunIds.length, "runs!");
89
+ assert.strictEqual(afterMerge.completedRunIds.length, 125);
90
+ });
91
+ it("integration-2: shows mergeShards creates new checkpoint instead of updating", async () => {
92
+ // Populate main checkpoint
93
+ await mainCheckpoint.saveIncremental(createMockResult("main-001", "sut-1", "case-1"));
94
+ await mainCheckpoint.saveIncremental(createMockResult("main-002", "sut-1", "case-2"));
95
+ const mainData = readCheckpointFile(mainPath);
96
+ console.log("Main checkpoint before:", mainData.completedRunIds.length, "runs");
97
+ // Create worker shard
98
+ const shardPath = join(testDir, "checkpoint-worker-00.json");
99
+ const shardStorage = new FileStorage(shardPath);
100
+ await shardStorage.save({
101
+ configHash: "test-hash",
102
+ createdAt: new Date().toISOString(),
103
+ updatedAt: new Date().toISOString(),
104
+ completedRunIds: ["worker-001"],
105
+ results: { "worker-001": createMockResult("worker-001", "sut-2", "case-2") },
106
+ totalPlanned: 132,
107
+ });
108
+ // Reload and merge
109
+ await mainCheckpoint.load();
110
+ const merged = await mainCheckpoint.mergeShards([shardPath]);
111
+ // The merged checkpoint should have both main runs and worker run
112
+ console.log("\nExpected runs: main-001, main-002, worker-001 (3 total)");
113
+ console.log("Actual runs:", merged.completedRunIds);
114
+ // Check if main checkpoint was preserved
115
+ const mainDataAfter = readCheckpointFile(mainPath);
116
+ console.log("Main checkpoint after merge:", mainDataAfter.completedRunIds.length, "runs");
117
+ assert.strictEqual(merged.completedRunIds.length, 3);
118
+ assert.ok(merged.completedRunIds.includes("main-001"));
119
+ assert.ok(merged.completedRunIds.includes("main-002"));
120
+ assert.ok(merged.completedRunIds.includes("worker-001"));
121
+ });
122
+ it("integration-3: demonstrates fix strategy - include main checkpoint in merge", async () => {
123
+ // This test shows what the correct behavior should be
124
+ console.log("\n=== Demonstrating Correct Merge Strategy ===\n");
125
+ // Populate main checkpoint
126
+ await mainCheckpoint.saveIncremental(createMockResult("main-001", "sut-1", "case-1"));
127
+ await mainCheckpoint.saveIncremental(createMockResult("main-002", "sut-1", "case-2"));
128
+ console.log("Main checkpoint: 2 runs");
129
+ // Create worker shard
130
+ const shardPath = join(testDir, "checkpoint-worker-00.json");
131
+ const shardStorage = new FileStorage(shardPath);
132
+ await shardStorage.save({
133
+ configHash: "test-hash",
134
+ createdAt: new Date().toISOString(),
135
+ updatedAt: new Date().toISOString(),
136
+ completedRunIds: ["worker-001"],
137
+ results: { "worker-001": createMockResult("worker-001", "sut-2", "case-2") },
138
+ totalPlanned: 132,
139
+ });
140
+ console.log("Worker shard: 1 run");
141
+ // Load both
142
+ const mainData = readCheckpointFile(mainPath);
143
+ const shardData = await shardStorage.load();
144
+ // Manual merge (correct approach)
145
+ const combinedRuns = new Set([...mainData.completedRunIds, ...shardData.completedRunIds]);
146
+ console.log("\nManual merge result:");
147
+ console.log(" Combined runs:", combinedRuns.size);
148
+ console.log(" Run IDs:", [...combinedRuns]);
149
+ // This is what mergeShards should do!
150
+ assert.strictEqual(combinedRuns.size, 3);
151
+ assert.ok([...combinedRuns].includes("main-001"));
152
+ assert.ok([...combinedRuns].includes("main-002"));
153
+ assert.ok([...combinedRuns].includes("worker-001"));
154
+ });
155
+ });
156
+ /**
157
+ * Create a batch of mock evaluation results
158
+ * @param count
159
+ */
160
+ const createMockRunBatch = (count) => {
161
+ const results = [];
162
+ for (let index = 0; index < count; index++) {
163
+ results.push(createMockResult(`run-${String(index).padStart(3, "0")}`, `sut-${index % 4}`, `case-${index}`));
164
+ }
165
+ return results;
166
+ };
167
+ /**
168
+ * Create a mock evaluation result
169
+ * @param runId
170
+ * @param sut
171
+ * @param caseId
172
+ */
173
+ const createMockResult = (runId, sut, caseId) => ({
174
+ run: {
175
+ runId,
176
+ sut,
177
+ sutRole: "primary",
178
+ sutVersion: "1.0.0",
179
+ caseId,
180
+ caseClass: "test-class",
181
+ seed: 42,
182
+ repetition: 0,
183
+ },
184
+ correctness: {
185
+ expectedExists: false,
186
+ producedOutput: true,
187
+ valid: true,
188
+ matchesExpected: null,
189
+ },
190
+ outputs: { summary: {} },
191
+ metrics: { numeric: { test: 1 } },
192
+ provenance: {
193
+ runtime: { platform: "linux", arch: "x64", nodeVersion: "v22.0.0" },
194
+ },
195
+ });
196
+ //# sourceMappingURL=parallel-checkpoint-merge.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-checkpoint-merge.integration.test.js","sourceRoot":"","sources":["../../../src/executor/__tests__/parallel-checkpoint-merge.integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Integration tests for ParallelExecutor
3
+ *
4
+ * Tests worker spawning, checkpoint file creation, and merge phase.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=parallel-executor.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-executor.integration.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/parallel-executor.integration.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Integration tests for ParallelExecutor
3
+ *
4
+ * Tests worker spawning, checkpoint file creation, and merge phase.
5
+ */
6
+ import { existsSync, readFileSync, rmSync, unlinkSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { describe, it, beforeEach, afterEach } from "node:test";
9
+ import * as assert from "node:assert/strict";
10
+ import { FileStorage } from "../checkpoint-storage.js";
11
+ import { shardPath } from "../parallel-executor.js";
12
+ const TEST_DIR = join(process.cwd(), "test-parallel-executor");
13
+ /**
14
+ * Clean up test directory.
15
+ */
16
+ const cleanupTestDir = () => {
17
+ try {
18
+ rmSync(TEST_DIR, { recursive: true, force: true });
19
+ }
20
+ catch {
21
+ // Ignore
22
+ }
23
+ };
24
+ describe("ParallelExecutor (Integration)", () => {
25
+ beforeEach(() => {
26
+ cleanupTestDir();
27
+ });
28
+ afterEach(() => {
29
+ cleanupTestDir();
30
+ });
31
+ describe("shardPath", () => {
32
+ it("should create shard paths that are properly formatted", () => {
33
+ const path0 = shardPath(TEST_DIR, 0);
34
+ const path1 = shardPath(TEST_DIR, 1);
35
+ const path10 = shardPath(TEST_DIR, 10);
36
+ assert.ok(path0.includes("checkpoint-worker-00.json"));
37
+ assert.ok(path1.includes("checkpoint-worker-01.json"));
38
+ assert.ok(path10.includes("checkpoint-worker-10.json"));
39
+ // All should be in the test directory
40
+ assert.ok(path0.includes(TEST_DIR));
41
+ assert.ok(path1.includes(TEST_DIR));
42
+ assert.ok(path10.includes(TEST_DIR));
43
+ });
44
+ it("should create unique paths for each worker index", () => {
45
+ const paths = new Set();
46
+ for (let index = 0; index < 10; index++) {
47
+ paths.add(shardPath(TEST_DIR, index));
48
+ }
49
+ assert.strictEqual(paths.size, 10);
50
+ });
51
+ });
52
+ describe("FileStorage with sharded checkpoints", () => {
53
+ it("should create and read sharded checkpoint files", async () => {
54
+ const numberWorkers = 3;
55
+ const checkpointPaths = [];
56
+ // Create checkpoint files for each worker
57
+ for (let index = 0; index < numberWorkers; index++) {
58
+ const path = shardPath(TEST_DIR, index);
59
+ checkpointPaths.push(path);
60
+ const storage = new FileStorage(path);
61
+ const checkpointData = {
62
+ configHash: `worker-${index}`,
63
+ createdAt: new Date().toISOString(),
64
+ updatedAt: new Date().toISOString(),
65
+ completedRunIds: [`run${index}-1`, `run${index}-2`],
66
+ results: {},
67
+ totalPlanned: 10,
68
+ workerIndex: index,
69
+ totalWorkers: numberWorkers,
70
+ };
71
+ await storage.save(checkpointData);
72
+ // Verify file exists
73
+ assert.strictEqual(existsSync(path), true);
74
+ }
75
+ // Verify each checkpoint can be loaded
76
+ for (let index = 0; index < numberWorkers; index++) {
77
+ const storage = new FileStorage(checkpointPaths[index]);
78
+ const loaded = await storage.load();
79
+ assert.ok(loaded);
80
+ assert.strictEqual(loaded.configHash, `worker-${index}`);
81
+ assert.strictEqual(loaded.workerIndex, index);
82
+ assert.strictEqual(loaded.totalWorkers, numberWorkers);
83
+ }
84
+ // Clean up
85
+ for (const path of checkpointPaths) {
86
+ try {
87
+ unlinkSync(path);
88
+ }
89
+ catch {
90
+ // Ignore
91
+ }
92
+ }
93
+ });
94
+ });
95
+ describe("FileStorage.findShards", () => {
96
+ it("should discover all worker checkpoint files", async () => {
97
+ const numberWorkers = 4;
98
+ // Create checkpoint files
99
+ for (let index = 0; index < numberWorkers; index++) {
100
+ const path = shardPath(TEST_DIR, index);
101
+ const storage = new FileStorage(path);
102
+ await storage.save({
103
+ configHash: `worker-${index}`,
104
+ createdAt: new Date().toISOString(),
105
+ updatedAt: new Date().toISOString(),
106
+ completedRunIds: [`run${index}`],
107
+ results: {},
108
+ totalPlanned: 10,
109
+ workerIndex: index,
110
+ totalWorkers: numberWorkers,
111
+ });
112
+ }
113
+ // Create a non-shard file (should be ignored)
114
+ const otherPath = join(TEST_DIR, "other.json");
115
+ const otherStorage = new FileStorage(otherPath);
116
+ await otherStorage.save({
117
+ configHash: "other",
118
+ createdAt: new Date().toISOString(),
119
+ updatedAt: new Date().toISOString(),
120
+ completedRunIds: [],
121
+ results: {},
122
+ totalPlanned: 0,
123
+ });
124
+ // Discover shards
125
+ const shards = await FileStorage.findShards(TEST_DIR);
126
+ assert.strictEqual(shards.length, numberWorkers);
127
+ // Verify shards are sorted by worker index
128
+ for (let index = 0; index < numberWorkers; index++) {
129
+ assert.ok(shards[index].includes(`checkpoint-worker-${String(index).padStart(2, "0")}.json`));
130
+ }
131
+ // Clean up
132
+ for (let index = 0; index < numberWorkers; index++) {
133
+ try {
134
+ unlinkSync(shardPath(TEST_DIR, index));
135
+ }
136
+ catch {
137
+ // Ignore
138
+ }
139
+ }
140
+ try {
141
+ unlinkSync(otherPath);
142
+ }
143
+ catch {
144
+ // Ignore
145
+ }
146
+ });
147
+ it("should return empty array when no shards exist", async () => {
148
+ const shards = await FileStorage.findShards(TEST_DIR);
149
+ assert.deepStrictEqual(shards, []);
150
+ });
151
+ it("should handle non-existent directory gracefully", async () => {
152
+ const nonExistentDir = join(TEST_DIR, "does-not-exist");
153
+ const shards = await FileStorage.findShards(nonExistentDir);
154
+ assert.deepStrictEqual(shards, []);
155
+ });
156
+ });
157
+ describe("Checkpoint file format", () => {
158
+ it("should write valid JSON that can be parsed", async () => {
159
+ const path = shardPath(TEST_DIR, 0);
160
+ const storage = new FileStorage(path);
161
+ // Create minimal valid EvaluationResult objects
162
+ const createMinimalResult = (runId) => ({
163
+ run: {
164
+ runId,
165
+ sut: "test-sut",
166
+ sutRole: "primary",
167
+ caseId: "test-case",
168
+ config: { repetitions: 1, seedBase: 42 },
169
+ },
170
+ correctness: {
171
+ expectedExists: false,
172
+ producedOutput: true,
173
+ valid: true,
174
+ matchesExpected: null,
175
+ },
176
+ outputs: {},
177
+ metrics: { numeric: {} },
178
+ provenance: {
179
+ runtime: {
180
+ platform: process.platform,
181
+ arch: process.arch,
182
+ nodeVersion: process.version,
183
+ },
184
+ },
185
+ });
186
+ const checkpointData = {
187
+ configHash: "test-config",
188
+ createdAt: "2024-01-01T00:00:00.000Z",
189
+ updatedAt: "2024-01-01T01:00:00.000Z",
190
+ completedRunIds: ["run1", "run2", "run3"],
191
+ results: {
192
+ run1: createMinimalResult("run1"),
193
+ run2: createMinimalResult("run2"),
194
+ run3: createMinimalResult("run3"),
195
+ },
196
+ totalPlanned: 10,
197
+ workerIndex: 0,
198
+ totalWorkers: 3,
199
+ };
200
+ await storage.save(checkpointData);
201
+ // Read raw file and verify JSON
202
+ const rawContent = readFileSync(path, "utf-8");
203
+ const parsed = JSON.parse(rawContent);
204
+ assert.strictEqual(parsed.configHash, "test-config");
205
+ assert.strictEqual(parsed.completedRunIds.length, 3);
206
+ assert.strictEqual(parsed.workerIndex, 0);
207
+ assert.strictEqual(parsed.totalWorkers, 3);
208
+ // Clean up
209
+ try {
210
+ unlinkSync(path);
211
+ }
212
+ catch {
213
+ // Ignore
214
+ }
215
+ });
216
+ });
217
+ describe("Worker identity", () => {
218
+ it("should store worker index and total workers in checkpoint", async () => {
219
+ const numberWorkers = 5;
220
+ for (let index = 0; index < numberWorkers; index++) {
221
+ const path = shardPath(TEST_DIR, index);
222
+ const storage = new FileStorage(path);
223
+ const checkpoint = {
224
+ configHash: "test",
225
+ createdAt: new Date().toISOString(),
226
+ updatedAt: new Date().toISOString(),
227
+ completedRunIds: [],
228
+ results: {},
229
+ totalPlanned: 10,
230
+ workerIndex: index,
231
+ totalWorkers: numberWorkers,
232
+ };
233
+ await storage.save(checkpoint);
234
+ // Reload and verify
235
+ const loaded = await storage.load();
236
+ assert.strictEqual(loaded.workerIndex, index);
237
+ assert.strictEqual(loaded.totalWorkers, numberWorkers);
238
+ // Clean up
239
+ try {
240
+ unlinkSync(path);
241
+ }
242
+ catch {
243
+ // Ignore
244
+ }
245
+ }
246
+ });
247
+ });
248
+ });
249
+ //# sourceMappingURL=parallel-executor.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-executor.integration.test.js","sourceRoot":"","sources":["../../../src/executor/__tests__/parallel-executor.integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Unit tests for ParallelExecutor
3
+ *
4
+ * Tests worker name generation, run batch distribution, and shard path generation.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=parallel-executor.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-executor.unit.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/parallel-executor.unit.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}