From 7f1b6c5665af06f76896e524b29446ad13d9610e Mon Sep 17 00:00:00 2001 From: Will Smythe Date: Thu, 7 Feb 2019 16:59:57 -0500 Subject: [PATCH 1/3] fix: Windows-specific test timeout issues introduced by Yarn 1.13.0 See #7760 for details * Change e2e/runJest.js to invoke node directly to avoid issue with hung process/test when invoked asynchronously ("until" method) * Refactor to avoid duplication between runJest and until methods * Undo downgrade of Yarn (to 1.9.4) in Azure Pipelines Windows jobs * Add /reports/* to .gitignore (these are junit test reports normally created in CI runs) --- .azure-pipelines.yml | 1 - .gitignore | 2 ++ e2e/runJest.js | 66 ++++++++++++++++---------------------------- 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index df022b431dec..e28f5b54627b 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -17,7 +17,6 @@ jobs: git config --global core.autocrlf false git config --global core.symlinks true displayName: 'Preserve LF endings and symbolic links on check out' - - script: npm install -g yarn@1.9.4 - template: .azure-pipelines-steps.yml - job: macOS diff --git a/.gitignore b/.gitignore index 60ba0f22d861..ee3195b8c97a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ /website/translated_docs /website/i18n/* +/reports/* + coverage lerna-debug.log npm-debug.log diff --git a/e2e/runJest.js b/e2e/runJest.js index 9df0726a6f26..dbffe4763023 100644 --- a/e2e/runJest.js +++ b/e2e/runJest.js @@ -20,7 +20,8 @@ const JEST_PATH = path.resolve(__dirname, '../packages/jest-cli/bin/jest.js'); type RunJestOptions = { nodePath?: string, skipPkgJsonCheck?: boolean, // don't complain if can't find package.json - stripAnsi?: boolean, // remove colors from stdout and stderr + stripAnsi?: boolean, // remove colors from stdout and stderr, + timeout?: number, // kill the Jest process after X milliseconds }; // return the result of the spawned process: @@ -30,6 +31,16 @@ export default function runJest( dir: string, args?: Array, options: RunJestOptions = {}, +) { + return normalizeResult(spawnJest(dir, args, options), options); +} + +// Spawns Jest and returns either a Promise (if spawnAsync is true) or the completed child process +function spawnJest( + dir: string, + args?: Array, + options: RunJestOptions = {}, + spawnAsync: boolean, ) { const isRelative = !path.isAbsolute(dir); @@ -51,12 +62,20 @@ export default function runJest( const env = {...process.env, FORCE_COLOR: 0}; if (options.nodePath) env['NODE_PATH'] = options.nodePath; - const result = spawnSync(JEST_PATH, args || [], { + + const spawnArgs = [JEST_PATH, ...(args || [])]; + const spawnOptions = { cwd: dir, env, reject: false, - }); + timeout: options.timeout || 0, + }; + + return (spawnAsync ? execa : execa.sync) + (process.execPath, spawnArgs, spawnOptions); +} +function normalizeResult(result, options) { // For compat with cross-spawn result.status = result.code; @@ -101,34 +120,7 @@ export const until = async function( text: string, options: RunJestOptions = {}, ) { - const isRelative = !path.isAbsolute(dir); - - if (isRelative) { - dir = path.resolve(__dirname, dir); - } - - const localPackageJson = path.resolve(dir, 'package.json'); - if (!options.skipPkgJsonCheck && !fs.existsSync(localPackageJson)) { - throw new Error( - ` - Make sure you have a local package.json file at - "${localPackageJson}". - Otherwise Jest will try to traverse the directory tree and find the - the global package.json, which will send Jest into infinite loop. - `, - ); - } - - const env = {...process.env, FORCE_COLOR: 0}; - if (options.nodePath) env['NODE_PATH'] = options.nodePath; - - const jestPromise = execa(JEST_PATH, args || [], { - cwd: dir, - env, - reject: false, - // this should never take more than 5-6 seconds, bailout after 30 - timeout: 30000, - }); + const jestPromise = spawnJest(dir, args, {timeout: 30000, ...options}, true); jestPromise.stderr.pipe( new Writable({ @@ -144,15 +136,5 @@ export const until = async function( }), ); - const result = await jestPromise; - - // For compat with cross-spawn - result.status = result.code; - - result.stdout = normalizeIcons(result.stdout); - if (options.stripAnsi) result.stdout = stripAnsi(result.stdout); - result.stderr = normalizeIcons(result.stderr); - if (options.stripAnsi) result.stderr = stripAnsi(result.stderr); - - return result; + return normalizeResult(await jestPromise, options); }; From 7ee33af30bd4ae95648ab6313b0dded17dcb9ab1 Mon Sep 17 00:00:00 2001 From: Will Smythe Date: Fri, 8 Feb 2019 15:59:43 -0500 Subject: [PATCH 2/3] Fix lint problems --- e2e/runJest.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/e2e/runJest.js b/e2e/runJest.js index dbffe4763023..614ab245f651 100644 --- a/e2e/runJest.js +++ b/e2e/runJest.js @@ -10,7 +10,7 @@ import path from 'path'; import fs from 'fs'; -import execa, {sync as spawnSync} from 'execa'; +import execa from 'execa'; import {Writable} from 'readable-stream'; import stripAnsi from 'strip-ansi'; import {normalizeIcons} from './Utils'; @@ -71,8 +71,11 @@ function spawnJest( timeout: options.timeout || 0, }; - return (spawnAsync ? execa : execa.sync) - (process.execPath, spawnArgs, spawnOptions); + return (spawnAsync ? execa : execa.sync)( + process.execPath, + spawnArgs, + spawnOptions, + ); } function normalizeResult(result, options) { From c1e64d355433a414c43c363fd98657c33f879b90 Mon Sep 17 00:00:00 2001 From: Will Smythe Date: Fri, 8 Feb 2019 16:38:08 -0500 Subject: [PATCH 3/3] fix flow check error in runJest.js --- e2e/runJest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/runJest.js b/e2e/runJest.js index 614ab245f651..ce6a9f8ba943 100644 --- a/e2e/runJest.js +++ b/e2e/runJest.js @@ -40,7 +40,7 @@ function spawnJest( dir: string, args?: Array, options: RunJestOptions = {}, - spawnAsync: boolean, + spawnAsync: boolean = false, ) { const isRelative = !path.isAbsolute(dir);