diff --git a/server/db.js b/server/db.js index 6d221cc..b88e974 100644 --- a/server/db.js +++ b/server/db.js @@ -133,13 +133,18 @@ export function _resetForTest() { } // ── Boot ────────────────────────────────────────────────────────────────────── +// Skipped in test environment — parallel Vitest workers would race to open +// the same file, causing "database is locked". _resetForTest() in beforeEach +// handles initialisation for every test worker using :memory: instead. -const DB_PATH = process.env.DB_PATH ?? DEFAULT_PATH; -try { - init(DB_PATH); -} catch (e) { - console.error('[catalyst] fatal: could not open database at', DB_PATH); - console.error('[catalyst] ensure the data directory exists and is writable by the server process.'); - console.error(e); - process.exit(1); +if (process.env.NODE_ENV !== 'test') { + const DB_PATH = process.env.DB_PATH ?? DEFAULT_PATH; + try { + init(DB_PATH); + } catch (e) { + console.error('[catalyst] fatal: could not open database at', DB_PATH); + console.error('[catalyst] ensure the data directory exists and is writable by the server process.'); + console.error(e); + process.exit(1); + } } diff --git a/tests/db.test.js b/tests/db.test.js index a61073e..746f2b5 100644 --- a/tests/db.test.js +++ b/tests/db.test.js @@ -165,3 +165,23 @@ describe('deleteInstance', () => { expect(getInstance(2)).not.toBeNull(); }); }); + +// ── Test environment boot isolation ─────────────────────────────────────────── + +describe('test environment boot isolation', () => { + it('vitest runs with NODE_ENV=test', () => { + // Vitest sets NODE_ENV=test automatically. This is the guard condition + // that prevents the boot init() from opening the real database file. + expect(process.env.NODE_ENV).toBe('test'); + }); + + it('db module loads cleanly in parallel workers without locking the real db file', () => { + // Regression: the module-level init(DEFAULT_PATH) used to run unconditionally, + // causing "database is locked" when multiple test workers imported db.js at + // the same time. process.exit(1) then killed the worker mid-suite. + // Fix: boot init is skipped when NODE_ENV=test. _resetForTest() handles setup. + // Reaching this line proves the module loaded without calling process.exit. + expect(() => _resetForTest()).not.toThrow(); + expect(getInstances()).toEqual([]); + }); +});