From 5146c722afd8c79414f06ab6b20d352fbb1c6d70 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 23 Oct 2026 17:50:37 +0200 Subject: [PATCH] Boot test: fail on a logged publication fault, and require presence at startup A silent early return in the startup publication would otherwise pass, the 10 s pulse loop filling in the frames later. Co-Authored-By: Claude Opus 5.5 --- tests/idunn-boot.test.ts | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/tests/idunn-boot.test.ts b/tests/idunn-boot.test.ts index d758910..a645986 100644 --- a/tests/idunn-boot.test.ts +++ b/tests/idunn-boot.test.ts @@ -199,13 +199,31 @@ describe.skipIf(!canLaunch)("the bundle booted as Idunn launches it", () => { const credential = await readFile(path.join(idunnRuntimeFixtures, "provider-identity.credential")); const generation = await launch("signs", credential); - // Startup publication, then one per 10 s pulse. + // Startup publication, then one per 10 s pulse. A publication fault is + // reported as it is logged rather than after the frames never arrive. + const publicationFault = new Promise((_resolve, reject) => { + const watch = setInterval(() => { + if (generation.stderr().includes(" failed on ")) { + clearInterval(watch); + reject(new Error(`publication failed; stderr: ${generation.stderr()}`)); + } + }, 200); + void idunn.frame(2).then(() => clearInterval(watch)); + }); + const exitedEarly = generation.exited.then((code) => { + throw new Error(`bundle exited ${code}; stderr: ${generation.stderr()}`); + }); + // The first statement is the startup publication, which follows the listen + // directly; the 10 s pulse loop has not yet fired. await Promise.race([ - idunn.frame(2), - generation.exited.then((code) => { - throw new Error(`bundle exited ${code}; stderr: ${generation.stderr()}`); - }), + idunn.frame(0), + publicationFault, + exitedEarly, + new Promise((_resolve, reject) => + setTimeout(() => reject(new Error(`no presence at startup; stderr: ${generation.stderr()}`)), 8_000) + ), ]); + await Promise.race([idunn.frame(2), publicationFault, exitedEarly]); expect(await answers(generation.candidatePort)).toBe(200);