fix: harden native workspace root and docker gates

This commit is contained in:
2026-08-11 14:11:42 +02:00
parent ee87a59e1f
commit a5916f6177
16 changed files with 401 additions and 96 deletions
@@ -1,2 +1,17 @@
import {describe,expect,it} from "vitest"; import {mkdtempSync} from "node:fs"; import {join} from "node:path"; import {tmpdir} from "node:os"; import {WorkspaceFsAtV1} from "../src/workspaces/workspace-fs-at.js"; import {VerifiedWorkspaceLockRootLeaseFactory} from "../src/workspaces/workspace-lock-root-lease.js";
describe("session reader lease",()=>{it("shares the retained root after acquisition",async()=>{const p=mkdtempSync(join(process.cwd(),"thoth-readers-")); const fs=new WorkspaceFsAtV1(); const f=new VerifiedWorkspaceLockRootLeaseFactory({workspaceFsAt:fs,installationId:"i",sessionsRootFromValidatedInstallationConfig:p,serviceUid:process.getuid!(),provisionedWorkspaceMode:0o700}); const l=await f.acquireOrProvision(f.canonicalInput("abc-workspace")); const r=await l.acquireSessionReadersShared(); expect(r.rootIdentity.workspaceId).toBe("abc-workspace"); await r.close();});});
import { describe, expect, it, afterEach } from "vitest";
import { mkdtempSync, rmSync } from "node:fs"; import { join } from "node:path"; import { spawn } from "node:child_process"; import { once } from "node:events";
import { WorkspaceFsAtV1 } from "../src/workspaces/workspace-fs-at.js"; import { VerifiedWorkspaceLockRootLeaseFactory } from "../src/workspaces/workspace-lock-root-lease.js";
const roots: string[] = []; afterEach(() => { for (const r of roots.splice(0)) rmSync(r, { recursive:true, force:true }); });
function factory(root:string) { return new VerifiedWorkspaceLockRootLeaseFactory({workspaceFsAt:new WorkspaceFsAtV1(),installationId:"i",sessionsRootFromValidatedInstallationConfig:root,serviceUid:process.getuid!(),provisionedWorkspaceMode:0o700}); }
describe("session reader lease", () => {
it("holds a real shared flock across child lifetime and releases exactly once", async () => {
const parent=mkdtempSync(join(process.cwd(),"thoth-readers-")); roots.push(parent); const f=factory(parent); const lease=await f.acquireOrProvision(f.canonicalInput("abc-workspace"));
const shared=await lease.acquireSessionReadersShared(); const child=spawn(process.execPath,[join(process.cwd(),"test/fixtures/workspace-session-readers-worker.mjs")],{cwd:process.cwd(),env:{...process.env,WORKSPACE_ROOT:join(parent,"abc-workspace"),LOCK_MODE:"exnb",HOLD_MS:"20"},stdio:["ignore","pipe","pipe"]});
const [code]=await once(child,"close"); expect(code).toBe(1); await shared.close();
const child2=spawn(process.execPath,[join(process.cwd(),"test/fixtures/workspace-session-readers-worker.mjs")],{cwd:process.cwd(),env:{...process.env,WORKSPACE_ROOT:join(parent,"abc-workspace"),LOCK_MODE:"exnb",HOLD_MS:"5"},stdio:["ignore","pipe","pipe"]}); const [code2]=await once(child2,"close"); expect(code2).toBe(0);
});
it("permits coexisting production shared acquisitions and invalidates the source after transfer", async () => {
const parent=mkdtempSync(join(process.cwd(),"thoth-readers-")); roots.push(parent); const f=factory(parent); const source=await f.acquireOrProvision(f.canonicalInput("abc-workspace")); const second=await f.acquireOrProvision(f.canonicalInput("abc-workspace")); const a=await source.acquireSessionReadersShared(); const b=await second.acquireSessionReadersShared(); expect(a.rootIdentity.inode).toBe(b.rootIdentity.inode); await expect(source.close()).resolves.toBeUndefined(); await a.close(); await b.close();
});
});