release: restore v2.1.19 baseline for v2.1.24
CI / verify (push) Has been cancelled

Restore the v2.1.19 application baseline and retain only the focused import preflight summary with duplicate, unavailable, destination, job, and size-limit visibility.
This commit is contained in:
Sucukdeluxe
2026-08-17 04:25:22 +02:00
parent 9a213a7395
commit d7c9f287e4
87 changed files with 2185 additions and 16125 deletions
+5 -228
View File
@@ -6,17 +6,13 @@ const path = require('path');
test('internal audit records never contaminate the MDU session link log', async () => {
let createUploadAuditWriter;
let createUploadAuditEvents;
try {
({ createUploadAuditWriter, createUploadAuditEvents } = require('../lib/upload-audit'));
({ createUploadAuditWriter } = require('../lib/upload-audit'));
} catch {}
assert.equal(typeof createUploadAuditWriter, 'function');
assert.equal(typeof createUploadAuditEvents, 'function');
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'mhu-upload-audit-'));
const sessionLog = path.join(directory, '13-08-2026-mdu-session-14-20-123456.log');
const debugLog = path.join(directory, 'upload-debug.log');
fs.writeFileSync(debugLog, 'debug-before\r\n');
const writer = createUploadAuditWriter({
fs,
path,
@@ -26,15 +22,13 @@ test('internal audit records never contaminate the MDU session link log', async
reportError: () => {},
retryDelays: [0]
});
const events = createUploadAuditEvents(writer, () => new Date('2026-08-13T12:00:00.000Z'));
await events.appendSourceCleanup({ outcome: 'deleted' });
await events.appendUploadPlan({ fileCount: 2, destinationCount: 2, plannedUploadCount: 4 }, 'start');
await writer.append('# SOURCE-CLEANUP {"outcome":"deleted"}\r\n', 'source-cleanup');
await writer.append('# UPLOAD-PLAN {"plannedUploadCount":4}\r\n', 'upload-plan');
const auditLog = path.join(directory, 'upload-audit.log');
assert.equal(fs.existsSync(sessionLog), false);
assert.equal(fs.readFileSync(debugLog, 'utf8'), 'debug-before\r\n');
assert.equal(fs.readFileSync(auditLog, 'utf8'), '# SOURCE-CLEANUP {"outcome":"deleted"}\r\n# UPLOAD-PLAN {"timestamp":"2026-08-13T12:00:00.000Z","mode":"start","fileCount":2,"destinationCount":2,"plannedUploadCount":4}\r\n');
assert.equal(fs.readFileSync(auditLog, 'utf8'), '# SOURCE-CLEANUP {"outcome":"deleted"}\r\n# UPLOAD-PLAN {"plannedUploadCount":4}\r\n');
fs.rmSync(directory, { recursive: true, force: true });
});
@@ -57,7 +51,7 @@ test('audit writer reports the actual fallback file after a failed primary write
}),
rotateLogFile: () => {},
invalidateUploadLogTarget: () => {},
persistFallbackLogPath: async targetPath => { persistedFallbacks.push(targetPath); return true; },
persistFallbackLogPath: async targetPath => { persistedFallbacks.push(targetPath); },
reportError: () => {},
retryDelays: [0, 0]
});
@@ -68,220 +62,3 @@ test('audit writer reports the actual fallback file after a failed primary write
assert.equal(fs.readFileSync(writer.getActivePath(), 'utf8'), '# UPLOAD-PLAN {}\r\n');
fs.rmSync(directory, { recursive: true, force: true });
});
test('audit writer retries a safe target after sync or close durability failures', async (t) => {
const { createUploadAuditWriter } = require('../lib/upload-audit');
for (const failedStage of ['sync', 'close']) {
await t.test(failedStage, async () => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), `mhu-upload-audit-${failedStage}-`));
const primaryLog = path.join(directory, 'primary', 'fileuploader.log');
const fallbackLog = path.join(directory, 'fallback', 'fileuploader.log');
const primaryAudit = path.join(directory, 'primary', 'upload-audit.log');
const fallbackAudit = path.join(directory, 'fallback', 'upload-audit.log');
const syncCalls = [];
const closeCalls = [];
const reports = [];
const durabilityFs = {
...fs,
promises: {
...fs.promises,
open: async (targetPath, flags) => {
const handle = await fs.promises.open(targetPath, flags);
return {
appendFile: handle.appendFile.bind(handle),
sync: async () => {
syncCalls.push(targetPath);
if (targetPath === primaryAudit && failedStage === 'sync') throw new Error('controlled sync failure');
return handle.sync();
},
close: async () => {
closeCalls.push(targetPath);
await handle.close();
if (targetPath === primaryAudit && failedStage === 'close') throw new Error('controlled close failure');
}
};
}
}
};
const writer = createUploadAuditWriter({
fs: durabilityFs,
path,
resolveUploadLogTarget: excluded => {
if (!excluded.has(primaryLog)) return { path: primaryLog, isFallback: false };
if (!excluded.has(fallbackLog)) return { path: fallbackLog, isFallback: true };
return null;
},
rotateLogFile: () => {},
invalidateUploadLogTarget: () => {},
persistFallbackLogPath: async () => true,
reportError: (label, error) => reports.push({ label, message: error.message }),
retryDelays: [0, 0]
});
assert.equal(await writer.append('# UPLOAD-PLAN {}\r\n', 'upload-plan'), true);
assert.equal(writer.getActivePath(), fallbackAudit);
assert.deepEqual(syncCalls, [primaryAudit, fallbackAudit]);
assert.deepEqual(closeCalls, [primaryAudit, fallbackAudit]);
assert.equal(fs.readFileSync(fallbackAudit, 'utf8'), '# UPLOAD-PLAN {}\r\n');
assert.equal(reports.some(report => report.label === 'upload-plan' && report.message.includes(failedStage)), true);
fs.rmSync(directory, { recursive: true, force: true });
});
}
});
test('audit writer fails closed when no target can sync the appended bytes', async () => {
const { createUploadAuditWriter } = require('../lib/upload-audit');
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'mhu-upload-audit-sync-exhausted-'));
const targets = ['first', 'second'].map(name => path.join(directory, name, 'fileuploader.log'));
const durabilityFs = {
...fs,
promises: {
...fs.promises,
open: async (targetPath, flags) => {
const handle = await fs.promises.open(targetPath, flags);
return {
appendFile: handle.appendFile.bind(handle),
sync: async () => { throw new Error(`controlled sync failure: ${targetPath}`); },
close: handle.close.bind(handle)
};
}
}
};
const writer = createUploadAuditWriter({
fs: durabilityFs,
path,
resolveUploadLogTarget: excluded => {
const targetPath = targets.find(candidate => !excluded.has(candidate));
return targetPath ? { path: targetPath, isFallback: true } : null;
},
rotateLogFile: () => {},
invalidateUploadLogTarget: () => {},
persistFallbackLogPath: async () => true,
reportError: () => {},
retryDelays: [0, 0]
});
assert.equal(await writer.append('# UPLOAD-PLAN {}\r\n', 'upload-plan'), false);
assert.equal(writer.getActivePath(), null);
fs.rmSync(directory, { recursive: true, force: true });
});
test('audit writer rejects false and thrown fallback persistence before trying the next safe target', async (t) => {
const { createUploadAuditWriter } = require('../lib/upload-audit');
for (const rejection of ['false', 'throw']) {
await t.test(rejection, async () => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), `mhu-upload-audit-${rejection}-`));
const first = path.join(directory, 'first', 'fileuploader.log');
const second = path.join(directory, 'second', 'fileuploader.log');
const targets = [first, second].map(targetPath => ({ path: targetPath, isFallback: true }));
const persistedFallbacks = [];
const writer = createUploadAuditWriter({
fs,
path,
resolveUploadLogTarget: excluded => {
const excludedPaths = excluded instanceof Set ? excluded : new Set(excluded ? [excluded] : []);
return targets.find(target => !excludedPaths.has(target.path)) || null;
},
rotateLogFile: () => {},
invalidateUploadLogTarget: () => {},
persistFallbackLogPath: async targetPath => {
persistedFallbacks.push(targetPath);
if (targetPath === first) {
if (rejection === 'throw') throw new Error('settings write failed');
return false;
}
return true;
},
reportError: () => {},
retryDelays: [0, 0, 0]
});
assert.equal(await writer.append('# UPLOAD-PLAN {}\r\n', 'upload-plan'), true);
assert.equal(writer.getActivePath(), path.join(directory, 'second', 'upload-audit.log'));
assert.deepEqual(persistedFallbacks, [first, second]);
assert.equal(fs.existsSync(path.join(directory, 'first', 'upload-audit.log')), false);
assert.equal(fs.readFileSync(writer.getActivePath(), 'utf8'), '# UPLOAD-PLAN {}\r\n');
fs.rmSync(directory, { recursive: true, force: true });
});
}
});
test('audit writer returns false only after every allowed fallback target is rejected', async () => {
const { createUploadAuditWriter } = require('../lib/upload-audit');
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'mhu-upload-audit-exhausted-'));
const targets = ['first', 'second'].map(name => ({ path: path.join(directory, name, 'fileuploader.log'), isFallback: true }));
const persistedFallbacks = [];
const writer = createUploadAuditWriter({
fs,
path,
resolveUploadLogTarget: excluded => {
const excludedPaths = excluded instanceof Set ? excluded : new Set(excluded ? [excluded] : []);
return targets.find(target => !excludedPaths.has(target.path)) || null;
},
rotateLogFile: () => {},
invalidateUploadLogTarget: () => {},
persistFallbackLogPath: async targetPath => {
persistedFallbacks.push(targetPath);
if (persistedFallbacks.length === 2) throw new Error('settings write failed');
return false;
},
reportError: () => {},
retryDelays: [0, 0, 0]
});
assert.equal(await writer.append('# UPLOAD-PLAN {}\r\n', 'upload-plan'), false);
assert.deepEqual(persistedFallbacks, targets.map(target => target.path));
assert.equal(writer.getActivePath(), null);
assert.equal(fs.existsSync(path.join(directory, 'first', 'upload-audit.log')), false);
assert.equal(fs.existsSync(path.join(directory, 'second', 'upload-audit.log')), false);
fs.rmSync(directory, { recursive: true, force: true });
});
test('durable audit gate never creates a manager or adds jobs after a false or thrown audit', async () => {
const { runAfterDurableAudit } = require('../lib/upload-audit');
assert.equal(typeof runAfterDurableAudit, 'function');
for (const actionName of ['manager', 'addJobs']) {
for (const audit of [async () => false, async () => { throw new Error('audit failed'); }]) {
let actions = 0;
const result = await runAfterDurableAudit(audit, () => { actions += 1; return actionName; });
assert.equal(result.ok, false);
assert.equal(actions, 0);
}
}
let actions = 0;
const result = await runAfterDurableAudit(async () => true, () => { actions += 1; return 'started'; });
assert.deepEqual(result, { ok: true, value: 'started' });
assert.equal(actions, 1);
});
test('audit failure message is localized and tells the user how to retry', () => {
const { getUploadAuditFailureMessage } = require('../lib/upload-audit');
const german = getUploadAuditFailureMessage('de');
const english = getUploadAuditFailureMessage('en');
assert.match(german, /Log-Pfad/);
assert.match(german, /erneut/);
assert.match(english, /log path/i);
assert.match(english, /try again/i);
assert.notEqual(german, english);
});
test('main process audits batch plans before creating or mutating upload work', () => {
const mainSource = fs.readFileSync(path.join(__dirname, '..', 'main.js'), 'utf8');
const startHandler = mainSource.slice(
mainSource.indexOf("ipcMain.handle('start-upload'"),
mainSource.indexOf("ipcMain.handle('cancel-upload'")
);
const addHandler = mainSource.slice(
mainSource.indexOf("ipcMain.handle('add-jobs-to-batch'"),
mainSource.indexOf("ipcMain.handle('finish-after-active'")
);
assert.ok(startHandler.indexOf("appendUploadPlanAudit(batchPlan, 'start')") < startHandler.indexOf('new UploadManager('));
assert.ok(startHandler.indexOf("appendUploadPlanAudit(batchPlan, 'start')") < startHandler.indexOf('persistRotation(pick)'));
assert.ok(addHandler.indexOf("appendUploadPlanAudit(summarizeBatchPlan({ jobs }), 'add')") < addHandler.indexOf('persistRotation(pick)'));
assert.ok(addHandler.indexOf("appendUploadPlanAudit(summarizeBatchPlan({ jobs }), 'add')") < addHandler.indexOf('registerGroups(sourceCleanupGroups)'));
assert.ok(addHandler.indexOf("appendUploadPlanAudit(summarizeBatchPlan({ jobs }), 'add')") < addHandler.indexOf('batchManager.addJobs(tasks)'));
assert.doesNotMatch(mainSource, /debugLog\(`source-cleanup:/);
assert.doesNotMatch(mainSource, /debugLog\(`upload-plan:/);
});