75 lines
4.3 KiB
JavaScript
75 lines
4.3 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { createPayloadRuntimeService, normalizeInstalled, normalizeRepository, payloadIdentity } = require('../../src/services/payload-runtime-service');
|
|
|
|
function fixture() {
|
|
const calls = [];
|
|
const responses = {
|
|
'/version': '0.3.1',
|
|
'/list_payloads': {
|
|
payloads: ['/data/pldmgr/payloads/websrv/websrv_v0.32.elf', '/data/pldmgr/payloads/etaHEN/etaHEN-2.6B.bin'],
|
|
meta: {
|
|
'websrv_v0.32.elf': { display_name: 'websrv', version: 'v0.32', checksum: 'a'.repeat(64) },
|
|
'etaHEN-2.6B.bin': { display_name: 'etaHEN-2.6B.bin' },
|
|
},
|
|
},
|
|
'/repository_payloads': { sources: [{ id: 'default', name: 'Official', payloads: [
|
|
{ name: 'websrv', filename: 'websrv_v0.33.elf', version: 'v0.33', source_id: 'default', url: 'https://example.test/websrv.elf' },
|
|
{ name: 'etaHEN', filename: 'etaHEN_2.5B.bin', version: '2.5B', source_id: 'default', url: 'https://example.test/etahen.bin' },
|
|
{ name: 'klogsrv', filename: 'klogsrv_v0.11.elf', version: 'v0.11', source_id: 'default', url: 'https://example.test/klogsrv.elf' },
|
|
] }] },
|
|
'/autoload_status': { list: 'websrv_v0.32.elf' },
|
|
'/sources_list': { sources: [{ id: 'default', name: 'Official', url: 'https://example.test/payloads.json' }] },
|
|
};
|
|
const payloadManager = { request: async route => {
|
|
calls.push(route);
|
|
if (route === '/repository_refresh') return { success: true };
|
|
if (route.startsWith('/repository_install?')) return { success: true };
|
|
if (!(route in responses)) throw new Error(`Unexpected ${route}`);
|
|
return responses[route];
|
|
} };
|
|
const settings = { get: (key, fallback) => key === 'ftp.host' ? '127.0.0.1' : fallback };
|
|
return { service: createPayloadRuntimeService({ settings, payloadManager, timeoutMs: 10 }), calls };
|
|
}
|
|
|
|
test('normalizers preserve trusted manager metadata and stable identities', () => {
|
|
const installed = normalizeInstalled({ payloads: ['/data/x/websrv_v0.32.elf'], meta: { 'websrv_v0.32.elf': { display_name: 'websrv', version: 'v0.32', checksum: 'b'.repeat(64) } } });
|
|
assert.equal(installed[0].identity, 'websrv');
|
|
assert.equal(installed[0].checksumVerified, true);
|
|
assert.equal(payloadIdentity('etaHEN-2.6B.bin'), 'etahen');
|
|
const repository = normalizeRepository({ sources: [{ id: 'official', payloads: [{ name: 'websrv', filename: 'websrv_v0.33.elf', url: 'http://unsafe.test/file' }] }] });
|
|
assert.equal(repository[0].url, '');
|
|
});
|
|
|
|
test('runtime update plan allows upgrades and blocks downgrades', async () => {
|
|
const f = fixture();
|
|
const plan = await f.service.updatePlan();
|
|
assert.equal(plan.stats.updates, 1);
|
|
assert.equal(plan.candidates.find(item => item.installed.identity === 'websrv').status, 'update-available');
|
|
assert.equal(plan.candidates.find(item => item.installed.identity === 'etahen').status, 'installed-newer');
|
|
assert.equal(plan.recommendations.find(item => item.identity === 'klogsrv').automaticInstall, false);
|
|
assert.equal(plan.safety.automaticInstall, false);
|
|
});
|
|
|
|
test('manager reads coalesce briefly and repository refresh forces a fresh inventory', async () => {
|
|
const f = fixture();
|
|
await Promise.all([f.service.managerState(), f.service.managerState(), f.service.updatePlan()]);
|
|
assert.equal(f.calls.filter(route => route === '/version').length, 1);
|
|
await f.service.refreshRepositories();
|
|
assert.equal(f.calls.filter(route => route === '/repository_refresh').length, 1);
|
|
assert.equal(f.calls.filter(route => route === '/version').length, 2);
|
|
assert.ok(!f.calls.some(route => route.startsWith('/repository_install?')));
|
|
});
|
|
|
|
test('installation revalidates the plan, requires exact filename confirmation and never launches', async () => {
|
|
const f = fixture();
|
|
await assert.rejects(() => f.service.installUpdate({ filename: 'websrv_v0.33.elf', sourceId: 'default', confirmation: 'yes' }), /Typ UPDATE/);
|
|
const result = await f.service.installUpdate({ filename: 'websrv_v0.33.elf', sourceId: 'default', confirmation: 'UPDATE websrv_v0.33.elf' });
|
|
assert.equal(result.ok, true);
|
|
assert.equal(result.launched, false);
|
|
assert.ok(f.calls.some(route => route === '/repository_install?filename=websrv_v0.33.elf&source_id=default'));
|
|
assert.ok(!f.calls.some(route => route.startsWith('/loadpayload:')));
|
|
});
|