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.
- package/README.md +172 -0
- package/dist/__tests__/framework-pipeline.integration.test.d.ts +7 -0
- package/dist/__tests__/framework-pipeline.integration.test.d.ts.map +1 -0
- package/dist/__tests__/framework-pipeline.integration.test.js +413 -0
- package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -0
- package/dist/__tests__/registry-executor.integration.test.d.ts +5 -0
- package/dist/__tests__/registry-executor.integration.test.d.ts.map +1 -0
- package/dist/__tests__/registry-executor.integration.test.js +349 -0
- package/dist/__tests__/registry-executor.integration.test.js.map +1 -0
- package/dist/__tests__/test-helpers.d.ts +94 -0
- package/dist/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/__tests__/test-helpers.js +271 -0
- package/dist/__tests__/test-helpers.js.map +1 -0
- package/dist/aggregation/aggregators.d.ts +54 -0
- package/dist/aggregation/aggregators.d.ts.map +1 -0
- package/dist/aggregation/aggregators.js +228 -0
- package/dist/aggregation/aggregators.js.map +1 -0
- package/dist/aggregation/index.d.ts +8 -0
- package/dist/aggregation/index.d.ts.map +1 -0
- package/dist/aggregation/index.js +8 -0
- package/dist/aggregation/index.js.map +1 -0
- package/dist/aggregation/pipeline.d.ts +38 -0
- package/dist/aggregation/pipeline.d.ts.map +1 -0
- package/dist/aggregation/pipeline.js +198 -0
- package/dist/aggregation/pipeline.js.map +1 -0
- package/dist/claims/evaluator.d.ts +33 -0
- package/dist/claims/evaluator.d.ts.map +1 -0
- package/dist/claims/evaluator.js +174 -0
- package/dist/claims/evaluator.js.map +1 -0
- package/dist/claims/index.d.ts +7 -0
- package/dist/claims/index.d.ts.map +1 -0
- package/dist/claims/index.js +7 -0
- package/dist/claims/index.js.map +1 -0
- package/dist/collector/index.d.ts +8 -0
- package/dist/collector/index.d.ts.map +1 -0
- package/dist/collector/index.js +8 -0
- package/dist/collector/index.js.map +1 -0
- package/dist/collector/result-collector.d.ts +159 -0
- package/dist/collector/result-collector.d.ts.map +1 -0
- package/dist/collector/result-collector.js +213 -0
- package/dist/collector/result-collector.js.map +1 -0
- package/dist/collector/schema.d.ts +34 -0
- package/dist/collector/schema.d.ts.map +1 -0
- package/dist/collector/schema.js +145 -0
- package/dist/collector/schema.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts +10 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js +122 -0
- package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts +7 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.js +330 -0
- package/dist/executor/__tests__/checkpoint-manager.integration.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js +449 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +11 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +224 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js +164 -0
- package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js +386 -0
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -0
- package/dist/executor/__tests__/executor.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/executor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/executor.unit.test.js +134 -0
- package/dist/executor/__tests__/executor.unit.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts +12 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js +196 -0
- package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.d.ts +7 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.js +249 -0
- package/dist/executor/__tests__/parallel-executor.integration.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.js +203 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -0
- package/dist/executor/checkpoint-manager.d.ts +231 -0
- package/dist/executor/checkpoint-manager.d.ts.map +1 -0
- package/dist/executor/checkpoint-manager.js +395 -0
- package/dist/executor/checkpoint-manager.js.map +1 -0
- package/dist/executor/checkpoint-storage.d.ts +230 -0
- package/dist/executor/checkpoint-storage.d.ts.map +1 -0
- package/dist/executor/checkpoint-storage.js +370 -0
- package/dist/executor/checkpoint-storage.js.map +1 -0
- package/dist/executor/checkpoint-types.d.ts +48 -0
- package/dist/executor/checkpoint-types.d.ts.map +1 -0
- package/dist/executor/checkpoint-types.js +8 -0
- package/dist/executor/checkpoint-types.js.map +1 -0
- package/dist/executor/executor.d.ts +164 -0
- package/dist/executor/executor.d.ts.map +1 -0
- package/dist/executor/executor.js +408 -0
- package/dist/executor/executor.js.map +1 -0
- package/dist/executor/index.d.ts +11 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +11 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/memory-monitor.d.ts +115 -0
- package/dist/executor/memory-monitor.d.ts.map +1 -0
- package/dist/executor/memory-monitor.js +168 -0
- package/dist/executor/memory-monitor.js.map +1 -0
- package/dist/executor/parallel-executor.d.ts +53 -0
- package/dist/executor/parallel-executor.d.ts.map +1 -0
- package/dist/executor/parallel-executor.js +194 -0
- package/dist/executor/parallel-executor.js.map +1 -0
- package/dist/executor/run-id.d.ts +71 -0
- package/dist/executor/run-id.d.ts.map +1 -0
- package/dist/executor/run-id.js +67 -0
- package/dist/executor/run-id.js.map +1 -0
- package/dist/executor/worker-entry.d.ts +8 -0
- package/dist/executor/worker-entry.d.ts.map +1 -0
- package/dist/executor/worker-entry.js +67 -0
- package/dist/executor/worker-entry.js.map +1 -0
- package/dist/index.cjs +11 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/case-registry.d.ts +113 -0
- package/dist/registry/case-registry.d.ts.map +1 -0
- package/dist/registry/case-registry.js +160 -0
- package/dist/registry/case-registry.js.map +1 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/sut-registry.d.ts +96 -0
- package/dist/registry/sut-registry.d.ts.map +1 -0
- package/dist/registry/sut-registry.js +126 -0
- package/dist/registry/sut-registry.js.map +1 -0
- package/dist/renderers/index.d.ts +10 -0
- package/dist/renderers/index.d.ts.map +1 -0
- package/dist/renderers/index.js +9 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/latex-renderer.d.ts +84 -0
- package/dist/renderers/latex-renderer.d.ts.map +1 -0
- package/dist/renderers/latex-renderer.js +208 -0
- package/dist/renderers/latex-renderer.js.map +1 -0
- package/dist/renderers/types.d.ts +106 -0
- package/dist/renderers/types.d.ts.map +1 -0
- package/dist/renderers/types.js +23 -0
- package/dist/renderers/types.js.map +1 -0
- package/dist/robustness/analyzer.d.ts +61 -0
- package/dist/robustness/analyzer.d.ts.map +1 -0
- package/dist/robustness/analyzer.js +191 -0
- package/dist/robustness/analyzer.js.map +1 -0
- package/dist/robustness/index.d.ts +8 -0
- package/dist/robustness/index.d.ts.map +1 -0
- package/dist/robustness/index.js +8 -0
- package/dist/robustness/index.js.map +1 -0
- package/dist/robustness/perturbations.d.ts +46 -0
- package/dist/robustness/perturbations.d.ts.map +1 -0
- package/dist/robustness/perturbations.js +184 -0
- package/dist/robustness/perturbations.js.map +1 -0
- package/dist/statistical/index.d.ts +8 -0
- package/dist/statistical/index.d.ts.map +1 -0
- package/dist/statistical/index.js +8 -0
- package/dist/statistical/index.js.map +1 -0
- package/dist/statistical/mann-whitney-u.d.ts +62 -0
- package/dist/statistical/mann-whitney-u.d.ts.map +1 -0
- package/dist/statistical/mann-whitney-u.js +127 -0
- package/dist/statistical/mann-whitney-u.js.map +1 -0
- package/dist/types/aggregate.d.ts +124 -0
- package/dist/types/aggregate.d.ts.map +1 -0
- package/dist/types/aggregate.js +9 -0
- package/dist/types/aggregate.js.map +1 -0
- package/dist/types/case.d.ts +105 -0
- package/dist/types/case.d.ts.map +1 -0
- package/dist/types/case.js +10 -0
- package/dist/types/case.js.map +1 -0
- package/dist/types/claims.d.ts +122 -0
- package/dist/types/claims.d.ts.map +1 -0
- package/dist/types/claims.js +14 -0
- package/dist/types/claims.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/perturbation.d.ts +105 -0
- package/dist/types/perturbation.d.ts.map +1 -0
- package/dist/types/perturbation.js +9 -0
- package/dist/types/perturbation.js.map +1 -0
- package/dist/types/result.d.ts +150 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +12 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/sut.d.ts +128 -0
- package/dist/types/sut.d.ts.map +1 -0
- package/dist/types/sut.js +12 -0
- package/dist/types/sut.js.map +1 -0
- package/package.json +283 -7
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for CheckpointStorage
|
|
3
|
+
*
|
|
4
|
+
* Tests FileStorage, GitStorage, FileSystem, and Lock implementations.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, beforeEach } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { FileStorage, GitStorage, InMemoryLock, NodeFileSystem, } from "../checkpoint-storage.js";
|
|
9
|
+
/**
|
|
10
|
+
* Mock file system for testing.
|
|
11
|
+
* Handles both relative and absolute paths.
|
|
12
|
+
*/
|
|
13
|
+
class MockFileSystem {
|
|
14
|
+
data = new Map();
|
|
15
|
+
throwsOnRead = new Set();
|
|
16
|
+
throwsOnWrite = new Set();
|
|
17
|
+
// Try multiple possible path resolutions
|
|
18
|
+
resolvePath(path) {
|
|
19
|
+
// Direct match
|
|
20
|
+
if (this.data.has(path)) {
|
|
21
|
+
return path;
|
|
22
|
+
}
|
|
23
|
+
// Try with leading slash if not present
|
|
24
|
+
if (!path.startsWith("/") && this.data.has(`/${path}`)) {
|
|
25
|
+
return `/${path}`;
|
|
26
|
+
}
|
|
27
|
+
// Try without leading slash if present
|
|
28
|
+
if (path.startsWith("/") && this.data.has(path.slice(1))) {
|
|
29
|
+
return path.slice(1);
|
|
30
|
+
}
|
|
31
|
+
return path;
|
|
32
|
+
}
|
|
33
|
+
async readFile(path) {
|
|
34
|
+
// Try multiple path resolutions
|
|
35
|
+
const pathsToTry = [
|
|
36
|
+
path,
|
|
37
|
+
path.startsWith("/") ? path : `/${path}`,
|
|
38
|
+
path.startsWith("/") ? path.slice(1) : path,
|
|
39
|
+
];
|
|
40
|
+
for (const tryPath of pathsToTry) {
|
|
41
|
+
if (this.data.has(tryPath) && this.throwsOnRead.has(tryPath)) {
|
|
42
|
+
throw new Error(`Mock read error: ${tryPath}`);
|
|
43
|
+
}
|
|
44
|
+
const content = this.data.get(tryPath);
|
|
45
|
+
if (content !== undefined) {
|
|
46
|
+
return content;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`File not found: ${path}`);
|
|
50
|
+
}
|
|
51
|
+
async writeFile(path, content) {
|
|
52
|
+
// Store with multiple path variants
|
|
53
|
+
this.data.set(path, content);
|
|
54
|
+
if (!path.startsWith("/")) {
|
|
55
|
+
this.data.set(`/${path}`, content);
|
|
56
|
+
}
|
|
57
|
+
this.data.set(`/${path}`, content);
|
|
58
|
+
const resolvedPath = this.resolvePath(path) ?? path;
|
|
59
|
+
if (this.throwsOnWrite.has(resolvedPath)) {
|
|
60
|
+
throw new Error(`Mock write error: ${resolvedPath}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async mkdir(_path, _options) {
|
|
64
|
+
// No-op for mock
|
|
65
|
+
}
|
|
66
|
+
async unlink(path) {
|
|
67
|
+
// Delete all variants
|
|
68
|
+
this.data.delete(path);
|
|
69
|
+
if (!path.startsWith("/")) {
|
|
70
|
+
this.data.delete(`/${path}`);
|
|
71
|
+
}
|
|
72
|
+
this.data.delete(`/${path}`);
|
|
73
|
+
const resolvedPath = this.resolvePath(path) ?? path;
|
|
74
|
+
this.data.delete(resolvedPath);
|
|
75
|
+
}
|
|
76
|
+
async access(_path) {
|
|
77
|
+
// No-op for mock
|
|
78
|
+
}
|
|
79
|
+
async readdir(path) {
|
|
80
|
+
const resolvedPath = this.resolvePath(path) ?? path;
|
|
81
|
+
const prefix = resolvedPath.endsWith("/") ? resolvedPath : `${resolvedPath}/`;
|
|
82
|
+
return [...this.data.keys()]
|
|
83
|
+
.filter((k) => k.startsWith(prefix))
|
|
84
|
+
.map((k) => k.slice(prefix.length))
|
|
85
|
+
.filter((k) => !k.includes("/"));
|
|
86
|
+
}
|
|
87
|
+
setFile(path, content) {
|
|
88
|
+
// Store with multiple path variants for flexibility
|
|
89
|
+
this.data.set(path, content);
|
|
90
|
+
if (!path.startsWith("/")) {
|
|
91
|
+
this.data.set(`/${path}`, content);
|
|
92
|
+
}
|
|
93
|
+
// Also store with cwd prefix (common during tests)
|
|
94
|
+
this.data.set(`/${path}`, content);
|
|
95
|
+
}
|
|
96
|
+
getFile(path) {
|
|
97
|
+
const resolvedPath = this.resolvePath(path) ?? path;
|
|
98
|
+
// Check multiple path variants
|
|
99
|
+
if (this.data.has(resolvedPath)) {
|
|
100
|
+
return this.data.get(resolvedPath);
|
|
101
|
+
}
|
|
102
|
+
// Also try with the full resolved path if provided
|
|
103
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
104
|
+
if (this.data.has(normalizedPath)) {
|
|
105
|
+
return this.data.get(normalizedPath);
|
|
106
|
+
}
|
|
107
|
+
// Try stripping leading slash if it exists
|
|
108
|
+
const strippedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
109
|
+
if (this.data.has(strippedPath)) {
|
|
110
|
+
return this.data.get(strippedPath);
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
clear() {
|
|
115
|
+
this.data.clear();
|
|
116
|
+
this.throwsOnRead.clear();
|
|
117
|
+
this.throwsOnWrite.clear();
|
|
118
|
+
}
|
|
119
|
+
setThrowsOnRead(path) {
|
|
120
|
+
this.throwsOnRead.add(path);
|
|
121
|
+
if (!path.startsWith("/")) {
|
|
122
|
+
this.throwsOnRead.add(`/${path}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
setThrowsOnWrite(path) {
|
|
126
|
+
this.throwsOnWrite.add(path);
|
|
127
|
+
if (!path.startsWith("/")) {
|
|
128
|
+
this.throwsOnWrite.add(`/${path}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
describe("FileSystem", () => {
|
|
133
|
+
describe("NodeFileSystem", () => {
|
|
134
|
+
it("should have all required methods", () => {
|
|
135
|
+
const fs = new NodeFileSystem();
|
|
136
|
+
assert.ok(fs.readFile instanceof Function);
|
|
137
|
+
assert.ok(fs.writeFile instanceof Function);
|
|
138
|
+
assert.ok(fs.mkdir instanceof Function);
|
|
139
|
+
assert.ok(fs.unlink instanceof Function);
|
|
140
|
+
assert.ok(fs.access instanceof Function);
|
|
141
|
+
assert.ok(fs.readdir instanceof Function);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("MockFileSystem", () => {
|
|
145
|
+
let mockFs;
|
|
146
|
+
beforeEach(() => {
|
|
147
|
+
mockFs = new MockFileSystem();
|
|
148
|
+
});
|
|
149
|
+
it("should store and retrieve files", async () => {
|
|
150
|
+
mockFs.setFile("test.json", '{"test": true}');
|
|
151
|
+
const content = await mockFs.readFile("test.json");
|
|
152
|
+
assert.strictEqual(content, '{"test": true}');
|
|
153
|
+
});
|
|
154
|
+
it("should throw on missing file", async () => {
|
|
155
|
+
await assert.rejects(() => mockFs.readFile("missing.json"));
|
|
156
|
+
});
|
|
157
|
+
it("should write files", async () => {
|
|
158
|
+
await mockFs.writeFile("new.json", '{"new": true}');
|
|
159
|
+
assert.strictEqual(mockFs.getFile("new.json"), '{"new": true}');
|
|
160
|
+
});
|
|
161
|
+
it("should delete files", async () => {
|
|
162
|
+
mockFs.setFile("delete.json", '{"delete": true}');
|
|
163
|
+
await mockFs.unlink("delete.json");
|
|
164
|
+
assert.strictEqual(mockFs.getFile("delete.json"), undefined);
|
|
165
|
+
});
|
|
166
|
+
it("should list directory contents", async () => {
|
|
167
|
+
mockFs.setFile("dir/file1.json", "{}");
|
|
168
|
+
mockFs.setFile("dir/file2.json", "{}");
|
|
169
|
+
mockFs.setFile("other/file.txt", "{}");
|
|
170
|
+
const entries = await mockFs.readdir("dir");
|
|
171
|
+
assert.ok(entries.includes("file1.json"));
|
|
172
|
+
assert.ok(entries.includes("file2.json"));
|
|
173
|
+
assert.ok(!entries.includes("file.txt"));
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
describe("Lock", () => {
|
|
178
|
+
describe("InMemoryLock", () => {
|
|
179
|
+
it("should allow concurrent acquisitions with queueing", async () => {
|
|
180
|
+
const lock = new InMemoryLock();
|
|
181
|
+
const results = [];
|
|
182
|
+
// First acquisition
|
|
183
|
+
void lock.acquire().then(async () => {
|
|
184
|
+
results.push(1);
|
|
185
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
186
|
+
lock.release();
|
|
187
|
+
});
|
|
188
|
+
// Second acquisition (should wait)
|
|
189
|
+
void lock.acquire().then(() => {
|
|
190
|
+
results.push(2);
|
|
191
|
+
lock.release();
|
|
192
|
+
});
|
|
193
|
+
// Third acquisition (should wait)
|
|
194
|
+
void lock.acquire().then(() => {
|
|
195
|
+
results.push(3);
|
|
196
|
+
lock.release();
|
|
197
|
+
});
|
|
198
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
199
|
+
assert.deepStrictEqual(results, [1, 2, 3]);
|
|
200
|
+
});
|
|
201
|
+
it("should release immediately when no waiters", () => {
|
|
202
|
+
const lock = new InMemoryLock();
|
|
203
|
+
lock.release(); // Should not throw
|
|
204
|
+
lock.release(); // Should not throw
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe("FileStorage", () => {
|
|
209
|
+
let mockFs;
|
|
210
|
+
let storage;
|
|
211
|
+
beforeEach(() => {
|
|
212
|
+
mockFs = new MockFileSystem();
|
|
213
|
+
storage = new FileStorage("test/checkpoint.json", mockFs);
|
|
214
|
+
});
|
|
215
|
+
/**
|
|
216
|
+
* Helper to set file content using the storage's resolved path.
|
|
217
|
+
* @param content
|
|
218
|
+
*/
|
|
219
|
+
const setStorageFile = (content) => {
|
|
220
|
+
const resolvedPath = storage.getPath();
|
|
221
|
+
mockFs.data.set(resolvedPath, content);
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Helper to get file content using the storage's resolved path.
|
|
225
|
+
*/
|
|
226
|
+
const getStorageFile = () => {
|
|
227
|
+
const resolvedPath = storage.getPath();
|
|
228
|
+
return mockFs.data.get(resolvedPath);
|
|
229
|
+
};
|
|
230
|
+
describe("load", () => {
|
|
231
|
+
it("should parse valid JSON checkpoint", async () => {
|
|
232
|
+
const checkpoint = {
|
|
233
|
+
configHash: "abc123",
|
|
234
|
+
createdAt: "2024-01-01T00:00:00.000Z",
|
|
235
|
+
updatedAt: "2024-01-01T00:00:00.000Z",
|
|
236
|
+
completedRunIds: ["run1", "run2"],
|
|
237
|
+
results: {},
|
|
238
|
+
totalPlanned: 10,
|
|
239
|
+
};
|
|
240
|
+
setStorageFile(JSON.stringify(checkpoint));
|
|
241
|
+
const loaded = await storage.load();
|
|
242
|
+
assert.deepStrictEqual(loaded, checkpoint);
|
|
243
|
+
});
|
|
244
|
+
it("should return null for missing file", async () => {
|
|
245
|
+
const loaded = await storage.load();
|
|
246
|
+
assert.strictEqual(loaded, null);
|
|
247
|
+
});
|
|
248
|
+
it("should return null for invalid JSON", async () => {
|
|
249
|
+
setStorageFile("not json");
|
|
250
|
+
const loaded = await storage.load();
|
|
251
|
+
assert.strictEqual(loaded, null);
|
|
252
|
+
});
|
|
253
|
+
it("should return null on read error", async () => {
|
|
254
|
+
const resolvedPath = storage.getPath();
|
|
255
|
+
mockFs.setThrowsOnRead(resolvedPath);
|
|
256
|
+
const loaded = await storage.load();
|
|
257
|
+
assert.strictEqual(loaded, null);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe("save", () => {
|
|
261
|
+
it("should write checkpoint with updated timestamp", async () => {
|
|
262
|
+
const checkpoint = {
|
|
263
|
+
configHash: "abc123",
|
|
264
|
+
createdAt: "2024-01-01T00:00:00.000Z",
|
|
265
|
+
updatedAt: "2024-01-01T00:00:00.000Z",
|
|
266
|
+
completedRunIds: ["run1"],
|
|
267
|
+
results: {},
|
|
268
|
+
totalPlanned: 10,
|
|
269
|
+
};
|
|
270
|
+
await storage.save(checkpoint);
|
|
271
|
+
const saved = getStorageFile();
|
|
272
|
+
assert.ok(saved);
|
|
273
|
+
const parsed = JSON.parse(saved);
|
|
274
|
+
assert.strictEqual(parsed.configHash, "abc123");
|
|
275
|
+
assert.notStrictEqual(parsed.updatedAt, "2024-01-01T00:00:00.000Z"); // Should be updated
|
|
276
|
+
});
|
|
277
|
+
it("should create parent directory via mkdir", async () => {
|
|
278
|
+
const checkpoint = {
|
|
279
|
+
configHash: "abc123",
|
|
280
|
+
createdAt: "2024-01-01T00:00:00.000Z",
|
|
281
|
+
updatedAt: "2024-01-01T00:00:00.000Z",
|
|
282
|
+
completedRunIds: [],
|
|
283
|
+
results: {},
|
|
284
|
+
totalPlanned: 0,
|
|
285
|
+
};
|
|
286
|
+
await storage.save(checkpoint);
|
|
287
|
+
assert.ok(getStorageFile());
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
describe("exists", () => {
|
|
291
|
+
it("should return true for valid checkpoint file", async () => {
|
|
292
|
+
const checkpoint = {
|
|
293
|
+
configHash: "abc123",
|
|
294
|
+
createdAt: "2024-01-01T00:00:00.000Z",
|
|
295
|
+
updatedAt: "2024-01-01T00:00:00.000Z",
|
|
296
|
+
completedRunIds: [],
|
|
297
|
+
results: {},
|
|
298
|
+
totalPlanned: 0,
|
|
299
|
+
};
|
|
300
|
+
setStorageFile(JSON.stringify(checkpoint));
|
|
301
|
+
const exists = await storage.exists();
|
|
302
|
+
assert.strictEqual(exists, true);
|
|
303
|
+
});
|
|
304
|
+
it("should return false for missing file", async () => {
|
|
305
|
+
const exists = await storage.exists();
|
|
306
|
+
assert.strictEqual(exists, false);
|
|
307
|
+
});
|
|
308
|
+
it("should return false for invalid JSON", async () => {
|
|
309
|
+
setStorageFile("not json");
|
|
310
|
+
const exists = await storage.exists();
|
|
311
|
+
assert.strictEqual(exists, false);
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
describe("delete", () => {
|
|
315
|
+
it("should remove checkpoint file", async () => {
|
|
316
|
+
setStorageFile('{"test": true}');
|
|
317
|
+
await storage.delete();
|
|
318
|
+
assert.strictEqual(getStorageFile(), undefined);
|
|
319
|
+
});
|
|
320
|
+
it("should not throw when deleting missing file", async () => {
|
|
321
|
+
await assert.doesNotReject(() => storage.delete());
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
describe("getPath", () => {
|
|
325
|
+
it("should return absolute path", () => {
|
|
326
|
+
const path = storage.getPath();
|
|
327
|
+
assert.ok(path.includes("checkpoint.json"));
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
describe("findShards", () => {
|
|
331
|
+
it("should find all worker checkpoint files", async () => {
|
|
332
|
+
mockFs.setFile("results/execute/checkpoint-worker-00.json", "{}");
|
|
333
|
+
mockFs.setFile("results/execute/checkpoint-worker-01.json", "{}");
|
|
334
|
+
mockFs.setFile("results/execute/checkpoint-worker-02.json", "{}");
|
|
335
|
+
mockFs.setFile("results/execute/other.json", "{}");
|
|
336
|
+
const shards = await FileStorage.findShards("results/execute", mockFs);
|
|
337
|
+
assert.strictEqual(shards.length, 3);
|
|
338
|
+
assert.ok(shards[0].includes("checkpoint-worker-00.json"));
|
|
339
|
+
assert.ok(shards[1].includes("checkpoint-worker-01.json"));
|
|
340
|
+
assert.ok(shards[2].includes("checkpoint-worker-02.json"));
|
|
341
|
+
});
|
|
342
|
+
it("should sort shards by worker index", async () => {
|
|
343
|
+
mockFs.setFile("results/execute/checkpoint-worker-02.json", "{}");
|
|
344
|
+
mockFs.setFile("results/execute/checkpoint-worker-00.json", "{}");
|
|
345
|
+
mockFs.setFile("results/execute/checkpoint-worker-01.json", "{}");
|
|
346
|
+
const shards = await FileStorage.findShards("results/execute", mockFs);
|
|
347
|
+
assert.ok(shards[0].includes("checkpoint-worker-00.json"));
|
|
348
|
+
assert.ok(shards[1].includes("checkpoint-worker-01.json"));
|
|
349
|
+
assert.ok(shards[2].includes("checkpoint-worker-02.json"));
|
|
350
|
+
});
|
|
351
|
+
it("should return empty array when directory has no shards", async () => {
|
|
352
|
+
const shards = await FileStorage.findShards("results/execute", mockFs);
|
|
353
|
+
assert.deepStrictEqual(shards, []);
|
|
354
|
+
});
|
|
355
|
+
it("should return empty array when directory does not exist", async () => {
|
|
356
|
+
const shards = await FileStorage.findShards("nonexistent", mockFs);
|
|
357
|
+
assert.deepStrictEqual(shards, []);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
describe("shardPath", () => {
|
|
361
|
+
it("should generate zero-padded shard paths", () => {
|
|
362
|
+
const path0 = FileStorage.shardPath("results/execute", 0);
|
|
363
|
+
const path1 = FileStorage.shardPath("results/execute", 1);
|
|
364
|
+
const path10 = FileStorage.shardPath("results/execute", 10);
|
|
365
|
+
assert.ok(path0.includes("checkpoint-worker-00.json"));
|
|
366
|
+
assert.ok(path1.includes("checkpoint-worker-01.json"));
|
|
367
|
+
assert.ok(path10.includes("checkpoint-worker-10.json"));
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
describe("GitStorage", () => {
|
|
372
|
+
describe("load", () => {
|
|
373
|
+
it("should return null when git is not available", async () => {
|
|
374
|
+
const storage = new GitStorage("test-namespace", "/nonexistent");
|
|
375
|
+
const loaded = storage.load();
|
|
376
|
+
assert.strictEqual(loaded, null);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
describe("type", () => {
|
|
380
|
+
it("should have type 'git'", () => {
|
|
381
|
+
const storage = new GitStorage("test-namespace");
|
|
382
|
+
assert.strictEqual(storage.type, "git");
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
//# sourceMappingURL=checkpoint-storage.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-storage.unit.test.js","sourceRoot":"","sources":["../../../src/executor/__tests__/checkpoint-storage.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.unit.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/executor.unit.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for Executor
|
|
3
|
+
*
|
|
4
|
+
* Tests executor behavior including planned runs filtering.
|
|
5
|
+
*/
|
|
6
|
+
import { beforeEach, describe, it } from "node:test";
|
|
7
|
+
import { strict as assert } from "node:assert";
|
|
8
|
+
import { Executor } from "../executor.js";
|
|
9
|
+
/**
|
|
10
|
+
* Mock expander for testing.
|
|
11
|
+
*/
|
|
12
|
+
class MockExpander {
|
|
13
|
+
async expand() {
|
|
14
|
+
// No-op
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a mock SUT definition.
|
|
19
|
+
* @param id
|
|
20
|
+
*/
|
|
21
|
+
const createMockSut = (id) => ({
|
|
22
|
+
registration: {
|
|
23
|
+
id,
|
|
24
|
+
name: `Mock SUT ${id}`,
|
|
25
|
+
role: "primary",
|
|
26
|
+
version: "1.0.0",
|
|
27
|
+
config: Object.freeze({}),
|
|
28
|
+
tags: [],
|
|
29
|
+
},
|
|
30
|
+
factory: () => ({
|
|
31
|
+
id,
|
|
32
|
+
config: {},
|
|
33
|
+
run: async () => ({ value: id }),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Create a mock case definition.
|
|
38
|
+
* @param id
|
|
39
|
+
*/
|
|
40
|
+
const createMockCase = (id) => ({
|
|
41
|
+
case: {
|
|
42
|
+
caseId: id,
|
|
43
|
+
caseClass: "test",
|
|
44
|
+
name: `Test Case ${id}`,
|
|
45
|
+
version: "1.0.0",
|
|
46
|
+
inputs: {},
|
|
47
|
+
},
|
|
48
|
+
getInput: async () => new MockExpander(),
|
|
49
|
+
getInputs: () => ({}),
|
|
50
|
+
});
|
|
51
|
+
describe("Executor", () => {
|
|
52
|
+
let executor;
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
executor = new Executor();
|
|
55
|
+
});
|
|
56
|
+
describe("plan", () => {
|
|
57
|
+
it("should generate planned runs for SUTs and cases", () => {
|
|
58
|
+
const suts = [createMockSut("sut1"), createMockSut("sut2")];
|
|
59
|
+
const cases = [createMockCase("case1"), createMockCase("case2")];
|
|
60
|
+
const planned = executor.plan(suts, cases);
|
|
61
|
+
assert.strictEqual(planned.length, 4); // 2 SUTs x 2 cases
|
|
62
|
+
});
|
|
63
|
+
it("should include repetition in planned runs", () => {
|
|
64
|
+
const executorWithRep = new Executor({ repetitions: 3 });
|
|
65
|
+
const suts = [createMockSut("sut1")];
|
|
66
|
+
const cases = [createMockCase("case1")];
|
|
67
|
+
const planned = executorWithRep.plan(suts, cases);
|
|
68
|
+
assert.strictEqual(planned.length, 3); // 1 SUT x 1 case x 3 reps
|
|
69
|
+
assert.strictEqual(planned[0].repetition, 0);
|
|
70
|
+
assert.strictEqual(planned[1].repetition, 1);
|
|
71
|
+
assert.strictEqual(planned[2].repetition, 2);
|
|
72
|
+
});
|
|
73
|
+
it("should generate unique run IDs", () => {
|
|
74
|
+
const suts = [createMockSut("sut1")];
|
|
75
|
+
const cases = [createMockCase("case1"), createMockCase("case2")];
|
|
76
|
+
const planned = executor.plan(suts, cases);
|
|
77
|
+
const runIds = new Set(planned.map((r) => r.runId));
|
|
78
|
+
assert.strictEqual(runIds.size, planned.length); // All unique
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("execute with plannedRuns parameter", () => {
|
|
82
|
+
it("should use provided plannedRuns instead of planning", async () => {
|
|
83
|
+
const suts = [createMockSut("sut1")];
|
|
84
|
+
const cases = [createMockCase("case1")];
|
|
85
|
+
// Plan all runs
|
|
86
|
+
const allPlanned = executor.plan(suts, cases);
|
|
87
|
+
// Filter to only run the first one
|
|
88
|
+
const filteredRuns = [allPlanned[0]];
|
|
89
|
+
const summary = await executor.execute(suts, cases, () => ({}), filteredRuns);
|
|
90
|
+
assert.strictEqual(summary.totalRuns, 1);
|
|
91
|
+
assert.strictEqual(summary.successfulRuns, 1);
|
|
92
|
+
});
|
|
93
|
+
it("should use filtered plannedRuns for single execution", async () => {
|
|
94
|
+
const suts = [createMockSut("sut1")];
|
|
95
|
+
const cases = [createMockCase("case1"), createMockCase("case2")];
|
|
96
|
+
// Plan all runs
|
|
97
|
+
const allPlanned = executor.plan(suts, cases);
|
|
98
|
+
// Filter to only run half
|
|
99
|
+
const filteredRuns = allPlanned.slice(0, 1);
|
|
100
|
+
const summary = await executor.execute(suts, cases, () => ({}), filteredRuns);
|
|
101
|
+
assert.strictEqual(summary.totalRuns, 1);
|
|
102
|
+
assert.strictEqual(summary.successfulRuns, 1);
|
|
103
|
+
});
|
|
104
|
+
it("should plan all runs when plannedRuns is undefined", async () => {
|
|
105
|
+
const suts = [createMockSut("sut1")];
|
|
106
|
+
const cases = [createMockCase("case1")];
|
|
107
|
+
const summary = await executor.execute(suts, cases, () => ({}));
|
|
108
|
+
assert.strictEqual(summary.totalRuns, 1);
|
|
109
|
+
assert.strictEqual(summary.successfulRuns, 1);
|
|
110
|
+
});
|
|
111
|
+
it("should work with empty plannedRuns array", async () => {
|
|
112
|
+
const suts = [createMockSut("sut1")];
|
|
113
|
+
const cases = [createMockCase("case1")];
|
|
114
|
+
const summary = await executor.execute(suts, cases, () => ({}), []);
|
|
115
|
+
assert.strictEqual(summary.totalRuns, 0);
|
|
116
|
+
assert.strictEqual(summary.successfulRuns, 0);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe("execute with parallel execution", () => {
|
|
120
|
+
it("should use provided plannedRuns with concurrency > 1", async () => {
|
|
121
|
+
const executorWithConcurrency = new Executor({ concurrency: 2 });
|
|
122
|
+
const suts = [createMockSut("sut1"), createMockSut("sut2")];
|
|
123
|
+
const cases = [createMockCase("case1")];
|
|
124
|
+
// Plan all runs
|
|
125
|
+
const allPlanned = executorWithConcurrency.plan(suts, cases);
|
|
126
|
+
// Filter to only run one
|
|
127
|
+
const filteredRuns = [allPlanned[0]];
|
|
128
|
+
const summary = await executorWithConcurrency.execute(suts, cases, () => ({}), filteredRuns);
|
|
129
|
+
assert.strictEqual(summary.totalRuns, 1);
|
|
130
|
+
assert.strictEqual(summary.successfulRuns, 1);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=executor.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.unit.test.js","sourceRoot":"","sources":["../../../src/executor/__tests__/executor.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=parallel-checkpoint-merge.integration.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel-checkpoint-merge.integration.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/parallel-checkpoint-merge.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|