diff --git a/packages/kbn-dev-utils/src/ci_stats_reporter/README.md b/packages/kbn-dev-utils/src/ci_stats_reporter/README.md index 6133f9871699f9..c7b98224c4e570 100644 --- a/packages/kbn-dev-utils/src/ci_stats_reporter/README.md +++ b/packages/kbn-dev-utils/src/ci_stats_reporter/README.md @@ -8,7 +8,7 @@ This class integrates with the `ciStats.trackBuild {}` Jenkins Pipeline function To create an instance of the reporter, import the class and call `CiStatsReporter.fromEnv(log)` (passing it a tooling log). -#### `CiStatsReporter#metric(name: string, subName: string, value: number)` +#### `CiStatsReporter#metrics(metrics: Array<{ group: string, id: string, value: number }>)` Use this method to record metrics in the Kibana CI Stats service. @@ -19,5 +19,11 @@ import { CiStatsReporter, ToolingLog } from '@kbn/dev-utils'; const log = new ToolingLog(...); const reporter = CiStatsReporter.fromEnv(log) -reporter.metric('Build speed', specificBuildName, timeToRunBuild) +reporter.metrics([ + { + group: 'Build size', + id: specificBuildName, + value: sizeOfBuild + } +]) ``` \ No newline at end of file diff --git a/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts b/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts index 5fe1844a85563c..4e912896104328 100644 --- a/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts +++ b/packages/kbn-dev-utils/src/ci_stats_reporter/ci_stats_reporter.ts @@ -84,13 +84,16 @@ export class CiStatsReporter { return !!this.config; } - async metric(name: string, subName: string, value: number) { + async metrics(metrics: Array<{ group: string; id: string; value: number }>) { if (!this.config) { return; } let attempt = 0; const maxAttempts = 5; + const bodySummary = metrics + .map(({ group, id, value }) => `[${group}/${id}=${value}]`) + .join(' '); while (true) { attempt += 1; @@ -98,18 +101,14 @@ export class CiStatsReporter { try { await Axios.request({ method: 'POST', - url: '/metric', + url: '/v1/metrics', baseURL: this.config.apiUrl, - params: { - buildId: this.config.buildId, - }, headers: { Authorization: `token ${this.config.apiToken}`, }, data: { - name, - subName, - value, + buildId: this.config.buildId, + metrics, }, }); @@ -125,14 +124,14 @@ export class CiStatsReporter { this.log.warning( `error recording metric [status=${error.response.status}] [resp=${inspect( error.response.data - )}] [${name}/${subName}=${value}]` + )}] ${bodySummary}` ); return; } if (attempt === maxAttempts) { this.log.warning( - `failed to reach kibana-ci-stats service too many times, unable to record metric [${name}/${subName}=${value}]` + `failed to reach kibana-ci-stats service too many times, unable to record metric ${bodySummary}` ); return; } diff --git a/packages/kbn-optimizer/src/cli.ts b/packages/kbn-optimizer/src/cli.ts index e46075eff63a77..a2fbe969e34d82 100644 --- a/packages/kbn-optimizer/src/cli.ts +++ b/packages/kbn-optimizer/src/cli.ts @@ -21,7 +21,7 @@ import 'source-map-support/register'; import Path from 'path'; -import { run, REPO_ROOT, createFlagError, createFailError, CiStatsReporter } from '@kbn/dev-utils'; +import { run, REPO_ROOT, createFlagError, CiStatsReporter } from '@kbn/dev-utils'; import { logOptimizerState } from './log_optimizer_state'; import { OptimizerConfig } from './optimizer'; @@ -82,9 +82,9 @@ run( throw createFlagError('expected --scan-dir to be a string'); } - const reportStatsName = flags['report-stats']; - if (reportStatsName !== undefined && typeof reportStatsName !== 'string') { - throw createFlagError('expected --report-stats to be a string'); + const reportStats = flags['report-stats'] ?? false; + if (typeof reportStats !== 'boolean') { + throw createFlagError('expected --report-stats to have no value'); } const config = OptimizerConfig.create({ @@ -103,22 +103,32 @@ run( let update$ = runOptimizer(config); - if (reportStatsName) { + if (reportStats) { const reporter = CiStatsReporter.fromEnv(log); if (!reporter.isEnabled()) { - throw createFailError('Unable to initialize CiStatsReporter from env'); + log.warning('Unable to initialize CiStatsReporter from env'); } - update$ = update$.pipe(reportOptimizerStats(reporter, reportStatsName)); + update$ = update$.pipe(reportOptimizerStats(reporter, config)); } await update$.pipe(logOptimizerState(log, config)).toPromise(); }, { flags: { - boolean: ['core', 'watch', 'oss', 'examples', 'dist', 'cache', 'profile', 'inspect-workers'], - string: ['workers', 'scan-dir', 'report-stats'], + boolean: [ + 'core', + 'watch', + 'oss', + 'examples', + 'dist', + 'cache', + 'profile', + 'inspect-workers', + 'report-stats', + ], + string: ['workers', 'scan-dir'], default: { core: true, examples: true, @@ -136,7 +146,7 @@ run( --dist create bundles that are suitable for inclusion in the Kibana distributable --scan-dir add a directory to the list of directories scanned for plugins (specify as many times as necessary) --no-inspect-workers when inspecting the parent process, don't inspect the workers - --report-stats=[name] attempt to report stats about this execution of the build to the kibana-ci-stats service using this name + --report-stats attempt to report stats about this execution of the build to the kibana-ci-stats service using this name `, }, } diff --git a/packages/kbn-optimizer/src/report_optimizer_stats.ts b/packages/kbn-optimizer/src/report_optimizer_stats.ts index 375978b9b79447..06161fb2567b94 100644 --- a/packages/kbn-optimizer/src/report_optimizer_stats.ts +++ b/packages/kbn-optimizer/src/report_optimizer_stats.ts @@ -21,10 +21,10 @@ import { materialize, mergeMap, dematerialize } from 'rxjs/operators'; import { CiStatsReporter } from '@kbn/dev-utils'; import { OptimizerUpdate$ } from './run_optimizer'; -import { OptimizerState } from './optimizer'; +import { OptimizerState, OptimizerConfig } from './optimizer'; import { pipeClosure } from './common'; -export function reportOptimizerStats(reporter: CiStatsReporter, name: string) { +export function reportOptimizerStats(reporter: CiStatsReporter, config: OptimizerConfig) { return pipeClosure((update$: OptimizerUpdate$) => { let lastState: OptimizerState | undefined; return update$.pipe( @@ -35,7 +35,18 @@ export function reportOptimizerStats(reporter: CiStatsReporter, name: string) { } if (n.kind === 'C' && lastState) { - await reporter.metric('@kbn/optimizer build time', name, lastState.durSec); + await reporter.metrics( + config.bundles.map(bundle => { + // make the cache read from the cache file since it was likely updated by the worker + bundle.cache.refresh(); + + return { + group: `@kbn/optimizer bundle module count`, + id: bundle.id, + value: bundle.cache.getModuleCount() || 0, + }; + }) + ); } return n; diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 28cf36dedba3f3..1b70cced4a5c9c 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -43933,30 +43933,29 @@ class CiStatsReporter { isEnabled() { return !!this.config; } - async metric(name, subName, value) { + async metrics(metrics) { var _a, _b, _c, _d; if (!this.config) { return; } let attempt = 0; const maxAttempts = 5; + const bodySummary = metrics + .map(({ group, id, value }) => `[${group}/${id}=${value}]`) + .join(' '); while (true) { attempt += 1; try { await axios_1.default.request({ method: 'POST', - url: '/metric', + url: '/v1/metrics', baseURL: this.config.apiUrl, - params: { - buildId: this.config.buildId, - }, headers: { Authorization: `token ${this.config.apiToken}`, }, data: { - name, - subName, - value, + buildId: this.config.buildId, + metrics, }, }); return; @@ -43968,11 +43967,11 @@ class CiStatsReporter { } if (((_b = error) === null || _b === void 0 ? void 0 : _b.response) && error.response.status !== 502) { // error response from service was received so warn the user and move on - this.log.warning(`error recording metric [status=${error.response.status}] [resp=${util_1.inspect(error.response.data)}] [${name}/${subName}=${value}]`); + this.log.warning(`error recording metric [status=${error.response.status}] [resp=${util_1.inspect(error.response.data)}] ${bodySummary}`); return; } if (attempt === maxAttempts) { - this.log.warning(`failed to reach kibana-ci-stats service too many times, unable to record metric [${name}/${subName}=${value}]`); + this.log.warning(`failed to reach kibana-ci-stats service too many times, unable to record metric ${bodySummary}`); return; } // we failed to reach the backend and we have remaining attempts, lets retry after a short delay diff --git a/src/dev/build/tasks/build_kibana_platform_plugins.js b/src/dev/build/tasks/build_kibana_platform_plugins.js index 28d6b49f9e89a8..153a3120f896f8 100644 --- a/src/dev/build/tasks/build_kibana_platform_plugins.js +++ b/src/dev/build/tasks/build_kibana_platform_plugins.js @@ -39,11 +39,10 @@ export const BuildKibanaPlatformPluginsTask = { }); const reporter = CiStatsReporter.fromEnv(log); - const reportStatsName = build.isOss() ? 'oss distributable' : 'default distributable'; await runOptimizer(optimizerConfig) .pipe( - reportOptimizerStats(reporter, reportStatsName), + reportOptimizerStats(reporter, optimizerConfig), logOptimizerState(log, optimizerConfig) ) .toPromise(); diff --git a/src/dev/build/tasks/create_archives_task.js b/src/dev/build/tasks/create_archives_task.js index 06be1bd0bd14f3..541b9551dbc9ba 100644 --- a/src/dev/build/tasks/create_archives_task.js +++ b/src/dev/build/tasks/create_archives_task.js @@ -17,13 +17,22 @@ * under the License. */ -import path from 'path'; +import Path from 'path'; +import Fs from 'fs'; +import { promisify } from 'util'; + +import { CiStatsReporter } from '@kbn/dev-utils'; + import { mkdirp, compress } from '../lib'; +const asyncStat = promisify(Fs.stat); + export const CreateArchivesTask = { description: 'Creating the archives for each platform', async run(config, log, build) { + const archives = []; + // archive one at a time, parallel causes OOM sometimes for (const platform of config.getTargetPlatforms()) { const source = build.resolvePathForPlatform(platform, '.'); @@ -31,10 +40,15 @@ export const CreateArchivesTask = { log.info('archiving', source, 'to', destination); - await mkdirp(path.dirname(destination)); + await mkdirp(Path.dirname(destination)); - switch (path.extname(destination)) { + switch (Path.extname(destination)) { case '.zip': + archives.push({ + format: 'zip', + path: destination, + }); + await compress( 'zip', { @@ -51,6 +65,11 @@ export const CreateArchivesTask = { break; case '.gz': + archives.push({ + format: 'tar', + path: destination, + }); + await compress( 'tar', { @@ -71,5 +90,20 @@ export const CreateArchivesTask = { throw new Error(`Unexpected extension for archive destination: ${destination}`); } } + + const reporter = CiStatsReporter.fromEnv(log); + if (reporter.isEnabled()) { + await reporter.metrics( + await Promise.all( + archives.map(async ({ format, path }) => { + return { + group: `${build.isOss() ? 'oss ' : ''}distributable size`, + id: format, + value: (await asyncStat(path)).size, + }; + }) + ) + ); + } }, }; diff --git a/x-pack/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap b/x-pack/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap index e5026778fec1c7..df2e119f511e17 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap +++ b/x-pack/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap @@ -88,6 +88,7 @@ exports[`CalendarForm Renders calendar form 1`] = ` size="xl" /> {isGlobalCalendar === false && ( diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json index d8c970e1794164..c792b981df30a5 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json @@ -30,7 +30,7 @@ { "url_name": "Process rate", "time_range": "1h", - "url_value": "kibana#/dashboard/ml_auditbeat_docker_process_event_rate_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:container.runtime,negate:!f,params:(query:docker),type:phrase,value:docker),query:(match:(container.runtime:(query:docker,type:phrase)))),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022\u0027))" + "url_value": "kibana#/dashboard/ml_auditbeat_docker_process_event_rate_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:container.runtime,negate:!f,params:(query:docker),type:phrase,value:docker),query:(match:(container.runtime:(query:docker,type:phrase)))),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022\u0027))" }, { "url_name": "Raw data", diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json index 76e3c8026c6310..b3f02ae5a6bf88 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json @@ -30,7 +30,7 @@ { "url_name": "Process explorer", "time_range": "1h", - "url_value": "kibana#/dashboard/ml_auditbeat_docker_process_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:container.runtime,negate:!f,params:(query:docker),type:phrase,value:docker),query:(match:(container.runtime:(query:docker,type:phrase)))),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022\u0027))" + "url_value": "kibana#/dashboard/ml_auditbeat_docker_process_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:container.runtime,negate:!f,params:(query:docker),type:phrase,value:docker),query:(match:(container.runtime:(query:docker,type:phrase)))),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022\u0027))" }, { "url_name": "Raw data", diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json index 487bee53118785..0e9336507b465b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json @@ -29,7 +29,7 @@ { "url_name": "Process rate", "time_range": "1h", - "url_value": "kibana#/dashboard/ml_auditbeat_hosts_process_event_rate_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),exists:(field:container.runtime),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:container.runtime,negate:!t,type:exists,value:exists)),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022\u0027))" + "url_value": "kibana#/dashboard/ml_auditbeat_hosts_process_event_rate_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),exists:(field:container.runtime),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:container.runtime,negate:!t,type:exists,value:exists)),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022\u0027))" }, { "url_name": "Raw data", diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json index 9ba6859bfa1669..4dd1409b71c793 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json @@ -30,7 +30,7 @@ { "url_name": "Process explorer", "time_range": "1h", - "url_value": "kibana#/dashboard/ml_auditbeat_hosts_process_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),exists:(field:container.runtime),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:container.runtime,negate:!t,type:exists,value:exists)),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:INDEX_PATTERN_ID,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022\u0027))" + "url_value": "kibana#/dashboard/ml_auditbeat_hosts_process_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.module,negate:!f,params:(query:auditd),type:phrase,value:auditd),query:(match:(event.module:(query:auditd,type:phrase)))),('$state':(store:appState),exists:(field:container.runtime),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:container.runtime,negate:!t,type:exists,value:exists)),('$state':(store:appState),exists:(field:auditd.data.syscall),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:auditd.data.syscall,negate:!f,type:exists,value:exists))),query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022\u0027))" }, { "url_name": "Raw data", diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/high_sum_total_sales.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/high_sum_total_sales.json index e0230e2a063734..c3d401085f7ae3 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/high_sum_total_sales.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/high_sum_total_sales.json @@ -27,7 +27,7 @@ "custom_urls": [ { "url_name": "Raw data", - "url_value": "kibana#/discover?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:ff959d40-b880-11e8-a6d9-e546fe2bba5f,query:(language:kuery,query:\u0027customer_full_name.keyword:\u0022$customer_full_name.keyword$\u0022\u0027),sort:!('@timestamp',desc))" + "url_value": "kibana#/discover?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027ff959d40-b880-11e8-a6d9-e546fe2bba5f\u0027,query:(language:kuery,query:\u0027customer_full_name.keyword:\u0022$customer_full_name.keyword$\u0022\u0027),sort:!('@timestamp',desc))" }, { "url_name": "Data dashboard", diff --git a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details.tsx b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details.tsx index ac2a2997515d52..6579d18556cc06 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details.tsx +++ b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details.tsx @@ -44,6 +44,7 @@ export const ShardDetails = ({ index, shard, operations }: Props) => { setShardVisibility(!shardVisibility)} + data-test-subj="openCloseShardDetails" > [{shard.id[0]}][ {shard.id[2]}] diff --git a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details_tree_node.tsx b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details_tree_node.tsx index 1d8f915d3d47d3..d89046090a9611 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details_tree_node.tsx +++ b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/shard_details/shard_details_tree_node.tsx @@ -94,6 +94,7 @@ export const ShardDetailsTreeNode = ({ operation, index, shard }: Props) => { highlight({ indexName: index.name, operation, shard })} > {i18n.translate('xpack.searchProfiler.profileTree.body.viewDetailsLabel', { diff --git a/x-pack/plugins/searchprofiler/public/application/components/searchprofiler_tabs.tsx b/x-pack/plugins/searchprofiler/public/application/components/searchprofiler_tabs.tsx index 19224e7099fd66..7e6dad7df5528a 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/searchprofiler_tabs.tsx +++ b/x-pack/plugins/searchprofiler/public/application/components/searchprofiler_tabs.tsx @@ -24,6 +24,7 @@ export const SearchProfilerTabs = ({ activeTab, activateTab, has }: Props) => { return ( activateTab('searches')} @@ -33,6 +34,7 @@ export const SearchProfilerTabs = ({ activeTab, activateTab, has }: Props) => { })} activateTab('aggregations')} diff --git a/x-pack/plugins/searchprofiler/public/application/containers/profile_query_editor.tsx b/x-pack/plugins/searchprofiler/public/application/containers/profile_query_editor.tsx index 5348c55ad52139..f6377d2b4f9067 100644 --- a/x-pack/plugins/searchprofiler/public/application/containers/profile_query_editor.tsx +++ b/x-pack/plugins/searchprofiler/public/application/containers/profile_query_editor.tsx @@ -120,7 +120,12 @@ export const ProfileQueryEditor = memo(() => { - handleProfileClick()}> + handleProfileClick()} + > {i18n.translate('xpack.searchProfiler.formProfileButtonLabel', { defaultMessage: 'Profile', diff --git a/x-pack/test/accessibility/apps/search_profiler.ts b/x-pack/test/accessibility/apps/search_profiler.ts new file mode 100644 index 00000000000000..0caf21643f32a7 --- /dev/null +++ b/x-pack/test/accessibility/apps/search_profiler.ts @@ -0,0 +1,93 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../ftr_provider_context'; + +export default function({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'security']); + const testSubjects = getService('testSubjects'); + const aceEditor = getService('aceEditor'); + const a11y = getService('a11y'); + const flyout = getService('flyout'); + + describe('Accessibility Search Profiler Editor', () => { + before(async () => { + await PageObjects.common.navigateToApp('searchProfiler'); + await a11y.testAppSnapshot(); + expect(await testSubjects.exists('searchProfilerEditor')).to.be(true); + }); + + it('input the JSON in the aceeditor', async () => { + const input = { + query: { + bool: { + should: [ + { + match: { + name: 'fred', + }, + }, + { + terms: { + name: ['sue', 'sally'], + }, + }, + ], + }, + }, + aggs: { + stats: { + stats: { + field: 'price', + }, + }, + }, + }; + + await aceEditor.setValue('searchProfilerEditor', JSON.stringify(input)); + await a11y.testAppSnapshot(); + }); + + it('click on the profile button', async () => { + await testSubjects.click('profileButton'); + await a11y.testAppSnapshot(); + }); + + it('click on the dropdown link', async () => { + const viewShardDetailslink = await testSubjects.findAll('viewShardDetails'); + await viewShardDetailslink[0].click(); + await a11y.testAppSnapshot(); + }); + + it('click on the open-close shard details link', async () => { + const openShardDetailslink = await testSubjects.findAll('openCloseShardDetails'); + await openShardDetailslink[0].click(); + await a11y.testAppSnapshot(); + }); + + it('close the fly out', async () => { + await flyout.ensureAllClosed(); + await a11y.testAppSnapshot(); + }); + + it('click on the Aggregation Profile link', async () => { + await testSubjects.click('aggregationProfileTab'); + await a11y.testAppSnapshot(); + }); + + it('click on the view details link', async () => { + const viewShardDetailslink = await testSubjects.findAll('viewShardDetails'); + await viewShardDetailslink[0].click(); + await a11y.testAppSnapshot(); + }); + + it('close the fly out', async () => { + await flyout.ensureAllClosed(); + await a11y.testAppSnapshot(); + }); + }); +} diff --git a/x-pack/test/accessibility/config.ts b/x-pack/test/accessibility/config.ts index 57822be18e267c..29c1eb31c00d8a 100644 --- a/x-pack/test/accessibility/config.ts +++ b/x-pack/test/accessibility/config.ts @@ -13,10 +13,12 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { return { ...functionalConfig.getAll(), + testFiles: [ require.resolve('./apps/login_page'), require.resolve('./apps/home'), require.resolve('./apps/grok_debugger'), + require.resolve('./apps/search_profiler'), require.resolve('./apps/uptime'), ], pageObjects,