maestro/src/instance-lock.test.ts
oss-sync c526adddc2
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (402599f)
2026-06-04 13:41:33 +00:00

60 lines
2.0 KiB
TypeScript

import { describe, it, expect, afterEach } from 'vitest';
import { mkdtempSync, writeFileSync, existsSync, rmSync } from 'fs';
import { tmpdir, hostname } from 'os';
import { join } from 'path';
import { acquireWorkerLock } from './instance-lock.js';
const dirs: string[] = [];
function tmpDb(): string {
const d = mkdtempSync(join(tmpdir(), 'maestro-lock-'));
dirs.push(d);
return join(d, 'maestro.db');
}
afterEach(() => {
for (const d of dirs) rmSync(d, { recursive: true, force: true });
dirs.length = 0;
delete process.env['MAESTRO_FORCE_WORKER_LOCK'];
});
describe('acquireWorkerLock', () => {
it('writes a lock file and release() removes it', () => {
const db = tmpDb();
const lock = acquireWorkerLock(db);
expect(existsSync(lock.path)).toBe(true);
lock.release();
expect(existsSync(lock.path)).toBe(false);
lock.release(); // idempotent
});
it('throws when a live process on this host already holds the lock', () => {
const db = tmpDb();
// process.ppid is alive (it spawned us) and is not our pid.
writeFileSync(`${db}.worker.lock`, JSON.stringify({
pid: process.ppid, host: hostname(), startedAt: new Date().toISOString(),
}));
expect(() => acquireWorkerLock(db)).toThrow(/already running/);
});
it('reclaims a stale lock from a dead pid', () => {
const db = tmpDb();
writeFileSync(`${db}.worker.lock`, JSON.stringify({
pid: 2147483646, host: hostname(), startedAt: new Date().toISOString(),
}));
const lock = acquireWorkerLock(db); // must not throw
expect(existsSync(lock.path)).toBe(true);
lock.release();
});
it('MAESTRO_FORCE_WORKER_LOCK=1 overrides a live lock', () => {
const db = tmpDb();
writeFileSync(`${db}.worker.lock`, JSON.stringify({
pid: process.ppid, host: hostname(), startedAt: new Date().toISOString(),
}));
process.env['MAESTRO_FORCE_WORKER_LOCK'] = '1';
const lock = acquireWorkerLock(db);
expect(existsSync(lock.path)).toBe(true);
lock.release();
});
});