// ═══════════════════════════════════════════════════════════════════════════════ // Toetst het herschrijven in tools/release-bump.mjs. // // Draaien: node tests/test_release_bump.mjs // // WAAROM DIT BESTAND ER IS. Dat script bestaat om één stille fout onmogelijk te // maken: een OUDE digest onder een NIEUWE tag levert de oude image en er is niets // dat dat meldt. Een script dat die fout zelf maakt is erger dan overtypen, want // dan vertrouw je erop. Vandaar dat de vervanging hier op de niet-gelukkige paden // getoetst wordt en niet alleen op het geval waarin alles klopt. // // De netwerkcontrole (hoort die digest bij die tag) staat hier NIET in: die vraagt // het register en dat is geen toets maar een meting. Wat hier staat is wat zonder // netwerk te bewijzen valt. // ═══════════════════════════════════════════════════════════════════════════════ import assert from 'node:assert/strict'; import { herschrijfImage, herschrijfVersie, huidigeAppVersie, kiesAppVersie, isHoger, } from '../tools/release-bump.mjs'; const DIGEST = `sha256:${'a'.repeat(64)}`; const OUD = `sha256:${'b'.repeat(64)}`; function test(naam, fn) { try { fn(); console.log(` ok ${naam}`); } catch (fout) { console.log(` FOUT ${naam}`); console.log(` ${fout.message}`); process.exitCode = 1; } } console.log('herschrijfImage'); test('vervangt de hele regel, dus de oude digest kan niet blijven staan', () => { const compose = `services:\n server:\n image: sc.kamenier-hamer.nl/sysop/atreides-assets:0.1.0@${OUD}\n restart: on-failure\n`; const { tekst, naam, aantal } = herschrijfImage(compose, '0.1.3', DIGEST); assert.equal(naam, 'sc.kamenier-hamer.nl/sysop/atreides-assets'); assert.equal(aantal, 1); assert.ok(tekst.includes(`atreides-assets:0.1.3@${DIGEST}`)); assert.ok(!tekst.includes(OUD), 'de oude digest staat er nog'); assert.ok(tekst.includes(' restart: on-failure'), 'de rest van het bestand is geraakt'); }); test('en houdt de inspringing aan die er stond', () => { const compose = ` image: sc.kamenier-hamer.nl/sysop/x:0.1.0\n`; assert.equal(herschrijfImage(compose, '0.2.0', DIGEST).tekst, ` image: sc.kamenier-hamer.nl/sysop/x:0.2.0@${DIGEST}\n`); }); test('neemt twee containers uit hetzelfde image samen mee', () => { const compose = ` a:\n image: sc.kamenier-hamer.nl/sysop/gate:0.1.0@${OUD}\n b:\n image: sc.kamenier-hamer.nl/sysop/gate:0.1.0@${OUD}\n`; const { aantal, tekst } = herschrijfImage(compose, '0.1.1', DIGEST); assert.equal(aantal, 2); assert.equal(tekst.match(/0\.1\.1/g).length, 2); }); test('laat een image van een ANDERE host met rust', () => { const compose = ` db:\n image: postgres:16-alpine\n app:\n image: sc.kamenier-hamer.nl/sysop/relay:0.7.1\n`; const { tekst, aantal } = herschrijfImage(compose, '0.7.2', DIGEST); assert.equal(aantal, 1); assert.ok(tekst.includes('image: postgres:16-alpine'), 'de vreemde image is meeverschoven'); }); test('weigert een compose zonder eigen image in plaats van er een bij te zetten', () => { assert.throws(() => herschrijfImage(' db:\n image: postgres:16\n', '1.0.0', DIGEST), /geen image-regel/); }); test('weigert twee verschillende eigen images, want dan is de bedoeling niet af te leiden', () => { const compose = ` image: sc.kamenier-hamer.nl/sysop/a:0.1.0\n image: sc.kamenier-hamer.nl/sysop/b:0.1.0\n`; assert.throws(() => herschrijfImage(compose, '0.2.0', DIGEST), /meerdere eigen images/); }); test('weigert een digest die niet de vorm heeft, want dat is de plakfout die telt', () => { const compose = ` image: sc.kamenier-hamer.nl/sysop/x:0.1.0\n`; assert.throws(() => herschrijfImage(compose, '0.2.0', 'sha256:kort'), /digest heeft niet de vorm/); assert.throws(() => herschrijfImage(compose, '0.2.0', 'a'.repeat(64)), /digest heeft niet de vorm/); assert.throws(() => herschrijfImage(compose, 'v0.2.0', DIGEST), /versie heeft niet de vorm/); }); console.log('de app-versie'); test('leest de huidige versie, met en zonder aanhalingstekens', () => { assert.equal(huidigeAppVersie('id: x\nversion: "0.1.2"\nname: X\n'), '0.1.2'); assert.equal(huidigeAppVersie('version: 1.2.3\n'), '1.2.3'); }); test('vergelijkt per deel en niet als tekst', () => { assert.equal(isHoger('0.10.0', '0.9.0'), true); assert.equal(isHoger('0.9.0', '0.10.0'), false); assert.equal(isHoger('1.0.0', '0.99.99'), true); }); test('trekt gelijk als de image erboven ligt, en verhoogt anders de patch', () => { assert.equal(kiesAppVersie('0.1.2', '0.1.3'), '0.1.3'); assert.equal(kiesAppVersie('0.2.0', '0.1.3'), '0.2.1'); // Gelijk is ook een verhoging waard: zonder verhoging rolt umbrelOS niets uit. assert.equal(kiesAppVersie('0.1.3', '0.1.3'), '0.1.4'); }); test('schrijft de versie met aanhalingstekens terug en laat de rest staan', () => { const manifest = 'id: x\nversion: "0.1.2"\nname: X\n'; assert.equal(herschrijfVersie(manifest, '0.1.3'), 'id: x\nversion: "0.1.3"\nname: X\n'); }); test('weigert een manifest zonder versie in plaats van er een bij te zetten', () => { assert.throws(() => herschrijfVersie('id: x\nname: X\n', '0.1.3'), /geen `version:`/); assert.throws(() => huidigeAppVersie('id: x\n'), /geen `version:`/); }); if (process.exitCode) console.log('\nER ZIJN FOUTEN'); else console.log('\nalles goed');