From f69e24eeff776c19cfadfd8f9e72d11b3eb61e49 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 24 Oct 2026 03:06:18 +0200 Subject: [PATCH] Test: the spawn is gated at the spawn, not by the request's earlier checks The fake Idunn signer can lose the lease once a job's meta.json exists, which pins the guards in startWorker (no logs or embeddings directory, no worker). Co-Authored-By: Claude Opus 5.5 --- scripts/fixtures/fake-idunn-entry.mjs | 9 ++++++++- scripts/test-vili-daemon.mjs | 25 +++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/scripts/fixtures/fake-idunn-entry.mjs b/scripts/fixtures/fake-idunn-entry.mjs index 7208cbc..2f26650 100644 --- a/scripts/fixtures/fake-idunn-entry.mjs +++ b/scripts/fixtures/fake-idunn-entry.mjs @@ -1,17 +1,24 @@ // Test seam only: the shipped Idunn runtime (scripts/idunn-entry.mjs idunnRuntime) over a signer whose write lease is // a file, so the lease gate is tested without Idunn's authority files. Present = leased. The daemon's own flags // arrive on argv as they do for the hand-run daemon. -import { existsSync, appendFileSync } from "node:fs"; +import { existsSync, appendFileSync, readdirSync } from "node:fs"; +import path from "node:path"; import { idunnRuntime } from "../idunn-entry.mjs"; import { serve } from "../vili-daemon.mjs"; const leasePath = process.env.FAKE_IDUNN_LEASE; const healthLog = process.env.FAKE_IDUNN_HEALTH_LOG; const answer = process.env.FAKE_IDUNN_ANSWER_THROWS !== "1"; +// An artifacts directory: the lease is gone from the moment a job there has written its meta.json, so a test can +// lose it between a job's first write and the spawn of its worker. +const loseAfterMeta = process.env.FAKE_IDUNN_LOSE_AFTER_META; const signer = { assertWriteLease() { if (!existsSync(leasePath)) throw new Error("no lease"); + if (loseAfterMeta && existsSync(loseAfterMeta) && readdirSync(loseAfterMeta).some((job) => existsSync(path.join(loseAfterMeta, job, "meta.json")))) { + throw new Error("lease lost"); + } return "lease"; }, answerRouteObservation(request) { diff --git a/scripts/test-vili-daemon.mjs b/scripts/test-vili-daemon.mjs index e409d72..0f3b836 100644 --- a/scripts/test-vili-daemon.mjs +++ b/scripts/test-vili-daemon.mjs @@ -766,13 +766,16 @@ for (let trial = 1; trial <= 40; trial += 1) { }); } -const idunnDaemon = async ({ leased = false, extraEnv = {} } = {}) => { +const idunnDaemon = async ({ leased = false, extraEnv = {}, loseAfterMeta = false } = {}) => { const root = mkdtempSync(path.join(os.tmpdir(), "vili-test-")); const lease = path.join(root, "lease"); const healthLog = path.join(root, "health.log"); if (leased) writeFileSync(lease, ""); const daemon = await startDaemon({ - root, nested: true, entry: fakeIdunnEntry, extraEnv: { FAKE_IDUNN_LEASE: lease, FAKE_IDUNN_HEALTH_LOG: healthLog, ...extraEnv }, + root, nested: true, entry: fakeIdunnEntry, extraEnv: { + FAKE_IDUNN_LEASE: lease, FAKE_IDUNN_HEALTH_LOG: healthLog, ...extraEnv, + ...(loseAfterMeta ? { FAKE_IDUNN_LOSE_AFTER_META: path.join(root, "a", "b", "state", "artifacts") } : {}), + }, }); return Object.assign(daemon, { lease, health: () => (existsSync(healthLog) ? readFileSync(healthLog, "utf8").split("\n").filter(Boolean) : []) }); }; @@ -863,6 +866,24 @@ for (const noticed of [false, true]) { }); } +// The lease goes after the job wrote its meta.json and before its worker would start: the spawn is gated at the +// spawn, not by the request's earlier checks. +test("a worker is not started, and its directories are not made, once the lease is gone", async () => { + const daemon = await idunnDaemon({ leased: true, loseAfterMeta: true }); + try { + await until(() => existsSync(path.join(daemon.stateRoot, "vili.service.cc")), "the service store", 10); + const answer = await generate(daemon); + assert.equal(answer.status, 503); + assert.equal(answer.body.code, "write-lease-lost"); + assert.deepEqual(daemon.spawns(), []); + assert.equal(existsSync(path.join(daemon.stateRoot, "logs")), false); + assert.equal(existsSync(path.join(daemon.stateRoot, "embeddings")), false); + assert.deepEqual(readdirSync(path.join(daemon.stateRoot, "jobs")), []); + } finally { + await daemon.stop(); + } +}); + test("a request arriving right after the lease is lost writes and spawns nothing", async () => { const daemon = await idunnDaemon({ leased: true }); try {