@aviaratech/ai-delivery 0.3.16 → 0.3.17
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/dist/lifecycle.test.js
CHANGED
|
@@ -5156,6 +5156,91 @@ test.each(['pass', 'chain-pass', 'command-error', 'cancel', 'persistent', 'limit
|
|
|
5156
5156
|
rmSync(output, { recursive: true, force: true });
|
|
5157
5157
|
}
|
|
5158
5158
|
});
|
|
5159
|
+
test.each(['pass', 'limit', 'command-error'])('validated alias deletion during identity readback keeps fresh slow-scan %s evidence', async (mode) => {
|
|
5160
|
+
const output = realpathSync(mkdtempSync(join(tmpdir(), 'ai-delivery-readback-deletion-')));
|
|
5161
|
+
const { root } = await fixture();
|
|
5162
|
+
const alias = join(output, 'alias'), target = join(output, 'target'), release = join(output, 'release'), fresh = join(output, 'z-new-output');
|
|
5163
|
+
writeFileSync(target, 'target');
|
|
5164
|
+
writeFileSync(join(output, 'unrelated'), 'preserved');
|
|
5165
|
+
symlinkSync('./target', alias);
|
|
5166
|
+
const fs = (await import('node:fs')).default;
|
|
5167
|
+
const actualLstat = fs.lstatSync;
|
|
5168
|
+
const now = Date.now.bind(Date);
|
|
5169
|
+
let removedDuringVisit = false, scannedFreshOutput = false, offset = 0;
|
|
5170
|
+
const clock = vi.spyOn(Date, 'now').mockImplementation(() => now() + offset);
|
|
5171
|
+
const scan = vi.spyOn(fs, 'lstatSync').mockImplementation((path, options) => {
|
|
5172
|
+
if (path === fresh && removedDuringVisit && !scannedFreshOutput) {
|
|
5173
|
+
scannedFreshOutput = true;
|
|
5174
|
+
// Inject scan duration only; removal, physical inventory and byte accounting are real.
|
|
5175
|
+
offset += 1500;
|
|
5176
|
+
}
|
|
5177
|
+
return actualLstat(path, options);
|
|
5178
|
+
});
|
|
5179
|
+
syncBuiltinESMExports();
|
|
5180
|
+
const progress = vi.spyOn(process.stderr, 'write').mockImplementation((line) => {
|
|
5181
|
+
if (!removedDuringVisit && String(line).includes('broken or cyclic symbolic link')) {
|
|
5182
|
+
writeFileSync(release, 'remove owned alias');
|
|
5183
|
+
const until = now() + 5000;
|
|
5184
|
+
for (;;) {
|
|
5185
|
+
try {
|
|
5186
|
+
actualLstat(alias);
|
|
5187
|
+
}
|
|
5188
|
+
catch (error) {
|
|
5189
|
+
if (error.code !== 'ENOENT')
|
|
5190
|
+
throw error;
|
|
5191
|
+
removedDuringVisit = true;
|
|
5192
|
+
break;
|
|
5193
|
+
}
|
|
5194
|
+
if (now() >= until)
|
|
5195
|
+
throw new Error('Owned alias deletion handshake failed.');
|
|
5196
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5);
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
return true;
|
|
5200
|
+
});
|
|
5201
|
+
const script = `(async () => {
|
|
5202
|
+
const fs = require('node:fs');
|
|
5203
|
+
fs.writeFileSync(${JSON.stringify(fresh)}, 'x'.repeat(${mode === 'limit' ? 8192 : 512}));
|
|
5204
|
+
fs.unlinkSync(${JSON.stringify(target)});
|
|
5205
|
+
while (!fs.existsSync(${JSON.stringify(release)})) await new Promise(resolve => setTimeout(resolve, 5));
|
|
5206
|
+
fs.unlinkSync(${JSON.stringify(alias)});
|
|
5207
|
+
${mode === 'command-error' ? "console.error('synthetic deletion command failure'); process.exitCode = 7;" : ''}
|
|
5208
|
+
})().catch(error => { console.error(error); process.exitCode = 1; });`;
|
|
5209
|
+
try {
|
|
5210
|
+
const { withRuntimeSetupWriter } = await import('./verification.js');
|
|
5211
|
+
const run = withRuntimeSetupWriter(root, (runner) => runner.run([process.execPath, '-e', script], {
|
|
5212
|
+
maxAggregateRssBytes: 1_000_000_000,
|
|
5213
|
+
minFreeDiskBytes: 1,
|
|
5214
|
+
maxNewOutputBytes: 4096,
|
|
5215
|
+
outputRoots: [output],
|
|
5216
|
+
}));
|
|
5217
|
+
if (mode === 'pass')
|
|
5218
|
+
await run;
|
|
5219
|
+
else
|
|
5220
|
+
await assert.rejects(run, (error) => {
|
|
5221
|
+
assert.match(String(error), mode === 'limit' ? /Positive new filesystem output 8192 exceeded limit 4096/u : /Command exit 7/u);
|
|
5222
|
+
assert.match(String(error), /Command output sha256:/u);
|
|
5223
|
+
assert.doesNotMatch(String(error), /observation remained unavailable|cleanup failed/u);
|
|
5224
|
+
return true;
|
|
5225
|
+
});
|
|
5226
|
+
assert.ok(removedDuringVisit);
|
|
5227
|
+
assert.ok(scannedFreshOutput);
|
|
5228
|
+
assert.equal(readdirSync(output).includes('alias'), false);
|
|
5229
|
+
assert.equal(readFileSync(fresh).length, mode === 'limit' ? 8192 : 512);
|
|
5230
|
+
assert.equal(readFileSync(join(output, 'unrelated'), 'utf8'), 'preserved');
|
|
5231
|
+
await withRuntimeSetupWriter(root, async (runner) => {
|
|
5232
|
+
runner.assertQuiescent();
|
|
5233
|
+
});
|
|
5234
|
+
}
|
|
5235
|
+
finally {
|
|
5236
|
+
progress.mockRestore();
|
|
5237
|
+
scan.mockRestore();
|
|
5238
|
+
syncBuiltinESMExports();
|
|
5239
|
+
clock.mockRestore();
|
|
5240
|
+
rmSync(root, { recursive: true, force: true });
|
|
5241
|
+
rmSync(output, { recursive: true, force: true });
|
|
5242
|
+
}
|
|
5243
|
+
});
|
|
5159
5244
|
test('injected first failed scan duration does not consume the subsequent observation stall window', async () => {
|
|
5160
5245
|
const output = realpathSync(mkdtempSync(join(tmpdir(), 'ai-delivery-scan-duration-')));
|
|
5161
5246
|
const { root } = await fixture();
|