From 04b13a7489423c5f044d1278808dc5da32dc3335 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Mon, 25 Mar 2019 23:38:21 +0100 Subject: [PATCH] workerForceExit e2e test --- e2e/Utils.ts | 15 +++++++ e2e/__tests__/fatalWorkerError.test.ts | 15 +++---- e2e/__tests__/workerForceExit.test.ts | 62 ++++++++++++++++++++++++++ package.json | 1 + yarn.lock | 9 ++++ 5 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 e2e/__tests__/workerForceExit.test.ts diff --git a/e2e/Utils.ts b/e2e/Utils.ts index c54e6a69bf9d..a921602bbd37 100644 --- a/e2e/Utils.ts +++ b/e2e/Utils.ts @@ -89,6 +89,21 @@ export const writeFiles = ( }); }; +const NUMBER_OF_TESTS_TO_FORCE_USING_WORKERS = 25; +/** + * Forces Jest to use workers by generating many test files to run. + * Slow and modifies the test output. Use sparingly. + */ +export const generateTestFilesToForceUsingWorkers = () => { + const testFiles = {}; + for (let i = 0; i <= NUMBER_OF_TESTS_TO_FORCE_USING_WORKERS; i++) { + testFiles[`__tests__/test${i}.test.js`] = ` + test('test ${i}', () => {}); + `; + } + return testFiles; +}; + export const copyDir = (src: string, dest: string) => { const srcStat = fs.lstatSync(src); if (srcStat.isDirectory()) { diff --git a/e2e/__tests__/fatalWorkerError.test.ts b/e2e/__tests__/fatalWorkerError.test.ts index 72a49181b428..5b091069c763 100644 --- a/e2e/__tests__/fatalWorkerError.test.ts +++ b/e2e/__tests__/fatalWorkerError.test.ts @@ -7,7 +7,11 @@ import path from 'path'; import os from 'os'; -import {cleanup, writeFiles} from '../Utils'; +import { + cleanup, + generateTestFilesToForceUsingWorkers, + writeFiles, +} from '../Utils'; import runJest from '../runJest'; const DIR = path.resolve(os.tmpdir(), 'fatal-worker-error'); @@ -15,10 +19,9 @@ const DIR = path.resolve(os.tmpdir(), 'fatal-worker-error'); beforeEach(() => cleanup(DIR)); afterAll(() => cleanup(DIR)); -const NUMBER_OF_TESTS_TO_FORCE_USING_WORKERS = 25; - test('fails a test that terminates the worker with a fatal error', () => { const testFiles = { + ...generateTestFilesToForceUsingWorkers(), '__tests__/fatalWorkerError.test.js': ` test('fatal worker error', () => { process.exit(134); @@ -26,12 +29,6 @@ test('fails a test that terminates the worker with a fatal error', () => { `, }; - for (let i = 0; i <= NUMBER_OF_TESTS_TO_FORCE_USING_WORKERS; i++) { - testFiles[`__tests__/test${i}.test.js`] = ` - test('test ${i}', () => {}); - `; - } - writeFiles(DIR, { ...testFiles, 'package.json': '{}', diff --git a/e2e/__tests__/workerForceExit.test.ts b/e2e/__tests__/workerForceExit.test.ts new file mode 100644 index 000000000000..b7d851ecfe89 --- /dev/null +++ b/e2e/__tests__/workerForceExit.test.ts @@ -0,0 +1,62 @@ +import {tmpdir} from 'os'; +import {resolve} from 'path'; +import findProcess from 'find-process'; + +import { + cleanup, + generateTestFilesToForceUsingWorkers, + writeFiles, +} from '../Utils'; +import runJest from '../runJest'; + +const DIR = resolve(tmpdir(), 'worker-force-exit'); + +beforeEach(() => cleanup(DIR)); +const testFiles = { + ...generateTestFilesToForceUsingWorkers(), + 'package.json': `{ + "testEnvironment": "node" + }`, +}; +afterEach(() => cleanup(DIR)); + +const verifyNumPassed = stderr => { + const numberOfTestsPassed = (stderr.match(/\bPASS\b/g) || []).length; + // assuming -1 because of package.json, but +1 because of the individual test file + expect(numberOfTestsPassed).toBe(Object.keys(testFiles).length); +}; + +test('prints a warning if a worker is force exited', () => { + writeFiles(DIR, { + ...testFiles, + '__tests__/simple.test.js': ` + test('t', () => { + require('http').createServer().listen(0); + }); + `, + }); + const {status, stderr, stdout} = runJest(DIR, ['--maxWorkers=2']); + + expect(status).toBe(0); + verifyNumPassed(stderr); + expect(stdout).toContain('A worker process has failed to exit gracefully'); +}); + +test('force exits a worker that fails to exit gracefully', async () => { + writeFiles(DIR, { + ...testFiles, + '__tests__/timeoutKilled.test.js': ` + test('t', () => { + require('http').createServer().listen(0); + console.error('pid: ' + process.pid); + }); + `, + }); + const {status, stderr} = runJest(DIR, ['--maxWorkers=2']); + + expect(status).toBe(0); + verifyNumPassed(stderr); + + const [pid] = /pid: \d+/.exec(stderr); + expect(await findProcess('pid', pid)).toHaveLength(0); +}); diff --git a/package.json b/package.json index 24e3e4673486..e9f7fbdea6a0 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "eslint-plugin-react": "^7.1.0", "eslint-plugin-relay": "~0.0.19", "execa": "^1.0.0", + "find-process": "^1.4.1", "glob": "^7.1.1", "graceful-fs": "^4.1.15", "isbinaryfile": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 93b6c8ef0001..4c7ee208ea1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5908,6 +5908,15 @@ find-cache-dir@^2.0.0: make-dir "^1.0.0" pkg-dir "^3.0.0" +find-process@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.1.tgz#628c576a494d1525a27673fb26c77af90db5db02" + integrity sha512-RkYWDeukxEoDKUyocqMGKAYuwhSwq77zL99gCqhX9czWon3otdlzihJ0MSZ6YWNKHyvS/MN2YR4+RGYOuIEANg== + dependencies: + chalk "^2.0.1" + commander "^2.11.0" + debug "^2.6.8" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"