import * as fs from "fs"; import * as os from "os"; import * as path from "path"; import { describe, it, expect, afterEach } from "vitest"; import { acquireLock } from "../../src/runtime/lockfile"; function makeTmpDir(): string { const suffix = Math.random().toString(36).slice(2); const dir = path.join(os.tmpdir(), `disclaw-test-${suffix}`); fs.mkdirSync(dir, { recursive: true }); return dir; } describe("acquireLock", () => { const dirs: string[] = []; afterEach(() => { for (const dir of dirs) { fs.rmSync(dir, { recursive: true, force: true }); } dirs.length = 0; }); it("(a) first acquire writes lock file with correct PID", async () => { const dir = makeTmpDir(); dirs.push(dir); const lockPath = path.join(dir, ".disclaw.lock"); const release = await acquireLock(lockPath); expect(fs.existsSync(lockPath)).toBe(true); const data = JSON.parse(fs.readFileSync(lockPath, "utf-8")) as { pid: number; started: string; }; expect(data.pid).toBe(process.pid); expect(typeof data.started).toBe("string"); expect(data.started).toMatch(/^\d{4}-\d{2}-\d{2}T/); release(); }); it("(b) second acquire on same live lock throws", async () => { const dir = makeTmpDir(); dirs.push(dir); const lockPath = path.join(dir, ".disclaw.lock"); const release = await acquireLock(lockPath); await expect(acquireLock(lockPath)).rejects.toThrow( `DisClaw bereits aktiv (PID ${process.pid})` ); release(); }); it("(c) stale lock (dead PID) is overwritten", async () => { const dir = makeTmpDir(); dirs.push(dir); const lockPath = path.join(dir, ".disclaw.lock"); // Write a stale lock with a PID that almost certainly doesn't exist const staleData = { pid: 99999999, started: new Date().toISOString() }; fs.writeFileSync(lockPath, JSON.stringify(staleData), "utf-8"); const release = await acquireLock(lockPath); const data = JSON.parse(fs.readFileSync(lockPath, "utf-8")) as { pid: number; started: string; }; expect(data.pid).toBe(process.pid); release(); }); it("(d) release() deletes the lock file", async () => { const dir = makeTmpDir(); dirs.push(dir); const lockPath = path.join(dir, ".disclaw.lock"); const release = await acquireLock(lockPath); expect(fs.existsSync(lockPath)).toBe(true); release(); expect(fs.existsSync(lockPath)).toBe(false); }); });