fix: skip db boot init in test env to prevent parallel worker lock
Vitest runs test files in parallel workers. Each worker imports server/db.js, which triggered module-level init(DEFAULT_PATH) unconditionally. Two workers racing to open the same SQLite file caused "database is locked", followed by process.exit(1) killing the worker — surfacing as: Error: process.exit unexpectedly called with "1" Fix: guard the boot init block behind NODE_ENV !== 'test'. Vitest sets NODE_ENV=test automatically. Each worker's beforeEach(() => _resetForTest()) initialises its own :memory: database, so no file coordination is needed. process.exit(1) is also guarded by the same condition — it must never fire inside a test runner process. TDD: two regression tests added to tests/db.test.js documenting the expected boot behaviour and proving the module loads cleanly in parallel. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -133,7 +133,11 @@ 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.
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
const DB_PATH = process.env.DB_PATH ?? DEFAULT_PATH;
|
||||
try {
|
||||
init(DB_PATH);
|
||||
@@ -143,3 +147,4 @@ try {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user