Skip to content

Commit 05f5634

Browse files
committed
#8708 Implement globalSetupPerWorker
1 parent e5c1453 commit 05f5634

File tree

5 files changed

+73
-7
lines changed

5 files changed

+73
-7
lines changed

packages/jest-runner/src/__tests__/testRunner.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jest.mock('jest-worker', () => ({
2020
end: jest.fn().mockResolvedValue({forceExited: false}),
2121
getStderr: jest.fn(),
2222
getStdout: jest.fn(),
23+
runInAllWorkers: jest.fn(),
2324
worker: jest.fn((data, callback) => require(worker)(data, callback)),
2425
}),
2526
),

packages/jest-runner/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
import {performance} from 'perf_hooks';
89
import chalk from 'chalk';
910
import Emittery from 'emittery';
1011
import pLimit from 'p-limit';
@@ -171,6 +172,16 @@ export default class TestRunner extends EmittingTestRunner {
171172
});
172173
});
173174

175+
if (tests.length > 0) {
176+
performance.mark('jest/globalSetupPerWorker:start');
177+
await worker.runInAllWorkers('runGlobal', {
178+
allTests: tests,
179+
globalConfig: this._globalConfig,
180+
moduleName: 'globalSetupPerWorker',
181+
});
182+
performance.mark('jest/globalSetupPerWorker:end');
183+
}
184+
174185
const runAllTests = Promise.all(
175186
tests.map(test =>
176187
runTestInWorker(test).then(

packages/jest-runner/src/runGlobalHook.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ export default async function runGlobalHook({
1818
}: {
1919
allTests: Array<Test>;
2020
globalConfig: Config.GlobalConfig;
21-
moduleName: 'globalSetup' | 'globalTeardown';
21+
moduleName:
22+
| 'globalSetup'
23+
| 'globalSetupPerWorker'
24+
| 'globalTeardown'
25+
| 'globalTeardownPerWorker';
2226
}): Promise<void> {
2327
const globalModulePaths = new Set(
2428
allTests.map(test => test.context.config[moduleName]),

packages/jest-runner/src/testWorker.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import exit from 'exit-x';
1010
import type {
1111
SerializableError,
12+
Test,
1213
TestFileEvent,
1314
TestResult,
1415
} from '@jest/test-result';
@@ -18,6 +19,7 @@ import {separateMessageFromStack} from 'jest-message-util';
1819
import type Resolver from 'jest-resolve';
1920
import Runtime from 'jest-runtime';
2021
import {messageParent} from 'jest-worker';
22+
import runGlobalHook from './runGlobalHook';
2123
import runTest from './runTest';
2224
import type {ErrorWithCode, TestRunnerSerializedContext} from './types';
2325

@@ -114,3 +116,11 @@ export async function worker({
114116
throw formatError(error);
115117
}
116118
}
119+
120+
export async function runGlobal(args: {
121+
allTests: Array<Test>;
122+
globalConfig: Config.GlobalConfig;
123+
moduleName: 'globalSetupPerWorker' | 'globalTeardownPerWorker';
124+
}): Promise<void> {
125+
return await runGlobalHook(args);
126+
}

packages/jest-worker/src/index.ts

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ import {isAbsolute} from 'path';
1010
import {fileURLToPath} from 'url';
1111
import Farm from './Farm';
1212
import WorkerPool from './WorkerPool';
13-
import type {
14-
PoolExitResult,
15-
WorkerFarmOptions,
16-
WorkerModule,
17-
WorkerPoolInterface,
18-
WorkerPoolOptions,
13+
import {
14+
CHILD_MESSAGE_CALL,
15+
type ChildMessageCall,
16+
type OnEnd,
17+
type PoolExitResult,
18+
type WorkerFarmOptions,
19+
type WorkerModule,
20+
type WorkerPoolInterface,
21+
type WorkerPoolOptions,
1922
} from './types';
2023

2124
export {default as PriorityQueue} from './PriorityQueue';
@@ -171,6 +174,39 @@ export class Worker {
171174
return this._workerPool.getStdout();
172175
}
173176

177+
async runInAllWorkers(
178+
method: string,
179+
...args: Array<unknown>
180+
): Promise<Array<unknown>> {
181+
const promises = this._workerPool.getWorkers().map(
182+
worker =>
183+
new Promise((resolve, reject) => {
184+
const request: ChildMessageCall = [
185+
CHILD_MESSAGE_CALL,
186+
false,
187+
method,
188+
args,
189+
];
190+
191+
const onStart = noop;
192+
193+
const onEnd: OnEnd = (error: Error | null, result: unknown) => {
194+
if (error) {
195+
reject(error);
196+
} else {
197+
resolve(result);
198+
}
199+
};
200+
201+
const onCustomMessage = noop;
202+
203+
worker.send(request, onStart, onEnd, onCustomMessage);
204+
}),
205+
);
206+
207+
return await Promise.all(promises);
208+
}
209+
174210
async start(): Promise<void> {
175211
await this._workerPool.start();
176212
}
@@ -184,3 +220,7 @@ export class Worker {
184220
return this._workerPool.end();
185221
}
186222
}
223+
224+
function noop(): void {
225+
// noop
226+
}

0 commit comments

Comments
 (0)