From 841e64e0c1a56e00b50394ff85567f2f6a20faab Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 27 Feb 2020 14:19:24 -0700 Subject: [PATCH] =?UTF-8?q?run=20jest=20with=20`--detectOpenHandles`=20on?= =?UTF-8?q?=20CI=20to=20figure=20out=20what=20i=E2=80=A6=20(#58543)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * run jest with `--detectOpenHandles` on CI to figure out what is happening with pauses * focus tests on jest integration * force kill child processes in config reload test * skip flaky suite * increase timeout for looking for installed packages * run all tests again --- .../reload_logging_config.test.ts | 318 +++++++++--------- .../installed_packages.test.ts | 2 +- tasks/test_jest.js | 2 +- test/scripts/jenkins_xpack.sh | 2 +- 4 files changed, 159 insertions(+), 165 deletions(-) diff --git a/src/cli/serve/integration_tests/reload_logging_config.test.ts b/src/cli/serve/integration_tests/reload_logging_config.test.ts index 2def3569828d3..9ad8438c312a1 100644 --- a/src/cli/serve/integration_tests/reload_logging_config.test.ts +++ b/src/cli/serve/integration_tests/reload_logging_config.test.ts @@ -84,180 +84,174 @@ function createConfigManager(configPath: string) { } describe('Server logging configuration', function() { - let child: Child.ChildProcess; + let child: undefined | Child.ChildProcess; + beforeEach(() => { Fs.mkdirSync(tempDir, { recursive: true }); }); afterEach(async () => { if (child !== undefined) { - child.kill(); - // wait for child to be killed otherwise jest complains that process not finished - await new Promise(res => setTimeout(res, 1000)); + const exitPromise = new Promise(resolve => child?.once('exit', resolve)); + child.kill('SIGKILL'); + await exitPromise; } + Del.sync(tempDir, { force: true }); }); - const isWindows = /^win/.test(process.platform); - if (isWindows) { + if (process.platform.startsWith('win')) { it('SIGHUP is not a feature of Windows.', () => { // nothing to do for Windows }); - } else { - describe('legacy logging', () => { - it( - 'should be reloadable via SIGHUP process signaling', - async function() { - const configFilePath = Path.resolve(tempDir, 'kibana.yml'); - Fs.copyFileSync(legacyConfig, configFilePath); - - child = Child.spawn(process.execPath, [ - kibanaPath, - '--oss', - '--config', - configFilePath, - '--verbose', - ]); - - const message$ = Rx.fromEvent(child.stdout, 'data').pipe( - map(messages => - String(messages) - .split('\n') - .filter(Boolean) - ) - ); - - await message$ - .pipe( - // We know the sighup handler will be registered before this message logged - filter(messages => messages.some(m => m.includes('setting up root'))), - take(1) - ) - .toPromise(); - - const lastMessage = await message$.pipe(take(1)).toPromise(); - expect(containsJsonOnly(lastMessage)).toBe(true); - - createConfigManager(configFilePath).modify(oldConfig => { - oldConfig.logging.json = false; - return oldConfig; - }); - - child.kill('SIGHUP'); - - await message$ - .pipe( - filter(messages => !containsJsonOnly(messages)), - take(1) - ) - .toPromise(); - }, - minute - ); - - it( - 'should recreate file handle on SIGHUP', - async function() { - const logPath = Path.resolve(tempDir, 'kibana.log'); - const logPathArchived = Path.resolve(tempDir, 'kibana_archive.log'); - - child = Child.spawn(process.execPath, [ - kibanaPath, - '--oss', - '--config', - legacyConfig, - '--logging.dest', - logPath, - '--verbose', - ]); - - await watchFileUntil(logPath, /setting up root/, 30 * second); - // once the server is running, archive the log file and issue SIGHUP - Fs.renameSync(logPath, logPathArchived); - child.kill('SIGHUP'); - - await watchFileUntil( - logPath, - /Reloaded logging configuration due to SIGHUP/, - 30 * second - ); - }, - minute - ); - }); - - describe('platform logging', () => { - it( - 'should be reloadable via SIGHUP process signaling', - async function() { - const configFilePath = Path.resolve(tempDir, 'kibana.yml'); - Fs.copyFileSync(configFileLogConsole, configFilePath); - - child = Child.spawn(process.execPath, [kibanaPath, '--oss', '--config', configFilePath]); - - const message$ = Rx.fromEvent(child.stdout, 'data').pipe( - map(messages => - String(messages) - .split('\n') - .filter(Boolean) - ) - ); - - await message$ - .pipe( - // We know the sighup handler will be registered before this message logged - filter(messages => messages.some(m => m.includes('setting up root'))), - take(1) - ) - .toPromise(); - - const lastMessage = await message$.pipe(take(1)).toPromise(); - expect(containsJsonOnly(lastMessage)).toBe(true); - - createConfigManager(configFilePath).modify(oldConfig => { - oldConfig.logging.appenders.console.layout.kind = 'pattern'; - return oldConfig; - }); - child.kill('SIGHUP'); - - await message$ - .pipe( - filter(messages => !containsJsonOnly(messages)), - take(1) - ) - .toPromise(); - }, - 30 * second - ); - it( - 'should recreate file handle on SIGHUP', - async function() { - const configFilePath = Path.resolve(tempDir, 'kibana.yml'); - Fs.copyFileSync(configFileLogFile, configFilePath); - - const logPath = Path.resolve(tempDir, 'kibana.log'); - const logPathArchived = Path.resolve(tempDir, 'kibana_archive.log'); - - createConfigManager(configFilePath).modify(oldConfig => { - oldConfig.logging.appenders.file.path = logPath; - return oldConfig; - }); - - child = Child.spawn(process.execPath, [kibanaPath, '--oss', '--config', configFilePath]); - - await watchFileUntil(logPath, /setting up root/, 30 * second); - // once the server is running, archive the log file and issue SIGHUP - Fs.renameSync(logPath, logPathArchived); - child.kill('SIGHUP'); - - await watchFileUntil( - logPath, - /Reloaded logging configuration due to SIGHUP/, - 30 * second - ); - }, - minute - ); - }); + return; } + + describe('legacy logging', () => { + it( + 'should be reloadable via SIGHUP process signaling', + async function() { + const configFilePath = Path.resolve(tempDir, 'kibana.yml'); + Fs.copyFileSync(legacyConfig, configFilePath); + + child = Child.spawn(process.execPath, [ + kibanaPath, + '--oss', + '--config', + configFilePath, + '--verbose', + ]); + + const message$ = Rx.fromEvent(child.stdout, 'data').pipe( + map(messages => + String(messages) + .split('\n') + .filter(Boolean) + ) + ); + + await message$ + .pipe( + // We know the sighup handler will be registered before this message logged + filter(messages => messages.some(m => m.includes('setting up root'))), + take(1) + ) + .toPromise(); + + const lastMessage = await message$.pipe(take(1)).toPromise(); + expect(containsJsonOnly(lastMessage)).toBe(true); + + createConfigManager(configFilePath).modify(oldConfig => { + oldConfig.logging.json = false; + return oldConfig; + }); + + child.kill('SIGHUP'); + + await message$ + .pipe( + filter(messages => !containsJsonOnly(messages)), + take(1) + ) + .toPromise(); + }, + minute + ); + + it( + 'should recreate file handle on SIGHUP', + async function() { + const logPath = Path.resolve(tempDir, 'kibana.log'); + const logPathArchived = Path.resolve(tempDir, 'kibana_archive.log'); + + child = Child.spawn(process.execPath, [ + kibanaPath, + '--oss', + '--config', + legacyConfig, + '--logging.dest', + logPath, + '--verbose', + ]); + + await watchFileUntil(logPath, /setting up root/, 30 * second); + // once the server is running, archive the log file and issue SIGHUP + Fs.renameSync(logPath, logPathArchived); + child.kill('SIGHUP'); + + await watchFileUntil(logPath, /Reloaded logging configuration due to SIGHUP/, 30 * second); + }, + minute + ); + }); + + describe('platform logging', () => { + it( + 'should be reloadable via SIGHUP process signaling', + async function() { + const configFilePath = Path.resolve(tempDir, 'kibana.yml'); + Fs.copyFileSync(configFileLogConsole, configFilePath); + + child = Child.spawn(process.execPath, [kibanaPath, '--oss', '--config', configFilePath]); + + const message$ = Rx.fromEvent(child.stdout, 'data').pipe( + map(messages => + String(messages) + .split('\n') + .filter(Boolean) + ) + ); + + await message$ + .pipe( + // We know the sighup handler will be registered before this message logged + filter(messages => messages.some(m => m.includes('setting up root'))), + take(1) + ) + .toPromise(); + + const lastMessage = await message$.pipe(take(1)).toPromise(); + expect(containsJsonOnly(lastMessage)).toBe(true); + + createConfigManager(configFilePath).modify(oldConfig => { + oldConfig.logging.appenders.console.layout.kind = 'pattern'; + return oldConfig; + }); + child.kill('SIGHUP'); + + await message$ + .pipe( + filter(messages => !containsJsonOnly(messages)), + take(1) + ) + .toPromise(); + }, + 30 * second + ); + it( + 'should recreate file handle on SIGHUP', + async function() { + const configFilePath = Path.resolve(tempDir, 'kibana.yml'); + Fs.copyFileSync(configFileLogFile, configFilePath); + + const logPath = Path.resolve(tempDir, 'kibana.log'); + const logPathArchived = Path.resolve(tempDir, 'kibana_archive.log'); + + createConfigManager(configFilePath).modify(oldConfig => { + oldConfig.logging.appenders.file.path = logPath; + return oldConfig; + }); + + child = Child.spawn(process.execPath, [kibanaPath, '--oss', '--config', configFilePath]); + + await watchFileUntil(logPath, /setting up root/, 30 * second); + // once the server is running, archive the log file and issue SIGHUP + Fs.renameSync(logPath, logPathArchived); + child.kill('SIGHUP'); + + await watchFileUntil(logPath, /Reloaded logging configuration due to SIGHUP/, 30 * second); + }, + minute + ); + }); }); diff --git a/src/dev/npm/integration_tests/installed_packages.test.ts b/src/dev/npm/integration_tests/installed_packages.test.ts index 5c942005d2eee..75cd0e5607698 100644 --- a/src/dev/npm/integration_tests/installed_packages.test.ts +++ b/src/dev/npm/integration_tests/installed_packages.test.ts @@ -41,7 +41,7 @@ describe('src/dev/npm/installed_packages', () => { includeDev: true, }), ]); - }, 60 * 1000); + }, 360 * 1000); it('reads all installed packages of a module', () => { expect(fixture1Packages).toEqual([ diff --git a/tasks/test_jest.js b/tasks/test_jest.js index ff1a941610ad9..bcb05a83675e5 100644 --- a/tasks/test_jest.js +++ b/tasks/test_jest.js @@ -33,7 +33,7 @@ module.exports = function(grunt) { function runJest(jestScript) { const serverCmd = { cmd: 'node', - args: [jestScript, '--ci'], + args: [jestScript, '--ci', '--detectOpenHandles'], opts: { stdio: 'inherit' }, }; diff --git a/test/scripts/jenkins_xpack.sh b/test/scripts/jenkins_xpack.sh index 3d30496ecb582..b629e064b39b5 100755 --- a/test/scripts/jenkins_xpack.sh +++ b/test/scripts/jenkins_xpack.sh @@ -11,7 +11,7 @@ if [[ -z "$CODE_COVERAGE" ]] ; then echo " -> Running jest tests" cd "$XPACK_DIR" - checks-reporter-with-killswitch "X-Pack Jest" node scripts/jest --ci --verbose + checks-reporter-with-killswitch "X-Pack Jest" node scripts/jest --ci --verbose --detectOpenHandles echo "" echo ""