From aa72b6c086ec747098a814642a60bc681d57d44a Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Thu, 16 Mar 2023 14:41:46 -0700 Subject: [PATCH 1/5] Restart worker if shut down --- packages/jest-worker/src/WorkerPool.ts | 1 + .../jest-worker/src/base/BaseWorkerPool.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/jest-worker/src/WorkerPool.ts b/packages/jest-worker/src/WorkerPool.ts index 4ac1da31c7a1..baa5f1cb43c7 100644 --- a/packages/jest-worker/src/WorkerPool.ts +++ b/packages/jest-worker/src/WorkerPool.ts @@ -24,6 +24,7 @@ class WorkerPool extends BaseWorkerPool implements WorkerPoolInterface { onEnd: OnEnd, onCustomMessage: OnCustomMessage, ): void { + this.restartWorkerIfShutDown(workerId); this.getWorkerById(workerId).send(request, onStart, onEnd, onCustomMessage); } diff --git a/packages/jest-worker/src/base/BaseWorkerPool.ts b/packages/jest-worker/src/base/BaseWorkerPool.ts index 92896aab5b2c..c26d7b4b1ee3 100644 --- a/packages/jest-worker/src/base/BaseWorkerPool.ts +++ b/packages/jest-worker/src/base/BaseWorkerPool.ts @@ -13,6 +13,7 @@ import { WorkerInterface, WorkerOptions, WorkerPoolOptions, + WorkerStates, } from '../types'; // How long to wait for the child process to terminate @@ -28,9 +29,11 @@ export default class BaseWorkerPool { private readonly _stdout: NodeJS.ReadableStream; protected readonly _options: WorkerPoolOptions; private readonly _workers: Array; + private readonly _workerPath: string; constructor(workerPath: string, options: WorkerPoolOptions) { this._options = options; + this._workerPath = workerPath; this._workers = new Array(options.numWorkers); const stdout = mergeStream(); @@ -84,6 +87,24 @@ export default class BaseWorkerPool { return this._workers[workerId]; } + restartWorkerIfShutDown(workerId: number): void { + if (this._workers[workerId].state === WorkerStates.SHUT_DOWN) { + const {forkOptions, maxRetries, resourceLimits, setupArgs} = + this._options; + const workerOptions: WorkerOptions = { + forkOptions, + idleMemoryLimit: this._options.idleMemoryLimit, + maxRetries, + resourceLimits, + setupArgs, + workerId, + workerPath: this._workerPath, + }; + const worker = this.createWorker(workerOptions); + this._workers[workerId] = worker; + } + } + createWorker(_workerOptions: WorkerOptions): WorkerInterface { throw Error('Missing method createWorker in WorkerPool'); } From edb8a623fb2c0097355e18db2dfdb442521b3b0b Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Thu, 16 Mar 2023 14:42:12 -0700 Subject: [PATCH 2/5] tests --- .../workerRestartBeforeSend.test.ts.snap | 9 ++++ e2e/__tests__/workerRestartBeforeSend.test.ts | 15 +++++++ .../__snapshots__/snapshot.test.js.snap | 31 ++++++++++++++ .../__snapshots__/snapshot.test_copy.js.snap | 31 ++++++++++++++ e2e/snapshot/__tests__/snapshot.test_copy.js | 41 +++++++++++++++++++ .../__tests__/custom-matchers.test.js | 9 ++++ .../accept-custom-snapshot-name.test.js | 3 ++ .../__tests__/test1.js | 15 +++++++ .../__tests__/test2.js | 10 +++++ .../__tests__/test3.js | 10 +++++ e2e/worker-restart-before-send/package.json | 6 +++ .../testSequencer.js | 13 ++++++ 12 files changed, 193 insertions(+) create mode 100644 e2e/__tests__/__snapshots__/workerRestartBeforeSend.test.ts.snap create mode 100644 e2e/__tests__/workerRestartBeforeSend.test.ts create mode 100644 e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap create mode 100644 e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap create mode 100644 e2e/snapshot/__tests__/snapshot.test_copy.js create mode 100644 e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js create mode 100644 e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js create mode 100644 e2e/worker-restart-before-send/__tests__/test1.js create mode 100644 e2e/worker-restart-before-send/__tests__/test2.js create mode 100644 e2e/worker-restart-before-send/__tests__/test3.js create mode 100644 e2e/worker-restart-before-send/package.json create mode 100644 e2e/worker-restart-before-send/testSequencer.js diff --git a/e2e/__tests__/__snapshots__/workerRestartBeforeSend.test.ts.snap b/e2e/__tests__/__snapshots__/workerRestartBeforeSend.test.ts.snap new file mode 100644 index 000000000000..33a283aa2937 --- /dev/null +++ b/e2e/__tests__/__snapshots__/workerRestartBeforeSend.test.ts.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`all 3 test files should complete 1`] = ` +"Test Suites: 1 failed, 2 passed, 3 total +Tests: 2 passed, 2 total +Snapshots: 0 total +Time: <> +Ran all test suites." +`; diff --git a/e2e/__tests__/workerRestartBeforeSend.test.ts b/e2e/__tests__/workerRestartBeforeSend.test.ts new file mode 100644 index 000000000000..0d8aaf05c945 --- /dev/null +++ b/e2e/__tests__/workerRestartBeforeSend.test.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {extractSummary} from '../Utils'; +import runJest from '../runJest'; + +it('all 3 test files should complete', () => { + const result = runJest('worker-restart-before-send'); + const {summary} = extractSummary(result.stderr); + expect(summary).toMatchSnapshot(); +}); diff --git a/e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap b/e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap new file mode 100644 index 000000000000..4d9551f6b936 --- /dev/null +++ b/e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`snapshot is not influenced by previous counter 1`] = ` +{ + "a": 43, + "b": "43", + "c": "fortythree", +} +`; + +exports[`snapshot works with \\r\\n 1`] = ` +"
+
" +`; + +exports[`snapshot works with plain objects and the title has \`escape\` characters 1`] = ` +{ + "a": 1, + "b": "2", + "c": "three\`", +} +`; + +exports[`snapshot works with plain objects and the title has \`escape\` characters 2`] = ` +{ + "a": 1, + "b": "2", + "c": "three\`", + "d": "4", +} +`; diff --git a/e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap b/e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap new file mode 100644 index 000000000000..4d9551f6b936 --- /dev/null +++ b/e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`snapshot is not influenced by previous counter 1`] = ` +{ + "a": 43, + "b": "43", + "c": "fortythree", +} +`; + +exports[`snapshot works with \\r\\n 1`] = ` +"
+
" +`; + +exports[`snapshot works with plain objects and the title has \`escape\` characters 1`] = ` +{ + "a": 1, + "b": "2", + "c": "three\`", +} +`; + +exports[`snapshot works with plain objects and the title has \`escape\` characters 2`] = ` +{ + "a": 1, + "b": "2", + "c": "three\`", + "d": "4", +} +`; diff --git a/e2e/snapshot/__tests__/snapshot.test_copy.js b/e2e/snapshot/__tests__/snapshot.test_copy.js new file mode 100644 index 000000000000..3947650b5b36 --- /dev/null +++ b/e2e/snapshot/__tests__/snapshot.test_copy.js @@ -0,0 +1,41 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +'use strict'; + +describe('snapshot', () => { + it('works with plain objects and the title has `escape` characters', () => { + const test = { + a: 1, + b: '2', + c: 'three`', + }; + expect(test).toMatchSnapshot(); + test.d = '4'; + expect(test).toMatchSnapshot(); + }); + + it('is not influenced by previous counter', () => { + const test = { + a: 43, + b: '43', + c: 'fortythree', + }; + expect(test).toMatchSnapshot(); + }); + + it('cannot be used with .not', () => { + expect(() => expect('').not.toMatchSnapshot()).toThrow( + 'Snapshot matchers cannot be used with not', + ); + }); + + // Issue reported here: https://github.com/facebook/jest/issues/2969 + it('works with \\r\\n', () => { + expect('
\r\n
').toMatchSnapshot(); + }); +}); diff --git a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js new file mode 100644 index 000000000000..9b242a435fb5 --- /dev/null +++ b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js @@ -0,0 +1,9 @@ +const { toMatchInlineSnapshot } = require('jest-snapshot'); +expect.extend({ + toMatchCustomInlineSnapshot(received, ...args) { + return toMatchInlineSnapshot.call(this, received, ...args); + } +}); +test('inline snapshots', () => { + expect({apple: "original value"}).toMatchCustomInlineSnapshot(); +}); \ No newline at end of file diff --git a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js new file mode 100644 index 000000000000..2f60cf90ab48 --- /dev/null +++ b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js @@ -0,0 +1,3 @@ +test('accepts custom snapshot name', () => { + expect(true).toMatchSnapshot('custom-name'); +}); \ No newline at end of file diff --git a/e2e/worker-restart-before-send/__tests__/test1.js b/e2e/worker-restart-before-send/__tests__/test1.js new file mode 100644 index 000000000000..a29f99a81bd5 --- /dev/null +++ b/e2e/worker-restart-before-send/__tests__/test1.js @@ -0,0 +1,15 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +test('jest-worker killed', async () => { + await new Promise(resolve => setTimeout(resolve, 100)); +}); + +setTimeout(() => { + // Self-kill process. + process.kill(process.pid); +}, 50); diff --git a/e2e/worker-restart-before-send/__tests__/test2.js b/e2e/worker-restart-before-send/__tests__/test2.js new file mode 100644 index 000000000000..95a24306a6ba --- /dev/null +++ b/e2e/worker-restart-before-send/__tests__/test2.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +test('basic test', async () => { + await new Promise(resolve => setTimeout(resolve, 100)); +}); diff --git a/e2e/worker-restart-before-send/__tests__/test3.js b/e2e/worker-restart-before-send/__tests__/test3.js new file mode 100644 index 000000000000..95a24306a6ba --- /dev/null +++ b/e2e/worker-restart-before-send/__tests__/test3.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +test('basic test', async () => { + await new Promise(resolve => setTimeout(resolve, 100)); +}); diff --git a/e2e/worker-restart-before-send/package.json b/e2e/worker-restart-before-send/package.json new file mode 100644 index 000000000000..4df13823d89a --- /dev/null +++ b/e2e/worker-restart-before-send/package.json @@ -0,0 +1,6 @@ +{ + "jest": { + "maxWorkers": 2, + "testSequencer": "./testSequencer.js" + } +} diff --git a/e2e/worker-restart-before-send/testSequencer.js b/e2e/worker-restart-before-send/testSequencer.js new file mode 100644 index 000000000000..98adff428d6e --- /dev/null +++ b/e2e/worker-restart-before-send/testSequencer.js @@ -0,0 +1,13 @@ +const Sequencer = require('@jest/test-sequencer').default; + +// Ensure that test1.js runs first. +class CustomSequencer extends Sequencer { + sort(tests) { + // Test structure information + // https://github.com/facebook/jest/blob/6b8b1404a1d9254e7d5d90a8934087a9c9899dab/packages/jest-runner/src/types.ts#L17-L21 + const copyTests = Array.from(tests); + return copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1)); + } +} + +module.exports = CustomSequencer; From 7da903750461dc8e8599e1e68c0ed265c1a7a9f3 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 14 Apr 2023 14:54:01 +0200 Subject: [PATCH 3/5] eslint --- .../__tests__/custom-matchers.test.js | 8 ++++---- .../__tests__/accept-custom-snapshot-name.test.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js index 9b242a435fb5..35838d0f4f49 100644 --- a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js +++ b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js @@ -1,9 +1,9 @@ -const { toMatchInlineSnapshot } = require('jest-snapshot'); +const {toMatchInlineSnapshot} = require('jest-snapshot'); expect.extend({ toMatchCustomInlineSnapshot(received, ...args) { return toMatchInlineSnapshot.call(this, received, ...args); - } + }, }); test('inline snapshots', () => { - expect({apple: "original value"}).toMatchCustomInlineSnapshot(); -}); \ No newline at end of file + expect({apple: 'original value'}).toMatchCustomInlineSnapshot(); +}); diff --git a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js index 2f60cf90ab48..d26285032e54 100644 --- a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js +++ b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js @@ -1,3 +1,3 @@ test('accepts custom snapshot name', () => { expect(true).toMatchSnapshot('custom-name'); -}); \ No newline at end of file +}); From 3f8ab1b926740cdebcdc8a0bd821e8264f34067f Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Fri, 14 Apr 2023 15:05:25 +0200 Subject: [PATCH 4/5] copyright headers --- .../__tests__/custom-matchers.test.js | 9 +++++++++ .../__tests__/accept-custom-snapshot-name.test.js | 9 +++++++++ e2e/worker-restart-before-send/testSequencer.js | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js index 35838d0f4f49..68a03e561271 100644 --- a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js +++ b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js @@ -1,3 +1,12 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + const {toMatchInlineSnapshot} = require('jest-snapshot'); expect.extend({ toMatchCustomInlineSnapshot(received, ...args) { diff --git a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js index d26285032e54..aef140b8af30 100644 --- a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js +++ b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js @@ -1,3 +1,12 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + test('accepts custom snapshot name', () => { expect(true).toMatchSnapshot('custom-name'); }); diff --git a/e2e/worker-restart-before-send/testSequencer.js b/e2e/worker-restart-before-send/testSequencer.js index 98adff428d6e..e5a470ed49fe 100644 --- a/e2e/worker-restart-before-send/testSequencer.js +++ b/e2e/worker-restart-before-send/testSequencer.js @@ -1,3 +1,12 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + const Sequencer = require('@jest/test-sequencer').default; // Ensure that test1.js runs first. From a24156f96a601eda92a3da0eaf2129939cefe006 Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Tue, 18 Apr 2023 14:32:40 -0700 Subject: [PATCH 5/5] Delete extra test files --- .../__snapshots__/snapshot.test.js.snap | 31 -------------- .../__snapshots__/snapshot.test_copy.js.snap | 31 -------------- e2e/snapshot/__tests__/snapshot.test_copy.js | 41 ------------------- .../__tests__/custom-matchers.test.js | 18 -------- .../accept-custom-snapshot-name.test.js | 12 ------ 5 files changed, 133 deletions(-) delete mode 100644 e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap delete mode 100644 e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap delete mode 100644 e2e/snapshot/__tests__/snapshot.test_copy.js delete mode 100644 e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js delete mode 100644 e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js diff --git a/e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap b/e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap deleted file mode 100644 index 4d9551f6b936..000000000000 --- a/e2e/snapshot/__tests__/__snapshots__/snapshot.test.js.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`snapshot is not influenced by previous counter 1`] = ` -{ - "a": 43, - "b": "43", - "c": "fortythree", -} -`; - -exports[`snapshot works with \\r\\n 1`] = ` -"
-
" -`; - -exports[`snapshot works with plain objects and the title has \`escape\` characters 1`] = ` -{ - "a": 1, - "b": "2", - "c": "three\`", -} -`; - -exports[`snapshot works with plain objects and the title has \`escape\` characters 2`] = ` -{ - "a": 1, - "b": "2", - "c": "three\`", - "d": "4", -} -`; diff --git a/e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap b/e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap deleted file mode 100644 index 4d9551f6b936..000000000000 --- a/e2e/snapshot/__tests__/__snapshots__/snapshot.test_copy.js.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`snapshot is not influenced by previous counter 1`] = ` -{ - "a": 43, - "b": "43", - "c": "fortythree", -} -`; - -exports[`snapshot works with \\r\\n 1`] = ` -"
-
" -`; - -exports[`snapshot works with plain objects and the title has \`escape\` characters 1`] = ` -{ - "a": 1, - "b": "2", - "c": "three\`", -} -`; - -exports[`snapshot works with plain objects and the title has \`escape\` characters 2`] = ` -{ - "a": 1, - "b": "2", - "c": "three\`", - "d": "4", -} -`; diff --git a/e2e/snapshot/__tests__/snapshot.test_copy.js b/e2e/snapshot/__tests__/snapshot.test_copy.js deleted file mode 100644 index 3947650b5b36..000000000000 --- a/e2e/snapshot/__tests__/snapshot.test_copy.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ -'use strict'; - -describe('snapshot', () => { - it('works with plain objects and the title has `escape` characters', () => { - const test = { - a: 1, - b: '2', - c: 'three`', - }; - expect(test).toMatchSnapshot(); - test.d = '4'; - expect(test).toMatchSnapshot(); - }); - - it('is not influenced by previous counter', () => { - const test = { - a: 43, - b: '43', - c: 'fortythree', - }; - expect(test).toMatchSnapshot(); - }); - - it('cannot be used with .not', () => { - expect(() => expect('').not.toMatchSnapshot()).toThrow( - 'Snapshot matchers cannot be used with not', - ); - }); - - // Issue reported here: https://github.com/facebook/jest/issues/2969 - it('works with \\r\\n', () => { - expect('
\r\n
').toMatchSnapshot(); - }); -}); diff --git a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js b/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js deleted file mode 100644 index 68a03e561271..000000000000 --- a/e2e/to-match-inline-snapshot/__tests__/custom-matchers.test.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -'use strict'; - -const {toMatchInlineSnapshot} = require('jest-snapshot'); -expect.extend({ - toMatchCustomInlineSnapshot(received, ...args) { - return toMatchInlineSnapshot.call(this, received, ...args); - }, -}); -test('inline snapshots', () => { - expect({apple: 'original value'}).toMatchCustomInlineSnapshot(); -}); diff --git a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js b/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js deleted file mode 100644 index aef140b8af30..000000000000 --- a/e2e/to-match-snapshot/__tests__/accept-custom-snapshot-name.test.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -'use strict'; - -test('accepts custom snapshot name', () => { - expect(true).toMatchSnapshot('custom-name'); -});