Skip to content

Commit ec17597

Browse files
fix(test): replace --runInBand with worker children + per-worker DB isolation (#3558)
* fix(test): replace --runInBand with worker children + per-worker DB isolation Drops --runInBand from test:coverage so Jest spawns worker child processes, making workerIdleMemoryLimit (#3550) effective and preventing the 4.9 GB OOM seen in trawl_node (#1074). Adds JEST_WORKER_ID suffix to db.uri in config/index.js so each worker targets an independent MongoDB database, preventing data races when the CI DEVKIT_NODE_db_uri override is active. globalSetup (no JEST_WORKER_ID) continues to operate on the unsuffixed URI. * fix(test): use URL API for worker DB URI suffix (safer path manipulation) Replaces the regex-based URI suffix with the URL API to correctly append the worker suffix to the database name path segment. Handles URIs with no explicit db name (defaults to 'test'), preserves query strings, and avoids potential corruption of host/port components.
1 parent f09c684 commit ec17597

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

config/index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,28 @@ const initGlobalConfig = async () => {
169169
// Print a warning if config.domain is not set
170170
if (process.env.NODE_ENV !== 'test') configHelper.validateDomainIsSet(config);
171171
if (process.env.NODE_ENV !== 'test') configHelper.validateJwtSecret(config);
172+
173+
// Worker DB isolation: when running inside a jest worker (--maxWorkers > 1, no --runInBand),
174+
// suffix db.uri with JEST_WORKER_ID so each worker hits an independent MongoDB database.
175+
// Without this, the CI DEVKIT_NODE_db_uri override flattens all workers onto the same DB
176+
// and causes data races. The main jest process (globalSetup) has no JEST_WORKER_ID so it
177+
// operates on the unsuffixed URI, which is intentional (single drop+migrate).
178+
if (process.env.NODE_ENV === 'test' && process.env.JEST_WORKER_ID) {
179+
const workerId = process.env.JEST_WORKER_ID;
180+
const uri = config.db?.uri ?? '';
181+
const workerSuffix = `_w${workerId}`;
182+
if (uri) {
183+
// Use the URL API to safely append the worker suffix to the database name
184+
// in the path segment, avoiding corruption of host/port or query string.
185+
const parsed = new URL(uri);
186+
const dbName = parsed.pathname.replace(/^\//, '') || 'test';
187+
if (!dbName.endsWith(workerSuffix)) {
188+
parsed.pathname = `/${dbName}${workerSuffix}`;
189+
config.db.uri = parsed.toString();
190+
}
191+
}
192+
}
193+
172194
// Expose configuration utilities
173195
const conf = { ...config };
174196
conf.utils = {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"test:integration": "cross-env NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --runInBand --testPathPatterns='integration'",
3535
"test:e2e": "cross-env NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --runInBand --testPathPatterns='e2e'",
3636
"test:watch": "cross-env NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --watchAll",
37-
"test:coverage": "cross-env NODE_ENV=test NODE_OPTIONS=\"--experimental-vm-modules --max-old-space-size=6144 --expose-gc\" jest --coverage --runInBand",
37+
"test:coverage": "cross-env NODE_ENV=test NODE_OPTIONS=\"--experimental-vm-modules --max-old-space-size=6144 --expose-gc\" jest --coverage --maxWorkers=2",
3838
"test:parallel-smoke": "cross-env NODE_ENV=test node scripts/parallel-integration.smoke.js",
3939
"lint": "eslint ./modules ./lib ./config ./scripts",
4040
"seed:dev": "cross-env NODE_ENV=development node scripts/seed.js seed",

0 commit comments

Comments
 (0)