From 10900980392b1b5253bea10f5b0f0b4a97da0d22 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 29 Oct 2020 15:43:04 +0100 Subject: [PATCH 01/26] Bump @types/webpack-env to v1.15.3 for compatibility with Node.js 12 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ade567c840da7..86340c5a9eb35 100644 --- a/package.json +++ b/package.json @@ -561,7 +561,7 @@ "@types/vinyl-fs": "^2.4.11", "@types/watchpack": "^1.1.5", "@types/webpack": "^4.41.3", - "@types/webpack-env": "^1.15.2", + "@types/webpack-env": "^1.15.3", "@types/webpack-merge": "^4.1.5", "@types/write-pkg": "^3.1.0", "@types/xml-crypto": "^1.4.1", diff --git a/yarn.lock b/yarn.lock index 0b429c96c1847..651e31e320d1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5881,10 +5881,10 @@ "@types/node" "*" chokidar "^2.1.2" -"@types/webpack-env@^1.15.2": - version "1.15.2" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a" - integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ== +"@types/webpack-env@^1.15.2", "@types/webpack-env@^1.15.3": + version "1.15.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.3.tgz#fb602cd4c2f0b7c0fb857e922075fdf677d25d84" + integrity sha512-5oiXqR7kwDGZ6+gmzIO2lTC+QsriNuQXZDWNYRV3l2XRN/zmPgnC21DLSx2D05zvD8vnXW6qUg7JnXZ4I6qLVQ== "@types/webpack-merge@^4.1.5": version "4.1.5" From cf4f127a5aa14854961463c5a6e5ae416374d5e7 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 2 Apr 2020 13:15:46 +0200 Subject: [PATCH 02/26] Improve ignore-logic in exit-on-warning guard --- src/setup_node_env/exit_on_warning.js | 67 +++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/setup_node_env/exit_on_warning.js b/src/setup_node_env/exit_on_warning.js index c0a0f0ecc0b83..3180823d72205 100644 --- a/src/setup_node_env/exit_on_warning.js +++ b/src/setup_node_env/exit_on_warning.js @@ -17,11 +17,28 @@ * under the License. */ -if (process.noProcessWarnings !== true) { - var ignore = ['MaxListenersExceededWarning']; +var EOL = require('os').EOL; + +// Be very careful of what you add to this list. Idealy this array should be +// empty, but in certain circumstances, we can allow a warning to be ignored +// temporarily. +// +// Each element in the array is a "rule-object". All rules defined in a +// "rule-object" has to match for a warning to be ignored. Possible rules are: +// `name`, `code`, `message`, `file`, `lines`, and `col`. +// +// The `file`, `line`, and `col` rules will be checked against the top stack +// frame only. Also, `file` doesn't have to match the full path, only the end of +// it. +var IGNORE_WARNINGS = [ + { + name: 'MaxListenersExceededWarning', + }, +]; +if (process.noProcessWarnings !== true) { process.on('warning', function (warn) { - if (ignore.includes(warn.name)) return; + if (shouldIgnore(warn)) return; if (process.traceProcessWarnings === true) { console.error('Node.js process-warning detected - Terminating process...'); @@ -48,3 +65,47 @@ if (process.noProcessWarnings !== true) { process.exit(1); }); } + +function shouldIgnore(warn) { + warn = parseWarn(warn); + return IGNORE_WARNINGS.some(function ({ name, code, message, file, line, col }) { + if (name && name !== warn.name) return false; + if (code && code !== warn.code) return false; + if (message && message !== warn.message) return false; + if (file && !warn.frames[0].file.endsWith(file)) return false; + if (line && line !== warn.frames[0].line) return false; + if (col && col !== warn.frames[0].col) return false; + return true; + }); +} + +function parseWarn(warn) { + var lines = warn.stack.split(EOL); + return { + name: warn.name, + code: warn.code, + message: lines[0].split(': ')[1], + frames: parseStack(lines.slice(1)), + }; +} + +function parseStack(stack) { + return stack.map(parseFrame).filter(function (frame) { + return frame; + }); +} + +function parseFrame(frame) { + // supports the following frame types: + // - " at function-name (file-path:1:2)" + // - " at function-name (file-path)" + // - " at file-path:1:2" + var match = frame.match(/^ at (?:([^(]+) )?\(?([^:)]+)(?::(\d+):(\d+))?\)?$/); + if (match === null) return; // in case the stack trace is modified by another module, e.g. jest + return { + func: match[1], + file: match[2], + line: Number(match[3]), + col: Number(match[4]), + }; +} From 4f132932236e98a305b34d973f27a969e9507131 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 27 Mar 2020 10:11:32 +0100 Subject: [PATCH 03/26] Bump Node.js version from 10.19.0 to 12.19.0 --- .ci/Dockerfile | 2 +- .node-version | 2 +- .nvmrc | 2 +- package.json | 2 +- src/dev/build/tasks/patch_native_modules_task.ts | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.ci/Dockerfile b/.ci/Dockerfile index d6eee046611bb..9ac6c32772e4b 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -1,7 +1,7 @@ # NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable. # If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts -ARG NODE_VERSION=10.22.1 +ARG NODE_VERSION=12.19.0 FROM node:${NODE_VERSION} AS base diff --git a/.node-version b/.node-version index c2f6421352c48..260a0e20f68fe 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -10.22.1 +12.19.0 diff --git a/.nvmrc b/.nvmrc index c2f6421352c48..260a0e20f68fe 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -10.22.1 +12.19.0 diff --git a/package.json b/package.json index 86340c5a9eb35..da3ee535bea00 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "**/typescript": "4.0.2" }, "engines": { - "node": "10.22.1", + "node": "12.19.0", "yarn": "^1.21.1" }, "dependencies": { diff --git a/src/dev/build/tasks/patch_native_modules_task.ts b/src/dev/build/tasks/patch_native_modules_task.ts index b56d01b616462..c3011fa80988c 100644 --- a/src/dev/build/tasks/patch_native_modules_task.ts +++ b/src/dev/build/tasks/patch_native_modules_task.ts @@ -47,16 +47,16 @@ const packages: Package[] = [ extractMethod: 'gunzip', archives: { darwin: { - url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/darwin-x64-64.gz', - sha256: '595c6653d796493ddb288fc0732a0d1df8560099796f55a1dd242357d96bb8d6', + url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/darwin-x64-72.gz', + sha256: '983106049bb86e21b7f823144b2b83e3f1408217401879b3cde0312c803512c9', }, linux: { - url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/linux-x64-64.gz', - sha256: 'e743587bc96314edf10c3e659c03168bc374a5cd9a6623ee99d989251e331f28', + url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/linux-x64-72.gz', + sha256: '8b6692037f7b0df24dabc9c9b039038d1c3a3110f62121616b406c482169710a', }, win32: { - url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/win32-x64-64.gz', - sha256: 'b33de62cda24fb02dc80a19fb79977d686468ac746e97cd211059d2d4c75d529', + url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/win32-x64-72.gz', + sha256: '0a6991e693577160c3e9a3f196bd2518368c52d920af331a1a183313e0175604', }, }, }, From 7eada67549d7b983ef083ef0dec376d9b1369575 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 27 Mar 2020 10:12:21 +0100 Subject: [PATCH 04/26] Bump @types/node version from 10.17.17 to 12.19.3 --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index da3ee535bea00..0ad9e442b1b00 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "**/@types/hapi__boom": "^7.4.1", "**/@types/hapi__hapi": "^18.2.6", "**/@types/hapi__mimos": "4.1.0", - "**/@types/node": ">=10.17.17 <10.20.0", + "**/@types/node": ">=12.12.64 <12.20.0", "**/cross-fetch/node-fetch": "^2.6.1", "**/deepmerge": "^4.2.2", "**/fast-deep-equal": "^3.1.1", @@ -499,7 +499,7 @@ "@types/mustache": "^0.8.31", "@types/ncp": "^2.0.1", "@types/nock": "^10.0.3", - "@types/node": ">=10.17.17 <10.20.0", + "@types/node": ">=12.12.64 <12.20.0", "@types/node-fetch": "^2.5.7", "@types/node-forge": "^0.9.5", "@types/nodemailer": "^6.2.1", diff --git a/yarn.lock b/yarn.lock index 651e31e320d1d..799a8362a8e6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5272,10 +5272,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@8.10.54", "@types/node@>= 8", "@types/node@>=10.17.17 <10.20.0", "@types/node@>=8.9.0", "@types/node@^12.0.2": - version "10.17.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.26.tgz#a8a119960bff16b823be4c617da028570779bcfd" - integrity sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw== +"@types/node@*", "@types/node@8.10.54", "@types/node@>= 8", "@types/node@>=12.12.64 <12.20.0", "@types/node@>=8.9.0", "@types/node@^12.0.2": + version "12.19.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.3.tgz#a6e252973214079155f749e8bef99cc80af182fa" + integrity sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg== "@types/nodemailer@^6.2.1": version "6.2.1" From ff14353d640c965f80191b431390db79d33becfb Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 27 Mar 2020 10:12:47 +0100 Subject: [PATCH 05/26] Fix TypeScript errors related to new @types/node version --- .../kbn-dev-utils/src/proc_runner/proc.ts | 8 ++++---- .../kbn-optimizer/src/optimizer/get_mtimes.ts | 2 +- .../src/optimizer/observe_worker.ts | 6 ++++-- packages/kbn-pm/src/commands/watch.ts | 2 +- packages/kbn-pm/src/utils/child_process.ts | 4 ++-- .../lib/docker_servers/container_logs.ts | 4 ++-- packages/kbn-test/src/kbn/kbn_test_config.ts | 4 ++-- .../reload_logging_config.test.ts | 10 ++++++---- src/core/public/http/types.ts | 19 +++++++++++++------ src/core/public/utils/crypto/sha256.ts | 14 +++++++++++++- .../client/configure_client.test.ts | 1 - src/core/server/http/ssl_config.ts | 6 +----- .../logging/appenders/file/file_appender.ts | 2 +- .../plugins/discovery/plugins_discovery.ts | 6 +++--- src/dev/build/lib/scan_delete.ts | 2 +- src/dev/build/lib/watch_stdio_for_line.ts | 4 ++-- src/dev/prs/run_update_prs_cli.ts | 5 ++++- .../state_management/url/kbn_url_storage.ts | 5 +++-- .../routes/lib/short_url_assert_valid.ts | 2 +- .../services/remote/create_stdout_stream.ts | 2 +- .../chromium/driver/chromium_driver.ts | 9 +++------ .../export_types/common/get_full_urls.ts | 6 +++--- .../utils/clone_http_fetch_query.test.ts | 3 +-- .../public/management/common/routing.ts | 2 +- .../spaces/common/lib/spaces_url_parser.ts | 6 ++++-- 25 files changed, 77 insertions(+), 57 deletions(-) diff --git a/packages/kbn-dev-utils/src/proc_runner/proc.ts b/packages/kbn-dev-utils/src/proc_runner/proc.ts index bd2368defd7e0..f9483255eda87 100644 --- a/packages/kbn-dev-utils/src/proc_runner/proc.ts +++ b/packages/kbn-dev-utils/src/proc_runner/proc.ts @@ -91,9 +91,9 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { }); if (stdin) { - childProcess.stdin.end(stdin, 'utf8'); + childProcess.stdin!.end(stdin, 'utf8'); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdin will not be null } else { - childProcess.stdin.end(); + childProcess.stdin!.end(); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdin will not be null } let stopCalled = false; @@ -123,8 +123,8 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { ).pipe(share()); const lines$ = Rx.merge( - observeLines(childProcess.stdout), - observeLines(childProcess.stderr) + observeLines(childProcess.stdout!), // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + observeLines(childProcess.stderr!) // TypeScript note: As long as the proc stdio[1] is 'pipe', then stderr will not be null ).pipe( tap((line) => log.write(` ${chalk.gray('proc')} [${chalk.gray(name)}] ${line}`)), share() diff --git a/packages/kbn-optimizer/src/optimizer/get_mtimes.ts b/packages/kbn-optimizer/src/optimizer/get_mtimes.ts index b6c3678709880..71c83d6533984 100644 --- a/packages/kbn-optimizer/src/optimizer/get_mtimes.ts +++ b/packages/kbn-optimizer/src/optimizer/get_mtimes.ts @@ -23,7 +23,7 @@ import * as Rx from 'rxjs'; import { mergeMap, map, catchError } from 'rxjs/operators'; import { allValuesFrom } from '../common'; -const stat$ = Rx.bindNodeCallback(Fs.stat); +const stat$ = Rx.bindNodeCallback(Fs.stat); /** * get mtimes of referenced paths concurrently, limit concurrency to 100 diff --git a/packages/kbn-optimizer/src/optimizer/observe_worker.ts b/packages/kbn-optimizer/src/optimizer/observe_worker.ts index 31b34bd5c5938..6745de40fd66c 100644 --- a/packages/kbn-optimizer/src/optimizer/observe_worker.ts +++ b/packages/kbn-optimizer/src/optimizer/observe_worker.ts @@ -164,7 +164,8 @@ export function observeWorker( type: 'worker started', bundles, }), - observeStdio$(proc.stdout).pipe( + // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + observeStdio$(proc.stdout!).pipe( map( (line): WorkerStdio => ({ type: 'worker stdio', @@ -173,7 +174,8 @@ export function observeWorker( }) ) ), - observeStdio$(proc.stderr).pipe( + // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null + observeStdio$(proc.stderr!).pipe( map( (line): WorkerStdio => ({ type: 'worker stdio', diff --git a/packages/kbn-pm/src/commands/watch.ts b/packages/kbn-pm/src/commands/watch.ts index 6775f728c1494..7bd78ba4e5a7e 100644 --- a/packages/kbn-pm/src/commands/watch.ts +++ b/packages/kbn-pm/src/commands/watch.ts @@ -80,7 +80,7 @@ export const WatchCommand: ICommand = { const completionHint = await waitUntilWatchIsReady( pkg.runScriptStreaming(watchScriptName, { debug: false, - }).stdout + }).stdout! // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null ); log.success(`[${pkg.name}] Initial build completed (${completionHint}).`); diff --git a/packages/kbn-pm/src/utils/child_process.ts b/packages/kbn-pm/src/utils/child_process.ts index bafe2bf57adc2..2f761676d77fe 100644 --- a/packages/kbn-pm/src/utils/child_process.ts +++ b/packages/kbn-pm/src/utils/child_process.ts @@ -71,8 +71,8 @@ export function spawnStreaming( const prefixedStdout = logTransformer({ tag: color.bold(prefix) }); const prefixedStderr = logTransformer({ mergeMultiline: true, tag: color.bold(prefix) }); - spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); - spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + spawned.stdout!.pipe(prefixedStdout).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + spawned.stderr!.pipe(prefixedStderr).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null return spawned; } diff --git a/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts b/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts index f8e8137ce40a2..788037b49b142 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts @@ -35,8 +35,8 @@ export function observeContainerLogs(name: string, containerId: string, log: Too const logLine$ = new Rx.Subject(); Rx.merge( - observeLines(logsProc.stdout).pipe(tap((line) => log.info(`[docker:${name}] ${line}`))), - observeLines(logsProc.stderr).pipe(tap((line) => log.error(`[docker:${name}] ${line}`))) + observeLines(logsProc.stdout!).pipe(tap((line) => log.info(`[docker:${name}] ${line}`))), // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + observeLines(logsProc.stderr!).pipe(tap((line) => log.error(`[docker:${name}] ${line}`))) // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null ).subscribe(logLine$); return logLine$.asObservable(); diff --git a/packages/kbn-test/src/kbn/kbn_test_config.ts b/packages/kbn-test/src/kbn/kbn_test_config.ts index 909c94098cf5d..1753fa3885f47 100644 --- a/packages/kbn-test/src/kbn/kbn_test_config.ts +++ b/packages/kbn-test/src/kbn/kbn_test_config.ts @@ -39,9 +39,9 @@ export const kbnTestConfig = new (class KbnTestConfig { const testKibanaUrl = url.parse(process.env.TEST_KIBANA_URL); return { protocol: testKibanaUrl.protocol?.slice(0, -1), - hostname: testKibanaUrl.hostname, + hostname: testKibanaUrl.hostname === null ? undefined : testKibanaUrl.hostname, port: testKibanaUrl.port ? parseInt(testKibanaUrl.port, 10) : undefined, - auth: testKibanaUrl.auth, + auth: testKibanaUrl.auth === null ? undefined : testKibanaUrl.auth, username: testKibanaUrl.auth?.split(':')[0], password: testKibanaUrl.auth?.split(':')[1], }; 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 55f71ea2401db..0a2c90460430f 100644 --- a/src/cli/serve/integration_tests/reload_logging_config.test.ts +++ b/src/cli/serve/integration_tests/reload_logging_config.test.ts @@ -121,14 +121,15 @@ describe('Server logging configuration', function () { '--verbose', ]); - const message$ = Rx.fromEvent(child.stdout, 'data').pipe( + // TypeScript note: As long as the child stdio[1] is 'pipe', then stdout will not be null + 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'))), + filter((messages: string[]) => messages.some((m) => m.includes('setting up root'))), take(1) ) .toPromise(); @@ -189,14 +190,15 @@ describe('Server logging configuration', function () { child = Child.spawn(process.execPath, [kibanaPath, '--oss', '--config', configFilePath]); - const message$ = Rx.fromEvent(child.stdout, 'data').pipe( + // TypeScript note: As long as the child stdio[1] is 'pipe', then stdout will not be null + 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'))), + filter((messages: string[]) => messages.some((m) => m.includes('setting up root'))), take(1) ) .toPromise(); diff --git a/src/core/public/http/types.ts b/src/core/public/http/types.ts index b12cd1fe09a91..2361d981b8597 100644 --- a/src/core/public/http/types.ts +++ b/src/core/public/http/types.ts @@ -206,12 +206,19 @@ export interface HttpRequestInit { /** @public */ export interface HttpFetchQuery { - [key: string]: - | string - | number - | boolean - | undefined - | Array; + /** + * TypeScript note: Technically we should use this interface instead, but @types/node uses the below stricter + * definition, so to avoid TypeScript errors, we'll restrict our version. + * + * [key: string]: + * | string + * | number + * | boolean + * | Array + * | undefined + * | null; + */ + [key: string]: string | number | boolean | string[] | number[] | boolean[] | undefined | null; } /** diff --git a/src/core/public/utils/crypto/sha256.ts b/src/core/public/utils/crypto/sha256.ts index 1617c8ca8d265..eaa057d604689 100644 --- a/src/core/public/utils/crypto/sha256.ts +++ b/src/core/public/utils/crypto/sha256.ts @@ -118,6 +118,18 @@ const K = [ const W = new Array(64); +type BufferEncoding = + | 'ascii' + | 'utf8' + | 'utf-8' + | 'utf16le' + | 'ucs2' + | 'ucs-2' + | 'base64' + | 'latin1' + | 'binary' + | 'hex'; + /* eslint-disable no-bitwise, no-shadow */ export class Sha256 { private _a: number; @@ -157,7 +169,7 @@ export class Sha256 { this._s = 0; } - update(data: string | Buffer, encoding?: string): Sha256 { + update(data: string | Buffer, encoding?: BufferEncoding): Sha256 { if (typeof data === 'string') { encoding = encoding || 'utf8'; data = Buffer.from(data, encoding); diff --git a/src/core/server/elasticsearch/client/configure_client.test.ts b/src/core/server/elasticsearch/client/configure_client.test.ts index 250cfc18a757d..614ec112e8f0b 100644 --- a/src/core/server/elasticsearch/client/configure_client.test.ts +++ b/src/core/server/elasticsearch/client/configure_client.test.ts @@ -322,7 +322,6 @@ describe('configureClient', () => { ); const response = createResponseWithBody( - // @ts-expect-error definition doesn't know about from Readable.from( JSON.stringify({ seq_no_primary_term: true, diff --git a/src/core/server/http/ssl_config.ts b/src/core/server/http/ssl_config.ts index 75dc05d1a801b..432a85f550c98 100644 --- a/src/core/server/http/ssl_config.ts +++ b/src/core/server/http/ssl_config.ts @@ -18,14 +18,10 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import crypto from 'crypto'; +import { constants as cryptoConstants } from 'crypto'; import { readFileSync } from 'fs'; import { readPkcs12Keystore, readPkcs12Truststore } from '../utils'; -// `crypto` type definitions doesn't currently include `crypto.constants`, see -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/fa5baf1733f49cf26228a4e509914572c1b74adf/types/node/v6/index.d.ts#L3412 -const cryptoConstants = (crypto as any).constants; - const protocolMap = new Map([ ['TLSv1', cryptoConstants.SSL_OP_NO_TLSv1], ['TLSv1.1', cryptoConstants.SSL_OP_NO_TLSv1_1], diff --git a/src/core/server/logging/appenders/file/file_appender.ts b/src/core/server/logging/appenders/file/file_appender.ts index b1712bd4e9412..c86ea4972324c 100644 --- a/src/core/server/logging/appenders/file/file_appender.ts +++ b/src/core/server/logging/appenders/file/file_appender.ts @@ -76,7 +76,7 @@ export class FileAppender implements DisposableAppender { return resolve(); } - this.outputStream.end(undefined, undefined, () => { + this.outputStream.end(() => { this.outputStream = undefined; resolve(); }); diff --git a/src/core/server/plugins/discovery/plugins_discovery.ts b/src/core/server/plugins/discovery/plugins_discovery.ts index 2b5b8ad071fb5..e4c9097a70208 100644 --- a/src/core/server/plugins/discovery/plugins_discovery.ts +++ b/src/core/server/plugins/discovery/plugins_discovery.ts @@ -17,7 +17,7 @@ * under the License. */ -import { readdir, stat } from 'fs'; +import { readdir, stat, Stats } from 'fs'; import { resolve } from 'path'; import { bindNodeCallback, from, merge, Observable } from 'rxjs'; import { catchError, filter, map, mergeMap, shareReplay } from 'rxjs/operators'; @@ -138,7 +138,7 @@ function findManifestInFolder( return fsStat$(resolve(dir, 'kibana.json')).pipe( mergeMap((stats) => { // `kibana.json` exists in given directory, we got a plugin - if (stats.isFile()) { + if ((stats as Stats).isFile()) { return [dir]; } return []; @@ -167,7 +167,7 @@ function mapSubdirectories( mergeMap((subDirs: string[]) => subDirs.map((subDir) => resolve(dir, subDir))), mergeMap((subDir) => fsStat$(subDir).pipe( - mergeMap((pathStat) => (pathStat.isDirectory() ? mapFunc(subDir) : [])), + mergeMap((pathStat) => ((pathStat as Stats).isDirectory() ? mapFunc(subDir) : [])), catchError((subDirStatError) => [ PluginDiscoveryError.invalidPluginPath(subDir, subDirStatError), ]) diff --git a/src/dev/build/lib/scan_delete.ts b/src/dev/build/lib/scan_delete.ts index 6e41d207e3111..aeccd711b032f 100644 --- a/src/dev/build/lib/scan_delete.ts +++ b/src/dev/build/lib/scan_delete.ts @@ -27,7 +27,7 @@ import { count, map, mergeAll, mergeMap } from 'rxjs/operators'; // @ts-ignore import { assertAbsolute } from './fs'; -const getStat$ = Rx.bindNodeCallback(Fs.stat); +const getStat$ = Rx.bindNodeCallback(Fs.stat); const getReadDir$ = Rx.bindNodeCallback(Fs.readdir); interface Options { diff --git a/src/dev/build/lib/watch_stdio_for_line.ts b/src/dev/build/lib/watch_stdio_for_line.ts index 3d7929ccfc33a..c97b1c3b26db5 100644 --- a/src/dev/build/lib/watch_stdio_for_line.ts +++ b/src/dev/build/lib/watch_stdio_for_line.ts @@ -69,13 +69,13 @@ export async function watchStdioForLine( } }), createPromiseFromStreams([ - proc.stdout, + proc.stdout!, // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null createSplitStream('\n'), skipLastEmptyLineStream(), createMapStream(onLogLine), ]), createPromiseFromStreams([ - proc.stderr, + proc.stderr!, // TypeScript note: As long as the proc stdio[1] is 'pipe', then stderr will not be null createSplitStream('\n'), skipLastEmptyLineStream(), createMapStream(onLogLine), diff --git a/src/dev/prs/run_update_prs_cli.ts b/src/dev/prs/run_update_prs_cli.ts index 49668199a26d4..57da9d164b395 100644 --- a/src/dev/prs/run_update_prs_cli.ts +++ b/src/dev/prs/run_update_prs_cli.ts @@ -72,7 +72,10 @@ run( await Promise.all([ proc.then(() => log.debug(` - ${cmd} exited with 0`)), - Rx.merge(getLine$(proc.stdout), getLine$(proc.stderr)) + Rx.merge( + getLine$(proc.stdout!), // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + getLine$(proc.stderr!) // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null + ) .pipe(tap((line) => log.debug(line))) .toPromise(), ]); diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index a3b220f911504..d5e46d79b3b1d 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -238,7 +238,8 @@ export const createKbnUrlControls = ( * 4. Hash history with base path */ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): History.Path { - function stripBasename(path: string = '') { + function stripBasename(path: string | null) { + if (path == null) path = ''; const stripLeadingHash = (_: string) => (_.charAt(0) === '#' ? _.substr(1) : _); const stripTrailingSlash = (_: string) => _.charAt(_.length - 1) === '/' ? _.substr(0, _.length - 1) : _; @@ -250,7 +251,7 @@ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): const parsedHash = isHashHistory ? null : parseUrlHash(absoluteUrl); return formatUrl({ - pathname: stripBasename(parsedUrl.pathname), + pathname: stripBasename(parsedUrl.pathname ?? null), search: stringify(urlUtils.encodeQuery(parsedUrl.query), { sort: false, encode: false }), hash: parsedHash ? formatUrl({ diff --git a/src/plugins/share/server/routes/lib/short_url_assert_valid.ts b/src/plugins/share/server/routes/lib/short_url_assert_valid.ts index 462fc31944b74..581410359322f 100644 --- a/src/plugins/share/server/routes/lib/short_url_assert_valid.ts +++ b/src/plugins/share/server/routes/lib/short_url_assert_valid.ts @@ -32,7 +32,7 @@ export function shortUrlAssertValid(url: string) { throw Boom.notAcceptable(`Short url targets cannot have a hostname, found "${hostname}"`); } - const pathnameParts = trim(pathname, '/').split('/'); + const pathnameParts = trim(pathname === null ? undefined : pathname, '/').split('/'); if (pathnameParts.length !== 2) { throw Boom.notAcceptable( `Short url target path must be in the format "/app/{{appId}}", found "${pathname}"` diff --git a/test/functional/services/remote/create_stdout_stream.ts b/test/functional/services/remote/create_stdout_stream.ts index 9af5cba63f9ea..9993cfb37d9b7 100644 --- a/test/functional/services/remote/create_stdout_stream.ts +++ b/test/functional/services/remote/create_stdout_stream.ts @@ -76,7 +76,7 @@ export async function createStdoutSocket() { throw new Error('server must listen to a random port, not a unix socket'); } - const input = Net.createConnection(addressInfo.port, addressInfo.address); + const input = Net.createConnection(addressInfo!.port, addressInfo!.address); // TypeScript note: addressInfo will not be null after 'listening' has been emitted await Rx.fromEvent(input, 'connect').pipe(take(1)).toPromise(); return { diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts index 04ab572a53dbc..2f19a8a8a7c61 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts @@ -333,17 +333,14 @@ export class HeadlessChromiumDriver { private _shouldUseCustomHeaders(conditions: ConditionalHeadersConditions, url: string) { const { hostname, protocol, port, pathname } = parseUrl(url); - if (pathname === undefined) { - // There's a discrepancy between the NodeJS docs and the typescript types. NodeJS docs - // just say 'string' and the typescript types say 'string | undefined'. We haven't hit a - // situation where it's undefined but here's an explicit Error if we do. - throw new Error(`pathname is undefined, don't know how to proceed`); - } + if (port === null) throw new Error(`URL missing port: ${url}`); + if (pathname === null) throw new Error(`URL missing pathname: ${url}`); return ( hostname === conditions.hostname && protocol === `${conditions.protocol}:` && this._shouldUseCustomHeadersForPort(conditions, port) && + // @ts-expect-error according to the types `pathname` is `string | undefined`, but it's actually `string | null` pathname.startsWith(`${conditions.basePath}/`) ); } diff --git a/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts b/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts index 7621a95083bc7..8b2507ed3d25e 100644 --- a/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts +++ b/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts @@ -50,9 +50,9 @@ export function getFullUrls(config: ReportingConfig, job: TaskPayloadPDF | TaskP const urls = relativeUrls.map((relativeUrl) => { const parsedRelative: UrlWithStringQuery = urlParse(relativeUrl); const jobUrl = getAbsoluteUrl({ - path: parsedRelative.pathname, - hash: parsedRelative.hash, - search: parsedRelative.search, + path: parsedRelative.pathname === null ? undefined : parsedRelative.pathname, + hash: parsedRelative.hash === null ? undefined : parsedRelative.hash, + search: parsedRelative.search === null ? undefined : parsedRelative.search, }); // capture the route to the visualization diff --git a/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts b/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts index f70c2e8b63885..efb0a712d9b43 100644 --- a/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts +++ b/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts @@ -14,7 +14,7 @@ describe('cloneHttpFetchQuery', () => { a: 'a', '1': 1, undefined, - array: [1, 2, undefined], + array: [1, 2], }; expect(cloneHttpFetchQuery(query)).toMatchInlineSnapshot(` Object { @@ -23,7 +23,6 @@ describe('cloneHttpFetchQuery', () => { "array": Array [ 1, 2, - undefined, ], "undefined": undefined, } diff --git a/x-pack/plugins/security_solution/public/management/common/routing.ts b/x-pack/plugins/security_solution/public/management/common/routing.ts index b3162a8708a5f..87545f7008760 100644 --- a/x-pack/plugins/security_solution/public/management/common/routing.ts +++ b/x-pack/plugins/security_solution/public/management/common/routing.ts @@ -32,7 +32,7 @@ type Exact = T extends Shape ? ExactKeys : never; * Ensures that when creating a URL query param string, that the given input strictly * matches the expected interface (guards against possibly leaking internal state) */ -const querystringStringify: ( +const querystringStringify: ( params: Exact ) => string = querystring.stringify; diff --git a/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts b/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts index be950e6a651e6..6466835899f16 100644 --- a/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts +++ b/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts @@ -8,9 +8,11 @@ import { DEFAULT_SPACE_ID } from '../constants'; const spaceContextRegex = /^\/s\/([a-z0-9_\-]+)/; export function getSpaceIdFromPath( - requestBasePath: string = '/', - serverBasePath: string = '/' + requestBasePath?: string | null, + serverBasePath?: string | null ): { spaceId: string; pathHasExplicitSpaceIdentifier: boolean } { + if (requestBasePath == null) requestBasePath = '/'; + if (serverBasePath == null) serverBasePath = '/'; const pathToCheck: string = stripServerBasePath(requestBasePath, serverBasePath); // Look for `/s/space-url-context` in the base path From f8bcaa7f06b9f5d05f1d8f13077a31cb057feeef Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 2 Apr 2020 13:16:41 +0200 Subject: [PATCH 06/26] Ignore deprecation warning in 'superagent' package --- src/setup_node_env/exit_on_warning.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/setup_node_env/exit_on_warning.js b/src/setup_node_env/exit_on_warning.js index 3180823d72205..d5f6ab00de2d4 100644 --- a/src/setup_node_env/exit_on_warning.js +++ b/src/setup_node_env/exit_on_warning.js @@ -34,6 +34,12 @@ var IGNORE_WARNINGS = [ { name: 'MaxListenersExceededWarning', }, + { + name: 'DeprecationWarning', + code: 'DEP0066', + file: '/node_modules/supertest/node_modules/superagent/lib/node/index.js', + line: 418, + }, ]; if (process.noProcessWarnings !== true) { From 34737a9d332783405c98c3543369334a572b0ec9 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 9 Nov 2020 16:21:54 +0100 Subject: [PATCH 07/26] Never manually emit errors on streams See: https://github.com/nodejs/node/issues/36053 --- packages/kbn-es-archiver/src/actions/load.ts | 2 +- .../src/lib/streams/concat_stream_providers.test.js | 2 +- .../kbn-es-archiver/src/lib/streams/concat_stream_providers.ts | 2 +- src/core/server/utils/streams/concat_stream_providers.test.ts | 2 +- src/core/server/utils/streams/concat_stream_providers.ts | 2 +- .../spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts | 2 +- .../server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/kbn-es-archiver/src/actions/load.ts b/packages/kbn-es-archiver/src/actions/load.ts index efb1fe9f9ea54..c2f5f18a07e9b 100644 --- a/packages/kbn-es-archiver/src/actions/load.ts +++ b/packages/kbn-es-archiver/src/actions/load.ts @@ -43,7 +43,7 @@ import { // are not listened for const pipeline = (...streams: Readable[]) => streams.reduce((source, dest) => - source.once('error', (error) => dest.emit('error', error)).pipe(dest as any) + source.once('error', (error) => dest.destroy(error)).pipe(dest as any) ); export async function loadAction({ diff --git a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js index b742a770b70c8..878d645d9b4a7 100644 --- a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js +++ b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js @@ -44,7 +44,7 @@ describe('concatStreamProviders() helper', () => { () => new Readable({ read() { - this.emit('error', new Error('foo')); + this.destroy(new Error('foo')); }, }), ]); diff --git a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts index 4794d76cc7f84..be0768316b293 100644 --- a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts +++ b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts @@ -50,7 +50,7 @@ export function concatStreamProviders( source // proxy errors from the source to the destination - .once('error', (error) => destination.emit('error', error)) + .once('error', (error) => destination.destroy(error)) // pipe the source to the destination but only proxy the // end event if this is the last source .pipe(destination, { end: isLast }); diff --git a/src/core/server/utils/streams/concat_stream_providers.test.ts b/src/core/server/utils/streams/concat_stream_providers.test.ts index b742a770b70c8..878d645d9b4a7 100644 --- a/src/core/server/utils/streams/concat_stream_providers.test.ts +++ b/src/core/server/utils/streams/concat_stream_providers.test.ts @@ -44,7 +44,7 @@ describe('concatStreamProviders() helper', () => { () => new Readable({ read() { - this.emit('error', new Error('foo')); + this.destroy(new Error('foo')); }, }), ]); diff --git a/src/core/server/utils/streams/concat_stream_providers.ts b/src/core/server/utils/streams/concat_stream_providers.ts index bb836e3d73787..236d68c89707e 100644 --- a/src/core/server/utils/streams/concat_stream_providers.ts +++ b/src/core/server/utils/streams/concat_stream_providers.ts @@ -54,7 +54,7 @@ export function concatStreamProviders( source // proxy errors from the source to the destination - .once('error', (error) => destination.emit('error', error)) + .once('error', (error) => destination.destroy(error)) // pipe the source to the destination but only proxy the // end event if this is the last source .pipe(destination, { end: isLast }); diff --git a/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts b/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts index 1cec7b769fa26..d1a8e93bff929 100644 --- a/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts +++ b/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts @@ -283,7 +283,7 @@ describe('copySavedObjectsToSpaces', () => { new Readable({ objectMode: true, read() { - this.emit('error', new Error('Something went wrong while reading this stream')); + this.destroy(new Error('Something went wrong while reading this stream')); }, }) ); diff --git a/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts b/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts index 37181c9d81649..f1b475ee9d1b3 100644 --- a/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts +++ b/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts @@ -290,7 +290,7 @@ describe('resolveCopySavedObjectsToSpacesConflicts', () => { new Readable({ objectMode: true, read() { - this.emit('error', new Error('Something went wrong while reading this stream')); + this.destroy(new Error('Something went wrong while reading this stream')); }, }) ); From 436bdc21c73ab6b8509a9b057184e3f3ec911f5d Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 27 Mar 2020 11:51:49 +0100 Subject: [PATCH 08/26] Add outcome of yarn kbn run build -i @kbn/pm --- packages/kbn-pm/dist/index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index b7d9803059aa8..f0ac050b128ff 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -32273,8 +32273,10 @@ function spawnStreaming(command, args, opts, { mergeMultiline: true, tag: color.bold(prefix) }); - spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); - spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + + spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null + return spawned; } @@ -51377,7 +51379,8 @@ const WatchCommand = { await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async pkg => { const completionHint = await Object(_utils_watch__WEBPACK_IMPORTED_MODULE_4__["waitUntilWatchIsReady"])(pkg.runScriptStreaming(watchScriptName, { debug: false - }).stdout); + }).stdout // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + ); _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${pkg.name}] Initial build completed (${completionHint}).`); }); } From a9351f7bca706b671b73aea0a5431c3e875b4725 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 27 Mar 2020 12:26:46 +0100 Subject: [PATCH 09/26] Add outcome of node scripts/check_published_api_changes.js --accept --- src/core/public/public.api.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 781a50f849e24..fe2a0aa6d7232 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -624,8 +624,7 @@ export interface HttpFetchOptionsWithPath extends HttpFetchOptions { // @public (undocumented) export interface HttpFetchQuery { - // (undocumented) - [key: string]: string | number | boolean | undefined | Array; + [key: string]: string | number | boolean | string[] | number[] | boolean[] | undefined | null; } // @public From 6ac85989178692f14fc51c6573322e4c61275a67 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 27 Mar 2020 14:49:03 +0100 Subject: [PATCH 10/26] [test] Fix tests --- .../src/types/stream_type.test.ts | 8 +++- .../tooling_log_text_writer.test.ts.snap | 3 +- .../src/__snapshots__/loader.test.ts.snap | 2 +- .../lib/lifecycle_phase.test.ts | 1 + src/cli/repl/__snapshots__/repl.test.js.snap | 30 +++++++++++--- .../core_usage_data_service.test.ts | 3 ++ .../__snapshots__/http_config.test.ts.snap | 3 ++ src/core/server/http/http_tools.test.ts | 4 +- .../http/router/validator/validator.test.ts | 2 +- .../appenders/file/file_appender.test.ts | 4 +- .../__snapshots__/data_view.test.tsx.snap | 2 + .../common/format_timestamp_to_duration.js | 6 +-- .../edit_space/manage_space_page.test.tsx | 41 ++++++++++--------- .../nav_control/nav_control_popover.test.tsx | 10 ++--- .../tests/transaction_groups/distribution.ts | 2 +- .../trial/tests/service_maps/service_maps.ts | 2 +- 16 files changed, 79 insertions(+), 44 deletions(-) diff --git a/packages/kbn-config-schema/src/types/stream_type.test.ts b/packages/kbn-config-schema/src/types/stream_type.test.ts index 2e6f31ad09b34..91a75d01bde93 100644 --- a/packages/kbn-config-schema/src/types/stream_type.test.ts +++ b/packages/kbn-config-schema/src/types/stream_type.test.ts @@ -57,7 +57,13 @@ test('includes namespace in failure', () => { describe('#defaultValue', () => { test('returns default when undefined', () => { const value = new Stream(); - expect(schema.stream({ defaultValue: value }).validate(undefined)).toStrictEqual(value); + expect(schema.stream({ defaultValue: value }).validate(undefined)).toMatchInlineSnapshot(` + Stream { + "_events": Object {}, + "_eventsCount": 0, + "_maxListeners": undefined, + } + `); }); test('returns value when specified', () => { diff --git a/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap b/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap index 76c018fdb3661..f5d084da6a4e0 100644 --- a/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap +++ b/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap @@ -2,8 +2,7 @@ exports[`formats %s patterns and indents multi-line messages correctly 1`] = ` " │ succ foo bar - │ { foo: { bar: { '1': [Array] } }, - │ bar: { bar: { '1': [Array] } } } + │ { foo: { bar: { '1': [Array] } }, bar: { bar: { '1': [Array] } } } │ │ Infinity " diff --git a/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap b/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap index 05b3fd17a6740..941d9fbf7d6a5 100644 --- a/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap +++ b/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap @@ -2,4 +2,4 @@ exports[`I18n loader registerTranslationFile should throw error if path to translation file is not an absolute 1`] = `"Paths to translation files must be absolute. Got relative path: \\"./en.json\\""`; -exports[`I18n loader registerTranslationFile should throw error if path to translation file is not specified 1`] = `"The \\"path\\" argument must be of type string. Received type undefined"`; +exports[`I18n loader registerTranslationFile should throw error if path to translation file is not specified 1`] = `"The \\"path\\" argument must be of type string. Received undefined"`; diff --git a/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts b/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts index d17c5503c42f8..5902127462129 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts @@ -59,6 +59,7 @@ describe('with randomness', () => { ); await phase.trigger(); + expect(order).toMatchInlineSnapshot(` Array [ "one", diff --git a/src/cli/repl/__snapshots__/repl.test.js.snap b/src/cli/repl/__snapshots__/repl.test.js.snap index 7171e99dbcc0e..c7751b5797f49 100644 --- a/src/cli/repl/__snapshots__/repl.test.js.snap +++ b/src/cli/repl/__snapshots__/repl.test.js.snap @@ -5,8 +5,14 @@ exports[`repl it allows print depth to be specified 1`] = `"{ '0': {  exports[`repl it colorizes raw values 1`] = `"{ meaning: 42 }"`; exports[`repl it handles deep and recursive objects 1`] = ` -"{ '0': { '1': { '2': { '3': { '4': { '5': [Object] } } } } }, - whoops: [Circular] }" +"{ + '0': { + '1': { + '2': { '3': { '4': { '5': [Object] } } } + } + }, + whoops: [Circular] +}" `; exports[`repl it handles undefined 1`] = `"undefined"`; @@ -45,8 +51,14 @@ Array [ Array [ "Promise Rejected: ", - "{ '0': { '1': { '2': { '3': { '4': { '5': [Object] } } } } }, - whoops: [Circular] }", + "{ + '0': { + '1': { + '2': { '3': { '4': { '5': [Object] } } } + } + }, + whoops: [Circular] +}", ], ] `; @@ -59,8 +71,14 @@ Array [ Array [ "Promise Resolved: ", - "{ '0': { '1': { '2': { '3': { '4': { '5': [Object] } } } } }, - whoops: [Circular] }", + "{ + '0': { + '1': { + '2': { '3': { '4': { '5': [Object] } } } + } + }, + whoops: [Circular] +}", ], ] `; diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index 9f9e18c08b0da..acb0d6f54cacb 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -145,6 +145,9 @@ describe('CoreUsageDataService', () => { "certificateAuthoritiesConfigured": false, "certificateConfigured": false, "cipherSuites": Array [ + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384", diff --git a/src/core/server/http/__snapshots__/http_config.test.ts.snap b/src/core/server/http/__snapshots__/http_config.test.ts.snap index e9b818fe859ec..64baabd3d7ec8 100644 --- a/src/core/server/http/__snapshots__/http_config.test.ts.snap +++ b/src/core/server/http/__snapshots__/http_config.test.ts.snap @@ -47,6 +47,9 @@ Object { "socketTimeout": 120000, "ssl": Object { "cipherSuites": Array [ + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384", diff --git a/src/core/server/http/http_tools.test.ts b/src/core/server/http/http_tools.test.ts index 336c491a131d6..1423e27b914a3 100644 --- a/src/core/server/http/http_tools.test.ts +++ b/src/core/server/http/http_tools.test.ts @@ -143,7 +143,7 @@ describe('getServerOptions', () => { Object { "ca": undefined, "cert": "content-some-certificate-path", - "ciphers": "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", + "ciphers": "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", "honorCipherOrder": true, "key": "content-some-key-path", "passphrase": undefined, @@ -175,7 +175,7 @@ describe('getServerOptions', () => { "content-ca-2", ], "cert": "content-some-certificate-path", - "ciphers": "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", + "ciphers": "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", "honorCipherOrder": true, "key": "content-some-key-path", "passphrase": undefined, diff --git a/src/core/server/http/router/validator/validator.test.ts b/src/core/server/http/router/validator/validator.test.ts index 30f66f5d41fbe..f6a1dd82cb10f 100644 --- a/src/core/server/http/router/validator/validator.test.ts +++ b/src/core/server/http/router/validator/validator.test.ts @@ -36,7 +36,7 @@ describe('Router validator', () => { expect(() => validator.getParams({})).toThrowError('[foo]: Not a string'); expect(() => validator.getParams(undefined)).toThrowError( - "Cannot destructure property `foo` of 'undefined' or 'null'." + "Cannot destructure property 'foo' of 'undefined' as it is undefined." ); expect(() => validator.getParams({}, 'myField')).toThrowError('[myField.foo]: Not a string'); diff --git a/src/core/server/logging/appenders/file/file_appender.test.ts b/src/core/server/logging/appenders/file/file_appender.test.ts index 645455c5ae04c..843eb1103b7a0 100644 --- a/src/core/server/logging/appenders/file/file_appender.test.ts +++ b/src/core/server/logging/appenders/file/file_appender.test.ts @@ -144,7 +144,7 @@ test('`dispose()` succeeds even if stream is not created.', async () => { test('`dispose()` closes stream.', async () => { const mockStreamEndFinished = jest.fn(); - const mockStreamEnd = jest.fn(async (chunk, encoding, callback) => { + const mockStreamEnd = jest.fn(async (callback) => { // It's required to make sure `dispose` waits for `end` to complete. await tickMs(100); mockStreamEndFinished(); @@ -170,7 +170,7 @@ test('`dispose()` closes stream.', async () => { await appender.dispose(); expect(mockStreamEnd).toHaveBeenCalledTimes(1); - expect(mockStreamEnd).toHaveBeenCalledWith(undefined, undefined, expect.any(Function)); + expect(mockStreamEnd).toHaveBeenCalledWith(expect.any(Function)); expect(mockStreamEndFinished).toHaveBeenCalled(); // Consequent `dispose` calls should not fail even if stream has been disposed. diff --git a/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap index 3bd3bb6531cc7..ec68b307734e3 100644 --- a/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap @@ -12,6 +12,7 @@ exports[`Inspector Data View component should render empty state 1`] = ` "_maxListeners": undefined, "tabular": [Function], "tabularOptions": Object {}, + Symbol(kCapture): false, }, } } @@ -130,6 +131,7 @@ exports[`Inspector Data View component should render empty state 1`] = ` "_maxListeners": undefined, "tabular": [Function], "tabularOptions": Object {}, + Symbol(kCapture): false, }, } } diff --git a/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js b/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js index 46c8f7db49b0f..9e1d421989f53 100644 --- a/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js +++ b/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js @@ -48,7 +48,7 @@ export function formatTimestampToDuration(timestamp, calculationFlag, initialTim } return duration - .replace(/ 0 mins$/, '') - .replace(/ 0 hrs$/, '') - .replace(/ 0 days$/, ''); // See https://github.com/jsmreese/moment-duration-format/issues/64 + .replace(/ -?0 mins$/, '') + .replace(/ -?0 hrs$/, '') + .replace(/ -?0 days$/, ''); // See https://github.com/jsmreese/moment-duration-format/issues/64 } diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx index 270cf862ccbd9..04d8dfb87cf95 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx @@ -7,6 +7,7 @@ import { EuiButton, EuiCheckboxProps } from '@elastic/eui'; import { ReactWrapper } from 'enzyme'; import React from 'react'; +import { wait } from '@testing-library/react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { ConfirmAlterActiveSpaceModal } from './confirm_alter_active_space_modal'; @@ -69,7 +70,10 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); + await wait(() => { + wrapper.update(); + expect(wrapper.find('input[name="name"]')).toHaveLength(1); + }); const nameInput = wrapper.find('input[name="name"]'); const descriptionInput = wrapper.find('textarea[name="description"]'); @@ -128,9 +132,11 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); + await wait(() => { + wrapper.update(); + expect(spacesManager.getSpace).toHaveBeenCalledWith('existing-space'); + }); - expect(spacesManager.getSpace).toHaveBeenCalledWith('existing-space'); expect(onLoadSpace).toHaveBeenCalledWith({ ...spaceToUpdate, }); @@ -179,10 +185,11 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); - - expect(notifications.toasts.addError).toHaveBeenCalledWith(error, { - title: 'Error loading available features', + await wait(() => { + wrapper.update(); + expect(notifications.toasts.addError).toHaveBeenCalledWith(error, { + title: 'Error loading available features', + }); }); }); @@ -216,9 +223,10 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); - - expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + await wait(() => { + wrapper.update(); + expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + }); await Promise.resolve(); @@ -277,9 +285,10 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); - - expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + await wait(() => { + wrapper.update(); + expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + }); await Promise.resolve(); @@ -327,9 +336,3 @@ async function clickSaveButton(wrapper: ReactWrapper) { wrapper.update(); } - -async function waitForDataLoad(wrapper: ReactWrapper) { - await Promise.resolve(); - await Promise.resolve(); - wrapper.update(); -} diff --git a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx index 5de7fcf69b363..be12550648a0a 100644 --- a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx +++ b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx @@ -13,6 +13,7 @@ import { SpacesManager } from '../spaces_manager'; import { NavControlPopover } from './nav_control_popover'; import { EuiHeaderSectionItemButton } from '@elastic/eui'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { wait } from '@testing-library/react'; describe('NavControlPopover', () => { it('renders without crashing', () => { @@ -64,10 +65,9 @@ describe('NavControlPopover', () => { wrapper.find(EuiHeaderSectionItemButton).simulate('click'); // Wait for `getSpaces` promise to resolve - await Promise.resolve(); - await Promise.resolve(); - wrapper.update(); - - expect(wrapper.find(SpaceAvatar)).toHaveLength(3); + await wait(() => { + wrapper.update(); + expect(wrapper.find(SpaceAvatar)).toHaveLength(3); + }); }); }); diff --git a/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts b/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts index c72d48094ca8d..e0b03e1a91f40 100644 --- a/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts +++ b/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts @@ -20,7 +20,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const url = `/api/apm/services/opbeans-java/transaction_groups/distribution?${qs.stringify({ start: metadata.start, end: metadata.end, - uiFilters: {}, + uiFilters: encodeURIComponent('{}'), transactionName: 'APIRestController#stats', transactionType: 'request', })}`; diff --git a/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts b/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts index 0cd91eb46a5e2..37305c02a34fc 100644 --- a/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts +++ b/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts @@ -111,7 +111,7 @@ export default function serviceMapsApiTests({ getService }: FtrProviderContext) const q = querystring.stringify({ start: metadata.start, end: metadata.end, - uiFilters: {}, + uiFilters: encodeURIComponent('{}'), }); const response = await supertest.get(`/api/apm/service-map/service/opbeans-node?${q}`); From 2b7d5aaef0be85ee332a1aa6de0df71787f440c8 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 6 Apr 2020 09:29:50 +0200 Subject: [PATCH 11/26] [test] Avoid 'no cipher match' in http_server test In Node.js 12 using an invalid cipher will result in a process level warning. This wasn't the case in Node.js 10. Simply use a valid cipher to avoid this issue. --- src/core/server/http/http_server.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts index 7507a08dd150a..5da4c5de5d313 100644 --- a/src/core/server/http/http_server.test.ts +++ b/src/core/server/http/http_server.test.ts @@ -79,7 +79,7 @@ beforeEach(() => { ssl: { enabled: true, certificate, - cipherSuites: ['cipherSuite'], + cipherSuites: ['TLS_AES_256_GCM_SHA384'], getSecureOptions: () => 0, key, redirectHttpFromPort: config.port + 1, From 687591944c070e07df0089d12370e74af793ccfe Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 6 Apr 2020 09:31:47 +0200 Subject: [PATCH 12/26] [test] Fix sense editor tests in Node.js 12 For some reason the array is in reverse order in Node.js 12 compared to Node.js 10 --- .../models/sense_editor/__tests__/integration.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js b/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js index 06823a981af46..0b443ef400d6f 100644 --- a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js +++ b/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js @@ -661,7 +661,7 @@ describe('Integration', () => { { name: 'Any of - mixed - both', cursor: { lineNumber: 14, column: 3 }, - autoCompleteSet: [tt('{'), tt(3)], + autoCompleteSet: [tt(3), tt('{')], }, ] ); From c3a4d07c66ded87bc35926e800f77666ac4c8944 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 29 Oct 2020 20:03:14 +0100 Subject: [PATCH 13/26] [test] V8 array sorting algorithm changed in Node.js 12 For details see: https://v8.dev/blog/array-sort --- .../lib/lifecycle_phase.test.ts | 7 +++- .../operations/operations.test.ts | 4 +-- .../xy_visualization/xy_suggestions.test.ts | 32 +++++++++---------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts b/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts index 5902127462129..d133d0e498b49 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts @@ -60,11 +60,16 @@ describe('with randomness', () => { await phase.trigger(); + // `phase.trigger()` uses `Math.random` to sort the internal array of + // handlers. But since the sorting algorithm used internally in + // `Array.prototype.sort` is not spec'ed, it can change between Node.js + // versions, and as a result the expected output below might not match if + // you up/downgrade Node.js. expect(order).toMatchInlineSnapshot(` Array [ - "one", "three", "two", + "one", ] `); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts index 6808bc724f26b..baa57cf64d51d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts @@ -315,12 +315,12 @@ describe('getOperationTypesForField', () => { }, Object { "field": "bytes", - "operationType": "max", + "operationType": "min", "type": "field", }, Object { "field": "bytes", - "operationType": "min", + "operationType": "max", "type": "field", }, Object { diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts index d6c6ee3082959..e8c3282146097 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts @@ -186,15 +186,15 @@ describe('xy_suggestions', () => { expect(suggestions).toHaveLength(visualizationTypes.length); expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ 'bar_stacked', - 'line', - 'area_percentage_stacked', - 'area_stacked', - 'area', - 'bar_horizontal_percentage_stacked', - 'bar_horizontal_stacked', - 'bar_percentage_stacked', - 'bar_horizontal', 'bar', + 'bar_horizontal', + 'bar_percentage_stacked', + 'bar_horizontal_stacked', + 'bar_horizontal_percentage_stacked', + 'area', + 'area_stacked', + 'area_percentage_stacked', + 'line', ]); }); @@ -226,15 +226,15 @@ describe('xy_suggestions', () => { ]); expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ 'bar_stacked', - 'line', - 'area_percentage_stacked', - 'area_stacked', - 'area', - 'bar_horizontal_percentage_stacked', - 'bar_horizontal_stacked', - 'bar_percentage_stacked', - 'bar_horizontal', 'bar', + 'bar_horizontal', + 'bar_percentage_stacked', + 'bar_horizontal_stacked', + 'bar_horizontal_percentage_stacked', + 'area', + 'area_stacked', + 'area_percentage_stacked', + 'line', ]); }); From 3177892d3fb19a5adf67fc43684fc2c523a15949 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 29 Oct 2020 21:05:32 +0100 Subject: [PATCH 14/26] [test] Fix more tests --- .../tests/actions/builtin_action_types/jira.ts | 2 +- .../tests/actions/builtin_action_types/resilient.ts | 2 +- .../tests/actions/builtin_action_types/servicenow.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 39f64dd037945..fe7e27473115b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -315,7 +315,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { actionId: simulatedActionId, status: 'error', retry: false, - message: `error validating action params: Cannot read property 'Symbol(Symbol.iterator)' of undefined`, + message: `error validating action params: undefined is not iterable (cannot read property Symbol(Symbol.iterator))`, }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts index 5d54ea99889c1..4d894bc3ddf8b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts @@ -316,7 +316,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { actionId: simulatedActionId, status: 'error', retry: false, - message: `error validating action params: Cannot read property 'Symbol(Symbol.iterator)' of undefined`, + message: `error validating action params: undefined is not iterable (cannot read property Symbol(Symbol.iterator))`, }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 0684707c73824..a4a78b2bd2d8f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -310,7 +310,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionId: simulatedActionId, status: 'error', retry: false, - message: `error validating action params: Cannot read property 'Symbol(Symbol.iterator)' of undefined`, + message: `error validating action params: undefined is not iterable (cannot read property Symbol(Symbol.iterator))`, }); }); }); From 7cd23b0a8e8c8362756973b73cf186178fbc581c Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 30 Oct 2020 11:39:01 +0100 Subject: [PATCH 15/26] [test] Fix weird Node.js 12 bug --- .../actions/builtin_action_types/jira.ts | 36 +++++++++++++++---- .../actions/builtin_action_types/resilient.ts | 36 +++++++++++++++---- .../builtin_action_types/servicenow.ts | 36 +++++++++++++++---- 3 files changed, 90 insertions(+), 18 deletions(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index fe7e27473115b..e4d54dd35518d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -311,12 +311,36 @@ export default function jiraTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: `error validating action params: undefined is not iterable (cannot read property Symbol(Symbol.iterator))`, - }); + expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']); + expect(resp.body.actionId).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circomstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts index 4d894bc3ddf8b..285e1e507f591 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts @@ -312,12 +312,36 @@ export default function resilientTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: `error validating action params: undefined is not iterable (cannot read property Symbol(Symbol.iterator))`, - }); + expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']); + expect(resp.body.actionId).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circomstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index a4a78b2bd2d8f..5559fec0642c0 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -306,12 +306,36 @@ export default function servicenowTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: `error validating action params: undefined is not iterable (cannot read property Symbol(Symbol.iterator))`, - }); + expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']); + expect(resp.body.actionId).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circomstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); }); }); From d1704100161cf761c266e3afc7e5676a16b7e0f7 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Sat, 31 Oct 2020 10:39:42 +0100 Subject: [PATCH 16/26] [test] Fix CSV reporting tests --- .../reporting/hugedata/data.json.gz | Bin 33744 -> 33744 bytes .../reporting/scripted_small2/data.json.gz | Bin 4248 -> 4436 bytes .../reporting_api_integration/fixtures.ts | 177 +++++++++--------- 3 files changed, 91 insertions(+), 86 deletions(-) diff --git a/x-pack/test/functional/es_archives/reporting/hugedata/data.json.gz b/x-pack/test/functional/es_archives/reporting/hugedata/data.json.gz index c524379640df7e2c11cd0f86603cf4048a826bd3..0773c1a526d5c42243cb51b3dee085624d09b3b0 100644 GIT binary patch delta 32865 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 F{{gj`Q+faZ delta 32865 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 G2=zaoC%b(B diff --git a/x-pack/test/functional/es_archives/reporting/scripted_small2/data.json.gz b/x-pack/test/functional/es_archives/reporting/scripted_small2/data.json.gz index 5e421015770b35b3d28e55aa861d306ba7abc559..c86627ddb07320033e080c6ab996e1f898cefced 100644 GIT binary patch literal 4436 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 Date: Mon, 9 Nov 2020 13:11:56 +0100 Subject: [PATCH 17/26] [test] fix timing related test failures Node.js 11.0.0 included changes to the Timers and the Microtask Queue which affects the behavior of setTimeout, setImmediate, process.nextTick and Promises. Some of the test relied on the old behavor and had to be updated. For more information, see: https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3 --- .../server/metrics/metrics_service.test.ts | 32 +++++++++++-------- .../actions/clone_panel_action.test.tsx | 1 + .../core/create_start_service_getter.test.ts | 2 ++ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/core/server/metrics/metrics_service.test.ts b/src/core/server/metrics/metrics_service.test.ts index 384a56c8dba94..c39f5f25b02b6 100644 --- a/src/core/server/metrics/metrics_service.test.ts +++ b/src/core/server/metrics/metrics_service.test.ts @@ -82,21 +82,23 @@ describe('MetricsService', () => { // `advanceTimersByTime` only ensure the interval handler is executed // however the `reset` call is executed after the async call to `collect` // meaning that we are going to miss the call if we don't wait for the - // actual observable emission that is performed after - const waitForNextEmission = () => getOpsMetrics$().pipe(take(1)).toPromise(); + // actual observable emission that is performed after. The extra + // `nextTick` is to ensure we've done a complete roundtrip of the event + // loop. + const nextEmission = async () => { + jest.advanceTimersByTime(testInterval); + await getOpsMetrics$().pipe(take(1)).toPromise(); + await new Promise((resolve) => process.nextTick(resolve)); + }; expect(mockOpsCollector.collect).toHaveBeenCalledTimes(1); expect(mockOpsCollector.reset).toHaveBeenCalledTimes(1); - let nextEmission = waitForNextEmission(); - jest.advanceTimersByTime(testInterval); - await nextEmission; + await nextEmission(); expect(mockOpsCollector.collect).toHaveBeenCalledTimes(2); expect(mockOpsCollector.reset).toHaveBeenCalledTimes(2); - nextEmission = waitForNextEmission(); - jest.advanceTimersByTime(testInterval); - await nextEmission; + await nextEmission(); expect(mockOpsCollector.collect).toHaveBeenCalledTimes(3); expect(mockOpsCollector.reset).toHaveBeenCalledTimes(3); }); @@ -117,13 +119,15 @@ describe('MetricsService', () => { await metricsService.setup({ http: httpMock }); const { getOpsMetrics$ } = await metricsService.start(); - const firstEmission = getOpsMetrics$().pipe(take(1)).toPromise(); - jest.advanceTimersByTime(testInterval); - expect(await firstEmission).toEqual({ metric: 'first' }); + const nextEmission = async () => { + jest.advanceTimersByTime(testInterval); + const emission = await getOpsMetrics$().pipe(take(1)).toPromise(); + await new Promise((resolve) => process.nextTick(resolve)); + return emission; + }; - const secondEmission = getOpsMetrics$().pipe(take(1)).toPromise(); - jest.advanceTimersByTime(testInterval); - expect(await secondEmission).toEqual({ metric: 'second' }); + expect(await nextEmission()).toEqual({ metric: 'first' }); + expect(await nextEmission()).toEqual({ metric: 'second' }); }); }); diff --git a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx index 25179fd7ccd38..5f001e3de55d0 100644 --- a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx @@ -111,6 +111,7 @@ test('Clone adds a new embeddable', async () => { expect(newPanel.type).toEqual('placeholder'); // let the placeholder load await dashboard.untilEmbeddableLoaded(newPanelId!); + await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion // now wait for the full embeddable to replace it const loadedPanel = await dashboard.untilEmbeddableLoaded(newPanelId!); expect(loadedPanel.type).toEqual(embeddable.type); diff --git a/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts b/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts index 1553257a04adb..a096430af362d 100644 --- a/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts +++ b/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts @@ -49,6 +49,7 @@ describe('createStartServicesGetter', () => { await new Promise((r) => setTimeout(r, 1)); future.resolve([core, plugins, self]); await future.promise; + await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion expect(start()).toEqual({ core, @@ -68,6 +69,7 @@ describe('createStartServicesGetter', () => { await new Promise((r) => setTimeout(r, 1)); future.resolve([core, plugins, self]); await future.promise; + await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion expect(start()).toEqual({ core, From 4bc1da53f0d07cc14827b8f0ab46f6814f26a91d Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 9 Nov 2020 21:20:16 +0100 Subject: [PATCH 18/26] [test] skip possibly broken test --- .../index_template_wizard/template_create.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx index b67e503f8d3e2..e9014c88a8204 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx @@ -263,11 +263,11 @@ describe('', () => { expect(find('stepTitle').text()).toEqual('Index settings (optional)'); }); - it('should not allow invalid json', async () => { + it.skip('should not allow invalid json', async () => { const { form, actions } = testBed; await act(async () => { - actions.completeStepThree('{ invalidJsonString '); + await actions.completeStepThree('{ invalidJsonString '); }); expect(form.getErrorsMessages()).toContain('Invalid JSON format.'); From eb5f4138120bc82b98bc5c421c058a834da89896 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 10 Nov 2020 11:36:45 +0100 Subject: [PATCH 19/26] Address review comments --- src/core/server/plugins/discovery/plugins_discovery.ts | 6 +++--- .../public/state_management/url/kbn_url_storage.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/server/plugins/discovery/plugins_discovery.ts b/src/core/server/plugins/discovery/plugins_discovery.ts index e4c9097a70208..2b5b8ad071fb5 100644 --- a/src/core/server/plugins/discovery/plugins_discovery.ts +++ b/src/core/server/plugins/discovery/plugins_discovery.ts @@ -17,7 +17,7 @@ * under the License. */ -import { readdir, stat, Stats } from 'fs'; +import { readdir, stat } from 'fs'; import { resolve } from 'path'; import { bindNodeCallback, from, merge, Observable } from 'rxjs'; import { catchError, filter, map, mergeMap, shareReplay } from 'rxjs/operators'; @@ -138,7 +138,7 @@ function findManifestInFolder( return fsStat$(resolve(dir, 'kibana.json')).pipe( mergeMap((stats) => { // `kibana.json` exists in given directory, we got a plugin - if ((stats as Stats).isFile()) { + if (stats.isFile()) { return [dir]; } return []; @@ -167,7 +167,7 @@ function mapSubdirectories( mergeMap((subDirs: string[]) => subDirs.map((subDir) => resolve(dir, subDir))), mergeMap((subDir) => fsStat$(subDir).pipe( - mergeMap((pathStat) => ((pathStat as Stats).isDirectory() ? mapFunc(subDir) : [])), + mergeMap((pathStat) => (pathStat.isDirectory() ? mapFunc(subDir) : [])), catchError((subDirStatError) => [ PluginDiscoveryError.invalidPluginPath(subDir, subDirStatError), ]) diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index d5e46d79b3b1d..cb3c9470c7abd 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -239,7 +239,7 @@ export const createKbnUrlControls = ( */ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): History.Path { function stripBasename(path: string | null) { - if (path == null) path = ''; + if (path === null) path = ''; const stripLeadingHash = (_: string) => (_.charAt(0) === '#' ? _.substr(1) : _); const stripTrailingSlash = (_: string) => _.charAt(_.length - 1) === '/' ? _.substr(0, _.length - 1) : _; From c33e36d723e9447f6b0c4a43dceb3ea605f20402 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 10 Nov 2020 14:06:10 +0100 Subject: [PATCH 20/26] [docs] list new ciphers in documentation --- docs/setup/settings.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 2f2c87ca9c7d4..8a9be52c49f39 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -513,7 +513,7 @@ In addition to this setting, trusted certificates may be specified via < Date: Tue, 10 Nov 2020 16:01:39 +0100 Subject: [PATCH 21/26] [docs] update link to correct version of OpenSSL --- docs/setup/settings.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 8a9be52c49f39..d583519a0e8b7 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -512,7 +512,7 @@ In addition to this setting, trusted certificates may be specified via < Date: Thu, 12 Nov 2020 00:17:17 +0100 Subject: [PATCH 22/26] Un-skip test fixed in master --- .../index_template_wizard/template_create.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx index 781e30b819ac2..da74dcabaf1e8 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx @@ -263,7 +263,7 @@ describe('', () => { expect(find('stepTitle').text()).toEqual('Index settings (optional)'); }); - it.skip('should not allow invalid json', async () => { + it('should not allow invalid json', async () => { const { form, actions } = testBed; await actions.completeStepThree('{ invalidJsonString '); From 5ffbd5b92b644e917c92df78d20573d3ce444108 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 12 Nov 2020 00:50:06 +0100 Subject: [PATCH 23/26] Finalize support for TLSv1.3 --- docs/setup/settings.asciidoc | 2 +- src/core/server/http/ssl_config.test.ts | 23 +++++++++++++++-------- src/core/server/http/ssl_config.ts | 11 +++++++++-- src/dev/build/tasks/bin/scripts/kibana | 2 +- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index d583519a0e8b7..efc7a1b930932 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -571,7 +571,7 @@ all http requests to https over the port configured as < { certificate: '/path/to/certificate', enabled: true, key: '/path/to/key', - supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'], + supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3'], }; const singleKnownProtocolConfig = sslSchema.validate(singleKnownProtocol); expect(singleKnownProtocolConfig.supportedProtocols).toEqual(['TLSv1']); const allKnownProtocolsConfig = sslSchema.validate(allKnownProtocols); - expect(allKnownProtocolsConfig.supportedProtocols).toEqual(['TLSv1', 'TLSv1.1', 'TLSv1.2']); + expect(allKnownProtocolsConfig.supportedProtocols).toEqual([ + 'TLSv1', + 'TLSv1.1', + 'TLSv1.2', + 'TLSv1.3', + ]); }); test('rejects unknown protocols`', () => { @@ -288,21 +293,23 @@ describe('#sslSchema', () => { certificate: '/path/to/certificate', enabled: true, key: '/path/to/key', - supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'SOMEv100500'], + supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3', 'SOMEv100500'], }; expect(() => sslSchema.validate(singleUnknownProtocol)).toThrowErrorMatchingInlineSnapshot(` "[supportedProtocols.0]: types that failed validation: - [supportedProtocols.0.0]: expected value to equal [TLSv1] - [supportedProtocols.0.1]: expected value to equal [TLSv1.1] -- [supportedProtocols.0.2]: expected value to equal [TLSv1.2]" +- [supportedProtocols.0.2]: expected value to equal [TLSv1.2] +- [supportedProtocols.0.3]: expected value to equal [TLSv1.3]" `); expect(() => sslSchema.validate(allKnownWithOneUnknownProtocols)) .toThrowErrorMatchingInlineSnapshot(` -"[supportedProtocols.3]: types that failed validation: -- [supportedProtocols.3.0]: expected value to equal [TLSv1] -- [supportedProtocols.3.1]: expected value to equal [TLSv1.1] -- [supportedProtocols.3.2]: expected value to equal [TLSv1.2]" +"[supportedProtocols.4]: types that failed validation: +- [supportedProtocols.4.0]: expected value to equal [TLSv1] +- [supportedProtocols.4.1]: expected value to equal [TLSv1.1] +- [supportedProtocols.4.2]: expected value to equal [TLSv1.2] +- [supportedProtocols.4.3]: expected value to equal [TLSv1.3]" `); }); }); diff --git a/src/core/server/http/ssl_config.ts b/src/core/server/http/ssl_config.ts index 432a85f550c98..0c5d0017614be 100644 --- a/src/core/server/http/ssl_config.ts +++ b/src/core/server/http/ssl_config.ts @@ -26,6 +26,8 @@ const protocolMap = new Map([ ['TLSv1', cryptoConstants.SSL_OP_NO_TLSv1], ['TLSv1.1', cryptoConstants.SSL_OP_NO_TLSv1_1], ['TLSv1.2', cryptoConstants.SSL_OP_NO_TLSv1_2], + // @ts-expect-error According to the docs SSL_OP_NO_TLSv1_3 should exist (https://nodejs.org/docs/latest-v12.x/api/crypto.html) + ['TLSv1.3', cryptoConstants.SSL_OP_NO_TLSv1_3], ]); export const sslSchema = schema.object( @@ -52,8 +54,13 @@ export const sslSchema = schema.object( }), redirectHttpFromPort: schema.maybe(schema.number()), supportedProtocols: schema.arrayOf( - schema.oneOf([schema.literal('TLSv1'), schema.literal('TLSv1.1'), schema.literal('TLSv1.2')]), - { defaultValue: ['TLSv1.1', 'TLSv1.2'], minSize: 1 } + schema.oneOf([ + schema.literal('TLSv1'), + schema.literal('TLSv1.1'), + schema.literal('TLSv1.2'), + schema.literal('TLSv1.3'), + ]), + { defaultValue: ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], minSize: 1 } ), clientAuthentication: schema.oneOf( [schema.literal('none'), schema.literal('optional'), schema.literal('required')], diff --git a/src/dev/build/tasks/bin/scripts/kibana b/src/dev/build/tasks/bin/scripts/kibana index a4fc5385500b5..3c12c8bbf58d0 100755 --- a/src/dev/build/tasks/bin/scripts/kibana +++ b/src/dev/build/tasks/bin/scripts/kibana @@ -26,4 +26,4 @@ if [ -f "${CONFIG_DIR}/node.options" ]; then KBN_NODE_OPTS="$(grep -v ^# < ${CONFIG_DIR}/node.options | xargs)" fi -NODE_OPTIONS="--no-warnings --max-http-header-size=65536 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" ${@} +NODE_OPTIONS="--no-warnings --max-http-header-size=65536 --tls-min-v1.0 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" ${@} From a28d9dc38f61058f587b6e215a6e48deca04f90a Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 12 Nov 2020 07:14:45 +0100 Subject: [PATCH 24/26] [test] Fix snapshots related to the TLSv1.3 change --- src/core/server/core_usage_data/core_usage_data_service.test.ts | 1 + src/core/server/http/__snapshots__/http_config.test.ts.snap | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index acb0d6f54cacb..e1c78edb902a9 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -177,6 +177,7 @@ describe('CoreUsageDataService', () => { "supportedProtocols": Array [ "TLSv1.1", "TLSv1.2", + "TLSv1.3", ], "truststoreConfigured": false, }, diff --git a/src/core/server/http/__snapshots__/http_config.test.ts.snap b/src/core/server/http/__snapshots__/http_config.test.ts.snap index 64baabd3d7ec8..8e8891b8a73aa 100644 --- a/src/core/server/http/__snapshots__/http_config.test.ts.snap +++ b/src/core/server/http/__snapshots__/http_config.test.ts.snap @@ -78,6 +78,7 @@ Object { "supportedProtocols": Array [ "TLSv1.1", "TLSv1.2", + "TLSv1.3", ], "truststore": Object {}, }, From 374d6f48b1694b20cfdc8289bdd1a7da03919ff6 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 12 Nov 2020 21:18:06 +0100 Subject: [PATCH 25/26] Bump @types/node to v12.19.4 and ensure it's pinned --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 57aa13a7a65af..7315007edf93d 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "**/@types/hapi__boom": "^7.4.1", "**/@types/hapi__hapi": "^18.2.6", "**/@types/hapi__mimos": "4.1.0", - "**/@types/node": ">=12.12.64 <12.20.0", + "**/@types/node": "12.19.4", "**/cross-fetch/node-fetch": "^2.6.1", "**/deepmerge": "^4.2.2", "**/fast-deep-equal": "^3.1.1", @@ -497,7 +497,7 @@ "@types/mustache": "^0.8.31", "@types/ncp": "^2.0.1", "@types/nock": "^10.0.3", - "@types/node": ">=12.12.64 <12.20.0", + "@types/node": "12.19.4", "@types/node-fetch": "^2.5.7", "@types/node-forge": "^0.9.5", "@types/nodemailer": "^6.2.1", diff --git a/yarn.lock b/yarn.lock index 8d82f690978db..367dd86f39077 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5272,10 +5272,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@8.10.54", "@types/node@>= 8", "@types/node@>=12.12.64 <12.20.0", "@types/node@>=8.9.0", "@types/node@^12.0.2": - version "12.19.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.3.tgz#a6e252973214079155f749e8bef99cc80af182fa" - integrity sha512-8Jduo8wvvwDzEVJCOvS/G6sgilOLvvhn1eMmK3TW8/T217O7u1jdrK6ImKLv80tVryaPSVeKu6sjDEiFjd4/eg== +"@types/node@*", "@types/node@12.19.4", "@types/node@8.10.54", "@types/node@>= 8", "@types/node@>=8.9.0", "@types/node@^12.0.2": + version "12.19.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.4.tgz#cdfbb62e26c7435ed9aab9c941393cc3598e9b46" + integrity sha512-o3oj1bETk8kBwzz1WlO6JWL/AfAA3Vm6J1B3C9CsdxHYp7XgPiH7OEXPUbZTndHlRaIElrANkQfe6ZmfJb3H2w== "@types/nodemailer@^6.2.1": version "6.2.1" From f5d6572a7cc710853a1dab2b5f7a1825286d6c8b Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 12 Nov 2020 21:50:44 +0100 Subject: [PATCH 26/26] Fix TypeScript errors not showing up in CI --- .../src/integration_tests/basic_optimization.test.ts | 1 - x-pack/plugins/actions/server/builtin_action_types/slack.ts | 1 + .../canvas/shareable_runtime/api/__tests__/shareable.test.tsx | 1 - x-pack/plugins/fleet/server/services/epm/registry/requests.ts | 1 + .../server/browsers/chromium/driver/chromium_driver.ts | 1 - .../security_solution/public/management/common/routing.ts | 4 ++-- .../pages/endpoint_hosts/view/url_from_query_params.ts | 2 +- .../public/network/pages/details/index.test.tsx | 4 +--- .../components/overview/__tests__/synthetics_callout.test.tsx | 1 - .../overview/monitor_list/__tests__/monitor_list.test.tsx | 1 - 10 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts b/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts index a89f84e5c543d..46660f0dd958b 100644 --- a/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts +++ b/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts @@ -261,7 +261,6 @@ const expectFileMatchesSnapshotWithCompression = (filePath: string, snapshotLabe // Verify the brotli variant matches expect( - // @ts-expect-error @types/node is missing the brotli functions Zlib.brotliDecompressSync( Fs.readFileSync(Path.resolve(MOCK_REPO_DIR, `${filePath}.br`)) ).toString() diff --git a/x-pack/plugins/actions/server/builtin_action_types/slack.ts b/x-pack/plugins/actions/server/builtin_action_types/slack.ts index 1605cd4b69f5e..628a13e19f7a9 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/slack.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/slack.ts @@ -126,6 +126,7 @@ async function slackExecutor( // https://slack.dev/node-slack-sdk/webhook // node-slack-sdk use Axios inside :) const webhook = new IncomingWebhook(webhookUrl, { + // @ts-expect-error The types exposed by 'HttpsProxyAgent' isn't up to date with 'Agent' agent: proxyAgent, }); result = await webhook.send(message); diff --git a/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx b/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx index 4b3aa8dc2fb6e..0851ae8d04eb0 100644 --- a/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx @@ -15,7 +15,6 @@ jest.mock('../../supported_renderers'); describe('Canvas Shareable Workpad API', () => { // Mock the AJAX load of the workpad. beforeEach(function () { - // @ts-expect-error Applying a global in Jest is alright. global.fetch = jest.fn().mockImplementation(() => { const p = new Promise((resolve, _reject) => { resolve({ diff --git a/x-pack/plugins/fleet/server/services/epm/registry/requests.ts b/x-pack/plugins/fleet/server/services/epm/registry/requests.ts index c8d158c8afaaa..7bd023219aeb3 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/requests.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/requests.ts @@ -93,6 +93,7 @@ export function getFetchOptions(targetUrl: string): RequestInit | undefined { logger.debug(`Using ${proxyUrl} as proxy for ${targetUrl}`); return { + // @ts-expect-error The types exposed by 'HttpsProxyAgent' isn't up to date with 'Agent' agent: getProxyAgent({ proxyUrl, targetUrl }), }; } diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts index 2f19a8a8a7c61..500185cd7e14f 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts @@ -340,7 +340,6 @@ export class HeadlessChromiumDriver { hostname === conditions.hostname && protocol === `${conditions.protocol}:` && this._shouldUseCustomHeadersForPort(conditions, port) && - // @ts-expect-error according to the types `pathname` is `string | undefined`, but it's actually `string | null` pathname.startsWith(`${conditions.basePath}/`) ); } diff --git a/x-pack/plugins/security_solution/public/management/common/routing.ts b/x-pack/plugins/security_solution/public/management/common/routing.ts index 87545f7008760..c2c82639bf7d5 100644 --- a/x-pack/plugins/security_solution/public/management/common/routing.ts +++ b/x-pack/plugins/security_solution/public/management/common/routing.ts @@ -32,9 +32,9 @@ type Exact = T extends Shape ? ExactKeys : never; * Ensures that when creating a URL query param string, that the given input strictly * matches the expected interface (guards against possibly leaking internal state) */ -const querystringStringify: ( +const querystringStringify = ( params: Exact -) => string = querystring.stringify; +): string => querystring.stringify((params as unknown) as querystring.ParsedUrlQueryInput); /** Make `selected_endpoint` required */ type EndpointDetailsUrlProps = Omit & diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts index c421f513556f4..c9f0ff6235cc0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts @@ -11,7 +11,7 @@ import { EndpointIndexUIQueryParams } from '../types'; import { AppLocation } from '../../../../../common/endpoint/types'; export function urlFromQueryParams(queryParams: EndpointIndexUIQueryParams): Partial { - const search = querystring.stringify(queryParams); + const search = querystring.stringify(queryParams as Record); return { search, }; diff --git a/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx b/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx index 430b5702be1bc..8b2810143cb19 100644 --- a/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx @@ -26,8 +26,6 @@ import { NetworkDetails } from './index'; type Action = 'PUSH' | 'POP' | 'REPLACE'; const pop: Action = 'POP'; -type GlobalWithFetch = NodeJS.Global & { fetch: jest.Mock }; - jest.mock('react-router-dom', () => { const original = jest.requireActual('react-router-dom'); @@ -85,7 +83,7 @@ describe('Network Details', () => { indicesExist: false, indexPattern: {}, }); - (global as GlobalWithFetch).fetch = jest.fn().mockImplementationOnce(() => + global.fetch = jest.fn().mockImplementationOnce(() => Promise.resolve({ ok: true, json: () => { diff --git a/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx b/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx index 88bae4c72b686..980021b7d6073 100644 --- a/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx @@ -19,7 +19,6 @@ describe('SyntheticsCallout', () => { setItem: setItemMock, }; - // @ts-expect-error replacing a call to localStorage we use for monitor list size global.localStorage = localStorageMock; }); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx index 352369cfdb72b..8e5ae13836f47 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx @@ -135,7 +135,6 @@ describe('MonitorList component', () => { setItem: jest.fn(), }; - // @ts-expect-error replacing a call to localStorage we use for monitor list size global.localStorage = localStorageMock; });