From 81926f04fb3e6730eb7842e1d190fa15d171d74c Mon Sep 17 00:00:00 2001
From: Tiago Costa
Date: Tue, 23 Aug 2022 19:02:58 +0100
Subject: [PATCH 01/18] skip flaky suite (#139300)
---
.../functional_with_es_ssl/apps/cases/attachment_framework.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts b/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts
index 72ce196c1ae620a..fcab559466a741c 100644
--- a/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts
@@ -107,7 +107,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
});
});
- describe('Persistable state attachments', () => {
+ // FLAKY: https://github.com/elastic/kibana/issues/139300
+ describe.skip('Persistable state attachments', () => {
const getLensState = (dataViewId: string) => ({
title: '',
visualizationType: 'lnsXY',
From 3fcd94b28de701e70c56d53e76a2453ac524b0a7 Mon Sep 17 00:00:00 2001
From: Devon Thomson
Date: Tue, 23 Aug 2022 14:15:38 -0400
Subject: [PATCH 02/18] [Dashboard] Test Service Codeowners (#139309)
Update .github/CODEOWNERS
Co-authored-by: Hannah Mudge
---
.github/CODEOWNERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index e6777e5e69f29a3..d4bf323f938a708 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -183,6 +183,7 @@ x-pack/examples/files_example @elastic/kibana-app-services
/src/plugins/controls/ @elastic/kibana-presentation
/test/functional/apps/dashboard/ @elastic/kibana-presentation
/test/functional/apps/dashboard_elements/ @elastic/kibana-presentation
+/test/functional/services/dashboard/ @elastic/kibana-presentation
/x-pack/plugins/canvas/ @elastic/kibana-presentation
/x-pack/plugins/dashboard_enhanced/ @elastic/kibana-presentation
/x-pack/test/functional/apps/canvas/ @elastic/kibana-presentation
From 33241437b0ed400e9c28365471624191ca61f2f6 Mon Sep 17 00:00:00 2001
From: Karl Godard
Date: Tue, 23 Aug 2022 11:52:12 -0700
Subject: [PATCH 03/18] [TTY Output] Zoom In/Out/Fit controls added to TTY
Player. (#139253)
* progress on fit to text feature
* text sizer working guud
* major improvements to search (handling of escape codes). Tests added for tty_text_sizer
* field rename in mock data
* lint fix
Co-authored-by: Karl Godard
---
.../plugins/session_view/common/constants.ts | 10 +-
.../responses/session_view_io_events.mock.ts | 84 ++++++++++-
.../common/types/process_tree/index.ts | 11 +-
.../public/components/session_view/index.tsx | 4 +-
.../components/tty_player/hooks.test.tsx | 15 +-
.../public/components/tty_player/hooks.ts | 131 +++++++++++-------
.../public/components/tty_player/index.tsx | 31 ++++-
.../public/components/tty_player/styles.ts | 45 ++++--
.../components/tty_player/translations.ts | 19 +++
.../components/tty_player/xterm_search.ts | 7 +-
.../components/tty_search_bar/index.test.tsx | 17 ++-
.../components/tty_search_bar/index.tsx | 77 ++++++----
.../components/tty_text_sizer/index.test.tsx | 76 ++++++++++
.../components/tty_text_sizer/index.tsx | 89 ++++++++++++
.../components/tty_text_sizer/translations.ts | 19 +++
.../session_view/io_events/data.json | 74 +++++++++-
16 files changed, 580 insertions(+), 129 deletions(-)
create mode 100644 x-pack/plugins/session_view/public/components/tty_player/translations.ts
create mode 100644 x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx
create mode 100644 x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx
create mode 100644 x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts
diff --git a/x-pack/plugins/session_view/common/constants.ts b/x-pack/plugins/session_view/common/constants.ts
index 5bf0dc53701fc08..538605bb591b0c9 100644
--- a/x-pack/plugins/session_view/common/constants.ts
+++ b/x-pack/plugins/session_view/common/constants.ts
@@ -43,7 +43,15 @@ export const ALERT_STATUS = {
export const LOCAL_STORAGE_DISPLAY_OPTIONS_KEY = 'sessionView:displayOptions';
export const MOUSE_EVENT_PLACEHOLDER = { stopPropagation: () => undefined } as React.MouseEvent;
export const DEBOUNCE_TIMEOUT = 500;
-export const DEFAULT_TTY_PLAYSPEED_MS = 40; // milli seconds per line of tty output.
+export const DEFAULT_TTY_PLAYSPEED_MS = 80; // milli seconds per line of tty output.
+export const DEFAULT_TTY_FONT_SIZE = 11;
+
+// we split terminal output on both newlines and cursor movements.
+export const TTY_LINE_SPLITTER_REGEX = /(\r?\n|\x1b\[\d+;\d+[Hf])/gi;
+
+// used when searching output
+export const TTY_STRIP_CONTROL_CODES_REGEX =
+ /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/gi;
// when showing the count of alerts in details panel tab, if the number
// exceeds ALERT_COUNT_THRESHOLD we put a + next to it, e.g 999+
diff --git a/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts b/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts
index 33b9ac56b035df1..c14dccc2bc3d654 100644
--- a/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts
+++ b/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts
@@ -17,6 +17,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '1',
@@ -30,7 +31,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
total_bytes_captured: 1024,
total_bytes_skipped: 0,
bytes_skipped: [],
- text: "256\n,\n Some Companies Puppet instance\n | | | CentOS Stream release 8 on x86_64\n .=/ = = =| =| = === = Load average: 1.23, 1.01, 0.63\n | || || || || || | | | | \n /= = = =' =' =' ' =' Hostname ********\n \\ Type xyz\n o Datacenter ********\n Cluster ********\n\n\n\n\n,0 loaded units listed. Pass --all to see loaded but inactive units, too.\nTo show all installed unit files use 'systemctl list-unit-files'.\n",
+ text: "256\n,\n Some Companies Puppet instance\n | | | CentOS Stream release 8 on x86_64\n *********************** Load average: 1.23, 1.01, 0.63\n ************************ \n ************************ Hostname ********\n \\ Type xyz\n o Datacenter ********\n Cluster ********\n\n\n\n\n,0 loaded units listed. Pass --all to see loaded but inactive units, too.\nTo show all installed unit files use 'systemctl list-unit-files'.\n",
+ },
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
},
},
},
@@ -44,6 +53,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '2',
@@ -57,7 +67,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
total_bytes_captured: 1024,
total_bytes_skipped: 0,
bytes_skipped: [],
- text: ',\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/galera_traffic_start.sh" [readonly] 14L, 397C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for setting the reject of queries in Galera\n\nmysql -h127.0.0.1 -P6033 -uroot -e "set global wsrep_reject_queries=\'NONE\'" 2>&1\nRC=$?\n\nif [[ $RC != 0 ]]; then\n >&2 echo "Failed to unset the reject of queries on Galera node, exiting."\n exit $RC\nelse\n echo "Successfully unset the reject of queries."\nfi\n\u001b[94m~ \u001b[16;1H~ \u001b[17;1H~ \u001b[18;1H~ \u001b[19;1H~ \u001b[20;1H~ \u001b[21;1H~ \u001b[22;1H~ \u001b[23;1H~ \u001b[24;1H~ \u001b[25;1H~ \u001b[26;1H~ \u001b[27;1H~ \u001b[28;1H~ \u001b[29;1H~ \u001b[30;1H~ \u001b[31;1H~ \u001b[32;1H~ \u001b[33;1H~ \u001b[34;1H~ \u001b[35;1H~ \u001b[36;1H~ \u001b[37;1H~ \u001b[38;1H~ \u001b[39;1H~ \u001b[40;1H~ \u001b[41;1H~ \u001b[42;1H~ \u001b[43;1H~ \u001b[44;1H~ \u001b[45;1H~ \u001b[46;1H~ \u001b[47;1H~ \u001b[48;1H~ \u001b[49;1H~ \u001b[50;1H~ \u001b[51;1H~ \u001b[52;1H~ \u001b[53;1H~ \u001b[54;1H~ \u001b[55;1H~ \u001b[56;1H~ \u001b[57;1H~ \u001b[58;1H~ \u001b[1;1H\u001b[?25h\u0007\u001b[?25l\u001b[m\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hq\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/galera_traffic_stop.sh" [readonly] 115L, 3570C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for rejecting connection on Galera cluster node, either gracefully or not,\n# depending on supplied arguments.\n\nfunction usage() {\n echo "\n This script disables DB connections to Galera node.\n The default is to stop them gracefully.\n\n Usage: $0 [-h] [-w ] [-s ] [-x]\n\n Options:\n -h Prints this help.\n -w Number of seconds for waiting to close the connections.\u001b[17;11HDefault value is to wait for mysql-wait_timeout.\n -s Sleep interval between connections checks.\n -x Kills all connections immediately. Other options are ignored."\n exit\n}\n',
+ text: ',\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/script_one.sh" [readonly] 14L, 397C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for setting the reject of queries in Mysql\n\nmysql -h127.0.0.1 -P6033 -uroot -e "set global wsrep_reject_queries=\'NONE\'" 2>&1\nRC=$?\n\nif [[ $RC != 0 ]]; then\n >&2 echo "Failed to unset the reject of queries on Mysql node, exiting."\n exit $RC\nelse\n echo "Successfully unset the reject of queries."\nfi\n\u001b[94m~ \u001b[16;1H~ \u001b[17;1H~ \u001b[18;1H~ \u001b[19;1H~ \u001b[20;1H~ \u001b[21;1H~ \u001b[22;1H~ \u001b[23;1H~ \u001b[24;1H~ \u001b[25;1H~ \u001b[26;1H~ \u001b[27;1H~ \u001b[28;1H~ \u001b[29;1H~ \u001b[30;1H~ \u001b[31;1H~ \u001b[32;1H~ \u001b[33;1H~ \u001b[34;1H~ \u001b[35;1H~ \u001b[36;1H~ \u001b[37;1H~ \u001b[38;1H~ \u001b[39;1H~ \u001b[40;1H~ \u001b[41;1H~ \u001b[42;1H~ \u001b[43;1H~ \u001b[44;1H~ \u001b[45;1H~ \u001b[46;1H~ \u001b[47;1H~ \u001b[48;1H~ \u001b[49;1H~ \u001b[50;1H~ \u001b[51;1H~ \u001b[52;1H~ \u001b[53;1H~ \u001b[54;1H~ \u001b[55;1H~ \u001b[56;1H~ \u001b[57;1H~ \u001b[58;1H~ \u001b[1;1H\u001b[?25h\u0007\u001b[?25l\u001b[m\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hq\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H"/usr/local/bin/script_two.sh" [readonly] 115L, 3570C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for rejecting connection on Mysql cluster node, either gracefully or not,\n# depending on supplied arguments.\n\nfunction usage() {\n echo "\n This script disables DB connections to Mysql node.\n The default is to stop them gracefully.\n\n Usage: $0 [-h] [-w ] [-s ] [-x]\n\n Options:\n -h Prints this help.\n -w Number of seconds for waiting to close the connections.\u001b[17;11HDefault value is to wait for mysql-wait_timeout.\n -s Sleep interval between connections checks.\n -x Kills all connections immediately. Other options are ignored."\n exit\n}\n',
+ },
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
},
},
},
@@ -71,6 +89,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '2',
@@ -84,7 +103,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
total_bytes_captured: 1024,
total_bytes_skipped: 0,
bytes_skipped: [],
- text: '\nfunction get_number_db_connections() {\n # count current\n DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%\' escapee\u001b[26;1H \'\\\'")\n}\n\nfunction set_number_grace_seconds() {\n local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timeout\'")\n GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n}\n\nfunction wait_for_connections() {\n local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\u001b[37;5Hecho "Waiting for connections to close for up to $GRACE_PERIOD seconds"\u001b[39;5Hfor i in $(seq 0 $number_of_loops); do\u001b[40;9Hget_number_db_connections\u001b[41;9Hif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;13Hecho "No connection found for user $DB_USER to this node"\u001b[43;13Hbreak\u001b[44;9Helse\u001b[45;13Hecho "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\u001b[46;13Hsleep $SLEEP_INTERVAL\u001b[47;9Hfi\n done\n}\n\nfunction parse_args() {\n while getopts \'hs:w:x\' opt; do\u001b[53;9Hcase "$opt" in\u001b[54;9Hh)\u001b[55;13Husage\u001b[56;13H;;\u001b[57;9Hs)\u001b[58;13Hif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\u001b[1;1H\u001b[?25h\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hset number\r\u001b[?25l\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Galera cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Galera node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m Default value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\u001b[31;16H\u001b[K\u001b[32;1H\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \u001b[m\u001b[34;10H\u001b[K\u001b[35;1H\u001b[38;5;130m 33 \u001b[mfunction wait_for_connections() {\u001b[35;42H\u001b[K\u001b[36;1H\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \u001b[m\u001b[37;10H\u001b[K\u001b[38;1H\u001b[38;5;130m 36 \u001b[m echo "Waiting for connections to close for up to $GRACE_PERIOD seconds"\n\u001b[38;5;130m 37 \u001b[m\u001b[39;9H\u001b[K\u001b[40;1H\u001b[38;5;130m 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n',
+ text: '\nfunction get_number_db_connections() {\n # count current\n DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%\' escapee\u001b[26;1H \'\\\'")\n}\n\nfunction set_number_grace_seconds() {\n local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timeout\'")\n GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n}\n\nfunction wait_for_connections() {\n local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\u001b[37;5Hecho "Waiting for connections to close for up to $GRACE_PERIOD seconds"\u001b[39;5Hfor i in $(seq 0 $number_of_loops); do\u001b[40;9Hget_number_db_connections\u001b[41;9Hif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;13Hecho "No connection found for user $DB_USER to this node"\u001b[43;13Hbreak\u001b[44;9Helse\u001b[45;13Hecho "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\u001b[46;13Hsleep $SLEEP_INTERVAL\u001b[47;9Hfi\n done\n}\n\nfunction parse_args() {\n while getopts \'hs:w:x\' opt; do\u001b[53;9Hcase "$opt" in\u001b[54;9Hh)\u001b[55;13Husage\u001b[56;13H;;\u001b[57;9Hs)\u001b[58;13Hif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\u001b[1;1H\u001b[?25h\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hset number\r\u001b[?25l\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Mysql cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Mysql node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m Default value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\u001b[31;16H\u001b[K\u001b[32;1H\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \u001b[m\u001b[34;10H\u001b[K\u001b[35;1H\u001b[38;5;130m 33 \u001b[mfunction wait_for_connections() {\u001b[35;42H\u001b[K\u001b[36;1H\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \u001b[m\u001b[37;10H\u001b[K\u001b[38;1H\u001b[38;5;130m 36 \u001b[m echo "Waiting for connections to close for up to $GRACE_PERIOD seconds"\n\u001b[38;5;130m 37 \u001b[m\u001b[39;9H\u001b[K\u001b[40;1H\u001b[38;5;130m 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n',
+ },
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
},
},
},
@@ -98,6 +125,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '2',
@@ -113,6 +141,14 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
bytes_skipped: [],
text: '\u001b[38;5;130m 39 \u001b[m get_number_db_connections\u001b[41;42H\u001b[K\u001b[42;1H\u001b[38;5;130m 40 \u001b[m if [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;60H\u001b[K\u001b[43;1H\u001b[38;5;130m 41 \u001b[m echo "No connection found for user $DB_USER to this node"\n\u001b[38;5;130m 42 \u001b[m \u001b[8Cbreak\n\u001b[38;5;130m 43 \u001b[m else\u001b[45;21H\u001b[K\u001b[46;1H\u001b[38;5;130m 44 \u001b[m echo "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\n\u001b[38;5;130m 45 \u001b[m \u001b[10Csleep $SLEEP_INTERVAL\n\u001b[38;5;130m 46 \u001b[m\u001b[8Cfi\n\u001b[38;5;130m 47 \u001b[m done\n\u001b[38;5;130m 48 \u001b[m}\n\u001b[38;5;130m 49 \u001b[m\u001b[51;10H\u001b[K\u001b[52;1H\u001b[38;5;130m 50 \u001b[mfunction parse_args() {\u001b[52;33H\u001b[K\u001b[53;1H\u001b[38;5;130m 51 \u001b[m while getopts \'hs:w:x\' opt; do\n\u001b[38;5;130m 52 \u001b[m case "$opt" in\n\u001b[38;5;130m 53 \u001b[m h)\n\u001b[38;5;130m 54 \u001b[m usage\n\u001b[38;5;130m 55 \u001b[m \u001b[10C;;\n\u001b[38;5;130m 56 \u001b[m s)\u001b[58;19H\u001b[K\u001b[1;9H\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 58 \u001b[m\u001b[16C>&2 echo "Sleep interval (-s) must be a number"\n\u001b[38;5;130m 59 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 60 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 61 \u001b[m\u001b[12CARG_SLEEP_INTERVAL="$OPTARG"\n\u001b[38;5;130m 62 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 63 \u001b[m\u001b[8Cw)\n\u001b[38;5;130m 64 \u001b[m\u001b[12Cif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\n\u001b[38;5;130m 65 \u001b[m\u001b[16C>&2 echo "Wait timeout (-w) must be a number"\n\u001b[38;5;130m 66 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 67 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 68 \u001b[m\u001b[12CARG_GRACE_PERIOD="$OPTARG"\n\u001b[38;5;130m 69 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 70 \u001b[m\u001b[8Cx)\n\u001b[38;5;130m 71 \u001b[m\u001b[12CARG_KILL_IMMEDIATELY=1\n\u001b[38;5;130m 72 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 73 \u001b[m\u001b[8Cesac\n\u001b[38;5;130m 74 \u001b[m done\n\u001b[38;5;130m 75 \n 76 \u001b[m GRACE_PERIOD=${ARG_GRACE_PERIOD:--1}\n\u001b[38;5;130m 77 \u001b[m SLEEP_INTERVAL=${ARG_SLEEP_INTERVAL:-30}\n\u001b[38;5;130m 78 \u001b[m KILL_IMMEDIATELY=${ARG_KILL_IMMEDIATELY:-0}\n\u001b[38;5;130m 79 \u001b[m}\n\u001b[38;5;130m 80 \n 81 \u001b[mDB_USER="rolap01"\n\u001b[38;5;130m 82 \n 83 \u001b[mparse_args $@\n\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n',
},
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
+ },
},
},
},
@@ -125,6 +161,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '2',
@@ -138,7 +175,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
total_bytes_captured: 1024,
total_bytes_skipped: 0,
bytes_skipped: [],
- text: '\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Galera node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Galera cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Galera node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m\u001b[10CDefault value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\n\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \n',
+ text: '\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Mysql node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Mysql cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo "\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Mysql node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m\u001b[10CDefault value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored."\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select count(1) from stats_mysql_processlist where user = \'$DB_USER\' and db like \'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m\' escape \'\\\'")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e "select variable_value from global_variables where variable_name = \'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout\'")\n\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \n',
+ },
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
},
},
},
@@ -152,6 +197,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '2',
@@ -167,6 +213,14 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
bytes_skipped: [],
text: ' 33 \u001b[mfunction wait_for_connections() {\n\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \n 36 \u001b[m echo "Waiting for connections to close for up to $GRACE_PERIOD seconds"\n\u001b[38;5;130m 37 \n 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n\u001b[38;5;130m 39 \u001b[m\u001b[8Cget_number_db_connections\n\u001b[38;5;130m 40 \u001b[m\u001b[8Cif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\n\u001b[38;5;130m 41 \u001b[m\u001b[12Cecho "No connection found for user $DB_USER to this node"\n\u001b[38;5;130m 42 \u001b[m\u001b[12Cbreak\n\u001b[38;5;130m 43 \u001b[m\u001b[8Celse\n\u001b[38;5;130m 44 \u001b[m\u001b[12Cecho "$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i"\n\u001b[38;5;130m 45 \u001b[m\u001b[12Csleep $SLEEP_INTERVAL\n\u001b[38;5;130m 46 \u001b[m\u001b[8Cfi\n\u001b[38;5;130m 47 \u001b[m done\n\u001b[38;5;130m 48 \u001b[m}\n\u001b[38;5;130m 49 \n 50 \u001b[mfunction parse_args() {\n\u001b[38;5;130m 51 \u001b[m while getopts \'hs:w:x\' opt; do\n\u001b[38;5;130m 52 \u001b[m\u001b[8Ccase "$opt" in\n\u001b[38;5;130m 53 \u001b[m\u001b[8Ch)\n\u001b[38;5;130m 54 \u001b[m\u001b[12Cusage\n\u001b[38;5;130m 55 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 56 \u001b[m\u001b[8Cs)\u001b[1;9H\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 58 \u001b[m\u001b[16C>&2 echo "Sleep interval (-s) must be a number"\n\u001b[38;5;130m 59 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 60 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 61 \u001b[m\u001b[12CARG_SLEEP_INTERVAL="$OPTARG"\n\u001b[38;5;130m 62 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 63 \u001b[m\u001b[8Cw)\n\u001b[38;5;130m 64 \u001b[m\u001b[12Cif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\n\u001b[38;5;130m 65 \u001b[m\u001b[16C>&2 echo "Wait timeout (-w) must be a number"\n\u001b[38;5;130m 66 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 67 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 68 \u001b[m\u001b[12CARG_GRACE_PERIOD="$OPTARG"\n\u001b[38;5;130m 69 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 70 \u001b[m\u001b[8Cx)\n\u001b[38;5;130m 71 \u001b[m\u001b[12CARG_KILL_IMMEDIATELY=1\n\u001b[38;5;130m 72 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 73 \u001b[m\u001b[8Cesac\n\u001b[38;5;130m 74 \u001b[m done\n\u001b[38;5;130m 75 \n 76 \u001b[m GRACE_PERIOD=${ARG_GRACE_PERIOD:--1}\n\u001b[38;5;130m 77 \u001b[m SLEEP_INTERVAL=${ARG_SLEEP_INTERVAL:-30}\n\u001b[38;5;130m 78 \u001b[m KILL_IMMEDIATELY=${ARG_KILL_IMMEDIATELY:-0}\n\u001b[38;5;130m 79 \u001b[m}\n\u001b[38;5;130m 80 \n 81 \u001b[mDB_USER="rolap01"\n\u001b[38;5;130m 82 \n 83 \u001b[mparse_args $@\n',
},
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
+ },
},
},
},
@@ -179,6 +233,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '2',
@@ -192,7 +247,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
total_bytes_captured: 1024,
total_bytes_skipped: 0,
bytes_skipped: [],
- text: '\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Galera node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n',
+ text: '\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Mysql node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n',
+ },
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
},
},
},
@@ -206,6 +269,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
message: 'hello world security',
event: {
action: 'text_output',
+ id: '1',
},
process: {
entity_id: '1',
@@ -219,7 +283,15 @@ export const sessionViewIOEventsMock: ProcessEventResults = {
total_bytes_captured: 1024,
total_bytes_skipped: 0,
bytes_skipped: [],
- text: '\u001bkroot@staging-host:~\u001b\\\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\b\b\b\b\b\n\u001bkroot@staging-host:~\u001b\\\b\u001b[K\b\u001b[K\b\u001b[K\n,\n22/05/26 09:24:09 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/galera_traffic_start.sh\u0007\n22/05/26 09:25:32 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/galera_traffic_start.sh.sh.sh.sho.shp.sh\n22/05/26 09:30:08 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] exi\u0007\u0007\u0007exitlogout\n,\u001bec2-user@staging-host:~\u001b\\\n\u001bec2-user@staging-host:~\u001b\\\n,\n22/05/26 09:24:01 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] sudo -i\n22/05/26 10:11:37 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] exitlogout\n\n',
+ text: '\u001bkroot@staging-host:~\u001b\\\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\b\b\b\b\b\n\u001bkroot@staging-host:~\u001b\\\b\u001b[K\b\u001b[K\b\u001b[K\n,\n22/05/26 09:24:09 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/script_one.sh\u0007\n22/05/26 09:25:32 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/script_one.sh.sh.sh.sho.shp.sh\n22/05/26 09:30:08 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] exi\u0007\u0007\u0007exitlogout\n,\u001bec2-user@staging-host:~\u001b\\\n\u001bec2-user@staging-host:~\u001b\\\n,\n22/05/26 09:24:01 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] sudo -i\n22/05/26 10:11:37 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] exitlogout\n\n',
+ },
+ tty: {
+ char_device: {
+ major: 4,
+ minor: 1,
+ },
+ rows: 59,
+ columns: 173,
},
},
},
diff --git a/x-pack/plugins/session_view/common/types/process_tree/index.ts b/x-pack/plugins/session_view/common/types/process_tree/index.ts
index e620b654db16ffa..a2b40347f1b5f65 100644
--- a/x-pack/plugins/session_view/common/types/process_tree/index.ts
+++ b/x-pack/plugins/session_view/common/types/process_tree/index.ts
@@ -60,16 +60,13 @@ export interface Teletype {
major?: number;
minor?: number;
};
+ rows?: number;
+ columns?: number;
}
-// used by tty_player component to split process.io.text into lines of IO
export interface IOLine {
- value?: string;
-
- // the following is only set client side for caching purposes
- process_name?: string;
- process_entity_id?: string;
- process_entity_cursor?: string;
+ event: ProcessEvent;
+ value: string;
}
export interface IOFields {
diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx
index e2d795283c7ce2e..921a3f7ce8b9c4c 100644
--- a/x-pack/plugins/session_view/public/components/session_view/index.tsx
+++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx
@@ -133,8 +133,8 @@ export const SessionView = ({
} = useFetchSessionViewAlerts(sessionEntityId, investigatedAlertId);
const handleRefresh = useCallback(() => {
- refetch({ refetchPage: (page, index, allPages) => allPages.length - 1 === index });
- refetchAlerts({ refetchPage: (page, index, allPages) => allPages.length - 1 === index });
+ refetch({ refetchPage: (_page, index, allPages) => allPages.length - 1 === index });
+ refetchAlerts({ refetchPage: (_page, index, allPages) => allPages.length - 1 === index });
}, [refetch, refetchAlerts]);
const alerts = useMemo(() => {
diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx
index 23f81d7941439ca..fb9095187438596 100644
--- a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx
+++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx
@@ -8,7 +8,9 @@ import { renderHook, act } from '@testing-library/react-hooks';
import { sessionViewIOEventsMock } from '../../../common/mocks/responses/session_view_io_events.mock';
import { useIOLines, useXtermPlayer, XtermPlayerDeps } from './hooks';
import { ProcessEventsPage } from '../../../common/types/process_tree';
-import { DEFAULT_TTY_PLAYSPEED_MS } from '../../../common/constants';
+import { DEFAULT_TTY_FONT_SIZE, DEFAULT_TTY_PLAYSPEED_MS } from '../../../common/constants';
+
+const VIM_LINE_START = 19;
describe('TTYPlayer/hooks', () => {
beforeAll(() => {
@@ -66,10 +68,11 @@ describe('TTYPlayer/hooks', () => {
initialProps = {
ref: mockRef,
isPlaying: false,
+ setIsPlaying: jest.fn(),
lines,
hasNextPage: false,
fetchNextPage: () => null,
- isFullscreen: false,
+ fontSize: DEFAULT_TTY_FONT_SIZE,
};
});
@@ -88,7 +91,7 @@ describe('TTYPlayer/hooks', () => {
expect(currentLine).toBe(0);
act(() => {
- seekToLine(17); // line where vim output starts
+ seekToLine(VIM_LINE_START); // line where vim output starts
});
jest.advanceTimersByTime(100);
@@ -102,14 +105,14 @@ describe('TTYPlayer/hooks', () => {
});
act(() => {
- xTermResult.current.seekToLine(17); // line where vim output starts
+ xTermResult.current.seekToLine(VIM_LINE_START); // line where vim output starts
});
jest.advanceTimersByTime(100);
const { terminal, currentLine } = xTermResult.current;
- expect(currentLine).toBe(17);
+ expect(currentLine).toBe(VIM_LINE_START);
expect(terminal.buffer.active.getLine(0)?.translateToString(true)).toBe('#!/bin/env bash');
});
@@ -152,7 +155,7 @@ describe('TTYPlayer/hooks', () => {
act(() => {
jest.advanceTimersByTime(DEFAULT_TTY_PLAYSPEED_MS * initialProps.lines.length + 100);
});
- expect(result.current.currentLine).toBe(initialProps.lines.length);
+ expect(result.current.currentLine).toBe(initialProps.lines.length - 1);
});
it('will allow a plain text search highlight on the last line printed', async () => {
diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts
index e122a2dbd0c112e..0138775199c6d03 100644
--- a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts
+++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts
@@ -6,13 +6,16 @@
*/
import { Terminal } from 'xterm';
import 'xterm/css/xterm.css';
-import { FitAddon } from 'xterm-addon-fit';
import { useMemo, useState, useEffect, useCallback } from 'react';
import { useInfiniteQuery } from '@tanstack/react-query';
import { CoreStart } from '@kbn/core/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { SearchAddon } from './xterm_search';
import { useEuiTheme } from '../../hooks';
+
+// eslint-disable-next-line @kbn/imports/no_boundary_crossing
+import { sessionViewIOEventsMock } from '../../../common/mocks/responses/session_view_io_events.mock';
+
import {
IOLine,
ProcessEvent,
@@ -24,8 +27,12 @@ import {
IO_EVENTS_PER_PAGE,
QUERY_KEY_IO_EVENTS,
DEFAULT_TTY_PLAYSPEED_MS,
+ DEFAULT_TTY_FONT_SIZE,
+ TTY_LINE_SPLITTER_REGEX,
} from '../../../common/constants';
+const MOCK_DEBUG = false; // This code will be removed once we have an agent to test with.
+
export const useFetchIOEvents = (sessionEntityId: string) => {
const { http } = useKibana().services;
const cachingKeys = useMemo(() => [QUERY_KEY_IO_EVENTS, sessionEntityId], [sessionEntityId]);
@@ -41,13 +48,18 @@ export const useFetchIOEvents = (sessionEntityId: string) => {
},
});
+ if (MOCK_DEBUG) {
+ res.events = sessionViewIOEventsMock.events;
+ res.total = res.events?.length || 0;
+ }
+
const events = res.events?.map((event: any) => event._source as ProcessEvent) ?? [];
return { events, cursor, total: res.total };
},
{
getNextPageParam: (lastPage) => {
- if (lastPage.events.length >= IO_EVENTS_PER_PAGE) {
+ if (!MOCK_DEBUG && lastPage.events.length >= IO_EVENTS_PER_PAGE) {
return {
cursor: lastPage.events[lastPage.events.length - 1]['@timestamp'],
};
@@ -77,9 +89,21 @@ export const useIOLines = (pages: ProcessEventsPage[] | undefined) => {
return pages.reduce((previous, current) => {
if (current.events) {
current.events.forEach((event) => {
- if (event?.process?.io?.text) {
- const data: IOLine[] = event.process.io.text.split(/\n\r?/).map((line) => {
+ const { process } = event;
+ if (process?.io?.text !== undefined) {
+ const splitLines = process.io.text.split(TTY_LINE_SPLITTER_REGEX);
+ const combinedLines = [splitLines[0]];
+
+ // delimiters e.g \r\n or cursor movements are merged with their line text
+ // we start on an odd number so that cursor movements happen at the start of each line
+ // this is needed for the search to work accurately
+ for (let i = 1; i < splitLines.length - 1; i = i + 2) {
+ combinedLines.push(splitLines[i] + splitLines[i + 1]);
+ }
+
+ const data: IOLine[] = combinedLines.map((line) => {
return {
+ event, // pointer to the event so it's easy to look up other details for the line
value: line,
};
});
@@ -99,85 +123,94 @@ export const useIOLines = (pages: ProcessEventsPage[] | undefined) => {
export interface XtermPlayerDeps {
ref: React.RefObject;
isPlaying: boolean;
+ setIsPlaying(value: boolean): void;
lines: IOLine[];
+ fontSize: number;
hasNextPage?: boolean;
fetchNextPage?: () => void;
- isFullscreen?: boolean;
}
export const useXtermPlayer = ({
ref,
isPlaying,
+ setIsPlaying,
lines,
+ fontSize,
hasNextPage,
fetchNextPage,
- isFullscreen,
}: XtermPlayerDeps) => {
const { euiTheme } = useEuiTheme();
const { font, colors } = euiTheme;
const [currentLine, setCurrentLine] = useState(0);
- const [userSeeked, setUserSeeked] = useState(false);
const [playSpeed] = useState(DEFAULT_TTY_PLAYSPEED_MS); // potentially configurable
+ const tty = lines?.[currentLine]?.event.process?.tty;
- const [terminal, fitAddon, searchAddon] = useMemo(() => {
+ const [terminal, searchAddon] = useMemo(() => {
const term = new Terminal({
theme: {
- background: 'rgba(0,0,0,0)',
selection: colors.warning,
},
fontFamily: font.familyCode,
- fontSize: 11,
- allowTransparency: true,
+ fontSize: DEFAULT_TTY_FONT_SIZE,
+ scrollback: 0,
+ convertEol: true,
});
- const fitInstance = new FitAddon();
const searchInstance = new SearchAddon();
-
- term.loadAddon(fitInstance);
term.loadAddon(searchInstance);
- return [term, fitInstance, searchInstance];
- }, [colors, font]);
+ return [term, searchInstance];
+ }, [font, colors]);
useEffect(() => {
- if (ref.current) {
+ if (ref.current && !terminal.element) {
terminal.open(ref.current);
}
}, [terminal, ref]);
- useEffect(() => {
- // isFullscreen check is there just to avoid the necessary "unnecessary" react-hook dep
- // When isFullscreen changes, e.g goes from false to true and vice versa, we need to call fit.
- if (isFullscreen !== undefined) {
- fitAddon.fit();
- }
- }, [isFullscreen, fitAddon]);
-
const render = useCallback(
- (lineNumber: number) => {
+ (lineNumber: number, clear: boolean) => {
if (lines.length === 0) {
return;
}
let linesToPrint;
- if (userSeeked) {
- linesToPrint = lines.slice(0, lineNumber);
+ if (clear) {
+ linesToPrint = lines.slice(0, lineNumber + 1);
+ terminal.reset();
terminal.clear();
- setUserSeeked(false);
} else {
linesToPrint = [lines[lineNumber]];
}
linesToPrint.forEach((line, index) => {
if (line?.value !== undefined) {
- terminal.writeln(line.value);
+ terminal.write(line.value);
}
});
},
- [terminal, lines, userSeeked]
+ [terminal, lines]
);
+ useEffect(() => {
+ const fontChanged = terminal.getOption('fontSize') !== fontSize;
+ const ttyChanged = tty && (terminal.rows !== tty?.rows || terminal.cols !== tty?.columns);
+
+ if (fontChanged) {
+ terminal.setOption('fontSize', fontSize);
+ }
+
+ if (tty?.rows && tty?.columns && ttyChanged) {
+ terminal.resize(tty.columns, tty.rows);
+ }
+
+ if (fontChanged || ttyChanged) {
+ // clear and rerender
+ render(currentLine, true);
+ }
+ }, [currentLine, fontSize, terminal, render, tty]);
+
useEffect(() => {
if (isPlaying) {
const timer = setTimeout(() => {
@@ -185,29 +218,32 @@ export const useXtermPlayer = ({
return;
}
- if (currentLine < lines.length) {
+ if (currentLine < lines.length - 1) {
setCurrentLine(currentLine + 1);
}
+
+ render(currentLine, false);
+
+ if (hasNextPage && fetchNextPage && currentLine === lines.length - 1) {
+ fetchNextPage();
+ }
}, playSpeed);
return () => {
- clearInterval(timer);
+ clearTimeout(timer);
};
}
- }, [lines, currentLine, isPlaying, playSpeed]);
+ }, [lines, currentLine, isPlaying, playSpeed, render, hasNextPage, fetchNextPage]);
- useEffect(() => {
- render(currentLine);
-
- if (hasNextPage && fetchNextPage && currentLine === lines.length - 1) {
- fetchNextPage();
- }
- }, [fetchNextPage, currentLine, lines, render, hasNextPage]);
+ const seekToLine = useCallback(
+ (index) => {
+ setCurrentLine(index);
+ setIsPlaying(false);
- const seekToLine = useCallback((line) => {
- setUserSeeked(true);
- setCurrentLine(line);
- }, []);
+ render(index, true);
+ },
+ [setIsPlaying, render]
+ );
const search = useCallback(
(query: string, startCol: number) => {
@@ -216,15 +252,10 @@ export const useXtermPlayer = ({
[searchAddon]
);
- const fit = useCallback(() => {
- fitAddon.fit();
- }, [fitAddon]);
-
return {
terminal,
currentLine,
seekToLine,
search,
- fit,
};
};
diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.tsx
index 48dbf82441e427a..7d3656d8ba7b7f3 100644
--- a/x-pack/plugins/session_view/public/components/tty_player/index.tsx
+++ b/x-pack/plugins/session_view/public/components/tty_player/index.tsx
@@ -7,6 +7,7 @@
import React, { useRef, useState, useCallback, ChangeEvent, MouseEvent } from 'react';
import { EuiPanel, EuiRange, EuiFlexGroup, EuiFlexItem, EuiButtonIcon } from '@elastic/eui';
import { TTYSearchBar } from '../tty_search_bar';
+import { TTYTextSizer } from '../tty_text_sizer';
import { useStyles } from './styles';
import { useFetchIOEvents, useIOLines, useXtermPlayer } from './hooks';
@@ -16,22 +17,31 @@ export interface TTYPlayerDeps {
isFullscreen: boolean;
}
+const DEFAULT_FONT_SIZE = 11;
+
export const TTYPlayer = ({ sessionEntityId, onClose, isFullscreen }: TTYPlayerDeps) => {
- const styles = useStyles();
- const ref = useRef(null);
+ const ref = useRef(null);
+ const scrollRef = useRef(null);
const { data, fetchNextPage, hasNextPage } = useFetchIOEvents(sessionEntityId);
const lines = useIOLines(data?.pages);
+
+ const [fontSize, setFontSize] = useState(DEFAULT_FONT_SIZE);
const [isPlaying, setIsPlaying] = useState(false);
+
const { search, currentLine, seekToLine } = useXtermPlayer({
ref,
isPlaying,
+ setIsPlaying,
lines,
+ fontSize,
hasNextPage,
fetchNextPage,
- isFullscreen,
});
+ const tty = lines?.[currentLine]?.event?.process?.tty;
+ const styles = useStyles(tty);
+
const onLineChange = useCallback(
(event: ChangeEvent | MouseEvent) => {
const line = parseInt((event?.target as HTMLInputElement).value || '0', 10);
@@ -65,7 +75,10 @@ export const TTYPlayer = ({ sessionEntityId, onClose, isFullscreen }: TTYPlayerD
-
+
+
{/* the following will be replaced by a new component */}
+
+
+
diff --git a/x-pack/plugins/session_view/public/components/tty_player/styles.ts b/x-pack/plugins/session_view/public/components/tty_player/styles.ts
index c4061c8a64dce65..e1d18e307502734 100644
--- a/x-pack/plugins/session_view/public/components/tty_player/styles.ts
+++ b/x-pack/plugins/session_view/public/components/tty_player/styles.ts
@@ -7,15 +7,14 @@
import { useMemo } from 'react';
import { CSSObject, css } from '@emotion/react';
-import { transparentize, useEuiScrollBar } from '@elastic/eui';
+import { transparentize } from '@elastic/eui';
import { useEuiTheme } from '../../hooks';
+import { Teletype } from '../../../common/types/process_tree';
-export const useStyles = () => {
+export const useStyles = (tty?: Teletype) => {
const { euiTheme } = useEuiTheme();
- const euiScrollBar = useEuiScrollBar();
-
const cached = useMemo(() => {
- const { size, colors, border } = euiTheme;
+ const { size, font, colors, border } = euiTheme;
const container: CSSObject = {
position: 'absolute',
@@ -23,6 +22,7 @@ export const useStyles = () => {
width: '100%',
height: '100%',
overflow: 'hidden',
+ zIndex: 10,
borderRadius: size.s,
backgroundColor: colors.ink,
'.euiRangeLevel--warning': {
@@ -36,20 +36,47 @@ export const useStyles = () => {
},
};
+ const windowBoundsColor = transparentize(colors.ghost, 0.6);
+
const terminal: CSSObject = {
+ minHeight: '100%',
+ '.xterm': css`
+ display: inline-block;
+ `,
+ '.xterm-screen': css`
+ overflow-y: visible;
+ border: ${border.width.thin} dotted ${windowBoundsColor};
+ border-top: 0;
+ border-left: 0;
+ box-sizing: content-box;
+ `,
+ };
+
+ if (tty?.rows) {
+ terminal['.xterm-screen:after'] = css`
+ position: absolute;
+ right: ${size.s};
+ top: ${size.s};
+ content: '${tty?.columns}x${tty?.rows}';
+ color: ${windowBoundsColor};
+ font-family: ${font.familyCode};
+ font-size: ${size.m};
+ `;
+ }
+
+ const scrollPane: CSSObject = {
width: '100%',
height: 'calc(100% - 142px)',
- '.xterm-viewport': css`
- ${euiScrollBar}
- `,
border: border.thin,
+ overflow: 'auto',
};
return {
container,
terminal,
+ scrollPane,
};
- }, [euiScrollBar, euiTheme]);
+ }, [tty, euiTheme]);
return cached;
};
diff --git a/x-pack/plugins/session_view/public/components/tty_player/translations.ts b/x-pack/plugins/session_view/public/components/tty_player/translations.ts
new file mode 100644
index 000000000000000..244a5a355b0ec73
--- /dev/null
+++ b/x-pack/plugins/session_view/public/components/tty_player/translations.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { i18n } from '@kbn/i18n';
+
+export const BETA = i18n.translate('xpack.sessionView.beta', {
+ defaultMessage: 'Beta',
+});
+
+export const REFRESH_SESSION = i18n.translate('xpack.sessionView.refreshSession', {
+ defaultMessage: 'Refresh session',
+});
+
+export const OPEN_TTY_PLAYER = i18n.translate('xpack.sessionView.openTTYPlayer', {
+ defaultMessage: 'Open TTY player',
+});
diff --git a/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts b/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts
index 258920319676c9d..3c430d691e3f7c4 100644
--- a/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts
+++ b/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts
@@ -94,7 +94,7 @@ export class SearchAddon implements ITerminalAddon {
}
if (searchOptions?.lastLineOnly) {
- startRow = this._terminal.buffer.active.cursorY - 1;
+ startRow = this._terminal.buffer.active.cursorY;
startCol = searchOptions?.startCol || 0;
}
@@ -176,10 +176,9 @@ export class SearchAddon implements ITerminalAddon {
// Start from selection start if there is a selection
startRow = currentSelection.startRow;
startCol = currentSelection.startColumn;
- }
-
- if (searchOptions?.lastLineOnly) {
+ } else if (searchOptions?.lastLineOnly) {
startRow = this._terminal.buffer.active.cursorY - 1;
+ startCol = this._terminal.cols;
}
this._initLinesCache();
diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx
index 4545acf1a457835..77e9c4576c5653e 100644
--- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx
+++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx
@@ -56,7 +56,9 @@ describe('TTYSearchBar component', () => {
// there is a slight delay in the seek in xtermjs, so we wait 100ms before trying to highlight a result.
await new Promise((r) => setTimeout(r, 100));
- expect(props.xTermSearchFn).toHaveBeenCalledTimes(1);
+ expect(props.xTermSearchFn).toHaveBeenCalledTimes(2);
+ expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '', 0);
+ expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 6);
});
it('calls seekToline and xTermSearchFn when currentMatch changes', async () => {
@@ -76,12 +78,13 @@ describe('TTYSearchBar component', () => {
// two calls, first instance -h is at line 22, 2nd at line 42
expect(props.seekToLine).toHaveBeenCalledTimes(2);
- expect(props.seekToLine).toHaveBeenNthCalledWith(1, 22);
- expect(props.seekToLine).toHaveBeenNthCalledWith(2, 42);
+ expect(props.seekToLine).toHaveBeenNthCalledWith(1, 24);
+ expect(props.seekToLine).toHaveBeenNthCalledWith(2, 94);
- expect(props.xTermSearchFn).toHaveBeenCalledTimes(2);
- expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '-h', 6);
- expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 13);
+ expect(props.xTermSearchFn).toHaveBeenCalledTimes(3);
+ expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '', 0);
+ expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 6);
+ expect(props.xTermSearchFn).toHaveBeenNthCalledWith(3, '-h', 13);
});
it('calls xTermSearchFn with empty query when search is cleared', async () => {
@@ -97,6 +100,6 @@ describe('TTYSearchBar component', () => {
userEvent.click(renderResult.getByTestId('clearSearchButton'));
await new Promise((r) => setTimeout(r, 100));
- expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '', 0);
+ expect(props.xTermSearchFn).toHaveBeenNthCalledWith(3, '', 0);
});
});
diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx
index af60bdf664f9d80..e5081a217dec13b 100644
--- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx
+++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx
@@ -4,9 +4,10 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import React, { useEffect, useMemo, useState, useCallback } from 'react';
+import React, { useMemo, useState, useCallback } from 'react';
import { SessionViewSearchBar } from '../session_view_search_bar';
import { IOLine } from '../../../common/types/process_tree';
+import { TTY_STRIP_CONTROL_CODES_REGEX } from '../../../common/constants';
interface SearchResult {
line: IOLine;
@@ -24,50 +25,71 @@ export const TTYSearchBar = ({ lines, seekToLine, xTermSearchFn }: TTYSearchBarD
const [currentMatch, setCurrentMatch] = useState(null);
const [searchQuery, setSearchQuery] = useState('');
- useEffect(() => {
- if (currentMatch) {
- const goToLine = lines.indexOf(currentMatch.line);
- seekToLine(goToLine);
- }
+ const jumpToMatch = useCallback(
+ (match) => {
+ if (match) {
+ const goToLine = lines.indexOf(match.line);
+ seekToLine(goToLine);
+ }
- const timeout = setTimeout(() => {
- return xTermSearchFn(searchQuery, currentMatch?.index || 0);
- }, 100);
+ const timeout = setTimeout(() => {
+ return xTermSearchFn(searchQuery, match?.index || 0);
+ }, 100);
- return () => {
- clearTimeout(timeout);
- };
- }, [currentMatch, searchQuery, lines, xTermSearchFn, seekToLine]);
+ return () => {
+ clearTimeout(timeout);
+ };
+ },
+ [lines, seekToLine, xTermSearchFn, searchQuery]
+ );
const searchResults = useMemo(() => {
- if (searchQuery) {
- const matches: SearchResult[] = [];
+ const matches: SearchResult[] = [];
+ if (searchQuery) {
lines.reduce((previous: SearchResult[], current: IOLine) => {
if (current.value) {
+ // check for cursor movement at the start of the line
+ const cursorMovement = current.value.match(/^\x1b\[\d+;(\d+)(H|d)/);
const regex = new RegExp(searchQuery.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'ig');
- const lineMatches = current.value.matchAll(regex);
+ const lineMatches = current.value
+ .replace(TTY_STRIP_CONTROL_CODES_REGEX, '')
+ .replace(/^\r?\n/, '')
+ .matchAll(regex);
+
if (lineMatches) {
for (const match of lineMatches) {
- previous.push({ line: current, match: match[0], index: match.index || 0 });
+ let matchOffset = 0;
+
+ if (cursorMovement) {
+ // the column position 1 based e.g \x1b[39;5H means row 39 column 5
+ matchOffset = parseInt(cursorMovement[1], 10) - 3;
+ }
+
+ previous.push({
+ line: current,
+ match: match[0],
+ index: matchOffset + (match.index || 0),
+ });
}
}
}
return previous;
}, matches);
+ }
- if (matches.length > 0) {
- setCurrentMatch(matches[0]);
- } else {
- setCurrentMatch(null);
- }
-
- return matches;
+ if (matches.length > 0) {
+ const firstMatch = matches[0];
+ setCurrentMatch(firstMatch);
+ jumpToMatch(firstMatch);
+ } else {
+ setCurrentMatch(null);
+ xTermSearchFn('', 0);
}
- return [];
- }, [searchQuery, lines]);
+ return matches;
+ }, [searchQuery, lines, jumpToMatch, xTermSearchFn]);
const onSearch = useCallback((query) => {
setSearchQuery(query);
@@ -80,9 +102,10 @@ export const TTYSearchBar = ({ lines, seekToLine, xTermSearchFn }: TTYSearchBarD
if (match && currentMatch !== match) {
setCurrentMatch(match);
+ jumpToMatch(match);
}
},
- [currentMatch, searchResults]
+ [jumpToMatch, currentMatch, searchResults]
);
return (
diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx
new file mode 100644
index 000000000000000..ec9e8ffd3cab25a
--- /dev/null
+++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.test.tsx
@@ -0,0 +1,76 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import React from 'react';
+import userEvent from '@testing-library/user-event';
+import { AppContextTestRender, createAppRootMockRenderer } from '../../test';
+import { DEFAULT_TTY_FONT_SIZE } from '../../../common/constants';
+import { TTYTextSizer, TTYTextSizerDeps } from '.';
+
+describe('TTYTextSizer component', () => {
+ let render: () => ReturnType;
+ let renderResult: ReturnType;
+ let mockedContext: AppContextTestRender;
+ let props: TTYTextSizerDeps;
+
+ beforeEach(() => {
+ mockedContext = createAppRootMockRenderer();
+
+ props = {
+ tty: {
+ rows: 24,
+ columns: 80,
+ },
+ containerHeight: 200,
+ fontSize: DEFAULT_TTY_FONT_SIZE,
+ onFontSizeChanged: jest.fn(),
+ };
+ });
+
+ it('mounts and renders the text sizer controls', async () => {
+ renderResult = mockedContext.render();
+ expect(renderResult.queryByTestId('sessionView:TTYTextSizer')).toBeTruthy();
+ });
+
+ it('emits a fontSize which will fit the container when ZoomFit clicked', async () => {
+ renderResult = mockedContext.render();
+
+ const zoomFitBtn = renderResult.queryByTestId('sessionView:TTYZoomFit');
+
+ if (zoomFitBtn) {
+ userEvent.click(zoomFitBtn);
+ }
+
+ expect(props.onFontSizeChanged).toHaveBeenCalledTimes(1);
+ expect(props.onFontSizeChanged).toHaveBeenCalledWith(6.41025641025641);
+ });
+
+ it('emits a larger fontSize when zoom in clicked', async () => {
+ renderResult = mockedContext.render();
+
+ const zoomInBtn = renderResult.queryByTestId('sessionView:TTYZoomIn');
+
+ if (zoomInBtn) {
+ userEvent.click(zoomInBtn);
+ }
+
+ expect(props.onFontSizeChanged).toHaveBeenCalledTimes(1);
+ expect(props.onFontSizeChanged).toHaveBeenCalledWith(DEFAULT_TTY_FONT_SIZE + 1);
+ });
+
+ it('emits a smaller fontSize when zoom out clicked', async () => {
+ renderResult = mockedContext.render();
+
+ const zoomOutBtn = renderResult.queryByTestId('sessionView:TTYZoomOut');
+
+ if (zoomOutBtn) {
+ userEvent.click(zoomOutBtn);
+ }
+
+ expect(props.onFontSizeChanged).toHaveBeenCalledTimes(1);
+ expect(props.onFontSizeChanged).toHaveBeenCalledWith(DEFAULT_TTY_FONT_SIZE - 1);
+ });
+});
diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx
new file mode 100644
index 000000000000000..463dbbbf80f6984
--- /dev/null
+++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx
@@ -0,0 +1,89 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import React, { useCallback, useMemo } from 'react';
+import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { Teletype } from '../../../common/types/process_tree';
+import { DEFAULT_TTY_FONT_SIZE } from '../../../common/constants';
+import { ZOOM_IN, ZOOM_FIT, ZOOM_OUT } from './translations';
+
+export interface TTYTextSizerDeps {
+ tty?: Teletype;
+ containerHeight: number;
+ fontSize: number;
+ onFontSizeChanged(newSize: number): void;
+}
+
+const LINE_HEIGHT_SCALE_RATIO = 1.3;
+const MINIMUM_FONT_SIZE = 2;
+const MAXIMUM_FONT_SIZE = 20;
+
+export const TTYTextSizer = ({
+ tty,
+ containerHeight,
+ fontSize,
+ onFontSizeChanged,
+}: TTYTextSizerDeps) => {
+ const onFitFontSize = useMemo(() => {
+ if (tty?.rows && containerHeight) {
+ const lineHeight = DEFAULT_TTY_FONT_SIZE * LINE_HEIGHT_SCALE_RATIO;
+ const desiredHeight = tty.rows * lineHeight;
+ return DEFAULT_TTY_FONT_SIZE * (containerHeight / desiredHeight);
+ }
+
+ return DEFAULT_TTY_FONT_SIZE;
+ }, [containerHeight, tty?.rows]);
+
+ const onFit = useCallback(() => {
+ if (fontSize === onFitFontSize || onFitFontSize > DEFAULT_TTY_FONT_SIZE) {
+ onFontSizeChanged(DEFAULT_TTY_FONT_SIZE);
+ } else {
+ onFontSizeChanged(onFitFontSize);
+ }
+ }, [fontSize, onFontSizeChanged, onFitFontSize]);
+
+ const onZoomOut = useCallback(() => {
+ onFontSizeChanged(Math.max(MINIMUM_FONT_SIZE, fontSize - 1));
+ }, [fontSize, onFontSizeChanged]);
+
+ const onZoomIn = useCallback(() => {
+ onFontSizeChanged(Math.min(MAXIMUM_FONT_SIZE, fontSize + 1));
+ }, [fontSize, onFontSizeChanged]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts b/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts
new file mode 100644
index 000000000000000..0bec7775d43c50b
--- /dev/null
+++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { i18n } from '@kbn/i18n';
+
+export const ZOOM_IN = i18n.translate('xpack.sessionView.zoomIn', {
+ defaultMessage: 'Zoom in',
+});
+
+export const ZOOM_FIT = i18n.translate('xpack.sessionView.zoomFit', {
+ defaultMessage: 'Zoom fit',
+});
+
+export const ZOOM_OUT = i18n.translate('xpack.sessionView.zoomOut', {
+ defaultMessage: 'Zoom out',
+});
diff --git a/x-pack/test/functional/es_archives/session_view/io_events/data.json b/x-pack/test/functional/es_archives/session_view/io_events/data.json
index 0cf008aa6834c68..a9553169850f1ad 100644
--- a/x-pack/test/functional/es_archives/session_view/io_events/data.json
+++ b/x-pack/test/functional/es_archives/session_view/io_events/data.json
@@ -45,6 +45,14 @@
"total_bytes_skipped": 0,
"bytes_skipped": [],
"text": "256\n,\n Some host somewhere in the cloud\n | | | CentOS Stream release 8 on x86_64\n .Load average: 1.23, 1.01, 0.63\n\nHostname ********\nType xyz\n o Datacenter ********\n Cluster ********\n\n\n\n\n,0 loaded units listed. Pass --all to see loaded but inactive units, too.\nTo show all installed unit files use 'systemctl list-unit-files'.\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -74,7 +82,15 @@
"total_bytes_captured": 1024,
"total_bytes_skipped": 0,
"bytes_skipped": [],
- "text": ",\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H\"/usr/local/bin/galera_traffic_start.sh\" [readonly] 14L, 397C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for setting the reject of queries in Galera\n\nmysql -h127.0.0.1 -P6033 -uroot -e \"set global wsrep_reject_queries='NONE'\" 2>&1\nRC=$?\n\nif [[ $RC != 0 ]]; then\n >&2 echo \"Failed to unset the reject of queries on Galera node, exiting.\"\n exit $RC\nelse\n echo \"Successfully unset the reject of queries.\"\nfi\n\u001b[94m~ \u001b[16;1H~ \u001b[17;1H~ \u001b[18;1H~ \u001b[19;1H~ \u001b[20;1H~ \u001b[21;1H~ \u001b[22;1H~ \u001b[23;1H~ \u001b[24;1H~ \u001b[25;1H~ \u001b[26;1H~ \u001b[27;1H~ \u001b[28;1H~ \u001b[29;1H~ \u001b[30;1H~ \u001b[31;1H~ \u001b[32;1H~ \u001b[33;1H~ \u001b[34;1H~ \u001b[35;1H~ \u001b[36;1H~ \u001b[37;1H~ \u001b[38;1H~ \u001b[39;1H~ \u001b[40;1H~ \u001b[41;1H~ \u001b[42;1H~ \u001b[43;1H~ \u001b[44;1H~ \u001b[45;1H~ \u001b[46;1H~ \u001b[47;1H~ \u001b[48;1H~ \u001b[49;1H~ \u001b[50;1H~ \u001b[51;1H~ \u001b[52;1H~ \u001b[53;1H~ \u001b[54;1H~ \u001b[55;1H~ \u001b[56;1H~ \u001b[57;1H~ \u001b[58;1H~ \u001b[1;1H\u001b[?25h\u0007\u001b[?25l\u001b[m\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hq\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H\"/usr/local/bin/galera_traffic_stop.sh\" [readonly] 115L, 3570C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for rejecting connection on Galera cluster node, either gracefully or not,\n# depending on supplied arguments.\n\nfunction usage() {\n echo \"\n This script disables DB connections to Galera node.\n The default is to stop them gracefully.\n\n Usage: $0 [-h] [-w ] [-s ] [-x]\n\n Options:\n -h Prints this help.\n -w Number of seconds for waiting to close the connections.\u001b[17;11HDefault value is to wait for mysql-wait_timeout.\n -s Sleep interval between connections checks.\n -x Kills all connections immediately. Other options are ignored.\"\n exit\n}\n"
+ "text": ",\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H\"/usr/local/bin/script_one.sh\" [readonly] 14L, 397C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for setting the reject of queries in MySQL\n\nmysql -h127.0.0.1 -P6033 -uroot -e \"set global wsrep_reject_queries='NONE'\" 2>&1\nRC=$?\n\nif [[ $RC != 0 ]]; then\n >&2 echo \"Failed to unset the reject of queries on MySQL node, exiting.\"\n exit $RC\nelse\n echo \"Successfully unset the reject of queries.\"\nfi\n\u001b[94m~ \u001b[16;1H~ \u001b[17;1H~ \u001b[18;1H~ \u001b[19;1H~ \u001b[20;1H~ \u001b[21;1H~ \u001b[22;1H~ \u001b[23;1H~ \u001b[24;1H~ \u001b[25;1H~ \u001b[26;1H~ \u001b[27;1H~ \u001b[28;1H~ \u001b[29;1H~ \u001b[30;1H~ \u001b[31;1H~ \u001b[32;1H~ \u001b[33;1H~ \u001b[34;1H~ \u001b[35;1H~ \u001b[36;1H~ \u001b[37;1H~ \u001b[38;1H~ \u001b[39;1H~ \u001b[40;1H~ \u001b[41;1H~ \u001b[42;1H~ \u001b[43;1H~ \u001b[44;1H~ \u001b[45;1H~ \u001b[46;1H~ \u001b[47;1H~ \u001b[48;1H~ \u001b[49;1H~ \u001b[50;1H~ \u001b[51;1H~ \u001b[52;1H~ \u001b[53;1H~ \u001b[54;1H~ \u001b[55;1H~ \u001b[56;1H~ \u001b[57;1H~ \u001b[58;1H~ \u001b[1;1H\u001b[?25h\u0007\u001b[?25l\u001b[m\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hq\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001b[?2004h\u001b[?1049h\u001b[22;0;0t\u001b[?1h\u001b=\u001b[?2004h\u001b[1;59r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[?25l\u001b[59;1H\"/usr/local/bin/galera_traffic_stop.sh\" [readonly] 115L, 3570C\u001b[1;1H#!/bin/env bash\n# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\n# Script for rejecting connection on MySQL cluster node, either gracefully or not,\n# depending on supplied arguments.\n\nfunction usage() {\n echo \"\n This script disables DB connections to MySQL node.\n The default is to stop them gracefully.\n\n Usage: $0 [-h] [-w ] [-s ] [-x]\n\n Options:\n -h Prints this help.\n -w Number of seconds for waiting to close the connections.\u001b[17;11HDefault value is to wait for mysql-wait_timeout.\n -s Sleep interval between connections checks.\n -x Kills all connections immediately. Other options are ignored.\"\n exit\n}\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -104,7 +120,15 @@
"total_bytes_captured": 1024,
"total_bytes_skipped": 0,
"bytes_skipped": [],
- "text": "\nfunction get_number_db_connections() {\n # count current\n DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select count(1) from stats_mysql_processlist where user = '$DB_USER' and db like 'db\\_%' escapee\u001b[26;1H '\\'\")\n}\n\nfunction set_number_grace_seconds() {\n local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select variable_value from global_variables where variable_name = 'mysql-wait_timeout'\")\n GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n}\n\nfunction wait_for_connections() {\n local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\u001b[37;5Hecho \"Waiting for connections to close for up to $GRACE_PERIOD seconds\"\u001b[39;5Hfor i in $(seq 0 $number_of_loops); do\u001b[40;9Hget_number_db_connections\u001b[41;9Hif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;13Hecho \"No connection found for user $DB_USER to this node\"\u001b[43;13Hbreak\u001b[44;9Helse\u001b[45;13Hecho \"$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i\"\u001b[46;13Hsleep $SLEEP_INTERVAL\u001b[47;9Hfi\n done\n}\n\nfunction parse_args() {\n while getopts 'hs:w:x' opt; do\u001b[53;9Hcase \"$opt\" in\u001b[54;9Hh)\u001b[55;13Husage\u001b[56;13H;;\u001b[57;9Hs)\u001b[58;13Hif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\u001b[1;1H\u001b[?25h\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hset number\r\u001b[?25l\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Galera cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo \"\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Galera node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m Default value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored.\"\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select count(1) from stats_mysql_processlist where user = '$DB_USER' and db like 'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m' escape '\\'\")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select variable_value from global_variables where variable_name = 'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout'\")\u001b[31;16H\u001b[K\u001b[32;1H\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \u001b[m\u001b[34;10H\u001b[K\u001b[35;1H\u001b[38;5;130m 33 \u001b[mfunction wait_for_connections() {\u001b[35;42H\u001b[K\u001b[36;1H\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \u001b[m\u001b[37;10H\u001b[K\u001b[38;1H\u001b[38;5;130m 36 \u001b[m echo \"Waiting for connections to close for up to $GRACE_PERIOD seconds\"\n\u001b[38;5;130m 37 \u001b[m\u001b[39;9H\u001b[K\u001b[40;1H\u001b[38;5;130m 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n"
+ "text": "\nfunction get_number_db_connections() {\n # count current\n DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select count(1) from stats_mysql_processlist where user = '$DB_USER' and db like 'db\\_%' escapee\u001b[26;1H '\\'\")\n}\n\nfunction set_number_grace_seconds() {\n local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select variable_value from global_variables where variable_name = 'mysql-wait_timeout'\")\n GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n}\n\nfunction wait_for_connections() {\n local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\u001b[37;5Hecho \"Waiting for connections to close for up to $GRACE_PERIOD seconds\"\u001b[39;5Hfor i in $(seq 0 $number_of_loops); do\u001b[40;9Hget_number_db_connections\u001b[41;9Hif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;13Hecho \"No connection found for user $DB_USER to this node\"\u001b[43;13Hbreak\u001b[44;9Helse\u001b[45;13Hecho \"$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i\"\u001b[46;13Hsleep $SLEEP_INTERVAL\u001b[47;9Hfi\n done\n}\n\nfunction parse_args() {\n while getopts 'hs:w:x' opt; do\u001b[53;9Hcase \"$opt\" in\u001b[54;9Hh)\u001b[55;13Husage\u001b[56;13H;;\u001b[57;9Hs)\u001b[58;13Hif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\u001b[1;1H\u001b[?25h\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hset number\r\u001b[?25l\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on MySQL cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo \"\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to MySQL node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m Default value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored.\"\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select count(1) from stats_mysql_processlist where user = '$DB_USER' and db like 'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m' escape '\\'\")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select variable_value from global_variables where variable_name = 'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout'\")\u001b[31;16H\u001b[K\u001b[32;1H\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \u001b[m\u001b[34;10H\u001b[K\u001b[35;1H\u001b[38;5;130m 33 \u001b[mfunction wait_for_connections() {\u001b[35;42H\u001b[K\u001b[36;1H\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \u001b[m\u001b[37;10H\u001b[K\u001b[38;1H\u001b[38;5;130m 36 \u001b[m echo \"Waiting for connections to close for up to $GRACE_PERIOD seconds\"\n\u001b[38;5;130m 37 \u001b[m\u001b[39;9H\u001b[K\u001b[40;1H\u001b[38;5;130m 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -135,6 +159,14 @@
"total_bytes_skipped": 0,
"bytes_skipped": [],
"text": "\u001b[38;5;130m 39 \u001b[m get_number_db_connections\u001b[41;42H\u001b[K\u001b[42;1H\u001b[38;5;130m 40 \u001b[m if [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\u001b[42;60H\u001b[K\u001b[43;1H\u001b[38;5;130m 41 \u001b[m echo \"No connection found for user $DB_USER to this node\"\n\u001b[38;5;130m 42 \u001b[m \u001b[8Cbreak\n\u001b[38;5;130m 43 \u001b[m else\u001b[45;21H\u001b[K\u001b[46;1H\u001b[38;5;130m 44 \u001b[m echo \"$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i\"\n\u001b[38;5;130m 45 \u001b[m \u001b[10Csleep $SLEEP_INTERVAL\n\u001b[38;5;130m 46 \u001b[m\u001b[8Cfi\n\u001b[38;5;130m 47 \u001b[m done\n\u001b[38;5;130m 48 \u001b[m}\n\u001b[38;5;130m 49 \u001b[m\u001b[51;10H\u001b[K\u001b[52;1H\u001b[38;5;130m 50 \u001b[mfunction parse_args() {\u001b[52;33H\u001b[K\u001b[53;1H\u001b[38;5;130m 51 \u001b[m while getopts 'hs:w:x' opt; do\n\u001b[38;5;130m 52 \u001b[m case \"$opt\" in\n\u001b[38;5;130m 53 \u001b[m h)\n\u001b[38;5;130m 54 \u001b[m usage\n\u001b[38;5;130m 55 \u001b[m \u001b[10C;;\n\u001b[38;5;130m 56 \u001b[m s)\u001b[58;19H\u001b[K\u001b[1;9H\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 58 \u001b[m\u001b[16C>&2 echo \"Sleep interval (-s) must be a number\"\n\u001b[38;5;130m 59 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 60 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 61 \u001b[m\u001b[12CARG_SLEEP_INTERVAL=\"$OPTARG\"\n\u001b[38;5;130m 62 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 63 \u001b[m\u001b[8Cw)\n\u001b[38;5;130m 64 \u001b[m\u001b[12Cif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\n\u001b[38;5;130m 65 \u001b[m\u001b[16C>&2 echo \"Wait timeout (-w) must be a number\"\n\u001b[38;5;130m 66 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 67 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 68 \u001b[m\u001b[12CARG_GRACE_PERIOD=\"$OPTARG\"\n\u001b[38;5;130m 69 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 70 \u001b[m\u001b[8Cx)\n\u001b[38;5;130m 71 \u001b[m\u001b[12CARG_KILL_IMMEDIATELY=1\n\u001b[38;5;130m 72 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 73 \u001b[m\u001b[8Cesac\n\u001b[38;5;130m 74 \u001b[m done\n\u001b[38;5;130m 75 \n 76 \u001b[m GRACE_PERIOD=${ARG_GRACE_PERIOD:--1}\n\u001b[38;5;130m 77 \u001b[m SLEEP_INTERVAL=${ARG_SLEEP_INTERVAL:-30}\n\u001b[38;5;130m 78 \u001b[m KILL_IMMEDIATELY=${ARG_KILL_IMMEDIATELY:-0}\n\u001b[38;5;130m 79 \u001b[m}\n\u001b[38;5;130m 80 \n 81 \u001b[mDB_USER=\"rolap01\"\n\u001b[38;5;130m 82 \n 83 \u001b[mparse_args $@\n\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo \"WARNING: Not waiting for connections to close gracefully\"\n\u001b[38;5;130m 87 \u001b[m echo \"Press any key to continue... wsrep_reject_queries will be set to 'ALL_KILL'\"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e \"set global wsrep_reject_queries='ALL_KILL'\"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e \"set global wsrep_reject_queries='ALL'\"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -164,7 +196,15 @@
"total_bytes_captured": 1024,
"total_bytes_skipped": 0,
"bytes_skipped": [],
- "text": "\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo \"Failed to set the reject of queries on Galera node, exiting.\"\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo \"Successfully stopped accepting queries.\"\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo \"ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections.\"\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on Galera cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo \"\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to Galera node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m\u001b[10CDefault value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored.\"\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select count(1) from stats_mysql_processlist where user = '$DB_USER' and db like 'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m' escape '\\'\")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select variable_value from global_variables where variable_name = 'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout'\")\n\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \n"
+ "text": "\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo \"Failed to set the reject of queries on MySQL node, exiting.\"\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo \"Successfully stopped accepting queries.\"\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo \"ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections.\"\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 1 \u001b[m#!/bin/env bash\n\u001b[38;5;130m 2 \u001b[m# Copyright (C) 2022, ********(R) Corporation. All rights reserved.\n\u001b[38;5;130m 3 \n 4 \u001b[m# Script for rejecting connection on MySQL cluster node, either gracefully or not,\n\u001b[38;5;130m 5 \u001b[m# depending on supplied arguments.\n\u001b[38;5;130m 6 \n 7 \u001b[mfunction usage() {\n\u001b[38;5;130m 8 \u001b[m echo \"\n\u001b[38;5;130m 9 \u001b[m This script disables DB connections to MySQL node.\n\u001b[38;5;130m 10 \u001b[m The default is to stop them gracefully.\n\u001b[38;5;130m 11 \n 12 \u001b[m Usage: $0 [-h] [-w ] [-s ] [-x]\n\u001b[38;5;130m 13 \n 14 \u001b[m Options:\n\u001b[38;5;130m 15 \u001b[m -h Prints this help.\n\u001b[38;5;130m 16 \u001b[m -w Number of seconds for waiting to close the connections.\n\u001b[38;5;130m 17 \u001b[m\u001b[10CDefault value is to wait for mysql-wait_timeout.\n\u001b[38;5;130m 18 \u001b[m -s Sleep interval between connections checks.\n\u001b[38;5;130m 19 \u001b[m -x Kills all connections immediately. Other options are ignored.\"\n\u001b[38;5;130m 20 \u001b[m exit\n\u001b[38;5;130m 21 \u001b[m}\n\u001b[38;5;130m 22 \n 23 \u001b[mfunction get_number_db_connections() {\n\u001b[38;5;130m 24 \u001b[m # count current\n\u001b[38;5;130m 25 \u001b[m DB_CONNECTIONS_NUMBER=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select count(1) from stats_mysql_processlist where user = '$DB_USER' and db like 'db\\_%%\u001b[26;1H\u001b[38;5;130m \u001b[m' escape '\\'\")\n\u001b[38;5;130m 26 \u001b[m}\n\u001b[38;5;130m 27 \n 28 \u001b[mfunction set_number_grace_seconds() {\n\u001b[38;5;130m 29 \u001b[m local mysql_wait_timeout_ms=$(mysql -h127.0.0.1 -P6032 -uadmin -N --silent -e \"select variable_value from global_variables where variable_name = 'mysql-wait_timm\u001b[31;1H\u001b[38;5;130m \u001b[meout'\")\n\u001b[38;5;130m 30 \u001b[m GRACE_PERIOD=$((($mysql_wait_timeout_ms+1000-1)/1000))\n\u001b[38;5;130m 31 \u001b[m}\n\u001b[38;5;130m 32 \n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -195,6 +235,14 @@
"total_bytes_skipped": 0,
"bytes_skipped": [],
"text": " 33 \u001b[mfunction wait_for_connections() {\n\u001b[38;5;130m 34 \u001b[m local number_of_loops=$(((($GRACE_PERIOD+$SLEEP_INTERVAL-1)/$SLEEP_INTERVAL)))\n\u001b[38;5;130m 35 \n 36 \u001b[m echo \"Waiting for connections to close for up to $GRACE_PERIOD seconds\"\n\u001b[38;5;130m 37 \n 38 \u001b[m for i in $(seq 0 $number_of_loops); do\n\u001b[38;5;130m 39 \u001b[m\u001b[8Cget_number_db_connections\n\u001b[38;5;130m 40 \u001b[m\u001b[8Cif [[ $DB_CONNECTIONS_NUMBER -eq 0 ]]; then\n\u001b[38;5;130m 41 \u001b[m\u001b[12Cecho \"No connection found for user $DB_USER to this node\"\n\u001b[38;5;130m 42 \u001b[m\u001b[12Cbreak\n\u001b[38;5;130m 43 \u001b[m\u001b[8Celse\n\u001b[38;5;130m 44 \u001b[m\u001b[12Cecho \"$DB_CONNECTIONS_NUMBER connection(s) found, waiting for ${SLEEP_INTERVAL}s, round $i\"\n\u001b[38;5;130m 45 \u001b[m\u001b[12Csleep $SLEEP_INTERVAL\n\u001b[38;5;130m 46 \u001b[m\u001b[8Cfi\n\u001b[38;5;130m 47 \u001b[m done\n\u001b[38;5;130m 48 \u001b[m}\n\u001b[38;5;130m 49 \n 50 \u001b[mfunction parse_args() {\n\u001b[38;5;130m 51 \u001b[m while getopts 'hs:w:x' opt; do\n\u001b[38;5;130m 52 \u001b[m\u001b[8Ccase \"$opt\" in\n\u001b[38;5;130m 53 \u001b[m\u001b[8Ch)\n\u001b[38;5;130m 54 \u001b[m\u001b[12Cusage\n\u001b[38;5;130m 55 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 56 \u001b[m\u001b[8Cs)\u001b[1;9H\u001b[?25h\u001b[?25l\u001b[27m\u001b[29m\u001b[m\u001b[H\u001b[2J\u001b[1;1H\u001b[38;5;130m 58 \u001b[m\u001b[16C>&2 echo \"Sleep interval (-s) must be a number\"\n\u001b[38;5;130m 59 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 60 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 61 \u001b[m\u001b[12CARG_SLEEP_INTERVAL=\"$OPTARG\"\n\u001b[38;5;130m 62 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 63 \u001b[m\u001b[8Cw)\n\u001b[38;5;130m 64 \u001b[m\u001b[12Cif ! [[ $OPTARG =~ ^[0-9]+$ ]]; then\n\u001b[38;5;130m 65 \u001b[m\u001b[16C>&2 echo \"Wait timeout (-w) must be a number\"\n\u001b[38;5;130m 66 \u001b[m\u001b[16Cexit 1\n\u001b[38;5;130m 67 \u001b[m\u001b[12Cfi\n\u001b[38;5;130m 68 \u001b[m\u001b[12CARG_GRACE_PERIOD=\"$OPTARG\"\n\u001b[38;5;130m 69 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 70 \u001b[m\u001b[8Cx)\n\u001b[38;5;130m 71 \u001b[m\u001b[12CARG_KILL_IMMEDIATELY=1\n\u001b[38;5;130m 72 \u001b[m\u001b[12C;;\n\u001b[38;5;130m 73 \u001b[m\u001b[8Cesac\n\u001b[38;5;130m 74 \u001b[m done\n\u001b[38;5;130m 75 \n 76 \u001b[m GRACE_PERIOD=${ARG_GRACE_PERIOD:--1}\n\u001b[38;5;130m 77 \u001b[m SLEEP_INTERVAL=${ARG_SLEEP_INTERVAL:-30}\n\u001b[38;5;130m 78 \u001b[m KILL_IMMEDIATELY=${ARG_KILL_IMMEDIATELY:-0}\n\u001b[38;5;130m 79 \u001b[m}\n\u001b[38;5;130m 80 \n 81 \u001b[mDB_USER=\"rolap01\"\n\u001b[38;5;130m 82 \n 83 \u001b[mparse_args $@\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -224,7 +272,15 @@
"total_bytes_captured": 1024,
"total_bytes_skipped": 0,
"bytes_skipped": [],
- "text": "\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo \"WARNING: Not waiting for connections to close gracefully\"\n\u001b[38;5;130m 87 \u001b[m echo \"Press any key to continue... wsrep_reject_queries will be set to 'ALL_KILL'\"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e \"set global wsrep_reject_queries='ALL_KILL'\"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e \"set global wsrep_reject_queries='ALL'\"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo \"Failed to set the reject of queries on Galera node, exiting.\"\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo \"Successfully stopped accepting queries.\"\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo \"ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections.\"\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n"
+ "text": "\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo \"WARNING: Not waiting for connections to close gracefully\"\n\u001b[38;5;130m 87 \u001b[m echo \"Press any key to continue... wsrep_reject_queries will be set to 'ALL_KILL'\"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e \"set global wsrep_reject_queries='ALL_KILL'\"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e \"set global wsrep_reject_queries='ALL'\"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo \"Failed to set the reject of queries on MySQL node, exiting.\"\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo \"Successfully stopped accepting queries.\"\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo \"ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections.\"\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
@@ -254,7 +310,15 @@
"total_bytes_captured": 1024,
"total_bytes_skipped": 0,
"bytes_skipped": [],
- "text": "\u001bkroot@staging-host:~\u001b\\\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\b\b\b\b\b\n\u001bkroot@staging-host:~\u001b\\\b\u001b[K\b\u001b[K\b\u001b[K\n,\n22/05/26 09:24:09 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/galera_traffic_start.sh\u0007\n22/05/26 09:25:32 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/galera_traffic_start.sh.sh.sh.sho.shp.sh\n22/05/26 09:30:08 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] exi\u0007\u0007\u0007exitlogout\n,\u001bec2-user@staging-host:~\u001b\\\n\u001bec2-user@staging-host:~\u001b\\\n,\n22/05/26 09:24:01 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] sudo -i\n22/05/26 10:11:37 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] exitlogout\n\n"
+ "text": "\u001bkroot@staging-host:~\u001b\\\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\u001b[1P\b\b\b\b\b\b\b\b\b\n\u001bkroot@staging-host:~\u001b\\\b\u001b[K\b\u001b[K\b\u001b[K\n,\n22/05/26 09:24:09 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/script_one.sh\u0007\n22/05/26 09:25:32 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] vi -R /usr/local/bin/script_one.sh.sh.sh.sho.shp.sh\n22/05/26 09:30:08 rack-na/cl_md (md), Cluster ********\n[root@staging-host:~] exi\u0007\u0007\u0007exitlogout\n,\u001bec2-user@staging-host:~\u001b\\\n\u001bec2-user@staging-host:~\u001b\\\n,\n22/05/26 09:24:01 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] sudo -i\n22/05/26 10:11:37 rack-na/cl_md (md), Cluster ********\n[ec2-user@staging-host:~] exitlogout\n\n"
+ },
+ "tty": {
+ "char_device": {
+ "major": 4,
+ "minor": 1
+ },
+ "rows": 66,
+ "columns": 280
}
}
}
From 6f0bfcfd0d528441fdeeb4d2b33936a20e6e82f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?=
Date: Tue, 23 Aug 2022 20:56:19 +0200
Subject: [PATCH 04/18] [APM] Use datastreams for API tests (#139283)
---
.../client/apm_synthtrace_kibana_client.ts | 7 +-
.../kbn-apm-synthtrace/src/lib/apm/index.ts | 2 +
.../common/bootstrap_apm_synthtrace.ts | 34 +
.../test/apm_api_integration/common/config.ts | 23 +-
.../apm_api_integration/common/registry.ts | 1 -
.../common/utils/create_and_run_apm_ml_job.ts | 8 +-
.../tests/alerts/anomaly_alert.spec.ts | 2 +-
.../tests/anomalies/anomaly_charts.spec.ts | 5 +-
.../tests/cold_start/cold_start.spec.ts | 230 +++--
.../cold_start_by_transaction_name.spec.ts | 2 +-
.../tests/data_view/static.spec.ts | 118 ++-
.../dependencies/dependency_metrics.spec.ts | 295 +++----
.../tests/dependencies/metadata.spec.ts | 2 +-
.../dependencies/service_dependencies.spec.ts | 84 +-
.../dependencies/top_dependencies.spec.ts | 154 ++--
.../tests/dependencies/top_operations.spec.ts | 236 +++--
.../tests/dependencies/top_spans.spec.ts | 2 +-
.../dependencies/upstream_services.spec.ts | 36 +-
.../tests/error_rate/service_apis.spec.ts | 2 +-
.../tests/error_rate/service_maps.spec.ts | 148 ++--
.../tests/errors/distribution.spec.ts | 190 ++--
.../tests/errors/error_group_list.spec.ts | 162 ++--
.../tests/errors/group_id.spec.ts | 46 +-
.../top_erroneous_transactions.spec.ts | 212 +++--
.../top_errors_main_stats.spec.ts | 75 +-
.../infrastructure_attributes.spec.ts | 52 +-
.../tests/latency/service_apis.spec.ts | 2 +-
.../tests/latency/service_maps.spec.ts | 109 ++-
.../observability_overview.spec.ts | 154 ++--
.../service_nodes/get_service_nodes.spec.ts | 56 +-
.../instances_main_statistics.spec.ts | 2 +-
.../error_groups_detailed_statistics.spec.ts | 214 +++--
.../error_groups_main_statistics.spec.ts | 69 +-
.../get_service_node_metadata.spec.ts | 2 +-
.../service_details/service_details.spec.ts | 130 ++-
.../service_icons/service_icons.spec.ts | 48 +-
.../sorted_and_filtered_services.spec.ts | 158 ++--
.../tests/services/throughput.spec.ts | 360 ++++----
.../tests/services/top_services.spec.ts | 4 +-
.../agent_configuration.spec.ts | 108 ++-
.../tests/span_links/span_links.spec.ts | 832 +++++++++---------
.../throughput/dependencies_apis.spec.ts | 254 +++---
.../tests/throughput/service_apis.spec.ts | 2 +-
.../tests/throughput/service_maps.spec.ts | 117 ++-
.../tests/traces/find_traces.spec.ts | 346 ++++----
.../tests/traces/trace_by_id.spec.ts | 2 +-
...actions_groups_detailed_statistics.spec.ts | 298 +++----
47 files changed, 2635 insertions(+), 2760 deletions(-)
create mode 100644 x-pack/test/apm_api_integration/common/bootstrap_apm_synthtrace.ts
diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts
index bf068d7f3318570..7bd2443031c8009 100644
--- a/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts
+++ b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts
@@ -54,9 +54,8 @@ export class ApmSynthtraceKibanaClient {
});
}
async fetchLatestApmPackageVersion(currentKibanaVersion: string) {
- const url =
- 'https://epr-snapshot.elastic.co/search?package=apm&prerelease=true&all=true&kibana.version=';
- const response = await fetch(url + currentKibanaVersion, { method: 'GET' });
+ const url = `https://epr-snapshot.elastic.co/search?package=apm&prerelease=true&all=true&kibana.version=${currentKibanaVersion}`;
+ const response = await fetch(url, { method: 'GET' });
const json = (await response.json()) as Array<{ version: string }>;
const packageVersions = (json ?? []).map((item) => item.version).sort(Semver.rcompare);
const validPackageVersions = packageVersions.filter((v) => Semver.valid(v));
@@ -71,7 +70,7 @@ export class ApmSynthtraceKibanaClient {
async installApmPackage(kibanaUrl: string, version: string, username: string, password: string) {
const packageVersion = await this.fetchLatestApmPackageVersion(version);
- const response = await fetch(kibanaUrl + '/api/fleet/epm/packages/apm/' + packageVersion, {
+ const response = await fetch(`${kibanaUrl}/api/fleet/epm/packages/apm/${packageVersion}`, {
method: 'POST',
headers: {
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/index.ts b/packages/kbn-apm-synthtrace/src/lib/apm/index.ts
index fcb8e078bf02abf..a136daabee8f2f6 100644
--- a/packages/kbn-apm-synthtrace/src/lib/apm/index.ts
+++ b/packages/kbn-apm-synthtrace/src/lib/apm/index.ts
@@ -13,6 +13,7 @@ import { getChromeUserAgentDefaults } from './defaults/get_chrome_user_agent_def
import { getBreakdownMetrics } from './processors/get_breakdown_metrics';
import { getApmWriteTargets } from './utils/get_apm_write_targets';
import { ApmSynthtraceEsClient } from './client/apm_synthtrace_es_client';
+import { ApmSynthtraceKibanaClient } from './client/apm_synthtrace_kibana_client';
import type { ApmException } from './apm_fields';
@@ -25,6 +26,7 @@ export const apm = {
getBreakdownMetrics,
getApmWriteTargets,
ApmSynthtraceEsClient,
+ ApmSynthtraceKibanaClient,
};
export type { ApmSynthtraceEsClient, ApmException };
diff --git a/x-pack/test/apm_api_integration/common/bootstrap_apm_synthtrace.ts b/x-pack/test/apm_api_integration/common/bootstrap_apm_synthtrace.ts
new file mode 100644
index 000000000000000..96d0cbf3f8e7bd4
--- /dev/null
+++ b/x-pack/test/apm_api_integration/common/bootstrap_apm_synthtrace.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { apm, createLogger, LogLevel } from '@kbn/apm-synthtrace';
+import { esTestConfig } from '@kbn/test';
+import { APM_TEST_PASSWORD } from './authentication';
+import { InheritedFtrProviderContext } from './ftr_provider_context';
+
+export async function bootstrapApmSynthtrace(
+ context: InheritedFtrProviderContext,
+ kibanaServerUrl: string
+) {
+ const es = context.getService('es');
+ const kibanaVersion = esTestConfig.getVersion();
+
+ const kibanaClient = new apm.ApmSynthtraceKibanaClient(createLogger(LogLevel.info));
+ await kibanaClient.installApmPackage(
+ kibanaServerUrl,
+ kibanaVersion,
+ 'elastic',
+ APM_TEST_PASSWORD
+ );
+
+ const esClient = new apm.ApmSynthtraceEsClient(es, createLogger(LogLevel.info), {
+ forceLegacyIndices: false,
+ refreshAfterIndex: true,
+ });
+
+ return esClient;
+}
diff --git a/x-pack/test/apm_api_integration/common/config.ts b/x-pack/test/apm_api_integration/common/config.ts
index 3c9e99d645c7b5d..6bb177ff770b3e2 100644
--- a/x-pack/test/apm_api_integration/common/config.ts
+++ b/x-pack/test/apm_api_integration/common/config.ts
@@ -16,7 +16,7 @@ import { createApmUser, APM_TEST_PASSWORD, ApmUsername } from './authentication'
import { APMFtrConfigName } from '../configs';
import { createApmApiClient } from './apm_api_supertest';
import { RegistryProvider } from './registry';
-import { synthtraceEsClientService } from './synthtrace_es_client_service';
+import { bootstrapApmSynthtrace } from './bootstrap_apm_synthtrace';
import { MachineLearningAPIProvider } from '../../functional/services/ml/api';
export interface ApmFtrConfig {
@@ -80,7 +80,7 @@ export function createTestConfig(config: ApmFtrConfig) {
const services = xPackAPITestsConfig.get('services') as InheritedServices;
const servers = xPackAPITestsConfig.get('servers');
- const kibanaServer = servers.kibana;
+ const kibanaServer = servers.kibana as UrlObject;
return {
testFiles: [require.resolve('../tests')],
@@ -90,7 +90,10 @@ export function createTestConfig(config: ApmFtrConfig) {
...services,
apmFtrConfig: () => config,
registry: RegistryProvider,
- synthtraceEsClient: synthtraceEsClientService,
+ synthtraceEsClient: (context: InheritedFtrProviderContext) => {
+ const kibanaServerUrl = format(kibanaServer);
+ return bootstrapApmSynthtrace(context, kibanaServerUrl);
+ },
apmApiClient: async (context: InheritedFtrProviderContext) => {
const security = context.getService('security');
const es = context.getService('es');
@@ -100,49 +103,49 @@ export function createTestConfig(config: ApmFtrConfig) {
return {
noAccessUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.noAccessUser,
es,
logger,
}),
readUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.viewerUser,
es,
logger,
}),
writeUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.editorUser,
es,
logger,
}),
annotationWriterUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.apmAnnotationsWriteUser,
es,
logger,
}),
noMlAccessUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.apmReadUserWithoutMlAccess,
es,
logger,
}),
manageOwnAgentKeysUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.apmManageOwnAgentKeys,
es,
logger,
}),
createAndAllAgentKeysUser: await getApmApiClient({
- kibanaServer: servers.kibana,
+ kibanaServer,
security,
username: ApmUsername.apmManageOwnAndCreateAgentKeys,
es,
diff --git a/x-pack/test/apm_api_integration/common/registry.ts b/x-pack/test/apm_api_integration/common/registry.ts
index 51f4bb6a84e7206..7611d054852df04 100644
--- a/x-pack/test/apm_api_integration/common/registry.ts
+++ b/x-pack/test/apm_api_integration/common/registry.ts
@@ -15,7 +15,6 @@ import { FtrProviderContext } from './ftr_provider_context';
type ArchiveName =
| 'apm_8.0.0'
- | 'apm_mappings_only_8.0.0'
| '8.0.0'
| 'metrics_8.0.0'
| 'ml_8.0.0'
diff --git a/x-pack/test/apm_api_integration/common/utils/create_and_run_apm_ml_job.ts b/x-pack/test/apm_api_integration/common/utils/create_and_run_apm_ml_job.ts
index 3a42456742caac4..2302fac7337f688 100644
--- a/x-pack/test/apm_api_integration/common/utils/create_and_run_apm_ml_job.ts
+++ b/x-pack/test/apm_api_integration/common/utils/create_and_run_apm_ml_job.ts
@@ -10,11 +10,12 @@ import datafeed from '@kbn/ml-plugin/server/models/data_recognizer/modules/apm_t
import { MlApi } from '../../../functional/services/ml/api';
export function createAndRunApmMlJob({ ml, environment }: { ml: MlApi; environment: string }) {
+ const jobId = `apm-tx-metrics-${environment}`;
return ml.createAndRunAnomalyDetectionLookbackJob(
// @ts-expect-error not entire job config
{
...job,
- job_id: `apm-tx-metrics-${environment}`,
+ job_id: jobId,
allow_lazy_open: false,
custom_settings: {
job_tags: {
@@ -25,8 +26,9 @@ export function createAndRunApmMlJob({ ml, environment }: { ml: MlApi; environme
},
{
...datafeed,
- job_id: `apm-tx-metrics-${environment}`,
- indices: ['apm-*'],
+ indices_options: { allow_no_indices: true },
+ job_id: jobId,
+ indices: ['metrics-apm*', 'apm-*'],
datafeed_id: `apm-tx-metrics-${environment}-datafeed`,
query: {
bool: {
diff --git a/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts b/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts
index d1c1c465dc576f3..43ba70cc100a15f 100644
--- a/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts
@@ -24,7 +24,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'fetching service anomalies with a trial license',
- { config: 'trial', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'trial', archives: [] },
() => {
const start = '2021-01-01T00:00:00.000Z';
const end = '2021-01-08T00:15:00.000Z';
diff --git a/x-pack/test/apm_api_integration/tests/anomalies/anomaly_charts.spec.ts b/x-pack/test/apm_api_integration/tests/anomalies/anomaly_charts.spec.ts
index b85a96c25869a92..0416a0124627af3 100644
--- a/x-pack/test/apm_api_integration/tests/anomalies/anomaly_charts.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/anomalies/anomaly_charts.spec.ts
@@ -18,7 +18,6 @@ import { createAndRunApmMlJob } from '../../common/utils/create_and_run_apm_ml_j
export default function ApiTest({ getService }: FtrProviderContext) {
const registry = getService('registry');
-
const apmApiClient = getService('apmApiClient');
const ml = getService('ml');
@@ -70,7 +69,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'fetching service anomalies with a basic license',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
it('returns a 501', async () => {
const status = await statusOf(
@@ -90,7 +89,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'fetching service anomalies with a trial license',
- { config: 'trial', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'trial', archives: [] },
() => {
const start = '2021-01-01T00:00:00.000Z';
const end = '2021-01-08T00:15:00.000Z';
diff --git a/x-pack/test/apm_api_integration/tests/cold_start/cold_start.spec.ts b/x-pack/test/apm_api_integration/tests/cold_start/cold_start.spec.ts
index fad428a96f18aa0..721f178a6413ec0 100644
--- a/x-pack/test/apm_api_integration/tests/cold_start/cold_start.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/cold_start/cold_start.spec.ts
@@ -66,139 +66,135 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Cold start rate when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('without comparison', () => {
- let body: ColdStartRate;
- let status: number;
-
- before(async () => {
- await generateData({
- synthtraceEsClient,
- start,
- end,
- coldStartRate: 10,
- warmStartRate: 30,
- });
- const response = await callApi();
- body = response.body;
- status = response.status;
+ registry.when('Cold start rate when data is generated', { config: 'basic', archives: [] }, () => {
+ describe('without comparison', () => {
+ let body: ColdStartRate;
+ let status: number;
+
+ before(async () => {
+ await generateData({
+ synthtraceEsClient,
+ start,
+ end,
+ coldStartRate: 10,
+ warmStartRate: 30,
});
+ const response = await callApi();
+ body = response.body;
+ status = response.status;
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- it('returns correct HTTP status', () => {
- expect(status).to.be(200);
- });
+ it('returns correct HTTP status', () => {
+ expect(status).to.be(200);
+ });
- it('returns an array of transaction cold start rates', () => {
- expect(body).to.have.property('currentPeriod');
- expect(body.currentPeriod.transactionColdstartRate).to.have.length(15);
- expect(body.currentPeriod.transactionColdstartRate.every(({ y }) => y === 0.25)).to.be(
- true
- );
- });
+ it('returns an array of transaction cold start rates', () => {
+ expect(body).to.have.property('currentPeriod');
+ expect(body.currentPeriod.transactionColdstartRate).to.have.length(15);
+ expect(body.currentPeriod.transactionColdstartRate.every(({ y }) => y === 0.25)).to.be(
+ true
+ );
+ });
- it('returns correct average rate', () => {
- expect(body.currentPeriod.average).to.be(0.25);
- });
+ it('returns correct average rate', () => {
+ expect(body.currentPeriod.average).to.be(0.25);
+ });
- it("doesn't have data for the previous period", () => {
- expect(body).to.have.property('previousPeriod');
- expect(body.previousPeriod.transactionColdstartRate).to.have.length(0);
- expect(body.previousPeriod.average).to.be(null);
- });
+ it("doesn't have data for the previous period", () => {
+ expect(body).to.have.property('previousPeriod');
+ expect(body.previousPeriod.transactionColdstartRate).to.have.length(0);
+ expect(body.previousPeriod.average).to.be(null);
});
+ });
- describe('with comparison', () => {
- let body: ColdStartRate;
- let status: number;
-
- before(async () => {
- const startDate = moment(start).add(6, 'minutes');
- const endDate = moment(start).add(9, 'minutes');
- const comparisonStartDate = new Date(start);
- const comparisonEndDate = moment(start).add(3, 'minutes');
-
- await generateData({
- synthtraceEsClient,
- start: startDate.valueOf(),
- end: endDate.valueOf(),
- coldStartRate: 10,
- warmStartRate: 30,
- });
- await generateData({
- synthtraceEsClient,
- start: comparisonStartDate.getTime(),
- end: comparisonEndDate.valueOf(),
- coldStartRate: 20,
- warmStartRate: 20,
- });
-
- const response = await callApi({
- query: {
- start: startDate.toISOString(),
- end: endDate.subtract(1, 'seconds').toISOString(),
- offset: '6m',
- },
- });
- body = response.body;
- status = response.status;
+ describe('with comparison', () => {
+ let body: ColdStartRate;
+ let status: number;
+
+ before(async () => {
+ const startDate = moment(start).add(6, 'minutes');
+ const endDate = moment(start).add(9, 'minutes');
+ const comparisonStartDate = new Date(start);
+ const comparisonEndDate = moment(start).add(3, 'minutes');
+
+ await generateData({
+ synthtraceEsClient,
+ start: startDate.valueOf(),
+ end: endDate.valueOf(),
+ coldStartRate: 10,
+ warmStartRate: 30,
});
-
- after(() => synthtraceEsClient.clean());
-
- it('returns correct HTTP status', () => {
- expect(status).to.be(200);
+ await generateData({
+ synthtraceEsClient,
+ start: comparisonStartDate.getTime(),
+ end: comparisonEndDate.valueOf(),
+ coldStartRate: 20,
+ warmStartRate: 20,
});
- it('returns some data', () => {
- expect(body.currentPeriod.average).not.to.be(null);
- expect(body.currentPeriod.transactionColdstartRate.length).to.be.greaterThan(0);
- const hasCurrentPeriodData = body.currentPeriod.transactionColdstartRate.some(({ y }) =>
- isFiniteNumber(y)
- );
- expect(hasCurrentPeriodData).to.equal(true);
-
- expect(body.previousPeriod.average).not.to.be(null);
- expect(body.previousPeriod.transactionColdstartRate.length).to.be.greaterThan(0);
- const hasPreviousPeriodData = body.previousPeriod.transactionColdstartRate.some(({ y }) =>
- isFiniteNumber(y)
- );
- expect(hasPreviousPeriodData).to.equal(true);
+ const response = await callApi({
+ query: {
+ start: startDate.toISOString(),
+ end: endDate.subtract(1, 'seconds').toISOString(),
+ offset: '6m',
+ },
});
+ body = response.body;
+ status = response.status;
+ });
- it('has same start time for both periods', () => {
- expect(first(body.currentPeriod.transactionColdstartRate)?.x).to.equal(
- first(body.previousPeriod.transactionColdstartRate)?.x
- );
- });
+ after(() => synthtraceEsClient.clean());
- it('has same end time for both periods', () => {
- expect(last(body.currentPeriod.transactionColdstartRate)?.x).to.equal(
- last(body.previousPeriod.transactionColdstartRate)?.x
- );
- });
+ it('returns correct HTTP status', () => {
+ expect(status).to.be(200);
+ });
- it('returns an array of transaction cold start rates', () => {
- expect(body.currentPeriod.transactionColdstartRate).to.have.length(3);
- expect(body.currentPeriod.transactionColdstartRate.every(({ y }) => y === 0.25)).to.be(
- true
- );
+ it('returns some data', () => {
+ expect(body.currentPeriod.average).not.to.be(null);
+ expect(body.currentPeriod.transactionColdstartRate.length).to.be.greaterThan(0);
+ const hasCurrentPeriodData = body.currentPeriod.transactionColdstartRate.some(({ y }) =>
+ isFiniteNumber(y)
+ );
+ expect(hasCurrentPeriodData).to.equal(true);
+
+ expect(body.previousPeriod.average).not.to.be(null);
+ expect(body.previousPeriod.transactionColdstartRate.length).to.be.greaterThan(0);
+ const hasPreviousPeriodData = body.previousPeriod.transactionColdstartRate.some(({ y }) =>
+ isFiniteNumber(y)
+ );
+ expect(hasPreviousPeriodData).to.equal(true);
+ });
- expect(body.previousPeriod.transactionColdstartRate).to.have.length(3);
- expect(body.previousPeriod.transactionColdstartRate.every(({ y }) => y === 0.5)).to.be(
- true
- );
- });
+ it('has same start time for both periods', () => {
+ expect(first(body.currentPeriod.transactionColdstartRate)?.x).to.equal(
+ first(body.previousPeriod.transactionColdstartRate)?.x
+ );
+ });
- it('has same average value for both periods', () => {
- expect(body.currentPeriod.average).to.be(0.25);
- expect(body.previousPeriod.average).to.be(0.5);
- });
+ it('has same end time for both periods', () => {
+ expect(last(body.currentPeriod.transactionColdstartRate)?.x).to.equal(
+ last(body.previousPeriod.transactionColdstartRate)?.x
+ );
});
- }
- );
+
+ it('returns an array of transaction cold start rates', () => {
+ expect(body.currentPeriod.transactionColdstartRate).to.have.length(3);
+ expect(body.currentPeriod.transactionColdstartRate.every(({ y }) => y === 0.25)).to.be(
+ true
+ );
+
+ expect(body.previousPeriod.transactionColdstartRate).to.have.length(3);
+ expect(body.previousPeriod.transactionColdstartRate.every(({ y }) => y === 0.5)).to.be(
+ true
+ );
+ });
+
+ it('has same average value for both periods', () => {
+ expect(body.currentPeriod.average).to.be(0.25);
+ expect(body.previousPeriod.average).to.be(0.5);
+ });
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/cold_start/cold_start_by_transaction_name/cold_start_by_transaction_name.spec.ts b/x-pack/test/apm_api_integration/tests/cold_start/cold_start_by_transaction_name/cold_start_by_transaction_name.spec.ts
index ed432f58d47aaf0..25e4cd208aeb02a 100644
--- a/x-pack/test/apm_api_integration/tests/cold_start/cold_start_by_transaction_name/cold_start_by_transaction_name.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/cold_start/cold_start_by_transaction_name/cold_start_by_transaction_name.spec.ts
@@ -70,7 +70,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'Cold start rate by transaction name when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
describe('without comparison', () => {
let body: ColdStartRate;
diff --git a/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts b/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts
index efe8f37f1c5dce7..a77a2e443b9d5e3 100644
--- a/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts
@@ -59,79 +59,75 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'mappings exists',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is generated', () => {
- let response: SupertestReturnType<'POST /internal/apm/data_view/static'>;
+ registry.when('mappings exists', { config: 'basic', archives: [] }, () => {
+ describe('when data is generated', () => {
+ let response: SupertestReturnType<'POST /internal/apm/data_view/static'>;
+
+ before(async () => {
+ await generateApmData(synthtrace);
+ response = await createDataViewViaApmApi();
+ });
+
+ after(async () => {
+ await deleteDataView();
+ await synthtrace.clean();
+ });
+
+ it('successfully creates the apm data view', async () => {
+ expect(response.status).to.be(200);
+
+ expect(response.body.dataView!.id).to.be('apm_static_index_pattern_id');
+ expect(response.body.dataView!.name).to.be('APM');
+ expect(response.body.dataView!.title).to.be(
+ 'traces-apm*,apm-*,logs-apm*,apm-*,metrics-apm*,apm-*'
+ );
+ });
+
+ describe('when fetching the data view', async () => {
+ let resBody: any;
before(async () => {
- await generateApmData(synthtrace);
- response = await createDataViewViaApmApi();
+ const res = await getDataView().expect(200);
+ resBody = res.body;
});
- after(async () => {
- await deleteDataView();
- await synthtrace.clean();
+ it('has correct id', () => {
+ expect(resBody.id).to.be('apm_static_index_pattern_id');
});
- it('successfully creates the apm data view', async () => {
- expect(response.status).to.be(200);
-
- expect(response.body.dataView!.id).to.be('apm_static_index_pattern_id');
- expect(response.body.dataView!.name).to.be('APM');
- expect(response.body.dataView!.title).to.be(
- 'traces-apm*,apm-*,logs-apm*,apm-*,metrics-apm*,apm-*'
- );
+ it('has correct title', () => {
+ expect(resBody.attributes.title).to.be(dataViewPattern);
});
- describe('when fetching the data view', async () => {
- let resBody: any;
-
- before(async () => {
- const res = await getDataView().expect(200);
- resBody = res.body;
- });
-
- it('has correct id', () => {
- expect(resBody.id).to.be('apm_static_index_pattern_id');
- });
-
- it('has correct title', () => {
- expect(resBody.attributes.title).to.be(dataViewPattern);
- });
-
- it('has correct attributes', () => {
- expect(resBody.attributes.fieldFormatMap).to.be(
- JSON.stringify({
- 'trace.id': {
- id: 'url',
- params: {
- urlTemplate: 'apm/link-to/trace/{{value}}',
- labelTemplate: '{{value}}',
- },
+ it('has correct attributes', () => {
+ expect(resBody.attributes.fieldFormatMap).to.be(
+ JSON.stringify({
+ 'trace.id': {
+ id: 'url',
+ params: {
+ urlTemplate: 'apm/link-to/trace/{{value}}',
+ labelTemplate: '{{value}}',
},
- 'transaction.id': {
- id: 'url',
- params: {
- urlTemplate: 'apm/link-to/transaction/{{value}}',
- labelTemplate: '{{value}}',
- },
+ },
+ 'transaction.id': {
+ id: 'url',
+ params: {
+ urlTemplate: 'apm/link-to/transaction/{{value}}',
+ labelTemplate: '{{value}}',
},
- })
- );
- });
-
- // this test ensures that the default APM Data View doesn't interfere with suggestions returned in the kuery bar (this has been a problem in the past)
- it('can get suggestions for `trace.id`', async () => {
- const suggestions = await getDataViewSuggestions('trace.id');
- expect(suggestions.body.length).to.be(10);
- });
+ },
+ })
+ );
+ });
+
+ // this test ensures that the default APM Data View doesn't interfere with suggestions returned in the kuery bar (this has been a problem in the past)
+ it('can get suggestions for `trace.id`', async () => {
+ const suggestions = await getDataViewSuggestions('trace.id');
+ expect(suggestions.body.length).to.be(10);
});
});
- }
- );
+ });
+ });
}
function generateApmData(synthtrace: ApmSynthtraceEsClient) {
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/dependency_metrics.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/dependency_metrics.spec.ts
index 686f6ba313d7e51..7d8dab710d7e0e6 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/dependency_metrics.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/dependency_metrics.spec.ts
@@ -94,180 +94,125 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Dependency metrics when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- before(async () => {
- await generateOperationData({
- synthtraceEsClient,
- start,
- end,
- });
+ registry.when('Dependency metrics when data is loaded', { config: 'basic', archives: [] }, () => {
+ before(async () => {
+ await generateOperationData({
+ synthtraceEsClient,
+ start,
+ end,
});
+ });
- describe('without spanName', () => {
- describe('without a kuery or environment', () => {
- it('returns the correct latency', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'latency',
- });
-
- const searchRate =
- ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_UNKNOWN_RATE;
- const bulkRate = ES_BULK_RATE;
-
- expect(avg(response.body.currentTimeseries)).to.eql(
- roundNumber(
- ((ES_SEARCH_DURATION * searchRate + ES_BULK_DURATION * bulkRate) /
- (searchRate + bulkRate)) *
- 1000
- )
- );
- });
-
- it('returns the correct throughput', async () => {
- const response = await callApi({
- dependencyName: 'redis',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'throughput',
- });
-
- expect(avg(response.body.currentTimeseries)).to.eql(REDIS_SET_RATE);
+ describe('without spanName', () => {
+ describe('without a kuery or environment', () => {
+ it('returns the correct latency', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
+ metric: 'latency',
});
- it('returns the correct failure rate', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'error_rate',
- });
+ const searchRate =
+ ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_UNKNOWN_RATE;
+ const bulkRate = ES_BULK_RATE;
- const expectedErrorRate =
- ES_SEARCH_FAILURE_RATE / (ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE);
+ expect(avg(response.body.currentTimeseries)).to.eql(
+ roundNumber(
+ ((ES_SEARCH_DURATION * searchRate + ES_BULK_DURATION * bulkRate) /
+ (searchRate + bulkRate)) *
+ 1000
+ )
+ );
+ });
- expect(avg(response.body.currentTimeseries)).to.eql(expectedErrorRate);
+ it('returns the correct throughput', async () => {
+ const response = await callApi({
+ dependencyName: 'redis',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
+ metric: 'throughput',
});
+
+ expect(avg(response.body.currentTimeseries)).to.eql(REDIS_SET_RATE);
});
- describe('with a kuery', () => {
- it('returns the correct latency', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'latency',
- kuery: `event.outcome:unknown`,
- });
-
- const searchRate = ES_SEARCH_UNKNOWN_RATE;
- const bulkRate = ES_BULK_RATE;
-
- expect(avg(response.body.currentTimeseries)).to.eql(
- roundNumber(
- ((ES_SEARCH_DURATION * searchRate + ES_BULK_DURATION * bulkRate) /
- (searchRate + bulkRate)) *
- 1000
- )
- );
+ it('returns the correct failure rate', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
+ metric: 'error_rate',
});
- it('returns the correct throughput', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'throughput',
- kuery: `event.outcome:unknown`,
- });
+ const expectedErrorRate =
+ ES_SEARCH_FAILURE_RATE / (ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE);
- const searchRate = ES_SEARCH_UNKNOWN_RATE;
- const bulkRate = ES_BULK_RATE;
+ expect(avg(response.body.currentTimeseries)).to.eql(expectedErrorRate);
+ });
+ });
- expect(avg(response.body.currentTimeseries)).to.eql(roundNumber(searchRate + bulkRate));
+ describe('with a kuery', () => {
+ it('returns the correct latency', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
+ metric: 'latency',
+ kuery: `event.outcome:unknown`,
});
- it('returns the correct failure rate', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'error_rate',
- kuery: 'event.outcome:success',
- });
+ const searchRate = ES_SEARCH_UNKNOWN_RATE;
+ const bulkRate = ES_BULK_RATE;
- expect(avg(response.body.currentTimeseries)).to.eql(0);
- });
+ expect(avg(response.body.currentTimeseries)).to.eql(
+ roundNumber(
+ ((ES_SEARCH_DURATION * searchRate + ES_BULK_DURATION * bulkRate) /
+ (searchRate + bulkRate)) *
+ 1000
+ )
+ );
});
- describe('with an environment', () => {
- it('returns the correct latency', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'latency',
- environment: 'production',
- });
-
- const searchRate = ES_SEARCH_UNKNOWN_RATE;
- const bulkRate = 0;
-
- expect(avg(response.body.currentTimeseries)).to.eql(
- roundNumber(
- ((ES_SEARCH_DURATION * searchRate + ES_BULK_DURATION * bulkRate) /
- (searchRate + bulkRate)) *
- 1000
- )
- );
+ it('returns the correct throughput', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
+ metric: 'throughput',
+ kuery: `event.outcome:unknown`,
});
- it('returns the correct throughput', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'throughput',
- environment: 'production',
- });
+ const searchRate = ES_SEARCH_UNKNOWN_RATE;
+ const bulkRate = ES_BULK_RATE;
- const searchRate =
- ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_UNKNOWN_RATE;
- const bulkRate = 0;
+ expect(avg(response.body.currentTimeseries)).to.eql(roundNumber(searchRate + bulkRate));
+ });
- expect(avg(response.body.currentTimeseries)).to.eql(roundNumber(searchRate + bulkRate));
+ it('returns the correct failure rate', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
+ metric: 'error_rate',
+ kuery: 'event.outcome:success',
});
- it('returns the correct failure rate', async () => {
- const response = await callApi({
- dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: true,
- spanName: '',
- metric: 'error_rate',
- environment: 'development',
- });
-
- expect(avg(response.body.currentTimeseries)).to.eql(null);
- });
+ expect(avg(response.body.currentTimeseries)).to.eql(0);
});
});
- describe('with spanName', () => {
+ describe('with an environment', () => {
it('returns the correct latency', async () => {
const response = await callApi({
dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: false,
- spanName: '/_search',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
metric: 'latency',
+ environment: 'production',
});
- const searchRate =
- ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_UNKNOWN_RATE;
+ const searchRate = ES_SEARCH_UNKNOWN_RATE;
const bulkRate = 0;
expect(avg(response.body.currentTimeseries)).to.eql(
@@ -281,28 +226,78 @@ export default function ApiTest({ getService }: FtrProviderContext) {
it('returns the correct throughput', async () => {
const response = await callApi({
- dependencyName: 'redis',
- searchServiceDestinationMetrics: false,
- spanName: 'SET',
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
metric: 'throughput',
+ environment: 'production',
});
- expect(avg(response.body.currentTimeseries)).to.eql(REDIS_SET_RATE);
+ const searchRate =
+ ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_UNKNOWN_RATE;
+ const bulkRate = 0;
+
+ expect(avg(response.body.currentTimeseries)).to.eql(roundNumber(searchRate + bulkRate));
});
it('returns the correct failure rate', async () => {
const response = await callApi({
dependencyName: 'elasticsearch',
- searchServiceDestinationMetrics: false,
- spanName: '/_bulk',
+ searchServiceDestinationMetrics: true,
+ spanName: '',
metric: 'error_rate',
+ environment: 'development',
});
expect(avg(response.body.currentTimeseries)).to.eql(null);
});
});
+ });
- after(() => synthtraceEsClient.clean());
- }
- );
+ describe('with spanName', () => {
+ it('returns the correct latency', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: false,
+ spanName: '/_search',
+ metric: 'latency',
+ });
+
+ const searchRate = ES_SEARCH_FAILURE_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_UNKNOWN_RATE;
+ const bulkRate = 0;
+
+ expect(avg(response.body.currentTimeseries)).to.eql(
+ roundNumber(
+ ((ES_SEARCH_DURATION * searchRate + ES_BULK_DURATION * bulkRate) /
+ (searchRate + bulkRate)) *
+ 1000
+ )
+ );
+ });
+
+ it('returns the correct throughput', async () => {
+ const response = await callApi({
+ dependencyName: 'redis',
+ searchServiceDestinationMetrics: false,
+ spanName: 'SET',
+ metric: 'throughput',
+ });
+
+ expect(avg(response.body.currentTimeseries)).to.eql(REDIS_SET_RATE);
+ });
+
+ it('returns the correct failure rate', async () => {
+ const response = await callApi({
+ dependencyName: 'elasticsearch',
+ searchServiceDestinationMetrics: false,
+ spanName: '/_bulk',
+ metric: 'error_rate',
+ });
+
+ expect(avg(response.body.currentTimeseries)).to.eql(null);
+ });
+ });
+
+ after(() => synthtraceEsClient.clean());
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts
index 0d7e4f01733e2d1..006a67f3f772477 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/metadata.spec.ts
@@ -44,7 +44,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'Dependency metadata when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
after(() => synthtraceEsClient.clean());
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/service_dependencies.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/service_dependencies.spec.ts
index e5d3b8a43608663..69e61e52ca1a421 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/service_dependencies.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/service_dependencies.spec.ts
@@ -47,33 +47,29 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Dependency for services',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- before(async () => {
- await generateData({ synthtraceEsClient, start, end });
- });
- after(() => synthtraceEsClient.clean());
+ registry.when('Dependency for services', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ before(async () => {
+ await generateData({ synthtraceEsClient, start, end });
+ });
+ after(() => synthtraceEsClient.clean());
- it('returns a list of dependencies for a service', async () => {
- const { status, body } = await callApi();
+ it('returns a list of dependencies for a service', async () => {
+ const { status, body } = await callApi();
- expect(status).to.be(200);
- expect(
- body.serviceDependencies.map(
- ({ location }) => (location as DependencyNode).dependencyName
- )
- ).to.eql([dependencyName]);
+ expect(status).to.be(200);
+ expect(
+ body.serviceDependencies.map(
+ ({ location }) => (location as DependencyNode).dependencyName
+ )
+ ).to.eql([dependencyName]);
- const currentStatsLatencyValues =
- body.serviceDependencies[0].currentStats.latency.timeseries;
- expect(currentStatsLatencyValues.every(({ y }) => y === 1000000)).to.be(true);
- });
+ const currentStatsLatencyValues =
+ body.serviceDependencies[0].currentStats.latency.timeseries;
+ expect(currentStatsLatencyValues.every(({ y }) => y === 1000000)).to.be(true);
});
- }
- );
+ });
+ });
registry.when(
'Dependency for service breakdown when data is not loaded',
@@ -88,31 +84,27 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Dependency for services breakdown',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- before(async () => {
- await generateData({ synthtraceEsClient, start, end });
- });
- after(() => synthtraceEsClient.clean());
+ registry.when('Dependency for services breakdown', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ before(async () => {
+ await generateData({ synthtraceEsClient, start, end });
+ });
+ after(() => synthtraceEsClient.clean());
- it('returns a list of dependencies for a service', async () => {
- const { status, body } = await callApi();
+ it('returns a list of dependencies for a service', async () => {
+ const { status, body } = await callApi();
- expect(status).to.be(200);
- expect(
- body.serviceDependencies.map(
- ({ location }) => (location as DependencyNode).dependencyName
- )
- ).to.eql([dependencyName]);
+ expect(status).to.be(200);
+ expect(
+ body.serviceDependencies.map(
+ ({ location }) => (location as DependencyNode).dependencyName
+ )
+ ).to.eql([dependencyName]);
- const currentStatsLatencyValues =
- body.serviceDependencies[0].currentStats.latency.timeseries;
- expect(currentStatsLatencyValues.every(({ y }) => y === 1000000)).to.be(true);
- });
+ const currentStatsLatencyValues =
+ body.serviceDependencies[0].currentStats.latency.timeseries;
+ expect(currentStatsLatencyValues.every(({ y }) => y === 1000000)).to.be(true);
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts
index 5160ea52b094e64..c0c67d9bb8f1924 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/top_dependencies.spec.ts
@@ -49,94 +49,90 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Top dependencies',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is generated', () => {
- let topDependencies: TopDependencies;
+ registry.when('Top dependencies', { config: 'basic', archives: [] }, () => {
+ describe('when data is generated', () => {
+ let topDependencies: TopDependencies;
+
+ before(async () => {
+ await generateData({ synthtraceEsClient, start, end });
+ const response = await callApi();
+ topDependencies = response.body;
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ it('returns an array of dependencies', () => {
+ expect(topDependencies).to.have.property('dependencies');
+ expect(topDependencies.dependencies).to.have.length(1);
+ });
- before(async () => {
- await generateData({ synthtraceEsClient, start, end });
- const response = await callApi();
- topDependencies = response.body;
+ it('returns correct dependency information', () => {
+ const location = topDependencies.dependencies[0].location as DependencyNode;
+ const { span } = dataConfig;
+
+ expect(location.type).to.be(NodeType.dependency);
+ expect(location.dependencyName).to.be(span.destination);
+ expect(location.spanType).to.be(span.type);
+ expect(location.spanSubtype).to.be(span.subType);
+ expect(location).to.have.property('id');
+ });
+
+ describe('returns the correct stats', () => {
+ let dependencies: TopDependencies['dependencies'][number];
+
+ before(() => {
+ dependencies = topDependencies.dependencies[0];
});
- after(() => synthtraceEsClient.clean());
+ it("doesn't have previous stats", () => {
+ expect(dependencies.previousStats).to.be(null);
+ });
- it('returns an array of dependencies', () => {
- expect(topDependencies).to.have.property('dependencies');
- expect(topDependencies.dependencies).to.have.length(1);
+ it('has an "impact" property', () => {
+ expect(dependencies.currentStats).to.have.property('impact');
});
- it('returns correct dependency information', () => {
- const location = topDependencies.dependencies[0].location as DependencyNode;
- const { span } = dataConfig;
+ it('returns the correct latency', () => {
+ const {
+ currentStats: { latency },
+ } = dependencies;
- expect(location.type).to.be(NodeType.dependency);
- expect(location.dependencyName).to.be(span.destination);
- expect(location.spanType).to.be(span.type);
- expect(location.spanSubtype).to.be(span.subType);
- expect(location).to.have.property('id');
+ const { transaction } = dataConfig;
+
+ expect(latency.value).to.be(transaction.duration * 1000);
+ expect(latency.timeseries.every(({ y }) => y === transaction.duration * 1000)).to.be(
+ true
+ );
+ });
+
+ it('returns the correct throughput', () => {
+ const {
+ currentStats: { throughput },
+ } = dependencies;
+ const { rate } = dataConfig;
+
+ expect(roundNumber(throughput.value)).to.be(roundNumber(rate));
+ });
+
+ it('returns the correct total time', () => {
+ const {
+ currentStats: { totalTime },
+ } = dependencies;
+ const { rate, transaction } = dataConfig;
+
+ expect(
+ totalTime.timeseries.every(({ y }) => y === rate * transaction.duration * 1000)
+ ).to.be(true);
});
- describe('returns the correct stats', () => {
- let dependencies: TopDependencies['dependencies'][number];
-
- before(() => {
- dependencies = topDependencies.dependencies[0];
- });
-
- it("doesn't have previous stats", () => {
- expect(dependencies.previousStats).to.be(null);
- });
-
- it('has an "impact" property', () => {
- expect(dependencies.currentStats).to.have.property('impact');
- });
-
- it('returns the correct latency', () => {
- const {
- currentStats: { latency },
- } = dependencies;
-
- const { transaction } = dataConfig;
-
- expect(latency.value).to.be(transaction.duration * 1000);
- expect(latency.timeseries.every(({ y }) => y === transaction.duration * 1000)).to.be(
- true
- );
- });
-
- it('returns the correct throughput', () => {
- const {
- currentStats: { throughput },
- } = dependencies;
- const { rate } = dataConfig;
-
- expect(roundNumber(throughput.value)).to.be(roundNumber(rate));
- });
-
- it('returns the correct total time', () => {
- const {
- currentStats: { totalTime },
- } = dependencies;
- const { rate, transaction } = dataConfig;
-
- expect(
- totalTime.timeseries.every(({ y }) => y === rate * transaction.duration * 1000)
- ).to.be(true);
- });
-
- it('returns the correct error rate', () => {
- const {
- currentStats: { errorRate },
- } = dependencies;
- expect(errorRate.value).to.be(0);
- expect(errorRate.timeseries.every(({ y }) => y === 0)).to.be(true);
- });
+ it('returns the correct error rate', () => {
+ const {
+ currentStats: { errorRate },
+ } = dependencies;
+ expect(errorRate.value).to.be(0);
+ expect(errorRate.timeseries.every(({ y }) => y === 0)).to.be(true);
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/top_operations.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/top_operations.spec.ts
index 1040bd58417f502..8d8de18eb6e0137 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/top_operations.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/top_operations.spec.ts
@@ -65,154 +65,150 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'Top operations when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- before(() =>
- generateOperationData({
- synthtraceEsClient,
- start,
- end,
- })
- );
-
- after(() => synthtraceEsClient.clean());
-
- describe('requested for elasticsearch', () => {
- let response: TopOperations;
- let searchOperation: ValuesType;
- let bulkOperation: ValuesType;
-
- before(async () => {
- response = await callApi({ dependencyName: 'elasticsearch' });
- searchOperation = response.find((op) => op.spanName === '/_search')!;
- bulkOperation = response.find((op) => op.spanName === '/_bulk')!;
- });
+ registry.when('Top operations when data is generated', { config: 'basic', archives: [] }, () => {
+ before(() =>
+ generateOperationData({
+ synthtraceEsClient,
+ start,
+ end,
+ })
+ );
- it('returns the correct operations', () => {
- expect(response.length).to.eql(2);
+ after(() => synthtraceEsClient.clean());
- expect(searchOperation).to.be.ok();
- expect(bulkOperation).to.be.ok();
- });
+ describe('requested for elasticsearch', () => {
+ let response: TopOperations;
+ let searchOperation: ValuesType;
+ let bulkOperation: ValuesType;
- it('returns the correct latency', () => {
- expect(searchOperation.latency).to.eql(ES_SEARCH_DURATION * 1000);
- expect(bulkOperation.latency).to.eql(ES_BULK_DURATION * 1000);
- });
+ before(async () => {
+ response = await callApi({ dependencyName: 'elasticsearch' });
+ searchOperation = response.find((op) => op.spanName === '/_search')!;
+ bulkOperation = response.find((op) => op.spanName === '/_bulk')!;
+ });
- it('returns the correct throughput', () => {
- const expectedSearchThroughput = roundNumber(
- ES_SEARCH_UNKNOWN_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_FAILURE_RATE
- );
- const expectedBulkThroughput = ES_BULK_RATE;
+ it('returns the correct operations', () => {
+ expect(response.length).to.eql(2);
- expect(roundNumber(searchOperation.throughput)).to.eql(expectedSearchThroughput);
- expect(roundNumber(bulkOperation.throughput)).to.eql(expectedBulkThroughput);
+ expect(searchOperation).to.be.ok();
+ expect(bulkOperation).to.be.ok();
+ });
- expect(
- searchOperation.timeseries.throughput
- .map((bucket) => bucket.y)
- .every((val) => val === expectedSearchThroughput)
- );
- });
+ it('returns the correct latency', () => {
+ expect(searchOperation.latency).to.eql(ES_SEARCH_DURATION * 1000);
+ expect(bulkOperation.latency).to.eql(ES_BULK_DURATION * 1000);
+ });
- it('returns the correct failure rate', () => {
- const expectedSearchFailureRate =
- ES_SEARCH_FAILURE_RATE / (ES_SEARCH_SUCCESS_RATE + ES_SEARCH_FAILURE_RATE);
- const expectedBulkFailureRate = null;
+ it('returns the correct throughput', () => {
+ const expectedSearchThroughput = roundNumber(
+ ES_SEARCH_UNKNOWN_RATE + ES_SEARCH_SUCCESS_RATE + ES_SEARCH_FAILURE_RATE
+ );
+ const expectedBulkThroughput = ES_BULK_RATE;
- expect(searchOperation.failureRate).to.be(expectedSearchFailureRate);
+ expect(roundNumber(searchOperation.throughput)).to.eql(expectedSearchThroughput);
+ expect(roundNumber(bulkOperation.throughput)).to.eql(expectedBulkThroughput);
- expect(bulkOperation.failureRate).to.be(expectedBulkFailureRate);
+ expect(
+ searchOperation.timeseries.throughput
+ .map((bucket) => bucket.y)
+ .every((val) => val === expectedSearchThroughput)
+ );
+ });
- expect(
- searchOperation.timeseries.failureRate
- .map((bucket) => bucket.y)
- .every((val) => val === expectedSearchFailureRate)
- );
+ it('returns the correct failure rate', () => {
+ const expectedSearchFailureRate =
+ ES_SEARCH_FAILURE_RATE / (ES_SEARCH_SUCCESS_RATE + ES_SEARCH_FAILURE_RATE);
+ const expectedBulkFailureRate = null;
- expect(
- bulkOperation.timeseries.failureRate
- .map((bucket) => bucket.y)
- .every((val) => val === expectedBulkFailureRate)
- );
- });
+ expect(searchOperation.failureRate).to.be(expectedSearchFailureRate);
- it('returns the correct impact', () => {
- expect(searchOperation.impact).to.eql(0);
- expect(bulkOperation.impact).to.eql(100);
- });
+ expect(bulkOperation.failureRate).to.be(expectedBulkFailureRate);
+
+ expect(
+ searchOperation.timeseries.failureRate
+ .map((bucket) => bucket.y)
+ .every((val) => val === expectedSearchFailureRate)
+ );
+
+ expect(
+ bulkOperation.timeseries.failureRate
+ .map((bucket) => bucket.y)
+ .every((val) => val === expectedBulkFailureRate)
+ );
});
- describe('requested for redis', () => {
- let response: TopOperations;
- let setOperation: ValuesType;
+ it('returns the correct impact', () => {
+ expect(searchOperation.impact).to.eql(0);
+ expect(bulkOperation.impact).to.eql(100);
+ });
+ });
- before(async () => {
- response = await callApi({ dependencyName: 'redis' });
- setOperation = response.find((op) => op.spanName === 'SET')!;
- });
+ describe('requested for redis', () => {
+ let response: TopOperations;
+ let setOperation: ValuesType;
- it('returns the correct operations', () => {
- expect(response.length).to.eql(1);
+ before(async () => {
+ response = await callApi({ dependencyName: 'redis' });
+ setOperation = response.find((op) => op.spanName === 'SET')!;
+ });
- expect(setOperation).to.be.ok();
- });
+ it('returns the correct operations', () => {
+ expect(response.length).to.eql(1);
- it('returns the correct latency', () => {
- expect(setOperation.latency).to.eql(REDIS_SET_DURATION * 1000);
- });
+ expect(setOperation).to.be.ok();
+ });
- it('returns the correct throughput', () => {
- expect(roundNumber(setOperation.throughput)).to.eql(roundNumber(REDIS_SET_RATE));
- });
+ it('returns the correct latency', () => {
+ expect(setOperation.latency).to.eql(REDIS_SET_DURATION * 1000);
});
- describe('requested for a specific service', () => {
- let response: TopOperations;
- let searchOperation: ValuesType;
- let bulkOperation: ValuesType | undefined;
-
- before(async () => {
- response = await callApi({
- dependencyName: 'elasticsearch',
- kuery: `service.name:"synth-go"`,
- });
- searchOperation = response.find((op) => op.spanName === '/_search')!;
- bulkOperation = response.find((op) => op.spanName === '/_bulk');
- });
+ it('returns the correct throughput', () => {
+ expect(roundNumber(setOperation.throughput)).to.eql(roundNumber(REDIS_SET_RATE));
+ });
+ });
- it('returns the correct operations', () => {
- expect(response.length).to.eql(1);
+ describe('requested for a specific service', () => {
+ let response: TopOperations;
+ let searchOperation: ValuesType;
+ let bulkOperation: ValuesType | undefined;
- expect(searchOperation).to.be.ok();
- expect(bulkOperation).not.to.be.ok();
+ before(async () => {
+ response = await callApi({
+ dependencyName: 'elasticsearch',
+ kuery: `service.name:"synth-go"`,
});
+ searchOperation = response.find((op) => op.spanName === '/_search')!;
+ bulkOperation = response.find((op) => op.spanName === '/_bulk');
});
- describe('requested for a specific environment', () => {
- let response: TopOperations;
- let searchOperation: ValuesType | undefined;
- let bulkOperation: ValuesType;
-
- before(async () => {
- response = await callApi({
- dependencyName: 'elasticsearch',
- environment: 'development',
- });
- searchOperation = response.find((op) => op.spanName === '/_search');
- bulkOperation = response.find((op) => op.spanName === '/_bulk')!;
- });
+ it('returns the correct operations', () => {
+ expect(response.length).to.eql(1);
- it('returns the correct operations', () => {
- expect(response.length).to.eql(1);
+ expect(searchOperation).to.be.ok();
+ expect(bulkOperation).not.to.be.ok();
+ });
+ });
- expect(searchOperation).not.to.be.ok();
- expect(bulkOperation).to.be.ok();
+ describe('requested for a specific environment', () => {
+ let response: TopOperations;
+ let searchOperation: ValuesType | undefined;
+ let bulkOperation: ValuesType;
+
+ before(async () => {
+ response = await callApi({
+ dependencyName: 'elasticsearch',
+ environment: 'development',
});
+ searchOperation = response.find((op) => op.spanName === '/_search');
+ bulkOperation = response.find((op) => op.spanName === '/_bulk')!;
+ });
+
+ it('returns the correct operations', () => {
+ expect(response.length).to.eql(1);
+
+ expect(searchOperation).not.to.be.ok();
+ expect(bulkOperation).to.be.ok();
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/top_spans.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/top_spans.spec.ts
index 97d9846e06f57ca..06890c0b6fd592a 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/top_spans.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/top_spans.spec.ts
@@ -68,7 +68,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'Top dependency spans when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
const javaInstance = apm.service('java', 'production', 'java').instance('instance-a');
diff --git a/x-pack/test/apm_api_integration/tests/dependencies/upstream_services.spec.ts b/x-pack/test/apm_api_integration/tests/dependencies/upstream_services.spec.ts
index 2d3a51054541bd6..b2ff45685de2e5d 100644
--- a/x-pack/test/apm_api_integration/tests/dependencies/upstream_services.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/dependencies/upstream_services.spec.ts
@@ -47,28 +47,24 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Dependency upstream services',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- before(async () => {
- await generateData({ synthtraceEsClient, start, end });
- });
- after(() => synthtraceEsClient.clean());
+ registry.when('Dependency upstream services', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ before(async () => {
+ await generateData({ synthtraceEsClient, start, end });
+ });
+ after(() => synthtraceEsClient.clean());
- it('returns a list of upstream services for the dependency', async () => {
- const { status, body } = await callApi();
+ it('returns a list of upstream services for the dependency', async () => {
+ const { status, body } = await callApi();
- expect(status).to.be(200);
- expect(body.services.map(({ location }) => (location as ServiceNode).serviceName)).to.eql(
- ['synth-go']
- );
+ expect(status).to.be(200);
+ expect(body.services.map(({ location }) => (location as ServiceNode).serviceName)).to.eql([
+ 'synth-go',
+ ]);
- const currentStatsLatencyValues = body.services[0].currentStats.latency.timeseries;
- expect(currentStatsLatencyValues.every(({ y }) => y === 1000000)).to.be(true);
- });
+ const currentStatsLatencyValues = body.services[0].currentStats.latency.timeseries;
+ expect(currentStatsLatencyValues.every(({ y }) => y === 1000000)).to.be(true);
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts
index 23cc77320b0ebc0..fe2f9c8cd2cf808 100644
--- a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts
@@ -114,7 +114,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let errorRateMetricValues: Awaited>;
let errorTransactionValues: Awaited>;
- registry.when('Services APIs', { config: 'basic', archives: ['apm_mappings_only_8.0.0'] }, () => {
+ registry.when('Services APIs', { config: 'basic', archives: [] }, () => {
describe('when data is loaded ', () => {
const GO_PROD_LIST_RATE = 75;
const GO_PROD_LIST_ERROR_RATE = 25;
diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts b/x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts
index 5374ddefc946e42..8c14a203f78007e 100644
--- a/x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts
@@ -60,87 +60,83 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let errorRateMetricValues: Awaited>;
let errorTransactionValues: Awaited>;
- registry.when(
- 'Service maps APIs',
- { config: 'trial', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded ', () => {
- const GO_PROD_LIST_RATE = 75;
- const GO_PROD_LIST_ERROR_RATE = 25;
- const GO_PROD_ID_RATE = 50;
- const GO_PROD_ID_ERROR_RATE = 50;
- before(async () => {
- const serviceGoProdInstance = apm
- .service(serviceName, 'production', 'go')
- .instance('instance-a');
+ registry.when('Service maps APIs', { config: 'trial', archives: [] }, () => {
+ describe('when data is loaded ', () => {
+ const GO_PROD_LIST_RATE = 75;
+ const GO_PROD_LIST_ERROR_RATE = 25;
+ const GO_PROD_ID_RATE = 50;
+ const GO_PROD_ID_ERROR_RATE = 50;
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service(serviceName, 'production', 'go')
+ .instance('instance-a');
- const transactionNameProductList = 'GET /api/product/list';
- const transactionNameProductId = 'GET /api/product/:id';
+ const transactionNameProductList = 'GET /api/product/list';
+ const transactionNameProductId = 'GET /api/product/:id';
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_LIST_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction(transactionNameProductList, 'Worker')
- .timestamp(timestamp)
- .duration(1000)
- .success()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_LIST_ERROR_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction(transactionNameProductList, 'Worker')
- .duration(1000)
- .timestamp(timestamp)
- .failure()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_ID_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction(transactionNameProductId)
- .timestamp(timestamp)
- .duration(1000)
- .success()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_ID_ERROR_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction(transactionNameProductId)
- .duration(1000)
- .timestamp(timestamp)
- .failure()
- ),
- ]);
- });
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_LIST_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction(transactionNameProductList, 'Worker')
+ .timestamp(timestamp)
+ .duration(1000)
+ .success()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_LIST_ERROR_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction(transactionNameProductList, 'Worker')
+ .duration(1000)
+ .timestamp(timestamp)
+ .failure()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_ID_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction(transactionNameProductId)
+ .timestamp(timestamp)
+ .duration(1000)
+ .success()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_ID_ERROR_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction(transactionNameProductId)
+ .duration(1000)
+ .timestamp(timestamp)
+ .failure()
+ ),
+ ]);
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('compare latency value between service inventory and service maps', () => {
- before(async () => {
- [errorTransactionValues, errorRateMetricValues] = await Promise.all([
- getErrorRateValues('transaction'),
- getErrorRateValues('metric'),
- ]);
- });
+ describe('compare latency value between service inventory and service maps', () => {
+ before(async () => {
+ [errorTransactionValues, errorRateMetricValues] = await Promise.all([
+ getErrorRateValues('transaction'),
+ getErrorRateValues('metric'),
+ ]);
+ });
- it('returns same avg error rate value for Transaction-based and Metric-based data', () => {
- [
- errorTransactionValues.serviceInventoryErrorRate,
- errorTransactionValues.serviceMapsNodeDetailsErrorRate,
- errorRateMetricValues.serviceInventoryErrorRate,
- errorRateMetricValues.serviceMapsNodeDetailsErrorRate,
- ].forEach((value) => expect(value).to.be.equal(GO_PROD_ID_ERROR_RATE / 100));
- });
+ it('returns same avg error rate value for Transaction-based and Metric-based data', () => {
+ [
+ errorTransactionValues.serviceInventoryErrorRate,
+ errorTransactionValues.serviceMapsNodeDetailsErrorRate,
+ errorRateMetricValues.serviceInventoryErrorRate,
+ errorRateMetricValues.serviceMapsNodeDetailsErrorRate,
+ ].forEach((value) => expect(value).to.be.equal(GO_PROD_ID_ERROR_RATE / 100));
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts b/x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts
index 4cd338441eefa5c..6d57addcc7bb7e5 100644
--- a/x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/errors/distribution.spec.ts
@@ -60,128 +60,124 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('errors distribution', () => {
- const { appleTransaction, bananaTransaction } = config;
+ registry.when('when data is loaded', { config: 'basic', archives: [] }, () => {
+ describe('errors distribution', () => {
+ const { appleTransaction, bananaTransaction } = config;
+ before(async () => {
+ await generateData({ serviceName, start, end, synthtraceEsClient });
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('without comparison', () => {
+ let errorsDistribution: ErrorsDistribution;
before(async () => {
- await generateData({ serviceName, start, end, synthtraceEsClient });
+ const response = await callApi();
+ errorsDistribution = response.body;
});
- after(() => synthtraceEsClient.clean());
-
- describe('without comparison', () => {
- let errorsDistribution: ErrorsDistribution;
- before(async () => {
- const response = await callApi();
- errorsDistribution = response.body;
- });
+ it('displays combined number of occurrences', () => {
+ const countSum = sumBy(errorsDistribution.currentPeriod, 'y');
+ const numberOfBuckets = 15;
+ expect(countSum).to.equal(
+ (appleTransaction.failureRate + bananaTransaction.failureRate) * numberOfBuckets
+ );
+ });
+ });
- it('displays combined number of occurrences', () => {
- const countSum = sumBy(errorsDistribution.currentPeriod, 'y');
- const numberOfBuckets = 15;
- expect(countSum).to.equal(
- (appleTransaction.failureRate + bananaTransaction.failureRate) * numberOfBuckets
- );
+ describe('displays occurrences for type "apple transaction" only', () => {
+ let errorsDistribution: ErrorsDistribution;
+ before(async () => {
+ const response = await callApi({
+ query: { kuery: `error.exception.type:"${appleTransaction.name}"` },
});
+ errorsDistribution = response.body;
});
+ it('displays combined number of occurrences', () => {
+ const countSum = sumBy(errorsDistribution.currentPeriod, 'y');
+ const numberOfBuckets = 15;
+ expect(countSum).to.equal(appleTransaction.failureRate * numberOfBuckets);
+ });
+ });
- describe('displays occurrences for type "apple transaction" only', () => {
+ describe('with comparison', () => {
+ describe('when data is returned', () => {
let errorsDistribution: ErrorsDistribution;
before(async () => {
+ const fiveMinutes = 5 * 60 * 1000;
const response = await callApi({
- query: { kuery: `error.exception.type:"${appleTransaction.name}"` },
+ query: {
+ start: new Date(end - fiveMinutes).toISOString(),
+ end: new Date(end).toISOString(),
+ offset: '5m',
+ },
});
errorsDistribution = response.body;
});
- it('displays combined number of occurrences', () => {
- const countSum = sumBy(errorsDistribution.currentPeriod, 'y');
- const numberOfBuckets = 15;
- expect(countSum).to.equal(appleTransaction.failureRate * numberOfBuckets);
- });
- });
-
- describe('with comparison', () => {
- describe('when data is returned', () => {
- let errorsDistribution: ErrorsDistribution;
- before(async () => {
- const fiveMinutes = 5 * 60 * 1000;
- const response = await callApi({
- query: {
- start: new Date(end - fiveMinutes).toISOString(),
- end: new Date(end).toISOString(),
- offset: '5m',
- },
- });
- errorsDistribution = response.body;
- });
- it('returns some data', () => {
- const hasCurrentPeriodData = errorsDistribution.currentPeriod.some(({ y }) =>
- isFiniteNumber(y)
- );
+ it('returns some data', () => {
+ const hasCurrentPeriodData = errorsDistribution.currentPeriod.some(({ y }) =>
+ isFiniteNumber(y)
+ );
- const hasPreviousPeriodData = errorsDistribution.previousPeriod.some(({ y }) =>
- isFiniteNumber(y)
- );
+ const hasPreviousPeriodData = errorsDistribution.previousPeriod.some(({ y }) =>
+ isFiniteNumber(y)
+ );
- expect(hasCurrentPeriodData).to.equal(true);
- expect(hasPreviousPeriodData).to.equal(true);
- });
+ expect(hasCurrentPeriodData).to.equal(true);
+ expect(hasPreviousPeriodData).to.equal(true);
+ });
- it('has same start time for both periods', () => {
- expect(first(errorsDistribution.currentPeriod)?.x).to.equal(
- first(errorsDistribution.previousPeriod)?.x
- );
- });
+ it('has same start time for both periods', () => {
+ expect(first(errorsDistribution.currentPeriod)?.x).to.equal(
+ first(errorsDistribution.previousPeriod)?.x
+ );
+ });
- it('has same end time for both periods', () => {
- expect(last(errorsDistribution.currentPeriod)?.x).to.equal(
- last(errorsDistribution.previousPeriod)?.x
- );
- });
+ it('has same end time for both periods', () => {
+ expect(last(errorsDistribution.currentPeriod)?.x).to.equal(
+ last(errorsDistribution.previousPeriod)?.x
+ );
+ });
- it('returns same number of buckets for both periods', () => {
- expect(errorsDistribution.currentPeriod.length).to.equal(
- errorsDistribution.previousPeriod.length
- );
- });
+ it('returns same number of buckets for both periods', () => {
+ expect(errorsDistribution.currentPeriod.length).to.equal(
+ errorsDistribution.previousPeriod.length
+ );
});
+ });
- describe('when no data is returned', () => {
- let errorsDistribution: ErrorsDistribution;
- before(async () => {
- const response = await callApi({
- query: {
- start: '2021-01-03T00:00:00.000Z',
- end: '2021-01-03T00:15:00.000Z',
- offset: '1d',
- },
- });
- errorsDistribution = response.body;
+ describe('when no data is returned', () => {
+ let errorsDistribution: ErrorsDistribution;
+ before(async () => {
+ const response = await callApi({
+ query: {
+ start: '2021-01-03T00:00:00.000Z',
+ end: '2021-01-03T00:15:00.000Z',
+ offset: '1d',
+ },
});
+ errorsDistribution = response.body;
+ });
- it('has same start time for both periods', () => {
- expect(first(errorsDistribution.currentPeriod)?.x).to.equal(
- first(errorsDistribution.previousPeriod)?.x
- );
- });
+ it('has same start time for both periods', () => {
+ expect(first(errorsDistribution.currentPeriod)?.x).to.equal(
+ first(errorsDistribution.previousPeriod)?.x
+ );
+ });
- it('has same end time for both periods', () => {
- expect(last(errorsDistribution.currentPeriod)?.x).to.equal(
- last(errorsDistribution.previousPeriod)?.x
- );
- });
+ it('has same end time for both periods', () => {
+ expect(last(errorsDistribution.currentPeriod)?.x).to.equal(
+ last(errorsDistribution.previousPeriod)?.x
+ );
+ });
- it('returns same number of buckets for both periods', () => {
- expect(errorsDistribution.currentPeriod.length).to.equal(
- errorsDistribution.previousPeriod.length
- );
- });
+ it('returns same number of buckets for both periods', () => {
+ expect(errorsDistribution.currentPeriod.length).to.equal(
+ errorsDistribution.previousPeriod.length
+ );
});
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts b/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts
index db630ba71cd1815..5156ed7f0547862 100644
--- a/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts
@@ -53,97 +53,91 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('errors group', () => {
- const appleTransaction = {
- name: 'GET /apple 🍎 ',
- successRate: 75,
- failureRate: 25,
- };
+ registry.when('when data is loaded', { config: 'basic', archives: [] }, () => {
+ describe('errors group', () => {
+ const appleTransaction = {
+ name: 'GET /apple 🍎 ',
+ successRate: 75,
+ failureRate: 25,
+ };
- const bananaTransaction = {
- name: 'GET /banana 🍌',
- successRate: 50,
- failureRate: 50,
- };
+ const bananaTransaction = {
+ name: 'GET /banana 🍌',
+ successRate: 50,
+ failureRate: 50,
+ };
- before(async () => {
- const serviceInstance = apm
- .service(serviceName, 'production', 'go')
- .instance('instance-a');
+ before(async () => {
+ const serviceInstance = apm.service(serviceName, 'production', 'go').instance('instance-a');
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(appleTransaction.successRate)
- .generator((timestamp) =>
- serviceInstance
- .transaction(appleTransaction.name)
- .timestamp(timestamp)
- .duration(1000)
- .success()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(appleTransaction.failureRate)
- .generator((timestamp) =>
- serviceInstance
- .transaction(appleTransaction.name)
- .errors(serviceInstance.error('error 1', 'foo').timestamp(timestamp))
- .duration(1000)
- .timestamp(timestamp)
- .failure()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(bananaTransaction.successRate)
- .generator((timestamp) =>
- serviceInstance
- .transaction(bananaTransaction.name)
- .timestamp(timestamp)
- .duration(1000)
- .success()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(bananaTransaction.failureRate)
- .generator((timestamp) =>
- serviceInstance
- .transaction(bananaTransaction.name)
- .errors(serviceInstance.error('error 2', 'bar').timestamp(timestamp))
- .duration(1000)
- .timestamp(timestamp)
- .failure()
- ),
- ]);
- });
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(appleTransaction.successRate)
+ .generator((timestamp) =>
+ serviceInstance
+ .transaction(appleTransaction.name)
+ .timestamp(timestamp)
+ .duration(1000)
+ .success()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(appleTransaction.failureRate)
+ .generator((timestamp) =>
+ serviceInstance
+ .transaction(appleTransaction.name)
+ .errors(serviceInstance.error('error 1', 'foo').timestamp(timestamp))
+ .duration(1000)
+ .timestamp(timestamp)
+ .failure()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(bananaTransaction.successRate)
+ .generator((timestamp) =>
+ serviceInstance
+ .transaction(bananaTransaction.name)
+ .timestamp(timestamp)
+ .duration(1000)
+ .success()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(bananaTransaction.failureRate)
+ .generator((timestamp) =>
+ serviceInstance
+ .transaction(bananaTransaction.name)
+ .errors(serviceInstance.error('error 2', 'bar').timestamp(timestamp))
+ .duration(1000)
+ .timestamp(timestamp)
+ .failure()
+ ),
+ ]);
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('returns the correct data', () => {
- let errorGroups: ErrorGroups;
- before(async () => {
- const response = await callApi();
- errorGroups = response.body.errorGroups;
- });
+ describe('returns the correct data', () => {
+ let errorGroups: ErrorGroups;
+ before(async () => {
+ const response = await callApi();
+ errorGroups = response.body.errorGroups;
+ });
- it('returns correct number of errors', () => {
- expect(errorGroups.length).to.equal(2);
- expect(errorGroups.map((error) => error.name).sort()).to.eql(['error 1', 'error 2']);
- });
+ it('returns correct number of errors', () => {
+ expect(errorGroups.length).to.equal(2);
+ expect(errorGroups.map((error) => error.name).sort()).to.eql(['error 1', 'error 2']);
+ });
- it('returns correct occurences', () => {
- const numberOfBuckets = 15;
- expect(errorGroups.map((error) => error.occurrences).sort()).to.eql([
- appleTransaction.failureRate * numberOfBuckets,
- bananaTransaction.failureRate * numberOfBuckets,
- ]);
- });
+ it('returns correct occurences', () => {
+ const numberOfBuckets = 15;
+ expect(errorGroups.map((error) => error.occurrences).sort()).to.eql([
+ appleTransaction.failureRate * numberOfBuckets,
+ bananaTransaction.failureRate * numberOfBuckets,
+ ]);
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts b/x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts
index af9a3d01f08a787..93965744c4ff35f 100644
--- a/x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/errors/group_id.spec.ts
@@ -58,35 +58,31 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- const { bananaTransaction } = config;
- describe('error group id', () => {
- before(async () => {
- await generateData({ serviceName, start, end, synthtraceEsClient });
- });
+ registry.when('when data is loaded', { config: 'basic', archives: [] }, () => {
+ const { bananaTransaction } = config;
+ describe('error group id', () => {
+ before(async () => {
+ await generateData({ serviceName, start, end, synthtraceEsClient });
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('return correct data', () => {
- let errorsDistribution: ErrorsDistribution;
- before(async () => {
- const response = await callApi({
- path: { groupId: '0000000000000000000000000Error 1' },
- });
- errorsDistribution = response.body;
+ describe('return correct data', () => {
+ let errorsDistribution: ErrorsDistribution;
+ before(async () => {
+ const response = await callApi({
+ path: { groupId: '0000000000000000000000000Error 1' },
});
+ errorsDistribution = response.body;
+ });
- it('displays correct number of occurrences', () => {
- const numberOfBuckets = 15;
- expect(errorsDistribution.occurrencesCount).to.equal(
- bananaTransaction.failureRate * numberOfBuckets
- );
- });
+ it('displays correct number of occurrences', () => {
+ const numberOfBuckets = 15;
+ expect(errorsDistribution.occurrencesCount).to.equal(
+ bananaTransaction.failureRate * numberOfBuckets
+ );
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/errors/top_erroneous_transactions/top_erroneous_transactions.spec.ts b/x-pack/test/apm_api_integration/tests/errors/top_erroneous_transactions/top_erroneous_transactions.spec.ts
index 8e8078e00ab7a6f..cd01ca49afcc553 100644
--- a/x-pack/test/apm_api_integration/tests/errors/top_erroneous_transactions/top_erroneous_transactions.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/errors/top_erroneous_transactions/top_erroneous_transactions.spec.ts
@@ -63,149 +63,141 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- const {
- firstTransaction: { name: firstTransactionName, failureRate: firstTransactionFailureRate },
- secondTransaction: {
- name: secondTransactionName,
- failureRate: secondTransactionFailureRate,
- },
- } = config;
+ registry.when('when data is loaded', { config: 'basic', archives: [] }, () => {
+ const {
+ firstTransaction: { name: firstTransactionName, failureRate: firstTransactionFailureRate },
+ secondTransaction: { name: secondTransactionName, failureRate: secondTransactionFailureRate },
+ } = config;
+
+ describe('returns the correct data', () => {
+ before(async () => {
+ await generateData({ serviceName, start, end, synthtraceEsClient });
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('without comparison', () => {
+ const numberOfBuckets = 15;
+ let erroneousTransactions: ErroneousTransactions;
- describe('returns the correct data', () => {
before(async () => {
- await generateData({ serviceName, start, end, synthtraceEsClient });
+ const response = await callApi({
+ path: { groupId: '0000000000000000000000Error test' },
+ });
+ erroneousTransactions = response.body;
});
- after(() => synthtraceEsClient.clean());
+ it('displays the correct number of occurrences', () => {
+ const { topErroneousTransactions } = erroneousTransactions;
+ expect(topErroneousTransactions.length).to.be(2);
+
+ const firstTransaction = topErroneousTransactions.find(
+ (x) => x.transactionName === firstTransactionName
+ );
+ expect(firstTransaction).to.not.be(undefined);
+ expect(firstTransaction?.occurrences).to.be(
+ firstTransactionFailureRate * numberOfBuckets
+ );
+
+ const secondTransaction = topErroneousTransactions.find(
+ (x) => x.transactionName === secondTransactionName
+ );
+ expect(secondTransaction).to.not.be(undefined);
+ expect(secondTransaction?.occurrences).to.be(
+ secondTransactionFailureRate * numberOfBuckets
+ );
+ });
+
+ it('displays the correct number of occurrences in time series', () => {
+ const { topErroneousTransactions } = erroneousTransactions;
+
+ const firstTransaction = topErroneousTransactions.find(
+ (x) => x.transactionName === firstTransactionName
+ );
+ const firstErrorCount = sumBy(firstTransaction?.currentPeriodTimeseries, 'y');
+ expect(firstErrorCount).to.be(firstTransactionFailureRate * numberOfBuckets);
+
+ const secondTransaction = topErroneousTransactions.find(
+ (x) => x.transactionName === secondTransactionName
+ );
+ const secondErrorCount = sumBy(secondTransaction?.currentPeriodTimeseries, 'y');
+ expect(secondErrorCount).to.be(secondTransactionFailureRate * numberOfBuckets);
+ });
+ });
- describe('without comparison', () => {
- const numberOfBuckets = 15;
+ describe('with comparison', () => {
+ describe('when there are data for the time periods', () => {
let erroneousTransactions: ErroneousTransactions;
before(async () => {
+ const fiveMinutes = 5 * 60 * 1000;
const response = await callApi({
path: { groupId: '0000000000000000000000Error test' },
+ query: {
+ start: new Date(end - fiveMinutes).toISOString(),
+ end: new Date(end).toISOString(),
+ offset: '5m',
+ },
});
erroneousTransactions = response.body;
});
- it('displays the correct number of occurrences', () => {
+ it('returns some data', () => {
const { topErroneousTransactions } = erroneousTransactions;
- expect(topErroneousTransactions.length).to.be(2);
- const firstTransaction = topErroneousTransactions.find(
- (x) => x.transactionName === firstTransactionName
- );
- expect(firstTransaction).to.not.be(undefined);
- expect(firstTransaction?.occurrences).to.be(
- firstTransactionFailureRate * numberOfBuckets
+ const hasCurrentPeriodData = topErroneousTransactions[0].currentPeriodTimeseries.some(
+ ({ y }) => isFiniteNumber(y)
);
- const secondTransaction = topErroneousTransactions.find(
- (x) => x.transactionName === secondTransactionName
- );
- expect(secondTransaction).to.not.be(undefined);
- expect(secondTransaction?.occurrences).to.be(
- secondTransactionFailureRate * numberOfBuckets
+ const hasPreviousPeriodData = topErroneousTransactions[0].previousPeriodTimeseries.some(
+ ({ y }) => isFiniteNumber(y)
);
+
+ expect(hasCurrentPeriodData).to.be(true);
+ expect(hasPreviousPeriodData).to.be(true);
});
- it('displays the correct number of occurrences in time series', () => {
+ it('has the same start time for both periods', () => {
const { topErroneousTransactions } = erroneousTransactions;
+ expect(first(topErroneousTransactions[0].currentPeriodTimeseries)?.x).to.be(
+ first(topErroneousTransactions[0].previousPeriodTimeseries)?.x
+ );
+ });
- const firstTransaction = topErroneousTransactions.find(
- (x) => x.transactionName === firstTransactionName
+ it('has same end time for both periods', () => {
+ const { topErroneousTransactions } = erroneousTransactions;
+ expect(last(topErroneousTransactions[0].currentPeriodTimeseries)?.x).to.be(
+ last(topErroneousTransactions[0].previousPeriodTimeseries)?.x
);
- const firstErrorCount = sumBy(firstTransaction?.currentPeriodTimeseries, 'y');
- expect(firstErrorCount).to.be(firstTransactionFailureRate * numberOfBuckets);
+ });
- const secondTransaction = topErroneousTransactions.find(
- (x) => x.transactionName === secondTransactionName
+ it('returns same number of buckets for both periods', () => {
+ const { topErroneousTransactions } = erroneousTransactions;
+ expect(topErroneousTransactions[0].currentPeriodTimeseries.length).to.be(
+ topErroneousTransactions[0].previousPeriodTimeseries.length
);
- const secondErrorCount = sumBy(secondTransaction?.currentPeriodTimeseries, 'y');
- expect(secondErrorCount).to.be(secondTransactionFailureRate * numberOfBuckets);
});
});
- describe('with comparison', () => {
- describe('when there are data for the time periods', () => {
- let erroneousTransactions: ErroneousTransactions;
-
- before(async () => {
- const fiveMinutes = 5 * 60 * 1000;
- const response = await callApi({
- path: { groupId: '0000000000000000000000Error test' },
- query: {
- start: new Date(end - fiveMinutes).toISOString(),
- end: new Date(end).toISOString(),
- offset: '5m',
- },
- });
- erroneousTransactions = response.body;
- });
-
- it('returns some data', () => {
- const { topErroneousTransactions } = erroneousTransactions;
-
- const hasCurrentPeriodData = topErroneousTransactions[0].currentPeriodTimeseries.some(
- ({ y }) => isFiniteNumber(y)
- );
-
- const hasPreviousPeriodData =
- topErroneousTransactions[0].previousPeriodTimeseries.some(({ y }) =>
- isFiniteNumber(y)
- );
-
- expect(hasCurrentPeriodData).to.be(true);
- expect(hasPreviousPeriodData).to.be(true);
- });
-
- it('has the same start time for both periods', () => {
- const { topErroneousTransactions } = erroneousTransactions;
- expect(first(topErroneousTransactions[0].currentPeriodTimeseries)?.x).to.be(
- first(topErroneousTransactions[0].previousPeriodTimeseries)?.x
- );
- });
-
- it('has same end time for both periods', () => {
- const { topErroneousTransactions } = erroneousTransactions;
- expect(last(topErroneousTransactions[0].currentPeriodTimeseries)?.x).to.be(
- last(topErroneousTransactions[0].previousPeriodTimeseries)?.x
- );
+ describe('when there are no data for the time period', () => {
+ it('returns an empty array', async () => {
+ const response = await callApi({
+ path: { groupId: '0000000000000000000000Error test' },
+ query: {
+ start: '2021-01-03T00:00:00.000Z',
+ end: '2021-01-03T00:15:00.000Z',
+ offset: '1d',
+ },
});
- it('returns same number of buckets for both periods', () => {
- const { topErroneousTransactions } = erroneousTransactions;
- expect(topErroneousTransactions[0].currentPeriodTimeseries.length).to.be(
- topErroneousTransactions[0].previousPeriodTimeseries.length
- );
- });
- });
+ const {
+ body: { topErroneousTransactions },
+ } = response;
- describe('when there are no data for the time period', () => {
- it('returns an empty array', async () => {
- const response = await callApi({
- path: { groupId: '0000000000000000000000Error test' },
- query: {
- start: '2021-01-03T00:00:00.000Z',
- end: '2021-01-03T00:15:00.000Z',
- offset: '1d',
- },
- });
-
- const {
- body: { topErroneousTransactions },
- } = response;
-
- expect(topErroneousTransactions).to.be.empty();
- });
+ expect(topErroneousTransactions).to.be.empty();
});
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/errors/top_errors_for_transaction/top_errors_main_stats.spec.ts b/x-pack/test/apm_api_integration/tests/errors/top_errors_for_transaction/top_errors_main_stats.spec.ts
index 75d3ba0624375f8..830e5032a8de7f0 100644
--- a/x-pack/test/apm_api_integration/tests/errors/top_errors_for_transaction/top_errors_main_stats.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/errors/top_errors_for_transaction/top_errors_main_stats.spec.ts
@@ -58,54 +58,47 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('top errors for transaction', () => {
- const {
- firstTransaction: {
- name: firstTransactionName,
- failureRate: firstTransactionFailureRate,
- },
- } = config;
+ registry.when('when data is loaded', { config: 'basic', archives: [] }, () => {
+ describe('top errors for transaction', () => {
+ const {
+ firstTransaction: { name: firstTransactionName, failureRate: firstTransactionFailureRate },
+ } = config;
- before(async () => {
- await generateData({ serviceName, start, end, synthtraceEsClient });
- });
+ before(async () => {
+ await generateData({ serviceName, start, end, synthtraceEsClient });
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('returns the correct data', () => {
- let errorGroups: ErrorGroups;
- before(async () => {
- const response = await callApi({ query: { transactionName: firstTransactionName } });
- errorGroups = response.body.errorGroups;
- });
+ describe('returns the correct data', () => {
+ let errorGroups: ErrorGroups;
+ before(async () => {
+ const response = await callApi({ query: { transactionName: firstTransactionName } });
+ errorGroups = response.body.errorGroups;
+ });
- it('returns correct number of errors and error data', () => {
- const numberOfBuckets = 15;
+ it('returns correct number of errors and error data', () => {
+ const numberOfBuckets = 15;
- expect(errorGroups.length).to.equal(2);
+ expect(errorGroups.length).to.equal(2);
- const firstErrorId = `Error 1 transaction ${firstTransactionName}`;
- const firstError = errorGroups.find((x) => x.groupId === firstErrorId);
- expect(firstError).to.not.be(undefined);
- expect(firstError?.groupId).to.be(firstErrorId);
- expect(firstError?.name).to.be(firstErrorId);
- expect(firstError?.occurrences).to.be(firstTransactionFailureRate * numberOfBuckets);
- expect(firstError?.lastSeen).to.be(moment(end).startOf('minute').valueOf());
+ const firstErrorId = `Error 1 transaction ${firstTransactionName}`;
+ const firstError = errorGroups.find((x) => x.groupId === firstErrorId);
+ expect(firstError).to.not.be(undefined);
+ expect(firstError?.groupId).to.be(firstErrorId);
+ expect(firstError?.name).to.be(firstErrorId);
+ expect(firstError?.occurrences).to.be(firstTransactionFailureRate * numberOfBuckets);
+ expect(firstError?.lastSeen).to.be(moment(end).startOf('minute').valueOf());
- const secondErrorId = `Error 2 transaction ${firstTransactionName}`;
- const secondError = errorGroups.find((x) => x.groupId === secondErrorId);
- expect(secondError).to.not.be(undefined);
- expect(secondError?.groupId).to.be(secondErrorId);
- expect(secondError?.name).to.be(secondErrorId);
- expect(secondError?.occurrences).to.be(firstTransactionFailureRate * numberOfBuckets);
- expect(secondError?.lastSeen).to.be(moment(end).startOf('minute').valueOf());
- });
+ const secondErrorId = `Error 2 transaction ${firstTransactionName}`;
+ const secondError = errorGroups.find((x) => x.groupId === secondErrorId);
+ expect(secondError).to.not.be(undefined);
+ expect(secondError?.groupId).to.be(secondErrorId);
+ expect(secondError?.name).to.be(secondErrorId);
+ expect(secondError?.occurrences).to.be(firstTransactionFailureRate * numberOfBuckets);
+ expect(secondError?.lastSeen).to.be(moment(end).startOf('minute').valueOf());
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/infrastructure/infrastructure_attributes.spec.ts b/x-pack/test/apm_api_integration/tests/infrastructure/infrastructure_attributes.spec.ts
index 39a45a9b396c715..19df36703591174 100644
--- a/x-pack/test/apm_api_integration/tests/infrastructure/infrastructure_attributes.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/infrastructure/infrastructure_attributes.spec.ts
@@ -48,39 +48,33 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Infrastructure attributes',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- beforeEach(async () => {
- await generateData({ start, end, synthtraceEsClient });
- });
+ registry.when('Infrastructure attributes', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ beforeEach(async () => {
+ await generateData({ start, end, synthtraceEsClient });
+ });
- afterEach(() => synthtraceEsClient.clean());
+ afterEach(() => synthtraceEsClient.clean());
- describe('when service runs in container', () => {
- it('returns arrays of container ids and pod names', async () => {
- const response = await callApi('synth-go');
- expect(response.status).to.be(200);
- expect(response.body.containerIds.length).to.be(1);
- // hostNames is always returning empty
- // we can not test the infra indices api call with synthtrace
- expect(response.body.hostNames.length).to.be(0);
- expect(response.body.podNames.length).to.be(1);
- });
+ describe('when service runs in container', () => {
+ it('returns arrays of container ids and pod names', async () => {
+ const response = await callApi('synth-go');
+ expect(response.status).to.be(200);
+ expect(response.body.containerIds.length).to.be(1);
+ expect(response.body.hostNames.length).to.be(1);
+ expect(response.body.podNames.length).to.be(1);
});
+ });
- describe('when service does NOT run in container', () => {
- it('returns array of host names', async () => {
- const response = await callApi('synth-java');
- expect(response.status).to.be(200);
- expect(response.body.containerIds.length).to.be(0);
- expect(response.body.hostNames.length).to.be(1);
- expect(response.body.podNames.length).to.be(0);
- });
+ describe('when service does NOT run in container', () => {
+ it('returns array of host names', async () => {
+ const response = await callApi('synth-java');
+ expect(response.status).to.be(200);
+ expect(response.body.containerIds.length).to.be(0);
+ expect(response.body.hostNames.length).to.be(1);
+ expect(response.body.podNames.length).to.be(0);
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts b/x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts
index 1ad8322443e1aec..b38a7ef3052c2c7 100644
--- a/x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/latency/service_apis.spec.ts
@@ -116,7 +116,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let latencyMetricValues: Awaited>;
let latencyTransactionValues: Awaited>;
- registry.when('Services APIs', { config: 'basic', archives: ['apm_mappings_only_8.0.0'] }, () => {
+ registry.when('Services APIs', { config: 'basic', archives: [] }, () => {
describe('when data is loaded ', () => {
const GO_PROD_RATE = 80;
const GO_DEV_RATE = 20;
diff --git a/x-pack/test/apm_api_integration/tests/latency/service_maps.spec.ts b/x-pack/test/apm_api_integration/tests/latency/service_maps.spec.ts
index e898dbb67f2e562..e9b9749b659e214 100644
--- a/x-pack/test/apm_api_integration/tests/latency/service_maps.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/latency/service_maps.spec.ts
@@ -59,68 +59,63 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let latencyMetricValues: Awaited>;
let latencyTransactionValues: Awaited>;
- registry.when(
- 'Service maps APIs',
- { config: 'trial', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded ', () => {
- const GO_PROD_RATE = 80;
- const GO_DEV_RATE = 20;
- const GO_PROD_DURATION = 1000;
- const GO_DEV_DURATION = 500;
- before(async () => {
- const serviceGoProdInstance = apm
- .service(serviceName, 'production', 'go')
- .instance('instance-a');
- const serviceGoDevInstance = apm
- .service(serviceName, 'development', 'go')
- .instance('instance-b');
+ registry.when('Service maps APIs', { config: 'trial', archives: [] }, () => {
+ describe('when data is loaded ', () => {
+ const GO_PROD_RATE = 80;
+ const GO_DEV_RATE = 20;
+ const GO_PROD_DURATION = 1000;
+ const GO_DEV_DURATION = 500;
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service(serviceName, 'production', 'go')
+ .instance('instance-a');
+ const serviceGoDevInstance = apm
+ .service(serviceName, 'development', 'go')
+ .instance('instance-b');
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction('GET /api/product/list', 'Worker')
- .duration(GO_PROD_DURATION)
- .timestamp(timestamp)
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_DEV_RATE)
- .generator((timestamp) =>
- serviceGoDevInstance
- .transaction('GET /api/product/:id')
- .duration(GO_DEV_DURATION)
- .timestamp(timestamp)
- ),
- ]);
- });
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction('GET /api/product/list', 'Worker')
+ .duration(GO_PROD_DURATION)
+ .timestamp(timestamp)
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_DEV_RATE)
+ .generator((timestamp) =>
+ serviceGoDevInstance
+ .transaction('GET /api/product/:id')
+ .duration(GO_DEV_DURATION)
+ .timestamp(timestamp)
+ ),
+ ]);
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('compare latency value between service inventory and service maps', () => {
- before(async () => {
- [latencyTransactionValues, latencyMetricValues] = await Promise.all([
- getLatencyValues('transaction'),
- getLatencyValues('metric'),
- ]);
- });
+ describe('compare latency value between service inventory and service maps', () => {
+ before(async () => {
+ [latencyTransactionValues, latencyMetricValues] = await Promise.all([
+ getLatencyValues('transaction'),
+ getLatencyValues('metric'),
+ ]);
+ });
- it('returns same avg latency value for Transaction-based and Metric-based data', () => {
- const expectedLatencyAvgValueMs =
- ((GO_DEV_RATE * GO_DEV_DURATION) / GO_DEV_RATE) * 1000;
+ it('returns same avg latency value for Transaction-based and Metric-based data', () => {
+ const expectedLatencyAvgValueMs = ((GO_DEV_RATE * GO_DEV_DURATION) / GO_DEV_RATE) * 1000;
- [
- latencyTransactionValues.serviceMapsNodeDetailsLatency,
- latencyTransactionValues.serviceInventoryLatency,
- latencyMetricValues.serviceMapsNodeDetailsLatency,
- latencyMetricValues.serviceInventoryLatency,
- ].forEach((value) => expect(value).to.be.equal(expectedLatencyAvgValueMs));
- });
+ [
+ latencyTransactionValues.serviceMapsNodeDetailsLatency,
+ latencyTransactionValues.serviceInventoryLatency,
+ latencyMetricValues.serviceMapsNodeDetailsLatency,
+ latencyMetricValues.serviceInventoryLatency,
+ ].forEach((value) => expect(value).to.be.equal(expectedLatencyAvgValueMs));
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts
index e924fc865c42f58..d25b17cc0dc6b33 100644
--- a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.spec.ts
@@ -83,93 +83,87 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('Observability overview api ', () => {
- const GO_PROD_RATE = 50;
- const GO_DEV_RATE = 5;
- const JAVA_PROD_RATE = 45;
- before(async () => {
- const serviceGoProdInstance = apm
- .service('synth-go', 'production', 'go')
- .instance('instance-a');
- const serviceGoDevInstance = apm
- .service('synth-go', 'development', 'go')
- .instance('instance-b');
+ registry.when('data is loaded', { config: 'basic', archives: [] }, () => {
+ describe('Observability overview api ', () => {
+ const GO_PROD_RATE = 50;
+ const GO_DEV_RATE = 5;
+ const JAVA_PROD_RATE = 45;
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service('synth-go', 'production', 'go')
+ .instance('instance-a');
+ const serviceGoDevInstance = apm
+ .service('synth-go', 'development', 'go')
+ .instance('instance-b');
- const serviceJavaInstance = apm
- .service('synth-java', 'production', 'java')
- .instance('instance-c');
+ const serviceJavaInstance = apm
+ .service('synth-java', 'production', 'java')
+ .instance('instance-c');
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction('GET /api/product/list')
- .duration(1000)
- .timestamp(timestamp)
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_DEV_RATE)
- .generator((timestamp) =>
- serviceGoDevInstance
- .transaction('GET /api/product/:id')
- .duration(1000)
- .timestamp(timestamp)
- ),
- timerange(start, end)
- .interval('1m')
- .rate(JAVA_PROD_RATE)
- .generator((timestamp) =>
- serviceJavaInstance
- .transaction('POST /api/product/buy')
- .duration(1000)
- .timestamp(timestamp)
- ),
- ]);
- });
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction('GET /api/product/list')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_DEV_RATE)
+ .generator((timestamp) =>
+ serviceGoDevInstance
+ .transaction('GET /api/product/:id')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(JAVA_PROD_RATE)
+ .generator((timestamp) =>
+ serviceJavaInstance
+ .transaction('POST /api/product/buy')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ ]);
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('compare throughput values', () => {
- let throughputValues: Awaited>;
- before(async () => {
- throughputValues = await getThroughputValues();
- });
+ describe('compare throughput values', () => {
+ let throughputValues: Awaited>;
+ before(async () => {
+ throughputValues = await getThroughputValues();
+ });
- it('returns same number of service as shown on service inventory API', () => {
- const { serviceInventoryCount, observabilityOverview } = throughputValues;
- [serviceInventoryCount, observabilityOverview.serviceCount].forEach((value) =>
- expect(value).to.be.equal(2)
- );
- });
+ it('returns same number of service as shown on service inventory API', () => {
+ const { serviceInventoryCount, observabilityOverview } = throughputValues;
+ [serviceInventoryCount, observabilityOverview.serviceCount].forEach((value) =>
+ expect(value).to.be.equal(2)
+ );
+ });
- it('returns same throughput value on service inventory and obs throughput count', () => {
- const { serviceInventoryThroughputSum, observabilityOverview } = throughputValues;
- const obsThroughputCount = roundNumber(
- observabilityOverview.transactionPerMinute.value
- );
- [serviceInventoryThroughputSum, obsThroughputCount].forEach((value) =>
- expect(value).to.be.equal(roundNumber(GO_PROD_RATE + GO_DEV_RATE + JAVA_PROD_RATE))
- );
- });
+ it('returns same throughput value on service inventory and obs throughput count', () => {
+ const { serviceInventoryThroughputSum, observabilityOverview } = throughputValues;
+ const obsThroughputCount = roundNumber(observabilityOverview.transactionPerMinute.value);
+ [serviceInventoryThroughputSum, obsThroughputCount].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(GO_PROD_RATE + GO_DEV_RATE + JAVA_PROD_RATE))
+ );
+ });
- it('returns same throughput value on service inventory and obs mean throughput timeseries', () => {
- const { serviceInventoryThroughputSum, observabilityOverview } = throughputValues;
- const obsThroughputMean = roundNumber(
- meanBy(observabilityOverview.transactionPerMinute.timeseries, 'y')
- );
- [serviceInventoryThroughputSum, obsThroughputMean].forEach((value) =>
- expect(value).to.be.equal(roundNumber(GO_PROD_RATE + GO_DEV_RATE + JAVA_PROD_RATE))
- );
- });
+ it('returns same throughput value on service inventory and obs mean throughput timeseries', () => {
+ const { serviceInventoryThroughputSum, observabilityOverview } = throughputValues;
+ const obsThroughputMean = roundNumber(
+ meanBy(observabilityOverview.transactionPerMinute.timeseries, 'y')
+ );
+ [serviceInventoryThroughputSum, obsThroughputMean].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(GO_PROD_RATE + GO_DEV_RATE + JAVA_PROD_RATE))
+ );
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/service_nodes/get_service_nodes.spec.ts b/x-pack/test/apm_api_integration/tests/service_nodes/get_service_nodes.spec.ts
index a6c53e0bade0523..c582c929c67cb45 100644
--- a/x-pack/test/apm_api_integration/tests/service_nodes/get_service_nodes.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/service_nodes/get_service_nodes.spec.ts
@@ -48,36 +48,33 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'Service nodes when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- before(async () => {
- const instance = apm.service(serviceName, 'production', 'go').instance(instanceName);
- await synthtraceEsClient.index(
- timerange(start, end)
- .interval('1m')
- .rate(1)
- .generator((timestamp) =>
- instance
- .appMetrics({
- 'system.process.cpu.total.norm.pct': 1,
- 'jvm.memory.heap.used': 1000,
- 'jvm.memory.non_heap.used': 100,
- 'jvm.thread.count': 25,
- })
- .timestamp(timestamp)
- )
- );
- });
- after(() => synthtraceEsClient.clean());
+ registry.when('Service nodes when data is loaded', { config: 'basic', archives: [] }, () => {
+ before(async () => {
+ const instance = apm.service(serviceName, 'production', 'go').instance(instanceName);
+ await synthtraceEsClient.index(
+ timerange(start, end)
+ .interval('1m')
+ .rate(1)
+ .generator((timestamp) =>
+ instance
+ .appMetrics({
+ 'system.process.cpu.total.norm.pct': 1,
+ 'jvm.memory.heap.used': 1000,
+ 'jvm.memory.non_heap.used': 100,
+ 'jvm.thread.count': 25,
+ })
+ .timestamp(timestamp)
+ )
+ );
+ });
+ after(() => synthtraceEsClient.clean());
- it('returns service nodes', async () => {
- const response = await callApi();
+ it('returns service nodes', async () => {
+ const response = await callApi();
- expect(response.status).to.be(200);
+ expect(response.status).to.be(200);
- expectSnapshot(response.body).toMatchInline(`
+ expectSnapshot(response.body).toMatchInline(`
Object {
"serviceNodes": Array [
Object {
@@ -91,7 +88,6 @@ export default function ApiTest({ getService }: FtrProviderContext) {
],
}
`);
- });
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts
index 8d92ec6a38573b4..8313ec635c69af1 100644
--- a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.spec.ts
@@ -283,7 +283,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'Service overview instances main statistics when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
describe('for two go instances and one java instance', () => {
const GO_A_INSTANCE_RATE_SUCCESS = 10;
diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts
index d6dc2bfb4b9ed7f..b9db3ae5e8fdd3c 100644
--- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts
@@ -64,136 +64,130 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Error groups detailed statistics',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- const { PROD_LIST_ERROR_RATE, PROD_ID_ERROR_RATE } = config;
+ registry.when('Error groups detailed statistics', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ const { PROD_LIST_ERROR_RATE, PROD_ID_ERROR_RATE } = config;
+ before(async () => {
+ await generateData({ serviceName, start, end, synthtraceEsClient });
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('without data comparison', () => {
+ let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics;
+ let errorIds: string[] = [];
before(async () => {
- await generateData({ serviceName, start, end, synthtraceEsClient });
+ errorIds = await getErrorGroupIds({ serviceName, start, end, apmApiClient });
+ const response = await callApi({
+ body: {
+ groupIds: JSON.stringify(errorIds),
+ },
+ });
+ errorGroupsDetailedStatistics = response.body;
+ });
+
+ it('return detailed statistics for all errors found', () => {
+ expect(Object.keys(errorGroupsDetailedStatistics.currentPeriod).sort()).to.eql(errorIds);
});
- after(() => synthtraceEsClient.clean());
-
- describe('without data comparison', () => {
- let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics;
- let errorIds: string[] = [];
- before(async () => {
- errorIds = await getErrorGroupIds({ serviceName, start, end, apmApiClient });
- const response = await callApi({
- body: {
- groupIds: JSON.stringify(errorIds),
- },
+ it('returns correct number of occurrencies', () => {
+ const numberOfBuckets = 15;
+ const detailedStatisticsOccurrenciesSum = Object.values(
+ errorGroupsDetailedStatistics.currentPeriod
+ )
+ .sort()
+ .map(({ timeseries }) => {
+ return sumBy(timeseries, 'y');
});
- errorGroupsDetailedStatistics = response.body;
- });
- it('return detailed statistics for all errors found', () => {
- expect(Object.keys(errorGroupsDetailedStatistics.currentPeriod).sort()).to.eql(
- errorIds
- );
- });
+ expect(detailedStatisticsOccurrenciesSum).to.eql([
+ PROD_ID_ERROR_RATE * numberOfBuckets,
+ PROD_LIST_ERROR_RATE * numberOfBuckets,
+ ]);
+ });
+ });
- it('returns correct number of occurrencies', () => {
- const numberOfBuckets = 15;
- const detailedStatisticsOccurrenciesSum = Object.values(
- errorGroupsDetailedStatistics.currentPeriod
- )
- .sort()
- .map(({ timeseries }) => {
- return sumBy(timeseries, 'y');
- });
-
- expect(detailedStatisticsOccurrenciesSum).to.eql([
- PROD_ID_ERROR_RATE * numberOfBuckets,
- PROD_LIST_ERROR_RATE * numberOfBuckets,
- ]);
+ describe('return empty state when invalid group id', () => {
+ let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics;
+ before(async () => {
+ const response = await callApi({
+ body: {
+ groupIds: JSON.stringify(['foo']),
+ },
});
+ errorGroupsDetailedStatistics = response.body;
});
- describe('return empty state when invalid group id', () => {
- let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics;
- before(async () => {
- const response = await callApi({
- body: {
- groupIds: JSON.stringify(['foo']),
- },
- });
- errorGroupsDetailedStatistics = response.body;
- });
-
- it('returns empty state', () => {
- expect(errorGroupsDetailedStatistics).to.be.eql({
- currentPeriod: {},
- previousPeriod: {},
- });
+ it('returns empty state', () => {
+ expect(errorGroupsDetailedStatistics).to.be.eql({
+ currentPeriod: {},
+ previousPeriod: {},
});
});
+ });
- describe('with comparison', () => {
- let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics;
- let errorIds: string[] = [];
- before(async () => {
- errorIds = await getErrorGroupIds({ serviceName, start, end, apmApiClient });
- const response = await callApi({
- query: {
- start: moment(end).subtract(7, 'minutes').toISOString(),
- end: new Date(end).toISOString(),
- offset: '7m',
- },
- body: {
- groupIds: JSON.stringify(errorIds),
- },
- });
- errorGroupsDetailedStatistics = response.body;
+ describe('with comparison', () => {
+ let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics;
+ let errorIds: string[] = [];
+ before(async () => {
+ errorIds = await getErrorGroupIds({ serviceName, start, end, apmApiClient });
+ const response = await callApi({
+ query: {
+ start: moment(end).subtract(7, 'minutes').toISOString(),
+ end: new Date(end).toISOString(),
+ offset: '7m',
+ },
+ body: {
+ groupIds: JSON.stringify(errorIds),
+ },
});
+ errorGroupsDetailedStatistics = response.body;
+ });
- it('returns some data', () => {
- expect(
- Object.keys(errorGroupsDetailedStatistics.currentPeriod).length
- ).to.be.greaterThan(0);
- expect(
- Object.keys(errorGroupsDetailedStatistics.previousPeriod).length
- ).to.be.greaterThan(0);
+ it('returns some data', () => {
+ expect(Object.keys(errorGroupsDetailedStatistics.currentPeriod).length).to.be.greaterThan(
+ 0
+ );
+ expect(
+ Object.keys(errorGroupsDetailedStatistics.previousPeriod).length
+ ).to.be.greaterThan(0);
- const hasCurrentPeriodData = Object.values(
- errorGroupsDetailedStatistics.currentPeriod
- )[0].timeseries.some(({ y }) => isFiniteNumber(y));
+ const hasCurrentPeriodData = Object.values(
+ errorGroupsDetailedStatistics.currentPeriod
+ )[0].timeseries.some(({ y }) => isFiniteNumber(y));
- const hasPreviousPeriodData = Object.values(
- errorGroupsDetailedStatistics.previousPeriod
- )[0].timeseries.some(({ y }) => isFiniteNumber(y));
+ const hasPreviousPeriodData = Object.values(
+ errorGroupsDetailedStatistics.previousPeriod
+ )[0].timeseries.some(({ y }) => isFiniteNumber(y));
- expect(hasCurrentPeriodData).to.equal(true);
- expect(hasPreviousPeriodData).to.equal(true);
- });
+ expect(hasCurrentPeriodData).to.equal(true);
+ expect(hasPreviousPeriodData).to.equal(true);
+ });
- it('has same start time for both periods', () => {
- expect(
- first(Object.values(errorGroupsDetailedStatistics.currentPeriod)[0].timeseries)?.x
- ).to.equal(
- first(Object.values(errorGroupsDetailedStatistics.previousPeriod)[0].timeseries)?.x
- );
- });
+ it('has same start time for both periods', () => {
+ expect(
+ first(Object.values(errorGroupsDetailedStatistics.currentPeriod)[0].timeseries)?.x
+ ).to.equal(
+ first(Object.values(errorGroupsDetailedStatistics.previousPeriod)[0].timeseries)?.x
+ );
+ });
- it('has same end time for both periods', () => {
- expect(
- last(Object.values(errorGroupsDetailedStatistics.currentPeriod)[0].timeseries)?.x
- ).to.equal(
- last(Object.values(errorGroupsDetailedStatistics.previousPeriod)[0].timeseries)?.x
- );
- });
+ it('has same end time for both periods', () => {
+ expect(
+ last(Object.values(errorGroupsDetailedStatistics.currentPeriod)[0].timeseries)?.x
+ ).to.equal(
+ last(Object.values(errorGroupsDetailedStatistics.previousPeriod)[0].timeseries)?.x
+ );
+ });
- it('returns same number of buckets for both periods', () => {
- expect(
- Object.values(errorGroupsDetailedStatistics.currentPeriod)[0].timeseries.length
- ).to.equal(
- Object.values(errorGroupsDetailedStatistics.previousPeriod)[0].timeseries.length
- );
- });
+ it('returns same number of buckets for both periods', () => {
+ expect(
+ Object.values(errorGroupsDetailedStatistics.currentPeriod)[0].timeseries.length
+ ).to.equal(
+ Object.values(errorGroupsDetailedStatistics.previousPeriod)[0].timeseries.length
+ );
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts
index df86dc2bda16fb1..32ae3b9bfd5acd1 100644
--- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts
@@ -58,51 +58,44 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Error groups main statistics',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- const { PROD_LIST_ERROR_RATE, PROD_ID_ERROR_RATE, ERROR_NAME_1, ERROR_NAME_2 } = config;
+ registry.when('Error groups main statistics', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ const { PROD_LIST_ERROR_RATE, PROD_ID_ERROR_RATE, ERROR_NAME_1, ERROR_NAME_2 } = config;
- before(async () => {
- await generateData({ serviceName, start, end, synthtraceEsClient });
- });
+ before(async () => {
+ await generateData({ serviceName, start, end, synthtraceEsClient });
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- describe('returns the correct data', () => {
- let errorGroupMainStatistics: ErrorGroupsMainStatistics;
- before(async () => {
- const response = await callApi();
- errorGroupMainStatistics = response.body;
- });
+ describe('returns the correct data', () => {
+ let errorGroupMainStatistics: ErrorGroupsMainStatistics;
+ before(async () => {
+ const response = await callApi();
+ errorGroupMainStatistics = response.body;
+ });
- it('returns correct number of occurrences', () => {
- expect(errorGroupMainStatistics.errorGroups.length).to.equal(2);
- expect(errorGroupMainStatistics.errorGroups.map((error) => error.name).sort()).to.eql([
- ERROR_NAME_1,
- ERROR_NAME_2,
- ]);
- });
+ it('returns correct number of occurrences', () => {
+ expect(errorGroupMainStatistics.errorGroups.length).to.equal(2);
+ expect(errorGroupMainStatistics.errorGroups.map((error) => error.name).sort()).to.eql([
+ ERROR_NAME_1,
+ ERROR_NAME_2,
+ ]);
+ });
- it('returns correct occurences', () => {
- const numberOfBuckets = 15;
- expect(
- errorGroupMainStatistics.errorGroups.map((error) => error.occurrences).sort()
- ).to.eql([
- PROD_LIST_ERROR_RATE * numberOfBuckets,
- PROD_ID_ERROR_RATE * numberOfBuckets,
- ]);
- });
+ it('returns correct occurences', () => {
+ const numberOfBuckets = 15;
+ expect(
+ errorGroupMainStatistics.errorGroups.map((error) => error.occurrences).sort()
+ ).to.eql([PROD_LIST_ERROR_RATE * numberOfBuckets, PROD_ID_ERROR_RATE * numberOfBuckets]);
+ });
- it('has same last seen value as end date', () => {
- errorGroupMainStatistics.errorGroups.map((error) => {
- expect(error.lastSeen).to.equal(moment(end).startOf('minute').valueOf());
- });
+ it('has same last seen value as end date', () => {
+ errorGroupMainStatistics.errorGroups.map((error) => {
+ expect(error.lastSeen).to.equal(moment(end).startOf('minute').valueOf());
});
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts b/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts
index 0033c5b8f026b33..49160f9b5caf2df 100644
--- a/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts
@@ -54,7 +54,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'Service node metadata when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
before(async () => {
const instance = apm.service(serviceName, 'production', 'go').instance(instanceName);
diff --git a/x-pack/test/apm_api_integration/tests/services/service_details/service_details.spec.ts b/x-pack/test/apm_api_integration/tests/services/service_details/service_details.spec.ts
index c53c9f9f16e8633..f54fbf26c7b99dd 100644
--- a/x-pack/test/apm_api_integration/tests/services/service_details/service_details.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/service_details/service_details.spec.ts
@@ -50,79 +50,75 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'Service details when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- let body: ServiceDetails;
- let status: number;
-
- before(async () => {
- await generateData({ synthtraceEsClient, start, end });
- const response = await callApi();
- body = response.body;
- status = response.status;
- });
+ registry.when('Service details when data is generated', { config: 'basic', archives: [] }, () => {
+ let body: ServiceDetails;
+ let status: number;
+
+ before(async () => {
+ await generateData({ synthtraceEsClient, start, end });
+ const response = await callApi();
+ body = response.body;
+ status = response.status;
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- it('returns correct HTTP status', () => {
- expect(status).to.be(200);
- });
+ it('returns correct HTTP status', () => {
+ expect(status).to.be(200);
+ });
- it('returns correct cloud details', () => {
- const { cloud } = dataConfig;
- const {
- provider,
- availabilityZone,
- region,
- machineType,
- projectName,
- serviceName: cloudServiceName,
- } = cloud;
-
- expect(first(body?.cloud?.availabilityZones)).to.be(availabilityZone);
- expect(first(body?.cloud?.machineTypes)).to.be(machineType);
- expect(body?.cloud?.provider).to.be(provider);
- expect(body?.cloud?.projectName).to.be(projectName);
- expect(body?.cloud?.serviceName).to.be(cloudServiceName);
- expect(first(body?.cloud?.regions)).to.be(region);
- });
+ it('returns correct cloud details', () => {
+ const { cloud } = dataConfig;
+ const {
+ provider,
+ availabilityZone,
+ region,
+ machineType,
+ projectName,
+ serviceName: cloudServiceName,
+ } = cloud;
+
+ expect(first(body?.cloud?.availabilityZones)).to.be(availabilityZone);
+ expect(first(body?.cloud?.machineTypes)).to.be(machineType);
+ expect(body?.cloud?.provider).to.be(provider);
+ expect(body?.cloud?.projectName).to.be(projectName);
+ expect(body?.cloud?.serviceName).to.be(cloudServiceName);
+ expect(first(body?.cloud?.regions)).to.be(region);
+ });
- it('returns correct container details', () => {
- const { containerOs } = dataConfig;
+ it('returns correct container details', () => {
+ const { containerOs } = dataConfig;
- expect(body?.container?.isContainerized).to.be(true);
- expect(body?.container?.os).to.be(containerOs);
- expect(body?.container?.totalNumberInstances).to.be(1);
- expect(body?.container?.type).to.be('Kubernetes');
- });
+ expect(body?.container?.isContainerized).to.be(true);
+ expect(body?.container?.os).to.be(containerOs);
+ expect(body?.container?.totalNumberInstances).to.be(1);
+ expect(body?.container?.type).to.be('Kubernetes');
+ });
- it('returns correct serverless details', () => {
- const { cloud, serverless } = dataConfig;
- const { serviceName: cloudServiceName } = cloud;
- const { faasTriggerType, firstFunctionName, secondFunctionName } = serverless;
+ it('returns correct serverless details', () => {
+ const { cloud, serverless } = dataConfig;
+ const { serviceName: cloudServiceName } = cloud;
+ const { faasTriggerType, firstFunctionName, secondFunctionName } = serverless;
- expect(body?.serverless?.type).to.be(cloudServiceName);
- expect(body?.serverless?.functionNames).to.have.length(2);
- expect(body?.serverless?.functionNames).to.contain(firstFunctionName);
- expect(body?.serverless?.functionNames).to.contain(secondFunctionName);
- expect(first(body?.serverless?.faasTriggerTypes)).to.be(faasTriggerType);
- });
+ expect(body?.serverless?.type).to.be(cloudServiceName);
+ expect(body?.serverless?.functionNames).to.have.length(2);
+ expect(body?.serverless?.functionNames).to.contain(firstFunctionName);
+ expect(body?.serverless?.functionNames).to.contain(secondFunctionName);
+ expect(first(body?.serverless?.faasTriggerTypes)).to.be(faasTriggerType);
+ });
- it('returns correct service details', () => {
- const { service } = dataConfig;
- const { version, runtime, framework, agent } = service;
- const { name: runTimeName, version: runTimeVersion } = runtime;
- const { name: agentName, version: agentVersion } = agent;
-
- expect(body?.service?.framework).to.be(framework);
- expect(body?.service?.agent.name).to.be(agentName);
- expect(body?.service?.agent.version).to.be(agentVersion);
- expect(body?.service?.runtime?.name).to.be(runTimeName);
- expect(body?.service?.runtime?.version).to.be(runTimeVersion);
- expect(first(body?.service?.versions)).to.be(version);
- });
- }
- );
+ it('returns correct service details', () => {
+ const { service } = dataConfig;
+ const { version, runtime, framework, agent } = service;
+ const { name: runTimeName, version: runTimeVersion } = runtime;
+ const { name: agentName, version: agentVersion } = agent;
+
+ expect(body?.service?.framework).to.be(framework);
+ expect(body?.service?.agent.name).to.be(agentName);
+ expect(body?.service?.agent.version).to.be(agentVersion);
+ expect(body?.service?.runtime?.name).to.be(runTimeName);
+ expect(body?.service?.runtime?.version).to.be(runTimeVersion);
+ expect(first(body?.service?.versions)).to.be(version);
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/services/service_icons/service_icons.spec.ts b/x-pack/test/apm_api_integration/tests/services/service_icons/service_icons.spec.ts
index 11cb59fff075619..756babbadd9f0d4 100644
--- a/x-pack/test/apm_api_integration/tests/services/service_icons/service_icons.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/service_icons/service_icons.spec.ts
@@ -43,35 +43,31 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'Service icons when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- let body: ServiceIconMetadata;
- let status: number;
+ registry.when('Service icons when data is generated', { config: 'basic', archives: [] }, () => {
+ let body: ServiceIconMetadata;
+ let status: number;
- before(async () => {
- await generateData({ synthtraceEsClient, start, end });
- const response = await callApi();
- body = response.body;
- status = response.status;
- });
+ before(async () => {
+ await generateData({ synthtraceEsClient, start, end });
+ const response = await callApi();
+ body = response.body;
+ status = response.status;
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- it('returns correct HTTP status', () => {
- expect(status).to.be(200);
- });
+ it('returns correct HTTP status', () => {
+ expect(status).to.be(200);
+ });
- it('returns correct metadata', () => {
- const { agentName, cloud } = dataConfig;
- const { provider, serviceName: cloudServiceName } = cloud;
+ it('returns correct metadata', () => {
+ const { agentName, cloud } = dataConfig;
+ const { provider, serviceName: cloudServiceName } = cloud;
- expect(body.agentName).to.be(agentName);
- expect(body.cloudProvider).to.be(provider);
- expect(body.containerType).to.be('Kubernetes');
- expect(body.serverlessType).to.be(cloudServiceName);
- });
- }
- );
+ expect(body.agentName).to.be(agentName);
+ expect(body.cloudProvider).to.be(provider);
+ expect(body.containerType).to.be('Kubernetes');
+ expect(body.serverlessType).to.be(cloudServiceName);
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts b/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts
index 92a6997244b20f4..ca2cb0c3d20a714 100644
--- a/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts
@@ -51,102 +51,98 @@ export default function ApiTest({ getService }: FtrProviderContext) {
type ServiceListItem = ValuesType>>;
// FLAKY: https://github.com/elastic/kibana/issues/127939
- registry.when.skip(
- 'Sorted and filtered services',
- { config: 'trial', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- before(async () => {
- const serviceA = apm.service(SERVICE_NAME_PREFIX + 'a', 'production', 'java').instance('a');
-
- const serviceB = apm.service(SERVICE_NAME_PREFIX + 'b', 'development', 'go').instance('b');
-
- const serviceC = apm.service(SERVICE_NAME_PREFIX + 'c', 'development', 'go').instance('c');
-
- const spikeStart = new Date('2021-01-07T12:00:00.000Z').getTime();
- const spikeEnd = new Date('2021-01-07T14:00:00.000Z').getTime();
-
- const eventsWithinTimerange = timerange(new Date(start).getTime(), new Date(end).getTime())
- .interval('15m')
- .rate(1)
- .generator((timestamp) => {
- const isInSpike = spikeStart <= timestamp && spikeEnd >= timestamp;
- return [
- serviceA
- .transaction('GET /api')
- .duration(isInSpike ? 1000 : 1100)
- .timestamp(timestamp),
- serviceB
- .transaction('GET /api')
- .duration(isInSpike ? 1000 : 4000)
- .timestamp(timestamp),
- ];
- });
-
- const eventsOutsideOfTimerange = timerange(
- new Date('2021-01-01T00:00:00.000Z').getTime(),
- new Date(start).getTime() - 1
- )
- .interval('15m')
- .rate(1)
- .generator((timestamp) => {
- return serviceC.transaction('GET /api', 'custom').duration(1000).timestamp(timestamp);
- });
-
- await synthtraceClient.index(eventsWithinTimerange.merge(eventsOutsideOfTimerange));
-
- await Promise.all([
- createAndRunApmMlJob({ environment: 'production', ml }),
- createAndRunApmMlJob({ environment: 'development', ml }),
- ]);
- });
+ registry.when.skip('Sorted and filtered services', { config: 'trial', archives: [] }, () => {
+ before(async () => {
+ const serviceA = apm.service(SERVICE_NAME_PREFIX + 'a', 'production', 'java').instance('a');
+
+ const serviceB = apm.service(SERVICE_NAME_PREFIX + 'b', 'development', 'go').instance('b');
+
+ const serviceC = apm.service(SERVICE_NAME_PREFIX + 'c', 'development', 'go').instance('c');
+
+ const spikeStart = new Date('2021-01-07T12:00:00.000Z').getTime();
+ const spikeEnd = new Date('2021-01-07T14:00:00.000Z').getTime();
+
+ const eventsWithinTimerange = timerange(new Date(start).getTime(), new Date(end).getTime())
+ .interval('15m')
+ .rate(1)
+ .generator((timestamp) => {
+ const isInSpike = spikeStart <= timestamp && spikeEnd >= timestamp;
+ return [
+ serviceA
+ .transaction('GET /api')
+ .duration(isInSpike ? 1000 : 1100)
+ .timestamp(timestamp),
+ serviceB
+ .transaction('GET /api')
+ .duration(isInSpike ? 1000 : 4000)
+ .timestamp(timestamp),
+ ];
+ });
- after(() => {
- return Promise.all([synthtraceClient.clean(), ml.cleanMlIndices()]);
- });
+ const eventsOutsideOfTimerange = timerange(
+ new Date('2021-01-01T00:00:00.000Z').getTime(),
+ new Date(start).getTime() - 1
+ )
+ .interval('15m')
+ .rate(1)
+ .generator((timestamp) => {
+ return serviceC.transaction('GET /api', 'custom').duration(1000).timestamp(timestamp);
+ });
- describe('with no kuery or environment are set', () => {
- let items: ServiceListItem[];
+ await synthtraceClient.index(eventsWithinTimerange.merge(eventsOutsideOfTimerange));
- before(async () => {
- items = await getSortedAndFilteredServices();
- });
+ await Promise.all([
+ createAndRunApmMlJob({ environment: 'production', ml }),
+ createAndRunApmMlJob({ environment: 'development', ml }),
+ ]);
+ });
- it('returns services based on the terms enum API and ML data', () => {
- const serviceNames = items.map((item) => item.serviceName);
+ after(() => {
+ return Promise.all([synthtraceClient.clean(), ml.cleanMlIndices()]);
+ });
- expect(serviceNames.sort()).to.eql(['a', 'b', 'c']);
- });
+ describe('with no kuery or environment are set', () => {
+ let items: ServiceListItem[];
+
+ before(async () => {
+ items = await getSortedAndFilteredServices();
});
- describe('with kuery set', () => {
- let items: ServiceListItem[];
+ it('returns services based on the terms enum API and ML data', () => {
+ const serviceNames = items.map((item) => item.serviceName);
- before(async () => {
- items = await getSortedAndFilteredServices({
- kuery: 'service.name:*',
- });
- });
+ expect(serviceNames.sort()).to.eql(['a', 'b', 'c']);
+ });
+ });
+
+ describe('with kuery set', () => {
+ let items: ServiceListItem[];
- it('does not return any services', () => {
- expect(items.length).to.be(0);
+ before(async () => {
+ items = await getSortedAndFilteredServices({
+ kuery: 'service.name:*',
});
});
- describe('with environment set to production', () => {
- let items: ServiceListItem[];
+ it('does not return any services', () => {
+ expect(items.length).to.be(0);
+ });
+ });
- before(async () => {
- items = await getSortedAndFilteredServices({
- environment: 'production',
- });
+ describe('with environment set to production', () => {
+ let items: ServiceListItem[];
+
+ before(async () => {
+ items = await getSortedAndFilteredServices({
+ environment: 'production',
});
+ });
- it('returns services for production only', () => {
- const serviceNames = items.map((item) => item.serviceName);
+ it('returns services for production only', () => {
+ const serviceNames = items.map((item) => item.serviceName);
- expect(serviceNames.sort()).to.eql(['a']);
- });
+ expect(serviceNames.sort()).to.eql(['a']);
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/services/throughput.spec.ts b/x-pack/test/apm_api_integration/tests/services/throughput.spec.ts
index 12c4c809193e2bd..c9c95b2e99bbc5f 100644
--- a/x-pack/test/apm_api_integration/tests/services/throughput.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/throughput.spec.ts
@@ -63,219 +63,213 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when(
- 'Throughput when data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('Throughput chart api', () => {
- const GO_PROD_RATE = 50;
- const GO_DEV_RATE = 5;
- const JAVA_PROD_RATE = 45;
+ registry.when('Throughput when data is loaded', { config: 'basic', archives: [] }, () => {
+ describe('Throughput chart api', () => {
+ const GO_PROD_RATE = 50;
+ const GO_DEV_RATE = 5;
+ const JAVA_PROD_RATE = 45;
+
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service(serviceName, 'production', 'go')
+ .instance('instance-a');
+ const serviceGoDevInstance = apm
+ .service(serviceName, 'development', 'go')
+ .instance('instance-b');
+
+ const serviceJavaInstance = apm
+ .service('synth-java', 'development', 'java')
+ .instance('instance-c');
+
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction('GET /api/product/list')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_DEV_RATE)
+ .generator((timestamp) =>
+ serviceGoDevInstance
+ .transaction('GET /api/product/:id')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(JAVA_PROD_RATE)
+ .generator((timestamp) =>
+ serviceJavaInstance
+ .transaction('POST /api/product/buy')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ ]);
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('compare transactions and metrics based throughput', () => {
+ let throughputMetrics: ThroughputReturn;
+ let throughputTransactions: ThroughputReturn;
before(async () => {
- const serviceGoProdInstance = apm
- .service(serviceName, 'production', 'go')
- .instance('instance-a');
- const serviceGoDevInstance = apm
- .service(serviceName, 'development', 'go')
- .instance('instance-b');
-
- const serviceJavaInstance = apm
- .service('synth-java', 'development', 'java')
- .instance('instance-c');
-
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction('GET /api/product/list')
- .duration(1000)
- .timestamp(timestamp)
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_DEV_RATE)
- .generator((timestamp) =>
- serviceGoDevInstance
- .transaction('GET /api/product/:id')
- .duration(1000)
- .timestamp(timestamp)
- ),
- timerange(start, end)
- .interval('1m')
- .rate(JAVA_PROD_RATE)
- .generator((timestamp) =>
- serviceJavaInstance
- .transaction('POST /api/product/buy')
- .duration(1000)
- .timestamp(timestamp)
- ),
+ const [throughputMetricsResponse, throughputTransactionsResponse] = await Promise.all([
+ callApi({ query: { kuery: 'processor.event : "metric"' } }),
+ callApi({ query: { kuery: 'processor.event : "transaction"' } }),
]);
+ throughputMetrics = throughputMetricsResponse.body;
+ throughputTransactions = throughputTransactionsResponse.body;
});
- after(() => synthtraceEsClient.clean());
-
- describe('compare transactions and metrics based throughput', () => {
- let throughputMetrics: ThroughputReturn;
- let throughputTransactions: ThroughputReturn;
+ it('returns some transactions data', () => {
+ expect(throughputTransactions.currentPeriod.length).to.be.greaterThan(0);
+ const hasData = throughputTransactions.currentPeriod.some(({ y }) => isFiniteNumber(y));
+ expect(hasData).to.equal(true);
+ });
- before(async () => {
- const [throughputMetricsResponse, throughputTransactionsResponse] = await Promise.all([
- callApi({ query: { kuery: 'processor.event : "metric"' } }),
- callApi({ query: { kuery: 'processor.event : "transaction"' } }),
- ]);
- throughputMetrics = throughputMetricsResponse.body;
- throughputTransactions = throughputTransactionsResponse.body;
- });
+ it('returns some metrics data', () => {
+ expect(throughputMetrics.currentPeriod.length).to.be.greaterThan(0);
+ const hasData = throughputMetrics.currentPeriod.some(({ y }) => isFiniteNumber(y));
+ expect(hasData).to.equal(true);
+ });
- it('returns some transactions data', () => {
- expect(throughputTransactions.currentPeriod.length).to.be.greaterThan(0);
- const hasData = throughputTransactions.currentPeriod.some(({ y }) => isFiniteNumber(y));
- expect(hasData).to.equal(true);
- });
+ it('has same mean value for metrics and transactions data', () => {
+ const transactionsMean = meanBy(throughputTransactions.currentPeriod, 'y');
+ const metricsMean = meanBy(throughputMetrics.currentPeriod, 'y');
+ [transactionsMean, metricsMean].forEach((value) =>
+ expect(roundNumber(value)).to.be.equal(roundNumber(GO_PROD_RATE + GO_DEV_RATE))
+ );
+ });
- it('returns some metrics data', () => {
- expect(throughputMetrics.currentPeriod.length).to.be.greaterThan(0);
- const hasData = throughputMetrics.currentPeriod.some(({ y }) => isFiniteNumber(y));
- expect(hasData).to.equal(true);
- });
+ it('has a bucket size of 30 seconds for transactions data', () => {
+ const firstTimerange = throughputTransactions.currentPeriod[0].x;
+ const secondTimerange = throughputTransactions.currentPeriod[1].x;
+ const timeIntervalAsSeconds = (secondTimerange - firstTimerange) / 1000;
+ expect(timeIntervalAsSeconds).to.equal(30);
+ });
- it('has same mean value for metrics and transactions data', () => {
- const transactionsMean = meanBy(throughputTransactions.currentPeriod, 'y');
- const metricsMean = meanBy(throughputMetrics.currentPeriod, 'y');
- [transactionsMean, metricsMean].forEach((value) =>
- expect(roundNumber(value)).to.be.equal(roundNumber(GO_PROD_RATE + GO_DEV_RATE))
- );
- });
+ it('has a bucket size of 1 minute for metrics data', () => {
+ const firstTimerange = throughputMetrics.currentPeriod[0].x;
+ const secondTimerange = throughputMetrics.currentPeriod[1].x;
+ const timeIntervalAsMinutes = (secondTimerange - firstTimerange) / 1000 / 60;
+ expect(timeIntervalAsMinutes).to.equal(1);
+ });
+ });
- it('has a bucket size of 30 seconds for transactions data', () => {
- const firstTimerange = throughputTransactions.currentPeriod[0].x;
- const secondTimerange = throughputTransactions.currentPeriod[1].x;
- const timeIntervalAsSeconds = (secondTimerange - firstTimerange) / 1000;
- expect(timeIntervalAsSeconds).to.equal(30);
- });
+ describe('production environment', () => {
+ let throughput: ThroughputReturn;
- it('has a bucket size of 1 minute for metrics data', () => {
- const firstTimerange = throughputMetrics.currentPeriod[0].x;
- const secondTimerange = throughputMetrics.currentPeriod[1].x;
- const timeIntervalAsMinutes = (secondTimerange - firstTimerange) / 1000 / 60;
- expect(timeIntervalAsMinutes).to.equal(1);
- });
+ before(async () => {
+ const throughputResponse = await callApi({ query: { environment: 'production' } });
+ throughput = throughputResponse.body;
});
- describe('production environment', () => {
- let throughput: ThroughputReturn;
+ it('returns some data', () => {
+ expect(throughput.currentPeriod.length).to.be.greaterThan(0);
+ const hasData = throughput.currentPeriod.some(({ y }) => isFiniteNumber(y));
+ expect(hasData).to.equal(true);
+ });
- before(async () => {
- const throughputResponse = await callApi({ query: { environment: 'production' } });
- throughput = throughputResponse.body;
- });
+ it('returns correct average throughput', () => {
+ const throughputMean = meanBy(throughput.currentPeriod, 'y');
+ expect(roundNumber(throughputMean)).to.be.equal(roundNumber(GO_PROD_RATE));
+ });
+ });
- it('returns some data', () => {
- expect(throughput.currentPeriod.length).to.be.greaterThan(0);
- const hasData = throughput.currentPeriod.some(({ y }) => isFiniteNumber(y));
- expect(hasData).to.equal(true);
- });
+ describe('when synth-java is selected', () => {
+ let throughput: ThroughputReturn;
- it('returns correct average throughput', () => {
- const throughputMean = meanBy(throughput.currentPeriod, 'y');
- expect(roundNumber(throughputMean)).to.be.equal(roundNumber(GO_PROD_RATE));
- });
+ before(async () => {
+ const throughputResponse = await callApi({ path: { serviceName: 'synth-java' } });
+ throughput = throughputResponse.body;
});
- describe('when synth-java is selected', () => {
- let throughput: ThroughputReturn;
+ it('returns some data', () => {
+ expect(throughput.currentPeriod.length).to.be.greaterThan(0);
+ const hasData = throughput.currentPeriod.some(({ y }) => isFiniteNumber(y));
+ expect(hasData).to.equal(true);
+ });
- before(async () => {
- const throughputResponse = await callApi({ path: { serviceName: 'synth-java' } });
- throughput = throughputResponse.body;
- });
+ it('returns throughput related to java agent', () => {
+ const throughputMean = meanBy(throughput.currentPeriod, 'y');
+ expect(roundNumber(throughputMean)).to.be.equal(roundNumber(JAVA_PROD_RATE));
+ });
+ });
- it('returns some data', () => {
- expect(throughput.currentPeriod.length).to.be.greaterThan(0);
- const hasData = throughput.currentPeriod.some(({ y }) => isFiniteNumber(y));
- expect(hasData).to.equal(true);
- });
+ describe('time comparisons', () => {
+ let throughputResponse: ThroughputReturn;
- it('returns throughput related to java agent', () => {
- const throughputMean = meanBy(throughput.currentPeriod, 'y');
- expect(roundNumber(throughputMean)).to.be.equal(roundNumber(JAVA_PROD_RATE));
+ before(async () => {
+ const response = await callApi({
+ query: {
+ start: moment(end).subtract(7, 'minutes').toISOString(),
+ end: new Date(end).toISOString(),
+ offset: '7m',
+ },
});
+ throughputResponse = response.body;
});
- describe('time comparisons', () => {
- let throughputResponse: ThroughputReturn;
-
- before(async () => {
- const response = await callApi({
- query: {
- start: moment(end).subtract(7, 'minutes').toISOString(),
- end: new Date(end).toISOString(),
- offset: '7m',
- },
- });
- throughputResponse = response.body;
- });
+ it('returns some data', () => {
+ expect(throughputResponse.currentPeriod.length).to.be.greaterThan(0);
+ expect(throughputResponse.previousPeriod.length).to.be.greaterThan(0);
- it('returns some data', () => {
- expect(throughputResponse.currentPeriod.length).to.be.greaterThan(0);
- expect(throughputResponse.previousPeriod.length).to.be.greaterThan(0);
+ const hasCurrentPeriodData = throughputResponse.currentPeriod.some(({ y }) =>
+ isFiniteNumber(y)
+ );
+ const hasPreviousPeriodData = throughputResponse.previousPeriod.some(({ y }) =>
+ isFiniteNumber(y)
+ );
- const hasCurrentPeriodData = throughputResponse.currentPeriod.some(({ y }) =>
- isFiniteNumber(y)
- );
- const hasPreviousPeriodData = throughputResponse.previousPeriod.some(({ y }) =>
- isFiniteNumber(y)
- );
-
- expect(hasCurrentPeriodData).to.equal(true);
- expect(hasPreviousPeriodData).to.equal(true);
- });
+ expect(hasCurrentPeriodData).to.equal(true);
+ expect(hasPreviousPeriodData).to.equal(true);
+ });
- it('has same start time for both periods', () => {
- expect(first(throughputResponse.currentPeriod)?.x).to.equal(
- first(throughputResponse.previousPeriod)?.x
- );
- });
+ it('has same start time for both periods', () => {
+ expect(first(throughputResponse.currentPeriod)?.x).to.equal(
+ first(throughputResponse.previousPeriod)?.x
+ );
+ });
- it('has same end time for both periods', () => {
- expect(last(throughputResponse.currentPeriod)?.x).to.equal(
- last(throughputResponse.previousPeriod)?.x
- );
- });
+ it('has same end time for both periods', () => {
+ expect(last(throughputResponse.currentPeriod)?.x).to.equal(
+ last(throughputResponse.previousPeriod)?.x
+ );
+ });
- it('returns same number of buckets for both periods', () => {
- expect(throughputResponse.currentPeriod.length).to.be(
- throughputResponse.previousPeriod.length
- );
- });
+ it('returns same number of buckets for both periods', () => {
+ expect(throughputResponse.currentPeriod.length).to.be(
+ throughputResponse.previousPeriod.length
+ );
+ });
- it('has same mean value for both periods', () => {
- const currentPeriodMean = meanBy(
- throughputResponse.currentPeriod.filter(
- (item) => isFiniteNumber(item.y) && item.y > 0
- ),
- 'y'
- );
- const previousPeriodMean = meanBy(
- throughputResponse.previousPeriod.filter(
- (item) => isFiniteNumber(item.y) && item.y > 0
- ),
- 'y'
- );
- const currentPeriod = throughputResponse.currentPeriod;
- const bucketSize = currentPeriod[1].x - currentPeriod[0].x;
- const durationAsMinutes = bucketSize / 1000 / 60;
- [currentPeriodMean, previousPeriodMean].every((value) =>
- expect(roundNumber(value)).to.be.equal(
- roundNumber((GO_PROD_RATE + GO_DEV_RATE) / durationAsMinutes)
- )
- );
- });
+ it('has same mean value for both periods', () => {
+ const currentPeriodMean = meanBy(
+ throughputResponse.currentPeriod.filter((item) => isFiniteNumber(item.y) && item.y > 0),
+ 'y'
+ );
+ const previousPeriodMean = meanBy(
+ throughputResponse.previousPeriod.filter(
+ (item) => isFiniteNumber(item.y) && item.y > 0
+ ),
+ 'y'
+ );
+ const currentPeriod = throughputResponse.currentPeriod;
+ const bucketSize = currentPeriod[1].x - currentPeriod[0].x;
+ const durationAsMinutes = bucketSize / 1000 / 60;
+ [currentPeriodMean, previousPeriodMean].every((value) =>
+ expect(roundNumber(value)).to.be.equal(
+ roundNumber((GO_PROD_RATE + GO_DEV_RATE) / durationAsMinutes)
+ )
+ );
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/services/top_services.spec.ts b/x-pack/test/apm_api_integration/tests/services/top_services.spec.ts
index 960c7e55f415340..898f12ceaeffb27 100644
--- a/x-pack/test/apm_api_integration/tests/services/top_services.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/services/top_services.spec.ts
@@ -33,7 +33,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'APM Services Overview with a basic license when data is not generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
it('handles the empty state', async () => {
const response = await apmApiClient.readUser({
@@ -57,7 +57,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when(
'APM Services Overview with a basic license when data is generated',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
+ { config: 'basic', archives: [] },
() => {
let response: {
status: number;
diff --git a/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts b/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts
index e4960791eee5acd..696c57779fb30c3 100644
--- a/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts
@@ -386,73 +386,69 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
}
);
- registry.when(
- 'Agent configurations through fleet',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- const name = 'myservice';
- const environment = 'development';
- const testConfig = {
- service: { name, environment },
- settings: { transaction_sample_rate: '0.9' },
- };
-
- let agentConfiguration:
- | APIReturnType<'GET /api/apm/settings/agent-configuration/view'>
- | undefined;
-
- before(async () => {
- log.debug('creating agent configuration');
- await createConfiguration(testConfig);
- const { body } = await findExactConfiguration(name, environment);
- agentConfiguration = body;
- });
+ registry.when('Agent configurations through fleet', { config: 'basic', archives: [] }, () => {
+ const name = 'myservice';
+ const environment = 'development';
+ const testConfig = {
+ service: { name, environment },
+ settings: { transaction_sample_rate: '0.9' },
+ };
+
+ let agentConfiguration:
+ | APIReturnType<'GET /api/apm/settings/agent-configuration/view'>
+ | undefined;
+
+ before(async () => {
+ log.debug('creating agent configuration');
+ await createConfiguration(testConfig);
+ const { body } = await findExactConfiguration(name, environment);
+ agentConfiguration = body;
+ });
- after(async () => {
- await deleteConfiguration(testConfig);
- });
+ after(async () => {
+ await deleteConfiguration(testConfig);
+ });
- it(`should have 'applied_by_agent=false' when there are no agent config metrics for this etag`, async () => {
- expect(agentConfiguration?.applied_by_agent).to.be(false);
- });
+ it(`should have 'applied_by_agent=false' when there are no agent config metrics for this etag`, async () => {
+ expect(agentConfiguration?.applied_by_agent).to.be(false);
+ });
- describe('when there are agent config metrics for this etag', () => {
- before(async () => {
- const start = new Date().getTime();
- const end = moment(start).add(15, 'minutes').valueOf();
-
- await addAgentConfigMetrics({
- synthtraceEsClient,
- start,
- end,
- etag: agentConfiguration?.etag,
- });
+ describe('when there are agent config metrics for this etag', () => {
+ before(async () => {
+ const start = new Date().getTime();
+ const end = moment(start).add(15, 'minutes').valueOf();
+
+ await addAgentConfigMetrics({
+ synthtraceEsClient,
+ start,
+ end,
+ etag: agentConfiguration?.etag,
});
+ });
- after(() => synthtraceEsClient.clean());
+ after(() => synthtraceEsClient.clean());
- it(`should have 'applied_by_agent=true' when getting a config from all configurations`, async () => {
- const {
- body: { configurations },
- } = await getAllConfigurations();
+ it(`should have 'applied_by_agent=true' when getting a config from all configurations`, async () => {
+ const {
+ body: { configurations },
+ } = await getAllConfigurations();
- const updatedConfig = configurations.find(
- (x) => x.service.name === name && x.service.environment === environment
- );
+ const updatedConfig = configurations.find(
+ (x) => x.service.name === name && x.service.environment === environment
+ );
- expect(updatedConfig?.applied_by_agent).to.be(true);
- });
+ expect(updatedConfig?.applied_by_agent).to.be(true);
+ });
- it(`should have 'applied_by_agent=true' when getting a single config`, async () => {
- const {
- body: { applied_by_agent: appliedByAgent },
- } = await findExactConfiguration(name, environment);
+ it(`should have 'applied_by_agent=true' when getting a single config`, async () => {
+ const {
+ body: { applied_by_agent: appliedByAgent },
+ } = await findExactConfiguration(name, environment);
- expect(appliedByAgent).to.be(true);
- });
+ expect(appliedByAgent).to.be(true);
});
- }
- );
+ });
+ });
registry.when(
'agent configuration when data is loaded',
diff --git a/x-pack/test/apm_api_integration/tests/span_links/span_links.spec.ts b/x-pack/test/apm_api_integration/tests/span_links/span_links.spec.ts
index 3c9e669db62d433..09ca2f454f1e6c9 100644
--- a/x-pack/test/apm_api_integration/tests/span_links/span_links.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/span_links/span_links.spec.ts
@@ -18,479 +18,467 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const start = new Date('2022-01-01T00:00:00.000Z').getTime();
const end = new Date('2022-01-01T00:15:00.000Z').getTime() - 1;
- registry.when(
- 'contains linked children',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- let ids: ReturnType['ids'];
-
- before(async () => {
- const spanLinksData = generateSpanLinksData();
-
- ids = spanLinksData.ids;
-
- await synthtraceEsClient.index(
- new EntityArrayIterable(spanLinksData.apmFields.producerInternalOnly).merge(
- new EntityArrayIterable(spanLinksData.apmFields.producerExternalOnly),
- new EntityArrayIterable(spanLinksData.apmFields.producerConsumer),
- new EntityArrayIterable(spanLinksData.apmFields.producerMultiple)
- )
- );
- });
-
- after(() => synthtraceEsClient.clean());
-
- describe('Span links count on traces', () => {
- async function fetchTraces({ traceId }: { traceId: string }) {
- return await apmApiClient.readUser({
- endpoint: `GET /internal/apm/traces/{traceId}`,
- params: {
- path: { traceId },
- query: {
- start: new Date(start).toISOString(),
- end: new Date(end).toISOString(),
- },
+ registry.when('contains linked children', { config: 'basic', archives: [] }, () => {
+ let ids: ReturnType['ids'];
+
+ before(async () => {
+ const spanLinksData = generateSpanLinksData();
+
+ ids = spanLinksData.ids;
+
+ await synthtraceEsClient.index(
+ new EntityArrayIterable(spanLinksData.apmFields.producerInternalOnly).merge(
+ new EntityArrayIterable(spanLinksData.apmFields.producerExternalOnly),
+ new EntityArrayIterable(spanLinksData.apmFields.producerConsumer),
+ new EntityArrayIterable(spanLinksData.apmFields.producerMultiple)
+ )
+ );
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('Span links count on traces', () => {
+ async function fetchTraces({ traceId }: { traceId: string }) {
+ return await apmApiClient.readUser({
+ endpoint: `GET /internal/apm/traces/{traceId}`,
+ params: {
+ path: { traceId },
+ query: {
+ start: new Date(start).toISOString(),
+ end: new Date(end).toISOString(),
},
- });
- }
+ },
+ });
+ }
- describe('producer-internal-only trace', () => {
- let traces: Awaited>['body'];
- before(async () => {
- const tracesResponse = await fetchTraces({ traceId: ids.producerInternalOnly.traceId });
- traces = tracesResponse.body;
- });
+ describe('producer-internal-only trace', () => {
+ let traces: Awaited>['body'];
+ before(async () => {
+ const tracesResponse = await fetchTraces({ traceId: ids.producerInternalOnly.traceId });
+ traces = tracesResponse.body;
+ });
- it('contains two children link on Span A', () => {
- expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(1);
- expect(
- traces.linkedChildrenOfSpanCountBySpanId[ids.producerInternalOnly.spanAId]
- ).to.equal(2);
- });
+ it('contains two children link on Span A', () => {
+ expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(1);
+ expect(
+ traces.linkedChildrenOfSpanCountBySpanId[ids.producerInternalOnly.spanAId]
+ ).to.equal(2);
});
+ });
- describe('producer-external-only trace', () => {
- let traces: Awaited>['body'];
- before(async () => {
- const tracesResponse = await fetchTraces({ traceId: ids.producerExternalOnly.traceId });
- traces = tracesResponse.body;
- });
+ describe('producer-external-only trace', () => {
+ let traces: Awaited>['body'];
+ before(async () => {
+ const tracesResponse = await fetchTraces({ traceId: ids.producerExternalOnly.traceId });
+ traces = tracesResponse.body;
+ });
- it('contains two children link on Span B', () => {
- expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(2);
- expect(
- traces.linkedChildrenOfSpanCountBySpanId[ids.producerExternalOnly.spanBId]
- ).to.equal(1);
- expect(
- traces.linkedChildrenOfSpanCountBySpanId[ids.producerExternalOnly.transactionBId]
- ).to.equal(1);
- });
+ it('contains two children link on Span B', () => {
+ expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(2);
+ expect(
+ traces.linkedChildrenOfSpanCountBySpanId[ids.producerExternalOnly.spanBId]
+ ).to.equal(1);
+ expect(
+ traces.linkedChildrenOfSpanCountBySpanId[ids.producerExternalOnly.transactionBId]
+ ).to.equal(1);
});
+ });
- describe('producer-consumer trace', () => {
- let traces: Awaited>['body'];
- before(async () => {
- const tracesResponse = await fetchTraces({ traceId: ids.producerConsumer.traceId });
- traces = tracesResponse.body;
- });
+ describe('producer-consumer trace', () => {
+ let traces: Awaited>['body'];
+ before(async () => {
+ const tracesResponse = await fetchTraces({ traceId: ids.producerConsumer.traceId });
+ traces = tracesResponse.body;
+ });
- it('contains one children link on transaction C and two on span C', () => {
- expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(2);
- expect(
- traces.linkedChildrenOfSpanCountBySpanId[ids.producerConsumer.transactionCId]
- ).to.equal(1);
- expect(traces.linkedChildrenOfSpanCountBySpanId[ids.producerConsumer.spanCId]).to.equal(
- 1
- );
- });
+ it('contains one children link on transaction C and two on span C', () => {
+ expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(2);
+ expect(
+ traces.linkedChildrenOfSpanCountBySpanId[ids.producerConsumer.transactionCId]
+ ).to.equal(1);
+ expect(traces.linkedChildrenOfSpanCountBySpanId[ids.producerConsumer.spanCId]).to.equal(
+ 1
+ );
});
+ });
- describe('consumer-multiple trace', () => {
- let traces: Awaited>['body'];
- before(async () => {
- const tracesResponse = await fetchTraces({ traceId: ids.producerMultiple.traceId });
- traces = tracesResponse.body;
- });
+ describe('consumer-multiple trace', () => {
+ let traces: Awaited>['body'];
+ before(async () => {
+ const tracesResponse = await fetchTraces({ traceId: ids.producerMultiple.traceId });
+ traces = tracesResponse.body;
+ });
- it('contains no children', () => {
- expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(0);
- expect(
- traces.linkedChildrenOfSpanCountBySpanId[ids.producerMultiple.transactionDId]
- ).to.equal(undefined);
- expect(traces.linkedChildrenOfSpanCountBySpanId[ids.producerMultiple.spanEId]).to.equal(
- undefined
- );
- });
+ it('contains no children', () => {
+ expect(Object.values(traces.linkedChildrenOfSpanCountBySpanId).length).to.equal(0);
+ expect(
+ traces.linkedChildrenOfSpanCountBySpanId[ids.producerMultiple.transactionDId]
+ ).to.equal(undefined);
+ expect(traces.linkedChildrenOfSpanCountBySpanId[ids.producerMultiple.spanEId]).to.equal(
+ undefined
+ );
});
});
-
- describe('Span links details', () => {
- async function fetchChildrenAndParentsDetails({
- kuery,
- traceId,
- spanId,
- processorEvent,
- }: {
- kuery: string;
- traceId: string;
- spanId: string;
- processorEvent: ProcessorEvent;
- }) {
- const [childrenLinksResponse, parentsLinksResponse] = await Promise.all([
- await apmApiClient.readUser({
- endpoint: 'GET /internal/apm/traces/{traceId}/span_links/{spanId}/children',
- params: {
- path: { traceId, spanId },
- query: {
- kuery,
- start: new Date(start).toISOString(),
- end: new Date(end).toISOString(),
- },
+ });
+
+ describe('Span links details', () => {
+ async function fetchChildrenAndParentsDetails({
+ kuery,
+ traceId,
+ spanId,
+ processorEvent,
+ }: {
+ kuery: string;
+ traceId: string;
+ spanId: string;
+ processorEvent: ProcessorEvent;
+ }) {
+ const [childrenLinksResponse, parentsLinksResponse] = await Promise.all([
+ await apmApiClient.readUser({
+ endpoint: 'GET /internal/apm/traces/{traceId}/span_links/{spanId}/children',
+ params: {
+ path: { traceId, spanId },
+ query: {
+ kuery,
+ start: new Date(start).toISOString(),
+ end: new Date(end).toISOString(),
},
- }),
- apmApiClient.readUser({
- endpoint: 'GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents',
- params: {
- path: { traceId, spanId },
- query: {
- kuery,
- start: new Date(start).toISOString(),
- end: new Date(end).toISOString(),
- processorEvent,
- },
+ },
+ }),
+ apmApiClient.readUser({
+ endpoint: 'GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents',
+ params: {
+ path: { traceId, spanId },
+ query: {
+ kuery,
+ start: new Date(start).toISOString(),
+ end: new Date(end).toISOString(),
+ processorEvent,
},
+ },
+ }),
+ ]);
+
+ return {
+ childrenLinks: childrenLinksResponse.body,
+ parentsLinks: parentsLinksResponse.body,
+ };
+ }
+
+ describe('producer-internal-only span links details', () => {
+ let transactionALinksDetails: Awaited>;
+ let spanALinksDetails: Awaited>;
+ before(async () => {
+ const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all([
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerInternalOnly.traceId,
+ spanId: ids.producerInternalOnly.transactionAId,
+ processorEvent: ProcessorEvent.transaction,
+ }),
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerInternalOnly.traceId,
+ spanId: ids.producerInternalOnly.spanAId,
+ processorEvent: ProcessorEvent.span,
}),
]);
+ transactionALinksDetails = transactionALinksDetailsResponse;
+ spanALinksDetails = spanALinksDetailsResponse;
+ });
- return {
- childrenLinks: childrenLinksResponse.body,
- parentsLinks: parentsLinksResponse.body,
- };
- }
-
- describe('producer-internal-only span links details', () => {
- let transactionALinksDetails: Awaited>;
- let spanALinksDetails: Awaited>;
- before(async () => {
- const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all(
- [
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerInternalOnly.traceId,
- spanId: ids.producerInternalOnly.transactionAId,
- processorEvent: ProcessorEvent.transaction,
- }),
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerInternalOnly.traceId,
- spanId: ids.producerInternalOnly.spanAId,
- processorEvent: ProcessorEvent.span,
- }),
- ]
- );
- transactionALinksDetails = transactionALinksDetailsResponse;
- spanALinksDetails = spanALinksDetailsResponse;
- });
+ it('returns no links for transaction A', () => {
+ expect(transactionALinksDetails.childrenLinks.spanLinksDetails).to.eql([]);
+ expect(transactionALinksDetails.parentsLinks.spanLinksDetails).to.eql([]);
+ });
- it('returns no links for transaction A', () => {
- expect(transactionALinksDetails.childrenLinks.spanLinksDetails).to.eql([]);
- expect(transactionALinksDetails.parentsLinks.spanLinksDetails).to.eql([]);
- });
+ it('returns no parents on Span A', () => {
+ expect(spanALinksDetails.parentsLinks.spanLinksDetails).to.eql([]);
+ });
- it('returns no parents on Span A', () => {
- expect(spanALinksDetails.parentsLinks.spanLinksDetails).to.eql([]);
+ it('returns two children on Span A', () => {
+ expect(spanALinksDetails.childrenLinks.spanLinksDetails.length).to.eql(2);
+ const serviceCDetails = spanALinksDetails.childrenLinks.spanLinksDetails.find(
+ (childDetails) => {
+ return (
+ childDetails.traceId === ids.producerConsumer.traceId &&
+ childDetails.spanId === ids.producerConsumer.transactionCId
+ );
+ }
+ );
+ expect(serviceCDetails?.details).to.eql({
+ serviceName: 'producer-consumer',
+ agentName: 'ruby',
+ transactionId: ids.producerConsumer.transactionCId,
+ spanName: 'Transaction C',
+ duration: 1000000,
});
- it('returns two children on Span A', () => {
- expect(spanALinksDetails.childrenLinks.spanLinksDetails.length).to.eql(2);
- const serviceCDetails = spanALinksDetails.childrenLinks.spanLinksDetails.find(
- (childDetails) => {
- return (
- childDetails.traceId === ids.producerConsumer.traceId &&
- childDetails.spanId === ids.producerConsumer.transactionCId
- );
- }
- );
- expect(serviceCDetails?.details).to.eql({
- serviceName: 'producer-consumer',
- agentName: 'ruby',
- transactionId: ids.producerConsumer.transactionCId,
- spanName: 'Transaction C',
- duration: 1000000,
- });
-
- const serviceDDetails = spanALinksDetails.childrenLinks.spanLinksDetails.find(
- (childDetails) => {
- return (
- childDetails.traceId === ids.producerMultiple.traceId &&
- childDetails.spanId === ids.producerMultiple.transactionDId
- );
- }
- );
- expect(serviceDDetails?.details).to.eql({
- serviceName: 'consumer-multiple',
- agentName: 'nodejs',
- transactionId: ids.producerMultiple.transactionDId,
- spanName: 'Transaction D',
- duration: 1000000,
- });
+ const serviceDDetails = spanALinksDetails.childrenLinks.spanLinksDetails.find(
+ (childDetails) => {
+ return (
+ childDetails.traceId === ids.producerMultiple.traceId &&
+ childDetails.spanId === ids.producerMultiple.transactionDId
+ );
+ }
+ );
+ expect(serviceDDetails?.details).to.eql({
+ serviceName: 'consumer-multiple',
+ agentName: 'nodejs',
+ transactionId: ids.producerMultiple.transactionDId,
+ spanName: 'Transaction D',
+ duration: 1000000,
});
});
+ });
- describe('producer-external-only span links details', () => {
- let transactionBLinksDetails: Awaited>;
- let spanBLinksDetails: Awaited>;
- before(async () => {
- const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all(
- [
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerExternalOnly.traceId,
- spanId: ids.producerExternalOnly.transactionBId,
- processorEvent: ProcessorEvent.transaction,
- }),
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerExternalOnly.traceId,
- spanId: ids.producerExternalOnly.spanBId,
- processorEvent: ProcessorEvent.span,
- }),
- ]
- );
- transactionBLinksDetails = transactionALinksDetailsResponse;
- spanBLinksDetails = spanALinksDetailsResponse;
- });
+ describe('producer-external-only span links details', () => {
+ let transactionBLinksDetails: Awaited>;
+ let spanBLinksDetails: Awaited>;
+ before(async () => {
+ const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all([
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerExternalOnly.traceId,
+ spanId: ids.producerExternalOnly.transactionBId,
+ processorEvent: ProcessorEvent.transaction,
+ }),
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerExternalOnly.traceId,
+ spanId: ids.producerExternalOnly.spanBId,
+ processorEvent: ProcessorEvent.span,
+ }),
+ ]);
+ transactionBLinksDetails = transactionALinksDetailsResponse;
+ spanBLinksDetails = spanALinksDetailsResponse;
+ });
- it('returns producer-consumer as children of transaction B', () => {
- expect(transactionBLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
- });
+ it('returns producer-consumer as children of transaction B', () => {
+ expect(transactionBLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
+ });
- it('returns no parent for transaction B', () => {
- expect(transactionBLinksDetails.parentsLinks.spanLinksDetails).to.eql([]);
- });
+ it('returns no parent for transaction B', () => {
+ expect(transactionBLinksDetails.parentsLinks.spanLinksDetails).to.eql([]);
+ });
- it('returns external parent on Span B', () => {
- expect(spanBLinksDetails.parentsLinks.spanLinksDetails.length).to.be(1);
- expect(spanBLinksDetails.parentsLinks.spanLinksDetails).to.eql([
- { traceId: 'trace#1', spanId: 'span#1' },
- ]);
- });
+ it('returns external parent on Span B', () => {
+ expect(spanBLinksDetails.parentsLinks.spanLinksDetails.length).to.be(1);
+ expect(spanBLinksDetails.parentsLinks.spanLinksDetails).to.eql([
+ { traceId: 'trace#1', spanId: 'span#1' },
+ ]);
+ });
- it('returns consumer-multiple as child on Span B', () => {
- expect(spanBLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
- expect(spanBLinksDetails.childrenLinks.spanLinksDetails).to.eql([
- {
- traceId: ids.producerMultiple.traceId,
- spanId: ids.producerMultiple.spanEId,
- details: {
- serviceName: 'consumer-multiple',
- agentName: 'nodejs',
- transactionId: ids.producerMultiple.transactionDId,
- spanName: 'Span E',
- duration: 100000,
- spanSubtype: 'http',
- spanType: 'external',
- },
+ it('returns consumer-multiple as child on Span B', () => {
+ expect(spanBLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
+ expect(spanBLinksDetails.childrenLinks.spanLinksDetails).to.eql([
+ {
+ traceId: ids.producerMultiple.traceId,
+ spanId: ids.producerMultiple.spanEId,
+ details: {
+ serviceName: 'consumer-multiple',
+ agentName: 'nodejs',
+ transactionId: ids.producerMultiple.transactionDId,
+ spanName: 'Span E',
+ duration: 100000,
+ spanSubtype: 'http',
+ spanType: 'external',
},
- ]);
- });
+ },
+ ]);
});
+ });
- describe('producer-consumer span links details', () => {
- let transactionCLinksDetails: Awaited>;
- let spanCLinksDetails: Awaited>;
- before(async () => {
- const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all(
- [
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerConsumer.traceId,
- spanId: ids.producerConsumer.transactionCId,
- processorEvent: ProcessorEvent.transaction,
- }),
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerConsumer.traceId,
- spanId: ids.producerConsumer.spanCId,
- processorEvent: ProcessorEvent.span,
- }),
- ]
- );
- transactionCLinksDetails = transactionALinksDetailsResponse;
- spanCLinksDetails = spanALinksDetailsResponse;
- });
+ describe('producer-consumer span links details', () => {
+ let transactionCLinksDetails: Awaited>;
+ let spanCLinksDetails: Awaited>;
+ before(async () => {
+ const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all([
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerConsumer.traceId,
+ spanId: ids.producerConsumer.transactionCId,
+ processorEvent: ProcessorEvent.transaction,
+ }),
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerConsumer.traceId,
+ spanId: ids.producerConsumer.spanCId,
+ processorEvent: ProcessorEvent.span,
+ }),
+ ]);
+ transactionCLinksDetails = transactionALinksDetailsResponse;
+ spanCLinksDetails = spanALinksDetailsResponse;
+ });
- it('returns producer-internal-only Span A, producer-external-only Transaction B, and External link as parents of Transaction C', () => {
- expect(transactionCLinksDetails.parentsLinks.spanLinksDetails.length).to.be(3);
- expect(transactionCLinksDetails.parentsLinks.spanLinksDetails).to.eql([
- {
- traceId: ids.producerInternalOnly.traceId,
- spanId: ids.producerInternalOnly.spanAId,
- details: {
- serviceName: 'producer-internal-only',
- agentName: 'go',
- transactionId: ids.producerInternalOnly.transactionAId,
- spanName: 'Span A',
- duration: 100000,
- spanSubtype: 'http',
- spanType: 'external',
- },
- },
- {
- traceId: ids.producerExternalOnly.traceId,
- spanId: ids.producerExternalOnly.transactionBId,
- details: {
- serviceName: 'producer-external-only',
- agentName: 'java',
- transactionId: ids.producerExternalOnly.transactionBId,
- duration: 1000000,
- spanName: 'Transaction B',
- },
+ it('returns producer-internal-only Span A, producer-external-only Transaction B, and External link as parents of Transaction C', () => {
+ expect(transactionCLinksDetails.parentsLinks.spanLinksDetails.length).to.be(3);
+ expect(transactionCLinksDetails.parentsLinks.spanLinksDetails).to.eql([
+ {
+ traceId: ids.producerInternalOnly.traceId,
+ spanId: ids.producerInternalOnly.spanAId,
+ details: {
+ serviceName: 'producer-internal-only',
+ agentName: 'go',
+ transactionId: ids.producerInternalOnly.transactionAId,
+ spanName: 'Span A',
+ duration: 100000,
+ spanSubtype: 'http',
+ spanType: 'external',
},
- {
- traceId: ids.producerConsumer.externalTraceId,
- spanId: ids.producerExternalOnly.spanBId,
+ },
+ {
+ traceId: ids.producerExternalOnly.traceId,
+ spanId: ids.producerExternalOnly.transactionBId,
+ details: {
+ serviceName: 'producer-external-only',
+ agentName: 'java',
+ transactionId: ids.producerExternalOnly.transactionBId,
+ duration: 1000000,
+ spanName: 'Transaction B',
},
- ]);
- });
+ },
+ {
+ traceId: ids.producerConsumer.externalTraceId,
+ spanId: ids.producerExternalOnly.spanBId,
+ },
+ ]);
+ });
- it('returns consumer-multiple Span E as child of Transaction C', () => {
- expect(transactionCLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
- expect(transactionCLinksDetails.childrenLinks.spanLinksDetails).to.eql([
- {
- traceId: ids.producerMultiple.traceId,
- spanId: ids.producerMultiple.spanEId,
- details: {
- serviceName: 'consumer-multiple',
- agentName: 'nodejs',
- transactionId: ids.producerMultiple.transactionDId,
- spanName: 'Span E',
- duration: 100000,
- spanSubtype: 'http',
- spanType: 'external',
- },
+ it('returns consumer-multiple Span E as child of Transaction C', () => {
+ expect(transactionCLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
+ expect(transactionCLinksDetails.childrenLinks.spanLinksDetails).to.eql([
+ {
+ traceId: ids.producerMultiple.traceId,
+ spanId: ids.producerMultiple.spanEId,
+ details: {
+ serviceName: 'consumer-multiple',
+ agentName: 'nodejs',
+ transactionId: ids.producerMultiple.transactionDId,
+ spanName: 'Span E',
+ duration: 100000,
+ spanSubtype: 'http',
+ spanType: 'external',
},
- ]);
- });
+ },
+ ]);
+ });
- it('returns no child on Span C', () => {
- expect(spanCLinksDetails.parentsLinks.spanLinksDetails.length).to.be(0);
- });
+ it('returns no child on Span C', () => {
+ expect(spanCLinksDetails.parentsLinks.spanLinksDetails.length).to.be(0);
+ });
- it('returns consumer-multiple as Child on producer-consumer', () => {
- expect(spanCLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
- expect(spanCLinksDetails.childrenLinks.spanLinksDetails).to.eql([
- {
- traceId: ids.producerMultiple.traceId,
- spanId: ids.producerMultiple.transactionDId,
- details: {
- serviceName: 'consumer-multiple',
- agentName: 'nodejs',
- transactionId: ids.producerMultiple.transactionDId,
- spanName: 'Transaction D',
- duration: 1000000,
- },
+ it('returns consumer-multiple as Child on producer-consumer', () => {
+ expect(spanCLinksDetails.childrenLinks.spanLinksDetails.length).to.be(1);
+ expect(spanCLinksDetails.childrenLinks.spanLinksDetails).to.eql([
+ {
+ traceId: ids.producerMultiple.traceId,
+ spanId: ids.producerMultiple.transactionDId,
+ details: {
+ serviceName: 'consumer-multiple',
+ agentName: 'nodejs',
+ transactionId: ids.producerMultiple.transactionDId,
+ spanName: 'Transaction D',
+ duration: 1000000,
},
- ]);
- });
+ },
+ ]);
});
+ });
- describe('consumer-multiple span links details', () => {
- let transactionDLinksDetails: Awaited>;
- let spanELinksDetails: Awaited>;
- before(async () => {
- const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all(
- [
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerMultiple.traceId,
- spanId: ids.producerMultiple.transactionDId,
- processorEvent: ProcessorEvent.transaction,
- }),
- fetchChildrenAndParentsDetails({
- kuery: '',
- traceId: ids.producerMultiple.traceId,
- spanId: ids.producerMultiple.spanEId,
- processorEvent: ProcessorEvent.span,
- }),
- ]
- );
- transactionDLinksDetails = transactionALinksDetailsResponse;
- spanELinksDetails = spanALinksDetailsResponse;
- });
+ describe('consumer-multiple span links details', () => {
+ let transactionDLinksDetails: Awaited>;
+ let spanELinksDetails: Awaited>;
+ before(async () => {
+ const [transactionALinksDetailsResponse, spanALinksDetailsResponse] = await Promise.all([
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerMultiple.traceId,
+ spanId: ids.producerMultiple.transactionDId,
+ processorEvent: ProcessorEvent.transaction,
+ }),
+ fetchChildrenAndParentsDetails({
+ kuery: '',
+ traceId: ids.producerMultiple.traceId,
+ spanId: ids.producerMultiple.spanEId,
+ processorEvent: ProcessorEvent.span,
+ }),
+ ]);
+ transactionDLinksDetails = transactionALinksDetailsResponse;
+ spanELinksDetails = spanALinksDetailsResponse;
+ });
- it('returns producer-internal-only Span A and producer-consumer Span C as parents of Transaction D', () => {
- expect(transactionDLinksDetails.parentsLinks.spanLinksDetails.length).to.be(2);
- expect(transactionDLinksDetails.parentsLinks.spanLinksDetails).to.eql([
- {
- traceId: ids.producerInternalOnly.traceId,
- spanId: ids.producerInternalOnly.spanAId,
- details: {
- serviceName: 'producer-internal-only',
- agentName: 'go',
- transactionId: ids.producerInternalOnly.transactionAId,
- spanName: 'Span A',
- duration: 100000,
- spanSubtype: 'http',
- spanType: 'external',
- },
+ it('returns producer-internal-only Span A and producer-consumer Span C as parents of Transaction D', () => {
+ expect(transactionDLinksDetails.parentsLinks.spanLinksDetails.length).to.be(2);
+ expect(transactionDLinksDetails.parentsLinks.spanLinksDetails).to.eql([
+ {
+ traceId: ids.producerInternalOnly.traceId,
+ spanId: ids.producerInternalOnly.spanAId,
+ details: {
+ serviceName: 'producer-internal-only',
+ agentName: 'go',
+ transactionId: ids.producerInternalOnly.transactionAId,
+ spanName: 'Span A',
+ duration: 100000,
+ spanSubtype: 'http',
+ spanType: 'external',
},
- {
- traceId: ids.producerConsumer.traceId,
- spanId: ids.producerConsumer.spanCId,
- details: {
- serviceName: 'producer-consumer',
- agentName: 'ruby',
- transactionId: ids.producerConsumer.transactionCId,
- spanName: 'Span C',
- duration: 100000,
- spanSubtype: 'http',
- spanType: 'external',
- },
+ },
+ {
+ traceId: ids.producerConsumer.traceId,
+ spanId: ids.producerConsumer.spanCId,
+ details: {
+ serviceName: 'producer-consumer',
+ agentName: 'ruby',
+ transactionId: ids.producerConsumer.transactionCId,
+ spanName: 'Span C',
+ duration: 100000,
+ spanSubtype: 'http',
+ spanType: 'external',
},
- ]);
- });
+ },
+ ]);
+ });
- it('returns no children on Transaction D', () => {
- expect(transactionDLinksDetails.childrenLinks.spanLinksDetails.length).to.be(0);
- });
+ it('returns no children on Transaction D', () => {
+ expect(transactionDLinksDetails.childrenLinks.spanLinksDetails.length).to.be(0);
+ });
- it('returns producer-external-only Span B and producer-consumer Transaction C as parents of Span E', () => {
- expect(spanELinksDetails.parentsLinks.spanLinksDetails.length).to.be(2);
-
- expect(spanELinksDetails.parentsLinks.spanLinksDetails).to.eql([
- {
- traceId: ids.producerExternalOnly.traceId,
- spanId: ids.producerExternalOnly.spanBId,
- details: {
- serviceName: 'producer-external-only',
- agentName: 'java',
- transactionId: ids.producerExternalOnly.transactionBId,
- spanName: 'Span B',
- duration: 100000,
- spanSubtype: 'http',
- spanType: 'external',
- },
+ it('returns producer-external-only Span B and producer-consumer Transaction C as parents of Span E', () => {
+ expect(spanELinksDetails.parentsLinks.spanLinksDetails.length).to.be(2);
+
+ expect(spanELinksDetails.parentsLinks.spanLinksDetails).to.eql([
+ {
+ traceId: ids.producerExternalOnly.traceId,
+ spanId: ids.producerExternalOnly.spanBId,
+ details: {
+ serviceName: 'producer-external-only',
+ agentName: 'java',
+ transactionId: ids.producerExternalOnly.transactionBId,
+ spanName: 'Span B',
+ duration: 100000,
+ spanSubtype: 'http',
+ spanType: 'external',
},
- {
- traceId: ids.producerConsumer.traceId,
- spanId: ids.producerConsumer.transactionCId,
- details: {
- serviceName: 'producer-consumer',
- agentName: 'ruby',
- transactionId: ids.producerConsumer.transactionCId,
- spanName: 'Transaction C',
- duration: 1000000,
- },
+ },
+ {
+ traceId: ids.producerConsumer.traceId,
+ spanId: ids.producerConsumer.transactionCId,
+ details: {
+ serviceName: 'producer-consumer',
+ agentName: 'ruby',
+ transactionId: ids.producerConsumer.transactionCId,
+ spanName: 'Transaction C',
+ duration: 1000000,
},
- ]);
- });
+ },
+ ]);
+ });
- it('returns no children on Span E', () => {
- expect(spanELinksDetails.childrenLinks.spanLinksDetails.length).to.be(0);
- });
+ it('returns no children on Span E', () => {
+ expect(spanELinksDetails.childrenLinks.spanLinksDetails.length).to.be(0);
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts
index 58be27fe311ae03..c990a7c632caa97 100644
--- a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.spec.ts
@@ -93,149 +93,145 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let throughputValues: Awaited>;
- registry.when(
- 'Dependencies throughput value',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded', () => {
- const GO_PROD_RATE = 75;
- const JAVA_PROD_RATE = 25;
+ registry.when('Dependencies throughput value', { config: 'basic', archives: [] }, () => {
+ describe('when data is loaded', () => {
+ const GO_PROD_RATE = 75;
+ const JAVA_PROD_RATE = 25;
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service('synth-go', 'production', 'go')
+ .instance('instance-a');
+ const serviceJavaInstance = apm
+ .service('synth-java', 'development', 'java')
+ .instance('instance-c');
+
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction('GET /api/product/list')
+ .duration(1000)
+ .timestamp(timestamp)
+ .children(
+ serviceGoProdInstance
+ .span('GET apm-*/_search', 'db', 'elasticsearch')
+ .duration(1000)
+ .success()
+ .destination('elasticsearch')
+ .timestamp(timestamp),
+ serviceGoProdInstance
+ .span('custom_operation', 'app')
+ .duration(550)
+ .children(
+ serviceGoProdInstance
+ .span('SELECT FROM products', 'db', 'postgresql')
+ .duration(500)
+ .success()
+ .destination('postgresql')
+ .timestamp(timestamp)
+ )
+ .success()
+ .timestamp(timestamp)
+ )
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(JAVA_PROD_RATE)
+ .generator((timestamp) =>
+ serviceJavaInstance
+ .transaction('POST /api/product/buy')
+ .duration(1000)
+ .timestamp(timestamp)
+ .children(
+ serviceJavaInstance
+ .span('GET apm-*/_search', 'db', 'elasticsearch')
+ .duration(1000)
+ .success()
+ .destination('elasticsearch')
+ .timestamp(timestamp),
+ serviceJavaInstance
+ .span('custom_operation', 'app')
+ .duration(50)
+ .success()
+ .timestamp(timestamp)
+ )
+ ),
+ ]);
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('verify top dependencies', () => {
before(async () => {
- const serviceGoProdInstance = apm
- .service('synth-go', 'production', 'go')
- .instance('instance-a');
- const serviceJavaInstance = apm
- .service('synth-java', 'development', 'java')
- .instance('instance-c');
-
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction('GET /api/product/list')
- .duration(1000)
- .timestamp(timestamp)
- .children(
- serviceGoProdInstance
- .span('GET apm-*/_search', 'db', 'elasticsearch')
- .duration(1000)
- .success()
- .destination('elasticsearch')
- .timestamp(timestamp),
- serviceGoProdInstance
- .span('custom_operation', 'app')
- .duration(550)
- .children(
- serviceGoProdInstance
- .span('SELECT FROM products', 'db', 'postgresql')
- .duration(500)
- .success()
- .destination('postgresql')
- .timestamp(timestamp)
- )
- .success()
- .timestamp(timestamp)
- )
- ),
- timerange(start, end)
- .interval('1m')
- .rate(JAVA_PROD_RATE)
- .generator((timestamp) =>
- serviceJavaInstance
- .transaction('POST /api/product/buy')
- .duration(1000)
- .timestamp(timestamp)
- .children(
- serviceJavaInstance
- .span('GET apm-*/_search', 'db', 'elasticsearch')
- .duration(1000)
- .success()
- .destination('elasticsearch')
- .timestamp(timestamp),
- serviceJavaInstance
- .span('custom_operation', 'app')
- .duration(50)
- .success()
- .timestamp(timestamp)
- )
- ),
- ]);
+ throughputValues = await getThroughputValues();
});
- after(() => synthtraceEsClient.clean());
+ it('returns elasticsearch and postgresql as dependencies', () => {
+ const { topDependencies } = throughputValues;
+ const topDependenciesAsObj = Object.fromEntries(topDependencies);
+ expect(topDependenciesAsObj.elasticsearch).to.equal(
+ roundNumber(JAVA_PROD_RATE + GO_PROD_RATE)
+ );
+ expect(topDependenciesAsObj.postgresql).to.equal(roundNumber(GO_PROD_RATE));
+ });
+ });
- describe('verify top dependencies', () => {
+ describe('compare throughput value between top backends, backend throughput chart and upstream services apis', () => {
+ describe('elasticsearch dependency', () => {
before(async () => {
- throughputValues = await getThroughputValues();
+ throughputValues = await getThroughputValues({ dependencyName: 'elasticsearch' });
+ });
+
+ it('matches throughput values between throughput chart and top dependency', () => {
+ const { topDependencies, dependencyThroughputChartMean } = throughputValues;
+ const topDependenciesAsObj = Object.fromEntries(topDependencies);
+ const elasticsearchDependency = topDependenciesAsObj.elasticsearch;
+ [elasticsearchDependency, dependencyThroughputChartMean].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(JAVA_PROD_RATE + GO_PROD_RATE))
+ );
});
- it('returns elasticsearch and postgresql as dependencies', () => {
- const { topDependencies } = throughputValues;
+ it('matches throughput values between upstream services and top dependency', () => {
+ const { topDependencies, upstreamServicesThroughput } = throughputValues;
const topDependenciesAsObj = Object.fromEntries(topDependencies);
- expect(topDependenciesAsObj.elasticsearch).to.equal(
- roundNumber(JAVA_PROD_RATE + GO_PROD_RATE)
+ const elasticsearchDependency = topDependenciesAsObj.elasticsearch;
+ const upstreamServiceThroughputSum = roundNumber(
+ sumBy(upstreamServicesThroughput, 'throughput')
+ );
+ [elasticsearchDependency, upstreamServiceThroughputSum].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(JAVA_PROD_RATE + GO_PROD_RATE))
);
- expect(topDependenciesAsObj.postgresql).to.equal(roundNumber(GO_PROD_RATE));
});
});
+ describe('postgresql dependency', () => {
+ before(async () => {
+ throughputValues = await getThroughputValues({ dependencyName: 'postgresql' });
+ });
- describe('compare throughput value between top backends, backend throughput chart and upstream services apis', () => {
- describe('elasticsearch dependency', () => {
- before(async () => {
- throughputValues = await getThroughputValues({ dependencyName: 'elasticsearch' });
- });
-
- it('matches throughput values between throughput chart and top dependency', () => {
- const { topDependencies, dependencyThroughputChartMean } = throughputValues;
- const topDependenciesAsObj = Object.fromEntries(topDependencies);
- const elasticsearchDependency = topDependenciesAsObj.elasticsearch;
- [elasticsearchDependency, dependencyThroughputChartMean].forEach((value) =>
- expect(value).to.be.equal(roundNumber(JAVA_PROD_RATE + GO_PROD_RATE))
- );
- });
-
- it('matches throughput values between upstream services and top dependency', () => {
- const { topDependencies, upstreamServicesThroughput } = throughputValues;
- const topDependenciesAsObj = Object.fromEntries(topDependencies);
- const elasticsearchDependency = topDependenciesAsObj.elasticsearch;
- const upstreamServiceThroughputSum = roundNumber(
- sumBy(upstreamServicesThroughput, 'throughput')
- );
- [elasticsearchDependency, upstreamServiceThroughputSum].forEach((value) =>
- expect(value).to.be.equal(roundNumber(JAVA_PROD_RATE + GO_PROD_RATE))
- );
- });
+ it('matches throughput values between throughput chart and top dependency', () => {
+ const { topDependencies, dependencyThroughputChartMean } = throughputValues;
+ const topDependenciesAsObj = Object.fromEntries(topDependencies);
+ const postgresqlDependency = topDependenciesAsObj.postgresql;
+ [postgresqlDependency, dependencyThroughputChartMean].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(GO_PROD_RATE))
+ );
});
- describe('postgresql dependency', () => {
- before(async () => {
- throughputValues = await getThroughputValues({ dependencyName: 'postgresql' });
- });
-
- it('matches throughput values between throughput chart and top dependency', () => {
- const { topDependencies, dependencyThroughputChartMean } = throughputValues;
- const topDependenciesAsObj = Object.fromEntries(topDependencies);
- const postgresqlDependency = topDependenciesAsObj.postgresql;
- [postgresqlDependency, dependencyThroughputChartMean].forEach((value) =>
- expect(value).to.be.equal(roundNumber(GO_PROD_RATE))
- );
- });
-
- it('matches throughput values between upstream services and top dependency', () => {
- const { topDependencies, upstreamServicesThroughput } = throughputValues;
- const topDependenciesAsObj = Object.fromEntries(topDependencies);
- const postgresqlDependency = topDependenciesAsObj.postgresql;
- const upstreamServiceThroughputSum = roundNumber(
- sumBy(upstreamServicesThroughput, 'throughput')
- );
- [postgresqlDependency, upstreamServiceThroughputSum].forEach((value) =>
- expect(value).to.be.equal(roundNumber(GO_PROD_RATE))
- );
- });
+
+ it('matches throughput values between upstream services and top dependency', () => {
+ const { topDependencies, upstreamServicesThroughput } = throughputValues;
+ const topDependenciesAsObj = Object.fromEntries(topDependencies);
+ const postgresqlDependency = topDependenciesAsObj.postgresql;
+ const upstreamServiceThroughputSum = roundNumber(
+ sumBy(upstreamServicesThroughput, 'throughput')
+ );
+ [postgresqlDependency, upstreamServiceThroughputSum].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(GO_PROD_RATE))
+ );
});
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts b/x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts
index 41124abf10c5f45..ef091dc83a429e9 100644
--- a/x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/throughput/service_apis.spec.ts
@@ -104,7 +104,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let throughputMetricValues: Awaited>;
let throughputTransactionValues: Awaited>;
- registry.when('Services APIs', { config: 'basic', archives: ['apm_mappings_only_8.0.0'] }, () => {
+ registry.when('Services APIs', { config: 'basic', archives: [] }, () => {
describe('when data is loaded ', () => {
const GO_PROD_RATE = 80;
const GO_DEV_RATE = 20;
diff --git a/x-pack/test/apm_api_integration/tests/throughput/service_maps.spec.ts b/x-pack/test/apm_api_integration/tests/throughput/service_maps.spec.ts
index c3dc9adcaef1958..fd775ec9af2a9e3 100644
--- a/x-pack/test/apm_api_integration/tests/throughput/service_maps.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/throughput/service_maps.spec.ts
@@ -69,74 +69,67 @@ export default function ApiTest({ getService }: FtrProviderContext) {
let throughputMetricValues: Awaited>;
let throughputTransactionValues: Awaited>;
- registry.when(
- 'Service maps APIs',
- { config: 'trial', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('when data is loaded ', () => {
- const GO_PROD_RATE = 80;
- const GO_DEV_RATE = 20;
+ registry.when('Service maps APIs', { config: 'trial', archives: [] }, () => {
+ describe('when data is loaded ', () => {
+ const GO_PROD_RATE = 80;
+ const GO_DEV_RATE = 20;
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service(serviceName, 'production', 'go')
+ .instance('instance-a');
+ const serviceGoDevInstance = apm
+ .service(serviceName, 'development', 'go')
+ .instance('instance-b');
+
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction('GET /apple 🍎 ', 'Worker')
+ .duration(1000)
+ .timestamp(timestamp)
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_DEV_RATE)
+ .generator((timestamp) =>
+ serviceGoDevInstance.transaction('GET /apple 🍎 ').duration(1000).timestamp(timestamp)
+ ),
+ ]);
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('compare throughput value between service inventory and service maps', () => {
before(async () => {
- const serviceGoProdInstance = apm
- .service(serviceName, 'production', 'go')
- .instance('instance-a');
- const serviceGoDevInstance = apm
- .service(serviceName, 'development', 'go')
- .instance('instance-b');
-
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction('GET /apple 🍎 ', 'Worker')
- .duration(1000)
- .timestamp(timestamp)
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_DEV_RATE)
- .generator((timestamp) =>
- serviceGoDevInstance
- .transaction('GET /apple 🍎 ')
- .duration(1000)
- .timestamp(timestamp)
- ),
+ [throughputTransactionValues, throughputMetricValues] = await Promise.all([
+ getThroughputValues('transaction'),
+ getThroughputValues('metric'),
]);
});
- after(() => synthtraceEsClient.clean());
-
- describe('compare throughput value between service inventory and service maps', () => {
- before(async () => {
- [throughputTransactionValues, throughputMetricValues] = await Promise.all([
- getThroughputValues('transaction'),
- getThroughputValues('metric'),
- ]);
- });
-
- it('returns same throughput value for Transaction-based and Metric-based data', () => {
- [
- ...Object.values(throughputTransactionValues),
- ...Object.values(throughputMetricValues),
- ].forEach((value) => expect(roundNumber(value)).to.be.equal(GO_DEV_RATE));
- });
+ it('returns same throughput value for Transaction-based and Metric-based data', () => {
+ [
+ ...Object.values(throughputTransactionValues),
+ ...Object.values(throughputMetricValues),
+ ].forEach((value) => expect(roundNumber(value)).to.be.equal(GO_DEV_RATE));
+ });
+ });
+
+ describe('when calling service maps transactions stats api', () => {
+ let serviceMapsNodeThroughput: number | null | undefined;
+ before(async () => {
+ const response = await callApi();
+ serviceMapsNodeThroughput =
+ response.body.currentPeriod.transactionStats?.throughput?.value;
});
- describe('when calling service maps transactions stats api', () => {
- let serviceMapsNodeThroughput: number | null | undefined;
- before(async () => {
- const response = await callApi();
- serviceMapsNodeThroughput =
- response.body.currentPeriod.transactionStats?.throughput?.value;
- });
-
- it('returns expected throughput value', () => {
- expect(roundNumber(serviceMapsNodeThroughput)).to.be.equal(GO_DEV_RATE);
- });
+ it('returns expected throughput value', () => {
+ expect(roundNumber(serviceMapsNodeThroughput)).to.be.equal(GO_DEV_RATE);
});
});
- }
- );
+ });
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/traces/find_traces.spec.ts b/x-pack/test/apm_api_integration/tests/traces/find_traces.spec.ts
index b71beb0513af21d..0c0696f801a9528 100644
--- a/x-pack/test/apm_api_integration/tests/traces/find_traces.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/traces/find_traces.spec.ts
@@ -80,185 +80,146 @@ export default function ApiTest({ getService }: FtrProviderContext) {
);
}
- registry.when(
- 'Find traces when traces do not exist',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- it('handles empty state', async () => {
- const response = await fetchTraceSamples({
- query: '',
- type: TraceSearchType.kql,
- environment: ENVIRONMENT_ALL.value,
- });
-
- expect(response.status).to.be(200);
- expect(response.body).to.eql({
- samples: [],
- });
+ registry.when('Find traces when traces do not exist', { config: 'basic', archives: [] }, () => {
+ it('handles empty state', async () => {
+ const response = await fetchTraceSamples({
+ query: '',
+ type: TraceSearchType.kql,
+ environment: ENVIRONMENT_ALL.value,
});
- }
- );
-
- registry.when(
- 'Find traces when traces exist',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- before(() => {
- const java = apm.service('java', 'production', 'java').instance('java');
-
- const node = apm.service('node', 'development', 'nodejs').instance('node');
-
- const python = apm.service('python', 'production', 'python').instance('python');
-
- function generateTrace(
- timestamp: number,
- order: Instance[],
- db?: 'elasticsearch' | 'redis'
- ) {
- return order
- .concat()
- .reverse()
- .reduce((prev, instance, index) => {
- const invertedIndex = order.length - index - 1;
-
- const duration = 50;
- const time = timestamp + invertedIndex * 10;
-
- const transaction: Transaction = instance
- .transaction(`GET /${instance.fields['service.name']!}/api`)
- .timestamp(time)
- .duration(duration);
-
- if (prev) {
- const next = order[invertedIndex + 1].fields['service.name']!;
- transaction.children(
- instance
- .span(`GET ${next}/api`, 'external', 'http')
- .destination(next)
- .duration(duration)
- .timestamp(time + 1)
- .children(prev)
- );
- } else if (db) {
- transaction.children(
- instance
- .span(db, 'db', db)
- .destination(db)
- .duration(duration)
- .timestamp(time + 1)
- );
- }
- return transaction;
- }, undefined)!;
- }
-
- return synthtraceEsClient.index(
- timerange(start, end)
- .interval('15m')
- .rate(1)
- .generator((timestamp) => {
- return [
- generateTrace(timestamp, [java, node]),
- generateTrace(timestamp, [node, java], 'redis'),
- generateTrace(timestamp, [python], 'redis'),
- generateTrace(timestamp, [python, node, java], 'elasticsearch'),
- generateTrace(timestamp, [java, python, node]),
- ];
- })
- );
+ expect(response.status).to.be(200);
+ expect(response.body).to.eql({
+ samples: [],
});
+ });
+ });
+
+ registry.when('Find traces when traces exist', { config: 'basic', archives: [] }, () => {
+ before(() => {
+ const java = apm.service('java', 'production', 'java').instance('java');
+
+ const node = apm.service('node', 'development', 'nodejs').instance('node');
+
+ const python = apm.service('python', 'production', 'python').instance('python');
+
+ function generateTrace(timestamp: number, order: Instance[], db?: 'elasticsearch' | 'redis') {
+ return order
+ .concat()
+ .reverse()
+ .reduce((prev, instance, index) => {
+ const invertedIndex = order.length - index - 1;
+
+ const duration = 50;
+ const time = timestamp + invertedIndex * 10;
+
+ const transaction: Transaction = instance
+ .transaction(`GET /${instance.fields['service.name']!}/api`)
+ .timestamp(time)
+ .duration(duration);
+
+ if (prev) {
+ const next = order[invertedIndex + 1].fields['service.name']!;
+ transaction.children(
+ instance
+ .span(`GET ${next}/api`, 'external', 'http')
+ .destination(next)
+ .duration(duration)
+ .timestamp(time + 1)
+ .children(prev)
+ );
+ } else if (db) {
+ transaction.children(
+ instance
+ .span(db, 'db', db)
+ .destination(db)
+ .duration(duration)
+ .timestamp(time + 1)
+ );
+ }
- describe('when using KQL', () => {
- describe('and the query is empty', () => {
- it('returns all trace samples', async () => {
- const {
- body: { samples },
- } = await fetchTraceSamples({
- query: '',
- type: TraceSearchType.kql,
- environment: 'ENVIRONMENT_ALL',
- });
+ return transaction;
+ }, undefined)!;
+ }
+
+ return synthtraceEsClient.index(
+ timerange(start, end)
+ .interval('15m')
+ .rate(1)
+ .generator((timestamp) => {
+ return [
+ generateTrace(timestamp, [java, node]),
+ generateTrace(timestamp, [node, java], 'redis'),
+ generateTrace(timestamp, [python], 'redis'),
+ generateTrace(timestamp, [python, node, java], 'elasticsearch'),
+ generateTrace(timestamp, [java, python, node]),
+ ];
+ })
+ );
+ });
- expect(samples.length).to.eql(5);
+ describe('when using KQL', () => {
+ describe('and the query is empty', () => {
+ it('returns all trace samples', async () => {
+ const {
+ body: { samples },
+ } = await fetchTraceSamples({
+ query: '',
+ type: TraceSearchType.kql,
+ environment: 'ENVIRONMENT_ALL',
});
- });
-
- describe('and query is set', () => {
- it('returns the relevant traces', async () => {
- const {
- body: { samples },
- } = await fetchTraceSamples({
- query: 'span.destination.service.resource:elasticsearch',
- type: TraceSearchType.kql,
- environment: 'ENVIRONMENT_ALL',
- });
- expect(samples.length).to.eql(1);
- });
+ expect(samples.length).to.eql(5);
});
});
- describe('when using EQL', () => {
- describe('and the query is invalid', () => {
- it.skip('returns a 400', async function () {
- try {
- await fetchTraceSamples({
- query: '',
- type: TraceSearchType.eql,
- environment: 'ENVIRONMENT_ALL',
- });
- this.fail();
- } catch (error: unknown) {
- const apiError = error as ApmApiError;
- expect(apiError.res.status).to.eql(400);
- }
+ describe('and query is set', () => {
+ it('returns the relevant traces', async () => {
+ const {
+ body: { samples },
+ } = await fetchTraceSamples({
+ query: 'span.destination.service.resource:elasticsearch',
+ type: TraceSearchType.kql,
+ environment: 'ENVIRONMENT_ALL',
});
+
+ expect(samples.length).to.eql(1);
});
+ });
+ });
- describe('and the query is set', () => {
- it('returns the correct trace samples for transaction sequences', async () => {
- const {
- body: { samples },
- } = await fetchTraceSamples({
- query: `sequence by trace.id
- [ transaction where service.name == "java" ]
- [ transaction where service.name == "node" ]`,
+ describe('when using EQL', () => {
+ describe('and the query is invalid', () => {
+ it.skip('returns a 400', async function () {
+ try {
+ await fetchTraceSamples({
+ query: '',
type: TraceSearchType.eql,
environment: 'ENVIRONMENT_ALL',
});
-
- const traces = await fetchTraces(samples);
-
- expect(traces.length).to.eql(2);
-
- const mapped = traces.map((traceDocs) => {
- return sortBy(traceDocs, '@timestamp')
- .filter((doc) => doc.processor.event === 'transaction')
- .map((doc) => doc.service.name);
- });
-
- expect(mapped).to.eql([
- ['java', 'node'],
- ['java', 'python', 'node'],
- ]);
- });
+ this.fail();
+ } catch (error: unknown) {
+ const apiError = error as ApmApiError;
+ expect(apiError.res.status).to.eql(400);
+ }
});
+ });
- it('returns the correct trace samples for join sequences', async () => {
+ describe('and the query is set', () => {
+ it('returns the correct trace samples for transaction sequences', async () => {
const {
body: { samples },
} = await fetchTraceSamples({
query: `sequence by trace.id
- [ span where service.name == "java" ] by span.id
- [ transaction where service.name == "python" ] by parent.id`,
+ [ transaction where service.name == "java" ]
+ [ transaction where service.name == "node" ]`,
type: TraceSearchType.eql,
environment: 'ENVIRONMENT_ALL',
});
const traces = await fetchTraces(samples);
- expect(traces.length).to.eql(1);
+ expect(traces.length).to.eql(2);
const mapped = traces.map((traceDocs) => {
return sortBy(traceDocs, '@timestamp')
@@ -266,42 +227,69 @@ export default function ApiTest({ getService }: FtrProviderContext) {
.map((doc) => doc.service.name);
});
- expect(mapped).to.eql([['java', 'python', 'node']]);
+ expect(mapped).to.eql([
+ ['java', 'node'],
+ ['java', 'python', 'node'],
+ ]);
});
+ });
- it('returns the correct trace samples for exit spans', async () => {
- const {
- body: { samples },
- } = await fetchTraceSamples({
- query: `sequence by trace.id
+ it('returns the correct trace samples for join sequences', async () => {
+ const {
+ body: { samples },
+ } = await fetchTraceSamples({
+ query: `sequence by trace.id
+ [ span where service.name == "java" ] by span.id
+ [ transaction where service.name == "python" ] by parent.id`,
+ type: TraceSearchType.eql,
+ environment: 'ENVIRONMENT_ALL',
+ });
+
+ const traces = await fetchTraces(samples);
+
+ expect(traces.length).to.eql(1);
+
+ const mapped = traces.map((traceDocs) => {
+ return sortBy(traceDocs, '@timestamp')
+ .filter((doc) => doc.processor.event === 'transaction')
+ .map((doc) => doc.service.name);
+ });
+
+ expect(mapped).to.eql([['java', 'python', 'node']]);
+ });
+
+ it('returns the correct trace samples for exit spans', async () => {
+ const {
+ body: { samples },
+ } = await fetchTraceSamples({
+ query: `sequence by trace.id
[ transaction where service.name == "python" ]
[ span where span.destination.service.resource == "redis" ]`,
- type: TraceSearchType.eql,
- environment: 'ENVIRONMENT_ALL',
- });
+ type: TraceSearchType.eql,
+ environment: 'ENVIRONMENT_ALL',
+ });
- const traces = await fetchTraces(samples);
+ const traces = await fetchTraces(samples);
- expect(traces.length).to.eql(1);
+ expect(traces.length).to.eql(1);
- const mapped = traces.map((traceDocs) => {
- return sortBy(traceDocs, '@timestamp')
- .filter(
- (doc) => doc.processor.event === 'transaction' || doc.processor.event === 'span'
- )
- .map((doc) => {
- if (doc.span && 'destination' in doc.span) {
- return doc.span.destination!.service.resource;
- }
- return doc.service.name;
- });
- });
-
- expect(mapped).to.eql([['python', 'redis']]);
+ const mapped = traces.map((traceDocs) => {
+ return sortBy(traceDocs, '@timestamp')
+ .filter(
+ (doc) => doc.processor.event === 'transaction' || doc.processor.event === 'span'
+ )
+ .map((doc) => {
+ if (doc.span && 'destination' in doc.span) {
+ return doc.span.destination!.service.resource;
+ }
+ return doc.service.name;
+ });
});
+
+ expect(mapped).to.eql([['python', 'redis']]);
});
+ });
- after(() => synthtraceEsClient.clean());
- }
- );
+ after(() => synthtraceEsClient.clean());
+ });
}
diff --git a/x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts b/x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts
index 108772a57bc26e1..509d70caf529167 100644
--- a/x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/traces/trace_by_id.spec.ts
@@ -52,7 +52,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
- registry.when('Trace exists', { config: 'basic', archives: ['apm_mappings_only_8.0.0'] }, () => {
+ registry.when('Trace exists', { config: 'basic', archives: [] }, () => {
let serviceATraceId: string;
before(async () => {
const instanceJava = apm.service('synth-apple', 'production', 'java').instance('instance-b');
diff --git a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts
index 4bbc2490dcd4b4e..350830abcbba3a4 100644
--- a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.spec.ts
@@ -75,178 +75,172 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when(
- 'data is loaded',
- { config: 'basic', archives: ['apm_mappings_only_8.0.0'] },
- () => {
- describe('transactions groups detailed stats', () => {
- const GO_PROD_RATE = 75;
- const GO_PROD_ERROR_RATE = 25;
+ registry.when('data is loaded', { config: 'basic', archives: [] }, () => {
+ describe('transactions groups detailed stats', () => {
+ const GO_PROD_RATE = 75;
+ const GO_PROD_ERROR_RATE = 25;
+ before(async () => {
+ const serviceGoProdInstance = apm
+ .service(serviceName, 'production', 'go')
+ .instance('instance-a');
+
+ const transactionName = 'GET /api/product/list';
+
+ await synthtraceEsClient.index([
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction(transactionName)
+ .timestamp(timestamp)
+ .duration(1000)
+ .success()
+ ),
+ timerange(start, end)
+ .interval('1m')
+ .rate(GO_PROD_ERROR_RATE)
+ .generator((timestamp) =>
+ serviceGoProdInstance
+ .transaction(transactionName)
+ .duration(1000)
+ .timestamp(timestamp)
+ .failure()
+ ),
+ ]);
+ });
+
+ after(() => synthtraceEsClient.clean());
+
+ describe('without comparisons', () => {
+ let transactionsStatistics: TransactionsGroupsDetailedStatistics;
+ let metricsStatistics: TransactionsGroupsDetailedStatistics;
before(async () => {
- const serviceGoProdInstance = apm
- .service(serviceName, 'production', 'go')
- .instance('instance-a');
-
- const transactionName = 'GET /api/product/list';
-
- await synthtraceEsClient.index([
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction(transactionName)
- .timestamp(timestamp)
- .duration(1000)
- .success()
- ),
- timerange(start, end)
- .interval('1m')
- .rate(GO_PROD_ERROR_RATE)
- .generator((timestamp) =>
- serviceGoProdInstance
- .transaction(transactionName)
- .duration(1000)
- .timestamp(timestamp)
- .failure()
- ),
+ [metricsStatistics, transactionsStatistics] = await Promise.all([
+ callApi({ query: { kuery: 'processor.event : "metric"' } }),
+ callApi({ query: { kuery: 'processor.event : "transaction"' } }),
]);
});
- after(() => synthtraceEsClient.clean());
-
- describe('without comparisons', () => {
- let transactionsStatistics: TransactionsGroupsDetailedStatistics;
- let metricsStatistics: TransactionsGroupsDetailedStatistics;
- before(async () => {
- [metricsStatistics, transactionsStatistics] = await Promise.all([
- callApi({ query: { kuery: 'processor.event : "metric"' } }),
- callApi({ query: { kuery: 'processor.event : "transaction"' } }),
- ]);
- });
-
- it('returns some transactions data', () => {
- expect(isEmpty(transactionsStatistics.currentPeriod)).to.be.equal(false);
- });
+ it('returns some transactions data', () => {
+ expect(isEmpty(transactionsStatistics.currentPeriod)).to.be.equal(false);
+ });
- it('returns some metrics data', () => {
- expect(isEmpty(metricsStatistics.currentPeriod)).to.be.equal(false);
- });
+ it('returns some metrics data', () => {
+ expect(isEmpty(metricsStatistics.currentPeriod)).to.be.equal(false);
+ });
- it('has same latency mean value for metrics and transactions data', () => {
- const transactionsCurrentPeriod =
- transactionsStatistics.currentPeriod[transactionNames[0]];
- const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
- const transactionsLatencyMean = meanBy(transactionsCurrentPeriod.latency, 'y');
- const metricsLatencyMean = meanBy(metricsCurrentPeriod.latency, 'y');
- [transactionsLatencyMean, metricsLatencyMean].forEach((value) =>
- expect(value).to.be.equal(1000000)
- );
- });
+ it('has same latency mean value for metrics and transactions data', () => {
+ const transactionsCurrentPeriod =
+ transactionsStatistics.currentPeriod[transactionNames[0]];
+ const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
+ const transactionsLatencyMean = meanBy(transactionsCurrentPeriod.latency, 'y');
+ const metricsLatencyMean = meanBy(metricsCurrentPeriod.latency, 'y');
+ [transactionsLatencyMean, metricsLatencyMean].forEach((value) =>
+ expect(value).to.be.equal(1000000)
+ );
+ });
- it('has same error rate mean value for metrics and transactions data', () => {
- const transactionsCurrentPeriod =
- transactionsStatistics.currentPeriod[transactionNames[0]];
- const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
+ it('has same error rate mean value for metrics and transactions data', () => {
+ const transactionsCurrentPeriod =
+ transactionsStatistics.currentPeriod[transactionNames[0]];
+ const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
- const transactionsErrorRateMean = meanBy(transactionsCurrentPeriod.errorRate, 'y');
- const metricsErrorRateMean = meanBy(metricsCurrentPeriod.errorRate, 'y');
- [transactionsErrorRateMean, metricsErrorRateMean].forEach((value) =>
- expect(asPercent(value, 1)).to.be.equal(`${GO_PROD_ERROR_RATE}%`)
- );
- });
+ const transactionsErrorRateMean = meanBy(transactionsCurrentPeriod.errorRate, 'y');
+ const metricsErrorRateMean = meanBy(metricsCurrentPeriod.errorRate, 'y');
+ [transactionsErrorRateMean, metricsErrorRateMean].forEach((value) =>
+ expect(asPercent(value, 1)).to.be.equal(`${GO_PROD_ERROR_RATE}%`)
+ );
+ });
- it('has same throughput mean value for metrics and transactions data', () => {
- const transactionsCurrentPeriod =
- transactionsStatistics.currentPeriod[transactionNames[0]];
- const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
- const transactionsThroughputMean = roundNumber(
- meanBy(transactionsCurrentPeriod.throughput, 'y')
- );
- const metricsThroughputMean = roundNumber(meanBy(metricsCurrentPeriod.throughput, 'y'));
- [transactionsThroughputMean, metricsThroughputMean].forEach((value) =>
- expect(value).to.be.equal(roundNumber(GO_PROD_RATE + GO_PROD_ERROR_RATE))
- );
- });
+ it('has same throughput mean value for metrics and transactions data', () => {
+ const transactionsCurrentPeriod =
+ transactionsStatistics.currentPeriod[transactionNames[0]];
+ const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
+ const transactionsThroughputMean = roundNumber(
+ meanBy(transactionsCurrentPeriod.throughput, 'y')
+ );
+ const metricsThroughputMean = roundNumber(meanBy(metricsCurrentPeriod.throughput, 'y'));
+ [transactionsThroughputMean, metricsThroughputMean].forEach((value) =>
+ expect(value).to.be.equal(roundNumber(GO_PROD_RATE + GO_PROD_ERROR_RATE))
+ );
+ });
- it('has same impact value for metrics and transactions data', () => {
- const transactionsCurrentPeriod =
- transactionsStatistics.currentPeriod[transactionNames[0]];
- const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
+ it('has same impact value for metrics and transactions data', () => {
+ const transactionsCurrentPeriod =
+ transactionsStatistics.currentPeriod[transactionNames[0]];
+ const metricsCurrentPeriod = metricsStatistics.currentPeriod[transactionNames[0]];
- const transactionsImpact = transactionsCurrentPeriod.impact;
- const metricsImpact = metricsCurrentPeriod.impact;
- [transactionsImpact, metricsImpact].forEach((value) => expect(value).to.be.equal(100));
- });
+ const transactionsImpact = transactionsCurrentPeriod.impact;
+ const metricsImpact = metricsCurrentPeriod.impact;
+ [transactionsImpact, metricsImpact].forEach((value) => expect(value).to.be.equal(100));
});
+ });
- describe('with comparisons', () => {
- let transactionsStatistics: TransactionsGroupsDetailedStatistics;
- before(async () => {
- transactionsStatistics = await callApi({
- query: {
- start: moment(end).subtract(7, 'minutes').toISOString(),
- end: new Date(end).toISOString(),
- offset: '8m',
- },
- });
+ describe('with comparisons', () => {
+ let transactionsStatistics: TransactionsGroupsDetailedStatistics;
+ before(async () => {
+ transactionsStatistics = await callApi({
+ query: {
+ start: moment(end).subtract(7, 'minutes').toISOString(),
+ end: new Date(end).toISOString(),
+ offset: '8m',
+ },
});
+ });
- it('returns some data for both periods', () => {
- expect(isEmpty(transactionsStatistics.currentPeriod)).to.be.equal(false);
- expect(isEmpty(transactionsStatistics.previousPeriod)).to.be.equal(false);
- });
+ it('returns some data for both periods', () => {
+ expect(isEmpty(transactionsStatistics.currentPeriod)).to.be.equal(false);
+ expect(isEmpty(transactionsStatistics.previousPeriod)).to.be.equal(false);
+ });
- it('has same start time for both periods', () => {
- const currentPeriod = transactionsStatistics.currentPeriod[transactionNames[0]];
- const previousPeriod = transactionsStatistics.previousPeriod[transactionNames[0]];
- [
- [currentPeriod.latency, previousPeriod.latency],
- [currentPeriod.errorRate, previousPeriod.errorRate],
- [currentPeriod.throughput, previousPeriod.throughput],
- ].forEach(([currentTimeseries, previousTimeseries]) => {
- const firstCurrentPeriodDate = new Date(
- first(currentTimeseries)?.x ?? NaN
- ).toISOString();
- const firstPreviousPeriodDate = new Date(
- first(previousPeriod.latency)?.x ?? NaN
- ).toISOString();
-
- expect(firstCurrentPeriodDate).to.equal(firstPreviousPeriodDate);
- });
+ it('has same start time for both periods', () => {
+ const currentPeriod = transactionsStatistics.currentPeriod[transactionNames[0]];
+ const previousPeriod = transactionsStatistics.previousPeriod[transactionNames[0]];
+ [
+ [currentPeriod.latency, previousPeriod.latency],
+ [currentPeriod.errorRate, previousPeriod.errorRate],
+ [currentPeriod.throughput, previousPeriod.throughput],
+ ].forEach(([currentTimeseries, previousTimeseries]) => {
+ const firstCurrentPeriodDate = new Date(
+ first(currentTimeseries)?.x ?? NaN
+ ).toISOString();
+ const firstPreviousPeriodDate = new Date(
+ first(previousPeriod.latency)?.x ?? NaN
+ ).toISOString();
+
+ expect(firstCurrentPeriodDate).to.equal(firstPreviousPeriodDate);
});
- it('has same end time for both periods', () => {
- const currentPeriod = transactionsStatistics.currentPeriod[transactionNames[0]];
- const previousPeriod = transactionsStatistics.previousPeriod[transactionNames[0]];
- [
- [currentPeriod.latency, previousPeriod.latency],
- [currentPeriod.errorRate, previousPeriod.errorRate],
- [currentPeriod.throughput, previousPeriod.throughput],
- ].forEach(([currentTimeseries, previousTimeseries]) => {
- const lastCurrentPeriodDate = new Date(
- last(currentTimeseries)?.x ?? NaN
- ).toISOString();
- const lastPreviousPeriodDate = new Date(
- last(previousPeriod.latency)?.x ?? NaN
- ).toISOString();
-
- expect(lastCurrentPeriodDate).to.equal(lastPreviousPeriodDate);
- });
+ });
+ it('has same end time for both periods', () => {
+ const currentPeriod = transactionsStatistics.currentPeriod[transactionNames[0]];
+ const previousPeriod = transactionsStatistics.previousPeriod[transactionNames[0]];
+ [
+ [currentPeriod.latency, previousPeriod.latency],
+ [currentPeriod.errorRate, previousPeriod.errorRate],
+ [currentPeriod.throughput, previousPeriod.throughput],
+ ].forEach(([currentTimeseries, previousTimeseries]) => {
+ const lastCurrentPeriodDate = new Date(last(currentTimeseries)?.x ?? NaN).toISOString();
+ const lastPreviousPeriodDate = new Date(
+ last(previousPeriod.latency)?.x ?? NaN
+ ).toISOString();
+
+ expect(lastCurrentPeriodDate).to.equal(lastPreviousPeriodDate);
});
+ });
- it('returns same number of buckets for both periods', () => {
- const currentPeriod = transactionsStatistics.currentPeriod[transactionNames[0]];
- const previousPeriod = transactionsStatistics.previousPeriod[transactionNames[0]];
- [
- [currentPeriod.latency, previousPeriod.latency],
- [currentPeriod.errorRate, previousPeriod.errorRate],
- [currentPeriod.throughput, previousPeriod.throughput],
- ].forEach(([currentTimeseries, previousTimeseries]) => {
- expect(currentTimeseries.length).to.equal(previousTimeseries.length);
- });
+ it('returns same number of buckets for both periods', () => {
+ const currentPeriod = transactionsStatistics.currentPeriod[transactionNames[0]];
+ const previousPeriod = transactionsStatistics.previousPeriod[transactionNames[0]];
+ [
+ [currentPeriod.latency, previousPeriod.latency],
+ [currentPeriod.errorRate, previousPeriod.errorRate],
+ [currentPeriod.throughput, previousPeriod.throughput],
+ ].forEach(([currentTimeseries, previousTimeseries]) => {
+ expect(currentTimeseries.length).to.equal(previousTimeseries.length);
});
});
});
- }
- );
+ });
+ });
}
From 50821db39c07d5d35d510c8082d5c608c4e2fd4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?=
Date: Tue, 23 Aug 2022 20:56:55 +0200
Subject: [PATCH 05/18] [APM] Improve Cypress tests with sessions and better
async handling (#139278)
---
x-pack/plugins/apm/ftr_e2e/cypress.json | 5 +-
.../feature_flag/comparison.spec.ts | 40 ++++++-----
.../infrastructure_page.spec.ts | 18 ++---
.../integration_policy.spec.ts | 8 +--
.../integration/power_user/no_data_screen.ts | 69 +++++++++----------
.../power_user/rules/error_count.spec.ts | 35 +++++-----
.../settings/agent_configurations.spec.ts | 10 +--
.../power_user/settings/custom_links.spec.ts | 6 +-
.../read_only_user/deep_links.spec.ts | 4 +-
.../read_only_user/dependencies.spec.ts | 20 +++---
.../errors/error_details.spec.ts | 22 +++---
.../read_only_user/errors/errors_page.spec.ts | 41 ++++++-----
.../integration/read_only_user/home.spec.ts | 14 ++--
.../header_filters/header_filters.spec.ts | 10 +--
.../service_inventory.spec.ts | 34 +++++----
.../aws_lambda/aws_lamba.spec.ts | 17 ++---
.../service_overview/errors_table.spec.ts | 16 ++---
.../service_overview/header_filters.spec.ts | 14 ++--
.../service_overview/instances_table.spec.ts | 32 ++++-----
.../service_overview/service_overview.spec.ts | 44 +++++++-----
.../service_overview/time_comparison.spec.ts | 20 +++---
.../generate_span_links_data.ts | 4 +-
.../transaction_details/span_links.spec.ts | 48 ++++++++-----
.../transaction_details.spec.ts | 10 +--
.../transactions_overview.spec.ts | 12 ++--
.../read_only_user/tutorial/tutorial.spec.ts | 4 +-
.../apm/ftr_e2e/cypress/support/commands.ts | 42 +++++++----
.../apm/ftr_e2e/cypress/support/types.d.ts | 1 +
x-pack/plugins/apm/ftr_e2e/synthtrace.ts | 9 +--
29 files changed, 322 insertions(+), 287 deletions(-)
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress.json b/x-pack/plugins/apm/ftr_e2e/cypress.json
index 1791baaa5aae49b..848a10efed66820 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress.json
+++ b/x-pack/plugins/apm/ftr_e2e/cypress.json
@@ -6,11 +6,14 @@
"screenshotsFolder": "./cypress/screenshots",
"supportFile": "./cypress/support/index.ts",
"videosFolder": "./cypress/videos",
+ "requestTimeout": 10000,
+ "responseTimeout": 40000,
"defaultCommandTimeout": 30000,
"execTimeout": 120000,
"pageLoadTimeout": 120000,
"viewportHeight": 900,
"viewportWidth": 1440,
"video": false,
- "screenshotOnRunFailure": false
+ "screenshotOnRunFailure": false,
+ "experimentalSessionAndOrigin": true
}
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts
index 1a58eb1ca4fda87..d1159efd0fc90ce 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/feature_flag/comparison.spec.ts
@@ -10,9 +10,9 @@ import { opbeans } from '../../../fixtures/synthtrace/opbeans';
const start = '2021-10-10T00:00:00.000Z';
const end = '2021-10-10T00:15:00.000Z';
-describe.skip('Comparison feature flag', () => {
- before(async () => {
- await synthtrace.index(
+describe('Comparison feature flag', () => {
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -20,29 +20,33 @@ describe.skip('Comparison feature flag', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
describe('when comparison feature is enabled', () => {
beforeEach(() => {
cy.loginAsEditorUser();
+
+ cy.updateAdvancedSettings({
+ 'observability:enableComparisonByDefault': true,
+ });
});
it('shows the comparison feature enabled in services overview', () => {
- cy.visit('/app/apm/services');
+ cy.visitKibana('/app/apm/services');
cy.get('input[type="checkbox"]#comparison').should('be.checked');
cy.get('[data-test-subj="comparisonSelect"]').should('not.be.disabled');
});
- it('shows the comparison feature enabled in services overview', () => {
- cy.visit('/app/apm/dependencies');
+ it('shows the comparison feature enabled in dependencies overview', () => {
+ cy.visitKibana('/app/apm/dependencies');
cy.get('input[type="checkbox"]#comparison').should('be.checked');
cy.get('[data-test-subj="comparisonSelect"]').should('not.be.disabled');
});
it('shows the comparison feature disabled in service map overview page', () => {
- cy.visit('/app/apm/service-map');
+ cy.visitKibana('/app/apm/service-map');
cy.get('input[type="checkbox"]#comparison').should('be.checked');
cy.get('[data-test-subj="comparisonSelect"]').should('not.be.disabled');
});
@@ -50,11 +54,11 @@ describe.skip('Comparison feature flag', () => {
describe('when comparison feature is disabled', () => {
beforeEach(() => {
- cy.loginAsEditorUser().then(() => {
- // Disables comparison feature on advanced settings
- cy.updateAdvancedSettings({
- 'observability:enableComparisonByDefault': false,
- });
+ cy.loginAsEditorUser();
+
+ // Disables comparison feature on advanced settings
+ cy.updateAdvancedSettings({
+ 'observability:enableComparisonByDefault': false,
});
});
@@ -65,7 +69,7 @@ describe.skip('Comparison feature flag', () => {
});
it('shows the comparison feature disabled in services overview', () => {
- cy.visit('/app/apm/services');
+ cy.visitKibana('/app/apm/services');
cy.get('input[type="checkbox"]#comparison').should('not.be.checked');
cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled');
});
@@ -74,14 +78,14 @@ describe.skip('Comparison feature flag', () => {
cy.intercept('GET', '/internal/apm/dependencies/top_dependencies?*').as(
'topDependenciesRequest'
);
- cy.visit('/app/apm/dependencies');
- cy.wait('@topDependenciesRequest', { requestTimeout: 10000 });
+ cy.visitKibana('/app/apm/dependencies');
+ cy.wait('@topDependenciesRequest');
cy.get('input[type="checkbox"]#comparison').should('not.be.checked');
cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled');
});
it('shows the comparison feature disabled in service map overview page', () => {
- cy.visit('/app/apm/service-map');
+ cy.visitKibana('/app/apm/service-map');
cy.get('input[type="checkbox"]#comparison').should('not.be.checked');
cy.get('[data-test-subj="comparisonSelect"]').should('be.disabled');
});
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts
index 46d654ef2a4aa90..439b95a796b7127 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/infrastructure/infrastructure_page.spec.ts
@@ -27,9 +27,9 @@ const nodeServiceInfraPageHref = url.format({
query: { rangeFrom: start, rangeTo: end },
});
-describe.skip('Infrastructure page', () => {
- before(async () => {
- await synthtrace.index(
+describe('Infrastructure page', () => {
+ before(() => {
+ synthtrace.index(
generateData({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -37,8 +37,8 @@ describe.skip('Infrastructure page', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -47,7 +47,7 @@ describe.skip('Infrastructure page', () => {
describe('when data is loaded', () => {
it('has no detectable a11y violations on load', () => {
- cy.visit(goServiceInfraPageHref);
+ cy.visitKibana(goServiceInfraPageHref);
cy.contains('Infrastructure');
// set skipFailures to true to not fail the test when there are accessibility failures
checkA11y({ skipFailures: true });
@@ -55,7 +55,7 @@ describe.skip('Infrastructure page', () => {
describe('when container ids, pod names and host names are returned by the api call', () => {
it('shows all tabs', () => {
- cy.visit(goServiceInfraPageHref);
+ cy.visitKibana(goServiceInfraPageHref);
cy.contains('Containers');
cy.contains('Pods');
cy.contains('Hosts');
@@ -64,14 +64,14 @@ describe.skip('Infrastructure page', () => {
describe('when only host names are returned by the api call', () => {
it('shows only Hosts tab', () => {
- cy.visit(javaServiceInfraPageHref);
+ cy.visitKibana(javaServiceInfraPageHref);
cy.contains('Hosts');
});
});
describe('when none infrastructure attributes are returned by the api call', () => {
it('shows no data message', () => {
- cy.visit(nodeServiceInfraPageHref);
+ cy.visitKibana(nodeServiceInfraPageHref);
cy.contains('No results match your search criteria.');
});
});
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts
index 655376eb3eb6341..7b97813cb121954 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/integration_settings/integration_policy.spec.ts
@@ -57,7 +57,7 @@ describe.skip('when navigating to integration page', () => {
const integrationsPath = '/app/integrations/browse';
cy.loginAsEditorUser();
- cy.visit(integrationsPath);
+ cy.visitKibana(integrationsPath);
// open integration policy form
cy.get('[data-test-subj="integration-card:epr:apm:featured').click();
@@ -79,17 +79,17 @@ describe.skip('when navigating to integration page', () => {
});
it('should display Tail-based section on latest version', () => {
- cy.visit('/app/fleet/integrations/apm/add-integration');
+ cy.visitKibana('/app/fleet/integrations/apm/add-integration');
cy.contains('Tail-based sampling').should('exist');
});
it('should hide Tail-based section for 8.0.0 apm package', () => {
- cy.visit('/app/fleet/integrations/apm-8.0.0/add-integration');
+ cy.visitKibana('/app/fleet/integrations/apm-8.0.0/add-integration');
cy.contains('Tail-based sampling').should('not.exist');
});
it('should Display Debug section', () => {
- cy.visit('/app/fleet/integrations/apm-8.0.0/add-integration');
+ cy.visitKibana('/app/fleet/integrations/apm-8.0.0/add-integration');
cy.contains('Debug settings').should('exist');
});
});
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts
index c7f33301a5dfc38..ae08bc1ea9b63e7 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/no_data_screen.ts
@@ -5,60 +5,55 @@
* 2.0.
*/
-const apmIndicesSaveURL = '/internal/apm/settings/apm-indices/save';
-
describe('No data screen', () => {
describe('bypass no data screen on settings pages', () => {
- beforeEach(() => {
- cy.loginAsEditorUser();
- });
-
before(() => {
- // Change default indices
- cy.request({
- url: apmIndicesSaveURL,
- method: 'POST',
- body: {
- sourcemap: 'foo-*',
- error: 'foo-*',
- onboarding: 'foo-*',
- span: 'foo-*',
- transaction: 'foo-*',
- metric: 'foo-*',
- },
- headers: {
- 'kbn-xsrf': true,
- },
- auth: { user: 'editor', pass: 'changeme' },
+ // Change indices
+ setApmIndices({
+ sourcemap: 'foo-*',
+ error: 'foo-*',
+ onboarding: 'foo-*',
+ span: 'foo-*',
+ transaction: 'foo-*',
+ metric: 'foo-*',
});
});
+ beforeEach(() => {
+ cy.loginAsEditorUser();
+ });
+
it('shows no data screen instead of service inventory', () => {
- cy.visit('/app/apm/');
+ cy.visitKibana('/app/apm/');
cy.contains('Welcome to Elastic Observability!');
});
+
it('shows settings page', () => {
- cy.visit('/app/apm/settings');
+ cy.visitKibana('/app/apm/settings');
cy.contains('Welcome to Elastic Observability!').should('not.exist');
cy.get('h1').contains('Settings');
});
after(() => {
// reset to default indices
- cy.request({
- url: apmIndicesSaveURL,
- method: 'POST',
- body: {
- sourcemap: '',
- error: '',
- onboarding: '',
- span: '',
- transaction: '',
- metric: '',
- },
- headers: { 'kbn-xsrf': true },
- auth: { user: 'editor', pass: 'changeme' },
+ setApmIndices({
+ sourcemap: '',
+ error: '',
+ onboarding: '',
+ span: '',
+ transaction: '',
+ metric: '',
});
});
});
});
+
+function setApmIndices(body: Record) {
+ cy.request({
+ url: '/internal/apm/settings/apm-indices/save',
+ method: 'POST',
+ body,
+ headers: { 'kbn-xsrf': true },
+ auth: { user: 'editor', pass: 'changeme' },
+ });
+}
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts
index b145369535225c9..ec01fc2df2da30e 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/rules/error_count.spec.ts
@@ -6,10 +6,12 @@
*/
function deleteAllRules() {
+ cy.log('Delete all rules');
cy.request({
log: false,
method: 'GET',
url: '/api/alerting/rules/_find',
+ auth: { user: 'editor', pass: 'changeme' },
}).then(({ body }) => {
if (body.data.length > 0) {
cy.log(`Deleting rules`);
@@ -21,12 +23,21 @@ function deleteAllRules() {
log: false,
method: 'DELETE',
url: `/api/alerting/rule/${id}`,
+ auth: { user: 'editor', pass: 'changeme' },
});
});
});
}
describe('Rules', () => {
+ beforeEach(() => {
+ deleteAllRules();
+ });
+
+ after(() => {
+ deleteAllRules();
+ });
+
describe('Error count', () => {
const ruleName = 'Error count threshold';
const comboBoxInputSelector =
@@ -36,18 +47,11 @@ describe('Rules', () => {
describe('when created from APM', () => {
describe('when created from Service Inventory', () => {
- before(() => {
+ it('creates a rule', () => {
cy.loginAsEditorUser();
- deleteAllRules();
- });
-
- after(() => {
- deleteAllRules();
- });
- it('creates a rule', () => {
// Create a rule in APM
- cy.visit('/app/apm/services');
+ cy.visitKibana('/app/apm/services');
cy.contains('Alerts and rules').click();
cy.contains('Create error count rule').click();
@@ -67,18 +71,13 @@ describe('Rules', () => {
});
describe('when created from Stack management', () => {
- before(() => {
+ it('creates a rule', () => {
cy.loginAsEditorUser();
- deleteAllRules();
- });
- after(() => {
- deleteAllRules();
- });
-
- it('creates a rule', () => {
// Go to stack management
- cy.visit('/app/management/insightsAndAlerting/triggersActions/rules');
+ cy.visitKibana(
+ '/app/management/insightsAndAlerting/triggersActions/rules'
+ );
// Create a rule
cy.contains('button', 'Create rule').click();
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts
index a2f5e055e80a84a..23154492c9f4418 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/agent_configurations.spec.ts
@@ -55,10 +55,10 @@ function generateData({
}
describe('Agent configuration', () => {
- before(async () => {
+ before(() => {
const { rangeFrom, rangeTo } = timeRange;
- await synthtrace.index(
+ synthtrace.index(
generateData({
from: new Date(rangeFrom).getTime(),
to: new Date(rangeTo).getTime(),
@@ -67,13 +67,13 @@ describe('Agent configuration', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
cy.loginAsEditorUser();
- cy.visit(agentConfigHref);
+ cy.visitKibana(agentConfigHref);
});
it('persists service enviroment when clicking on edit button', () => {
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts
index e5c409cb6da0d23..53dbb82c1c6ae2c 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/power_user/settings/custom_links.spec.ts
@@ -13,13 +13,13 @@ describe('Custom links', () => {
});
it('shows empty message and create button', () => {
- cy.visit(basePath);
+ cy.visitKibana(basePath);
cy.contains('No links found');
cy.contains('Create custom link');
});
it('creates custom link', () => {
- cy.visit(basePath);
+ cy.visitKibana(basePath);
const emptyPrompt = cy.get('[data-test-subj="customLinksEmptyPrompt"]');
cy.contains('Create custom link').click();
cy.contains('Create link');
@@ -36,7 +36,7 @@ describe('Custom links', () => {
});
it('clears filter values when field is selected', () => {
- cy.visit(basePath);
+ cy.visitKibana(basePath);
cy.contains('Create custom link').click();
cy.get('[data-test-subj="filter-0"]').select('service.name');
cy.get(
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts
index 76c43ef03f3322f..cfcabe85b5b2a73 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/deep_links.spec.ts
@@ -6,11 +6,11 @@
*/
describe('APM deep links', () => {
- before(() => {
+ beforeEach(() => {
cy.loginAsViewerUser();
});
it('navigates to apm links on search elastic', () => {
- cy.visit('/');
+ cy.visitKibana('/');
cy.get('[data-test-subj="nav-search-input"]').type('APM');
cy.contains('APM');
cy.contains('APM / Services');
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts
index 8042a1a07f8a2e8..e3746489936ab86 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts
@@ -17,8 +17,8 @@ const timeRange = {
};
describe.skip('Dependencies', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -26,8 +26,8 @@ describe.skip('Dependencies', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -36,7 +36,7 @@ describe.skip('Dependencies', () => {
describe('top-level dependencies page', () => {
it('has a list of dependencies and you can navigate to the page for one', () => {
- cy.visit(`/app/apm/services?${new URLSearchParams(timeRange)}`);
+ cy.visitKibana(`/app/apm/services?${new URLSearchParams(timeRange)}`);
cy.contains('nav a', 'Dependencies').click();
// `force: true` because Cypress says the element is 0x0
@@ -46,7 +46,7 @@ describe.skip('Dependencies', () => {
});
it('has no detectable a11y violations on load', () => {
- cy.visit(
+ cy.visitKibana(
`/app/apm/services/opbeans-java/dependencies?${new URLSearchParams(
timeRange
)}`
@@ -59,7 +59,7 @@ describe.skip('Dependencies', () => {
describe.skip('dependency overview page', () => {
it('shows dependency information and you can navigate to a page for an upstream service', () => {
- cy.visit(
+ cy.visitKibana(
`/app/apm/dependencies/overview?${new URLSearchParams({
...timeRange,
dependencyName: 'postgresql',
@@ -76,7 +76,7 @@ describe.skip('Dependencies', () => {
});
it('has no detectable a11y violations on load', () => {
- cy.visit(
+ cy.visitKibana(
`/app/apm/dependencies/overview?${new URLSearchParams({
...timeRange,
dependencyName: 'postgresql',
@@ -90,7 +90,7 @@ describe.skip('Dependencies', () => {
describe('service overview page', () => {
it('shows dependency information and you can navigate to a page for a dependency', () => {
- cy.visit(
+ cy.visitKibana(
`/app/apm/services/opbeans-java/overview?${new URLSearchParams(
timeRange
)}`
@@ -104,7 +104,7 @@ describe.skip('Dependencies', () => {
describe('service dependencies tab', () => {
it('shows dependency information and you can navigate to a page for a dependency', () => {
- cy.visit(
+ cy.visitKibana(
`/app/apm/services/opbeans-java/overview?${new URLSearchParams(
timeRange
)}`
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts
index 59c0d870295179e..28b3068503644be 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/error_details.spec.ts
@@ -27,8 +27,8 @@ describe('Error details', () => {
});
describe('when data is loaded', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
generateData({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -36,12 +36,12 @@ describe('Error details', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
it('has no detectable a11y violations on load', () => {
- cy.visit(errorDetailsPageHref);
+ cy.visitKibana(errorDetailsPageHref);
cy.contains('Error group 00000');
// set skipFailures to true to not fail the test when there are accessibility failures
checkA11y({ skipFailures: true });
@@ -49,7 +49,7 @@ describe('Error details', () => {
describe('when error has no occurrences', () => {
it('shows an empty message', () => {
- cy.visit(
+ cy.visitKibana(
url.format({
pathname:
'/app/apm/services/opbeans-java/errors/0000000000000000000000000Error%201',
@@ -66,13 +66,13 @@ describe('Error details', () => {
describe('when error has data', () => {
it('shows errors distribution chart', () => {
- cy.visit(errorDetailsPageHref);
+ cy.visitKibana(errorDetailsPageHref);
cy.contains('Error group 00000');
cy.get('[data-test-subj="errorDistribution"]').contains('Occurrences');
});
it('shows top erroneous transactions table', () => {
- cy.visit(errorDetailsPageHref);
+ cy.visitKibana(errorDetailsPageHref);
cy.contains('Top 5 affected transactions');
cy.get('[data-test-subj="topErroneousTransactionsTable"]')
.contains('a', 'GET /apple 🍎')
@@ -81,14 +81,14 @@ describe('Error details', () => {
});
it('shows a Stacktrace and Metadata tabs', () => {
- cy.visit(errorDetailsPageHref);
+ cy.visitKibana(errorDetailsPageHref);
cy.contains('button', 'Exception stack trace');
cy.contains('button', 'Metadata');
});
describe('when clicking on related transaction sample', () => {
it('should redirects to the transaction details page', () => {
- cy.visit(errorDetailsPageHref);
+ cy.visitKibana(errorDetailsPageHref);
cy.contains('Error group 00000');
cy.contains('a', 'GET /apple 🍎').click();
cy.url().should('include', 'opbeans-java/transactions/view');
@@ -97,7 +97,7 @@ describe('Error details', () => {
describe('when clicking on View x occurences in discover', () => {
it.skip('should redirects the user to discover', () => {
- cy.visit(errorDetailsPageHref);
+ cy.visitKibana(errorDetailsPageHref);
cy.contains('View 1 occurrence in Discover').click();
cy.url().should('include', 'app/discover');
});
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts
index b000a3a8c2f3f49..301b3384ee2eb86 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts
@@ -29,8 +29,8 @@ describe('Errors page', () => {
});
describe('when data is loaded', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
generateData({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -38,12 +38,12 @@ describe('Errors page', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
it('has no detectable a11y violations on load', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('Error occurrences');
// set skipFailures to true to not fail the test when there are accessibility failures
checkA11y({ skipFailures: true });
@@ -51,7 +51,7 @@ describe('Errors page', () => {
describe('when service has no errors', () => {
it('shows empty message', () => {
- cy.visit(nodeServiceErrorsPageHref);
+ cy.visitKibana(nodeServiceErrorsPageHref);
cy.contains('opbeans-node');
cy.contains('No errors found');
});
@@ -59,28 +59,28 @@ describe('Errors page', () => {
describe('when service has errors', () => {
it('shows errors distribution chart', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('Error occurrences');
});
it('shows failed transaction rate chart', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('Failed transaction rate');
});
it('errors table is populated', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('Error 0');
});
it('clicking on an error in the list navigates to error detail page', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('a', 'Error 1').click();
cy.contains('div', 'Error 1');
});
it('clicking on type adds a filter in the kuerybar', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.get('[data-test-subj="headerFilterKuerybar"]')
.invoke('val')
.should('be.empty');
@@ -97,13 +97,13 @@ describe('Errors page', () => {
});
it('sorts by ocurrences', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('span', 'Occurrences').click();
cy.url().should('include', '&sortField=occurrences&sortDirection=asc');
});
it('sorts by latest occurrences', () => {
- cy.visit(javaServiceErrorsPageHref);
+ cy.visitKibana(javaServiceErrorsPageHref);
cy.contains('span', 'Last seen').click();
cy.url().should('include', '&sortField=lastSeen&sortDirection=asc');
});
@@ -112,9 +112,8 @@ describe('Errors page', () => {
});
describe('Check detailed statistics API with multiple errors', () => {
- before(async () => {
- cy.loginAsViewerUser();
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
generateErrors({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -123,8 +122,12 @@ describe('Check detailed statistics API with multiple errors', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ beforeEach(() => {
+ cy.loginAsViewerUser();
+ });
+
+ after(() => {
+ synthtrace.clean();
});
it('calls detailed API with visible items only', () => {
@@ -136,7 +139,7 @@ describe('Check detailed statistics API with multiple errors', () => {
'POST',
'/internal/apm/services/opbeans-java/errors/groups/detailed_statistics?*'
).as('errorsDetailedStatistics');
- cy.visit(`${javaServiceErrorsPageHref}&pageSize=10`);
+ cy.visitKibana(`${javaServiceErrorsPageHref}&pageSize=10`);
cy.wait('@errorsMainStatistics');
cy.get('.euiPagination__list').children().should('have.length', 5);
cy.wait('@errorsDetailedStatistics').then((payload) => {
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts
index 42ca9319b4ea341..be09ae3f06122ab 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/home.spec.ts
@@ -24,8 +24,8 @@ const serviceInventoryHref = url.format({
});
describe.skip('Home page', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -33,8 +33,8 @@ describe.skip('Home page', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -42,7 +42,7 @@ describe.skip('Home page', () => {
});
it('Redirects to service page with comparisonEnabled, environment, rangeFrom, rangeTo and offset added to the URL', () => {
- cy.visit('/app/apm');
+ cy.visitKibana('/app/apm');
cy.url().should(
'include',
@@ -51,7 +51,7 @@ describe.skip('Home page', () => {
});
it('includes services with only metric documents', () => {
- cy.visit(
+ cy.visitKibana(
`${serviceInventoryHref}&kuery=not%20(processor.event%3A%22transaction%22)`
);
cy.contains('opbeans-java');
@@ -60,7 +60,7 @@ describe.skip('Home page', () => {
describe('navigations', () => {
it('navigates to service overview page with transaction type', () => {
- cy.visit(serviceInventoryHref);
+ cy.visitKibana(serviceInventoryHref);
cy.contains('Services');
cy.contains('opbeans-rum').click({ force: true });
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts
index 03972eb0d0f207f..c4e87ac15fbe194 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/header_filters/header_filters.spec.ts
@@ -20,8 +20,8 @@ const specialServiceName =
'service 1 / ? # [ ] @ ! $ & ( ) * + , ; = < > % {} | ^ ` <>';
describe('Service inventory - header filters', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
generateData({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -30,8 +30,8 @@ describe('Service inventory - header filters', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -40,7 +40,7 @@ describe('Service inventory - header filters', () => {
describe('Filtering by kuerybar', () => {
it('filters by service.name with special characters', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('Services');
cy.contains('opbeans-node');
cy.contains('service 1');
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts
index 6575d015abde2ec..5b98284cdf52a1e 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts
@@ -44,12 +44,9 @@ const mainAliasNames = mainApiRequestsToIntercept.map(
);
describe('When navigating to the service inventory', () => {
- before(async () => {
- cy.loginAsViewerUser();
- cy.visit(serviceInventoryHref);
-
+ before(() => {
const { rangeFrom, rangeTo } = timeRange;
- await synthtrace.index(
+ synthtrace.index(
opbeans({
from: new Date(rangeFrom).getTime(),
to: new Date(rangeTo).getTime(),
@@ -57,8 +54,13 @@ describe('When navigating to the service inventory', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ beforeEach(() => {
+ cy.loginAsViewerUser();
+ cy.visitKibana(serviceInventoryHref);
+ });
+
+ after(() => {
+ synthtrace.clean();
});
it('has no detectable a11y violations on load', () => {
@@ -92,7 +94,7 @@ describe('When navigating to the service inventory', () => {
);
cy.loginAsViewerUser();
- cy.visit(serviceInventoryHref);
+ cy.visitKibana(serviceInventoryHref);
});
it('with the correct environment when changing the environment', () => {
@@ -135,11 +137,9 @@ describe('When navigating to the service inventory', () => {
});
describe('Check detailed statistics API with multiple services', () => {
- before(async () => {
- cy.loginAsViewerUser();
+ before(() => {
const { rangeFrom, rangeTo } = timeRange;
-
- await synthtrace.index(
+ synthtrace.index(
generateMultipleServicesData({
from: new Date(rangeFrom).getTime(),
to: new Date(rangeTo).getTime(),
@@ -147,8 +147,12 @@ describe('Check detailed statistics API with multiple services', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ beforeEach(() => {
+ cy.loginAsViewerUser();
+ });
+
+ after(() => {
+ synthtrace.clean();
});
it('calls detailed API with visible items only', () => {
@@ -157,7 +161,7 @@ describe('Check detailed statistics API with multiple services', () => {
);
cy.intercept('GET', '/internal/apm/services?*').as('mainStatisticsRequest');
- cy.visit(
+ cy.visitKibana(
`${serviceInventoryHref}&pageSize=10&sortField=serviceName&sortDirection=asc`
);
cy.wait('@mainStatisticsRequest');
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts
index a2674d056e317cd..a70620ee18f829b 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/aws_lambda/aws_lamba.spec.ts
@@ -23,8 +23,8 @@ const apiToIntercept = {
};
describe('Service overview - aws lambda', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
generateData({
start: new Date(start).getTime(),
end: new Date(end).getTime(),
@@ -32,19 +32,16 @@ describe('Service overview - aws lambda', () => {
);
});
- after(async () => {
- await synthtrace.clean();
- });
-
- beforeEach(() => {
- cy.loginAsViewerUser();
+ after(() => {
+ synthtrace.clean();
});
it('displays a cold start rate chart and not a transaction breakdown chart', () => {
const { endpoint, name } = apiToIntercept;
-
cy.intercept('GET', endpoint).as(name);
- cy.visit(serviceOverviewHref);
+
+ cy.loginAsViewerUser();
+ cy.visitKibana(serviceOverviewHref);
cy.wait(`@${name}`);
cy.contains('Cold start rate');
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts
index 8d7cfd4e65288ae..b175eb0430ed4c0 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/errors_table.spec.ts
@@ -18,8 +18,8 @@ const serviceOverviewHref = url.format({
});
describe('Errors table', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -27,8 +27,8 @@ describe('Errors table', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -36,20 +36,20 @@ describe('Errors table', () => {
});
it('errors table is populated', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
cy.contains('[MockError] Foo');
});
it('navigates to the errors page', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
cy.contains('a', 'View errors').click();
cy.url().should('include', '/opbeans-java/errors');
});
it('clicking on type adds a filter in the kuerybar and navigates to errors page', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.get('[data-test-subj="headerFilterKuerybar"]')
.invoke('val')
.should('be.empty');
@@ -64,7 +64,7 @@ describe('Errors table', () => {
});
it('navigates to error detail page', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('a', '[MockError] Foo').click();
cy.contains('div', 'Exception message');
});
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts
index 3b7b0c87a7f846e..cf5102ee6e37e2c 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts
@@ -59,14 +59,14 @@ const apisToIntercept = [
];
describe('Service overview - header filters', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime() })
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
describe('Filtering by transaction type', () => {
@@ -74,7 +74,7 @@ describe('Service overview - header filters', () => {
cy.loginAsViewerUser();
});
it('changes url when selecting different value', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-node');
cy.url().should('not.include', 'transactionType');
cy.get('[data-test-subj="headerFilterTransactionType"]').should(
@@ -93,7 +93,7 @@ describe('Service overview - header filters', () => {
apisToIntercept.map(({ endpoint, name }) => {
cy.intercept('GET', endpoint).as(name);
});
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.get('[data-test-subj="headerFilterTransactionType"]').should(
'have.value',
'request'
@@ -122,7 +122,7 @@ describe('Service overview - header filters', () => {
cy.loginAsViewerUser();
});
it('filters by transaction.name', () => {
- cy.visit(
+ cy.visitKibana(
url.format({
pathname: '/app/apm/services/opbeans-java/overview',
query: { rangeFrom: start, rangeTo: end },
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts
index 1fc83b3e2eb0acb..c3b5f37c32acc77 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/instances_table.spec.ts
@@ -41,19 +41,19 @@ describe('Instances table', () => {
cy.loginAsViewerUser();
});
- // describe('when data is not loaded', () => {
- // it('shows empty message', () => {
- // cy.visit(serviceOverviewHref);
- // cy.contains('opbeans-java');
- // cy.get('[data-test-subj="serviceInstancesTableContainer"]').contains(
- // 'No items found'
- // );
- // });
- // });
+ describe.skip('when data is not loaded', () => {
+ it('shows empty message', () => {
+ cy.visitKibana(serviceOverviewHref);
+ cy.contains('opbeans-java');
+ cy.get('[data-test-subj="serviceInstancesTableContainer"]').contains(
+ 'No items found'
+ );
+ });
+ });
describe('when data is loaded', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -61,12 +61,12 @@ describe('Instances table', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
it('has data in the table', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
cy.contains(serviceNodeName);
});
@@ -75,7 +75,7 @@ describe('Instances table', () => {
cy.intercept('GET', endpoint).as(name);
});
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
cy.wait('@instancesMainRequest');
@@ -96,7 +96,7 @@ describe('Instances table', () => {
cy.intercept('GET', endpoint).as(name);
});
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
cy.wait('@instancesMainRequest');
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts
index f61ad0c0761c67d..d73713290b4eff5 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/service_overview.spec.ts
@@ -86,8 +86,8 @@ const aliasNamesWithComparison = apiRequestsToInterceptWithComparison.map(
const aliasNames = [...aliasNamesNoComparison, ...aliasNamesWithComparison];
describe('Service Overview', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -95,14 +95,14 @@ describe('Service Overview', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
describe('renders', () => {
- before(() => {
+ beforeEach(() => {
cy.loginAsViewerUser();
- cy.visit(baseUrl);
+ cy.visitKibana(baseUrl);
});
it('renders all components on the page', () => {
@@ -122,7 +122,6 @@ describe('Service Overview', () => {
describe('transactions', () => {
beforeEach(() => {
cy.loginAsViewerUser();
- cy.visit(baseUrl);
});
it('persists transaction type selected when clicking on Transactions tab', () => {
@@ -130,6 +129,9 @@ describe('Service Overview', () => {
'GET',
'/internal/apm/services/opbeans-node/transaction_types?*'
).as('transactionTypesRequest');
+
+ cy.visitKibana(baseUrl);
+
cy.wait('@transactionTypesRequest');
cy.get('[data-test-subj="headerFilterTransactionType"]').should(
@@ -148,11 +150,14 @@ describe('Service Overview', () => {
);
});
- it.skip('persists transaction type selected when clicking on View Transactions link', () => {
+ it('persists transaction type selected when clicking on View Transactions link', () => {
cy.intercept(
'GET',
'/internal/apm/services/opbeans-node/transaction_types?*'
).as('transactionTypesRequest');
+
+ cy.visitKibana(baseUrl);
+
cy.wait('@transactionTypesRequest');
cy.get('[data-test-subj="headerFilterTransactionType"]').should(
'have.value',
@@ -173,20 +178,20 @@ describe('Service Overview', () => {
});
describe('when RUM service', () => {
- before(() => {
+ it('hides dependency tab when RUM service', () => {
cy.loginAsViewerUser();
- cy.visit(
+
+ cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as(
+ 'agentRequest'
+ );
+
+ cy.visitKibana(
url.format({
pathname: '/app/apm/services/opbeans-rum/overview',
query: { rangeFrom: start, rangeTo: end },
})
);
- });
- it('hides dependency tab when RUM service', () => {
- cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as(
- 'agentRequest'
- );
cy.contains('Overview');
cy.contains('Transactions');
cy.contains('Error');
@@ -204,17 +209,18 @@ describe('Service Overview', () => {
describe('Calls APIs', () => {
beforeEach(() => {
cy.loginAsViewerUser();
- cy.visit(baseUrl);
+
apiRequestsToIntercept.map(({ endpoint, aliasName }) => {
cy.intercept('GET', endpoint).as(aliasName);
});
apiRequestsToInterceptWithComparison.map(({ endpoint, aliasName }) => {
cy.intercept('GET', endpoint).as(aliasName);
});
+ cy.visitKibana(baseUrl);
});
it.skip('with the correct environment when changing the environment', () => {
- cy.wait(aliasNames, { requestTimeout: 10000 });
+ cy.wait(aliasNames);
cy.intercept('GET', 'internal/apm/suggestions?*').as(
'suggestionsRequest'
@@ -241,11 +247,11 @@ describe('Service Overview', () => {
it('when clicking the refresh button', () => {
cy.contains('Refresh').click();
- cy.wait(aliasNames, { requestTimeout: 10000 });
+ cy.wait(aliasNames);
});
it.skip('when selecting a different time range and clicking the update button', () => {
- cy.wait(aliasNames, { requestTimeout: 10000 });
+ cy.wait(aliasNames);
const timeStart = moment(start).subtract(5, 'm').toISOString();
const timeEnd = moment(end).subtract(5, 'm').toISOString();
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts
index 25591cd358bd541..611455163eca3a0 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts
@@ -51,8 +51,8 @@ const apisToIntercept = [
];
describe.skip('Service overview: Time Comparison', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -60,8 +60,8 @@ describe.skip('Service overview: Time Comparison', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -69,14 +69,14 @@ describe.skip('Service overview: Time Comparison', () => {
});
it('enables by default the time comparison feature with Last 24 hours selected', () => {
- cy.visit(serviceOverviewPath);
+ cy.visitKibana(serviceOverviewPath);
cy.url().should('include', 'comparisonEnabled=true');
cy.url().should('include', 'offset=1d');
});
describe('when comparison is toggled off', () => {
it('disables select box', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
// Comparison is enabled by default
@@ -91,7 +91,7 @@ describe.skip('Service overview: Time Comparison', () => {
apisToIntercept.map(({ endpoint, name }) => {
cy.intercept('GET', endpoint).as(name);
});
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.get('[data-test-subj="comparisonSelect"]').should('be.enabled');
const offset = `offset=1d`;
@@ -125,7 +125,7 @@ describe.skip('Service overview: Time Comparison', () => {
apisToIntercept.map(({ endpoint, name }) => {
cy.intercept('GET', endpoint).as(name);
});
- cy.visit(serviceOverviewPath);
+ cy.visitKibana(serviceOverviewPath);
cy.contains('opbeans-java');
// opens the page with "Day before" selected
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', '1d');
@@ -136,7 +136,7 @@ describe.skip('Service overview: Time Comparison', () => {
});
it('changes comparison type when a new time range is selected', () => {
- cy.visit(serviceOverviewHref);
+ cy.visitKibana(serviceOverviewHref);
cy.contains('opbeans-java');
// Time comparison default value
cy.get('[data-test-subj="comparisonSelect"]').should('have.value', '1d');
@@ -189,7 +189,7 @@ describe.skip('Service overview: Time Comparison', () => {
apisToIntercept.map(({ endpoint, name }) => {
cy.intercept('GET', endpoint).as(name);
});
- cy.visit(
+ cy.visitKibana(
url.format({
pathname: serviceOverviewPath,
query: {
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts
index 0ced34d8a1b7c95..9fd2cfe6eab0b43 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/generate_span_links_data.ts
@@ -296,7 +296,7 @@ function getConsumerMultiple({
* ----Span E
* ------span.links= producer-external-only / Span B | producer-consumer / Transaction C
*/
-export async function generateSpanLinksData() {
+export function generateSpanLinksData() {
const producerInternalOnly = getProducerInternalOnly();
const producerExternalOnly = getProducerExternalOnly();
const producerConsumer = getProducerConsumer({
@@ -309,7 +309,7 @@ export async function generateSpanLinksData() {
producerExternalOnlySpanBSpanLink: producerExternalOnly.spanBSpanLink,
});
- await synthtrace.index(
+ synthtrace.index(
new EntityArrayIterable(producerInternalOnly.apmFields).merge(
new EntityArrayIterable(producerExternalOnly.apmFields),
new EntityArrayIterable(producerConsumer.apmFields),
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts
index 3dff8f075f187c7..cddba048e8a1808 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/span_links.spec.ts
@@ -35,17 +35,17 @@ describe('Span links', () => {
describe('when data is loaded', () => {
let ids: Awaited>;
- before(async () => {
- ids = await generateSpanLinksData();
+ before(() => {
+ ids = generateSpanLinksData();
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
describe('span links count on trace waterfall', () => {
it('Shows two children and no parents on producer-internal-only Span A', () => {
- cy.visit(
+ cy.visitKibana(
getServiceInventoryUrl({ serviceName: 'producer-internal-only' })
);
cy.contains('Transaction A').click();
@@ -59,7 +59,7 @@ describe('Span links', () => {
});
it('Shows one parent and one children on producer-external-only Span B', () => {
- cy.visit(
+ cy.visitKibana(
getServiceInventoryUrl({ serviceName: 'producer-external-only' })
);
cy.contains('Transaction B').click();
@@ -73,7 +73,9 @@ describe('Span links', () => {
});
it('Shows one parent and one children on producer-consumer Transaction C', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'producer-consumer' })
+ );
cy.contains('Transaction C').click();
cy.contains('2 Span links');
cy.get(
@@ -85,7 +87,9 @@ describe('Span links', () => {
});
it('Shows no parent and one children on producer-consumer Span C', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'producer-consumer' })
+ );
cy.contains('Transaction C').click();
cy.contains('1 Span link');
cy.get(
@@ -97,7 +101,9 @@ describe('Span links', () => {
});
it('Shows two parents and one children on consumer-multiple Transaction D', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'consumer-multiple' })
+ );
cy.contains('Transaction D').click();
cy.contains('2 Span links');
cy.get(
@@ -109,7 +115,9 @@ describe('Span links', () => {
});
it('Shows two parents and one children on consumer-multiple Span E', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'consumer-multiple' })
+ );
cy.contains('Transaction D').click();
cy.contains('2 Span links');
cy.get(
@@ -123,7 +131,7 @@ describe('Span links', () => {
describe('span link flyout', () => {
it('Shows children details on producer-internal-only Span A', () => {
- cy.visit(
+ cy.visitKibana(
getServiceInventoryUrl({ serviceName: 'producer-internal-only' })
);
cy.contains('Transaction A').click();
@@ -154,7 +162,7 @@ describe('Span links', () => {
});
it('Shows children and parents details on producer-external-only Span B', () => {
- cy.visit(
+ cy.visitKibana(
getServiceInventoryUrl({ serviceName: 'producer-external-only' })
);
cy.contains('Transaction B').click();
@@ -178,7 +186,9 @@ describe('Span links', () => {
});
it('Shows children and parents details on producer-consumer Transaction C', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'producer-consumer' })
+ );
cy.contains('Transaction C').click();
cy.get(
`[aria-controls="${ids.producerConsumerIds.transactionCId}"]`
@@ -210,7 +220,9 @@ describe('Span links', () => {
});
it('Shows children and parents details on producer-consumer Span C', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'producer-consumer' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'producer-consumer' })
+ );
cy.contains('Transaction C').click();
cy.contains('Span C').click();
cy.get('[data-test-subj="spanLinksTab"]').click();
@@ -232,7 +244,9 @@ describe('Span links', () => {
});
it('Shows children and parents details on consumer-multiple Transaction D', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'consumer-multiple' })
+ );
cy.contains('Transaction D').click();
cy.get(
`[aria-controls="${ids.producerMultipleIds.transactionDId}"]`
@@ -266,7 +280,9 @@ describe('Span links', () => {
});
it('Shows children and parents details on consumer-multiple Span E', () => {
- cy.visit(getServiceInventoryUrl({ serviceName: 'consumer-multiple' }));
+ cy.visitKibana(
+ getServiceInventoryUrl({ serviceName: 'consumer-multiple' })
+ );
cy.contains('Transaction D').click();
cy.contains('Span E').click();
cy.get('[data-test-subj="spanLinksTab"]').click();
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts
index c5eeda6645ce810..ee2aade9ec1dff2 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transaction_details/transaction_details.spec.ts
@@ -17,8 +17,8 @@ const timeRange = {
};
describe('Transaction details', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -26,13 +26,13 @@ describe('Transaction details', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
cy.loginAsViewerUser();
- cy.visit(
+ cy.visitKibana(
`/app/apm/services/opbeans-java/transactions/view?${new URLSearchParams({
...timeRange,
transactionName: 'GET /api/product',
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts
index 671b35741f91b38..83753b7fe25954a 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/transactions_overview/transactions_overview.spec.ts
@@ -19,8 +19,8 @@ const serviceTransactionsHref = url.format({
});
describe('Transactions Overview', () => {
- before(async () => {
- await synthtrace.index(
+ before(() => {
+ synthtrace.index(
opbeans({
from: new Date(start).getTime(),
to: new Date(end).getTime(),
@@ -28,8 +28,8 @@ describe('Transactions Overview', () => {
);
});
- after(async () => {
- await synthtrace.clean();
+ after(() => {
+ synthtrace.clean();
});
beforeEach(() => {
@@ -37,7 +37,7 @@ describe('Transactions Overview', () => {
});
it('has no detectable a11y violations on load', () => {
- cy.visit(serviceTransactionsHref);
+ cy.visitKibana(serviceTransactionsHref);
cy.get('a:contains(Transactions)').should(
'have.attr',
'aria-selected',
@@ -48,7 +48,7 @@ describe('Transactions Overview', () => {
});
it('persists transaction type selected when navigating to Overview tab', () => {
- cy.visit(serviceTransactionsHref);
+ cy.visitKibana(serviceTransactionsHref);
cy.get('[data-test-subj="headerFilterTransactionType"]').should(
'have.value',
'request'
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts
index e2ebe9c2bdda812..cb8d9218b4ec1e2 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/tutorial/tutorial.spec.ts
@@ -6,9 +6,9 @@
*/
describe('APM tutorial', () => {
- before(() => {
+ beforeEach(() => {
cy.loginAsViewerUser();
- cy.visit('/app/home#/tutorial/apm');
+ cy.visitKibana('/app/home#/tutorial/apm');
});
it('includes section for APM Server', () => {
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts b/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts
index 0559b07b1cbf29d..37182e328ebf37b 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts
@@ -21,21 +21,24 @@ Cypress.Commands.add('loginAsEditorUser', () => {
Cypress.Commands.add(
'loginAs',
({ username, password }: { username: string; password: string }) => {
- cy.log(`Logging in as ${username}`);
- const kibanaUrl = Cypress.env('KIBANA_URL');
- return cy.request({
- log: false,
- method: 'POST',
- url: `${kibanaUrl}/internal/security/login`,
- body: {
- providerType: 'basic',
- providerName: 'basic',
- currentURL: `${kibanaUrl}/login`,
- params: { username, password },
- },
- headers: {
- 'kbn-xsrf': 'e2e_test',
- },
+ cy.log(`Calling 'loginAs'`);
+ cy.session([username, password], () => {
+ cy.log(`Logging in as ${username}`);
+ const kibanaUrl = Cypress.env('KIBANA_URL');
+ cy.request({
+ log: false,
+ method: 'POST',
+ url: `${kibanaUrl}/internal/security/login`,
+ body: {
+ providerType: 'basic',
+ providerName: 'basic',
+ currentURL: `${kibanaUrl}/login`,
+ params: { username, password },
+ },
+ headers: {
+ 'kbn-xsrf': 'e2e_test',
+ },
+ });
});
}
);
@@ -45,6 +48,14 @@ Cypress.Commands.add('changeTimeRange', (value: string) => {
cy.contains(value).click();
});
+Cypress.Commands.add('visitKibana', (url: string) => {
+ cy.visit(url);
+ cy.get('[data-test-subj="kbnLoadingMessage"]').should('exist');
+ cy.get('[data-test-subj="kbnLoadingMessage"]').should('not.exist', {
+ timeout: 50000,
+ });
+});
+
Cypress.Commands.add(
'selectAbsoluteTimeRange',
(start: string, end: string) => {
@@ -96,6 +107,7 @@ Cypress.Commands.add(
headers: {
'kbn-xsrf': 'e2e_test',
},
+ auth: { user: 'editor', pass: 'changeme' },
});
}
);
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts b/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts
index f46a54142de0ea8..27720210b668aac 100644
--- a/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/support/types.d.ts
@@ -14,6 +14,7 @@ declare namespace Cypress {
password: string;
}): Cypress.Chainable>;
changeTimeRange(value: string): void;
+ visitKibana(url: string): void;
selectAbsoluteTimeRange(start: string, end: string): void;
expectAPIsToHaveBeenCalledWith(params: {
apisIntercepted: string[];
diff --git a/x-pack/plugins/apm/ftr_e2e/synthtrace.ts b/x-pack/plugins/apm/ftr_e2e/synthtrace.ts
index 6fb880c40b0cc0a..a421edea04a6e91 100644
--- a/x-pack/plugins/apm/ftr_e2e/synthtrace.ts
+++ b/x-pack/plugins/apm/ftr_e2e/synthtrace.ts
@@ -8,11 +8,6 @@ import type { EntityIterable } from '@kbn/apm-synthtrace';
export const synthtrace = {
index: (events: EntityIterable) =>
- new Promise((resolve) => {
- cy.task('synthtrace:index', events.toArray()).then(resolve);
- }),
- clean: () =>
- new Promise((resolve) => {
- cy.task('synthtrace:clean').then(resolve);
- }),
+ cy.task('synthtrace:index', events.toArray()),
+ clean: () => cy.task('synthtrace:clean'),
};
From f2c20b7c9f2f0dfdce6009e1662ed74cef6ebca4 Mon Sep 17 00:00:00 2001
From: Lee Drengenberg
Date: Tue, 23 Aug 2022 14:31:39 -0500
Subject: [PATCH 06/18] [Archive Migration] batch 2 of removing
es_archives/empty_kibana (#138208)
* replace es_archives/empty_kibana with kibanaServer.savedObjects.cleanStandardList
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* add missing kibanaServer
* add a tearDown
* revert changes that don't pass
* revert fleet_setup, delete spaces in tearDown
* Don't fail on deleting spaces
* revert file for failing test
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
.../security_and_spaces/setup.ts | 6 ++++--
.../apis/metrics_ui/log_entry_highlights.ts | 5 +++--
x-pack/test/api_integration/apis/metrics_ui/sources.ts | 5 +++--
x-pack/test/api_integration/apis/ml/modules/index.ts | 8 ++++----
x-pack/test/api_integration/apis/osquery/packs.ts | 4 ++--
.../apis/security_solution/saved_objects/notes.ts | 6 +++---
.../security_solution/saved_objects/pinned_events.ts | 6 +++---
.../apis/security_solution/saved_objects/timeline.ts | 6 +++---
x-pack/test/common/services/spaces.ts | 10 +++++-----
.../apis/agent_policy/agent_policy.ts | 4 ++--
.../apis/download_sources/crud.ts | 5 +++--
.../apis/epm/install_error_rollback.ts | 6 +++---
.../test/fleet_api_integration/apis/fleet_telemetry.ts | 5 +++--
x-pack/test/fleet_api_integration/apis/outputs/crud.ts | 5 +++--
.../apis/package_policy/create.ts | 5 +++--
.../fleet_api_integration/apis/package_policy/get.ts | 5 +++--
.../apis/package_policy/upgrade.ts | 5 +++--
.../apis/preconfiguration/preconfiguration.ts | 5 +++--
.../test/fleet_api_integration/apis/service_tokens.ts | 6 +++---
.../with_host_configured/app_search/engines.ts | 8 +++-----
.../without_host_configured/app_search/setup_guide.ts | 9 +++++----
.../workplace_search/setup_guide.ts | 9 +++++----
.../test_suites/event_log/public_api_integration.ts | 3 ++-
.../reporting_without_security/management.ts | 5 ++---
.../apps/endpoint/endpoint_telemetry.ts | 5 +++--
x-pack/test/visual_regression/tests/login_page.ts | 6 +++---
26 files changed, 82 insertions(+), 70 deletions(-)
diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/setup.ts b/x-pack/test/alerting_api_integration/security_and_spaces/setup.ts
index 69ca58e1edc1259..74dcdc3989e2aac 100644
--- a/x-pack/test/alerting_api_integration/security_and_spaces/setup.ts
+++ b/x-pack/test/alerting_api_integration/security_and_spaces/setup.ts
@@ -39,7 +39,7 @@ export async function setupSpacesAndUsers(getService: FtrProviderContext['getSer
export async function tearDown(getService: FtrProviderContext['getService']) {
const securityService = getService('security');
- const esArchiver = getService('esArchiver');
+ const spacesService = getService('spaces');
for (const user of Users) {
await securityService.user.delete(user.username);
@@ -52,5 +52,7 @@ export async function tearDown(getService: FtrProviderContext['getService']) {
}
}
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ for (const space of Spaces) {
+ await spacesService.delete(space.id);
+ }
}
diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts
index bd9a9a0e7c480b1..aba182274c9a3ce 100644
--- a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts
+++ b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts
@@ -37,6 +37,7 @@ const COMMON_HEADERS = {
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const kibanaServer = getService('kibanaServer');
describe('log highlight apis', () => {
before(() => esArchiver.load('x-pack/test/functional/es_archives/infra/simple_logs'));
@@ -44,8 +45,8 @@ export default function ({ getService }: FtrProviderContext) {
describe('/log_entries/highlights', () => {
describe('with the default source', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'));
+ before(() => kibanaServer.savedObjects.cleanStandardList());
+ after(() => kibanaServer.savedObjects.cleanStandardList());
it('Handles empty responses', async () => {
const { body } = await supertest
diff --git a/x-pack/test/api_integration/apis/metrics_ui/sources.ts b/x-pack/test/api_integration/apis/metrics_ui/sources.ts
index 0ba6f49634b54e1..c58b332c7102f4c 100644
--- a/x-pack/test/api_integration/apis/metrics_ui/sources.ts
+++ b/x-pack/test/api_integration/apis/metrics_ui/sources.ts
@@ -18,6 +18,7 @@ export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
const SOURCE_API_URL = '/api/metrics/source/default';
+ const kibanaServer = getService('kibanaServer');
const patchRequest = async (
body: PartialMetricsSourceConfigurationProperties
): Promise => {
@@ -32,8 +33,8 @@ export default function ({ getService }: FtrProviderContext) {
describe('sources', () => {
before(() => esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'));
after(() => esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'));
- beforeEach(() => esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
- afterEach(() => esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'));
+ before(() => kibanaServer.savedObjects.cleanStandardList());
+ after(() => kibanaServer.savedObjects.cleanStandardList());
describe('patch request', () => {
it('applies all top-level field updates to an existing source', async () => {
diff --git a/x-pack/test/api_integration/apis/ml/modules/index.ts b/x-pack/test/api_integration/apis/ml/modules/index.ts
index 182de3e2648cba0..de8919976fd3310 100644
--- a/x-pack/test/api_integration/apis/ml/modules/index.ts
+++ b/x-pack/test/api_integration/apis/ml/modules/index.ts
@@ -8,7 +8,7 @@
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService, loadTestFile }: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
const ml = getService('ml');
const fleetPackages = ['apache', 'nginx'];
@@ -16,8 +16,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
describe('modules', function () {
before(async () => {
- // use empty_kibana to make sure the fleet setup is removed correctly after the tests
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ // use await kibanaServer.savedObjects.cleanStandardList(); to make sure the fleet setup is removed correctly after the tests
+ await kibanaServer.savedObjects.cleanStandardList();
// Fleet need to be setup to be able to setup packages
await ml.testResources.setupFleet();
@@ -32,7 +32,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
for (const fleetPackage of installedPackages) {
await ml.testResources.removeFleetPackage(fleetPackage.pkgName, fleetPackage.version);
}
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
loadTestFile(require.resolve('./get_module'));
diff --git a/x-pack/test/api_integration/apis/osquery/packs.ts b/x-pack/test/api_integration/apis/osquery/packs.ts
index 840d5aecaeae03b..dc019bffeec6fac 100644
--- a/x-pack/test/api_integration/apis/osquery/packs.ts
+++ b/x-pack/test/api_integration/apis/osquery/packs.ts
@@ -50,13 +50,13 @@ export default function ({ getService }: FtrProviderContext) {
let hostedPolicy: Record;
let packagePolicyId: string;
before(async () => {
- await getService('esArchiver').load('x-pack/test/functional/es_archives/empty_kibana');
+ await getService('kibanaServer').savedObjects.cleanStandardList();
await getService('esArchiver').load(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
});
after(async () => {
- await getService('esArchiver').unload('x-pack/test/functional/es_archives/empty_kibana');
+ await getService('kibanaServer').savedObjects.cleanStandardList();
await getService('esArchiver').unload(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
diff --git a/x-pack/test/api_integration/apis/security_solution/saved_objects/notes.ts b/x-pack/test/api_integration/apis/security_solution/saved_objects/notes.ts
index 03ea91775d1bf80..a6dc1f88c596e54 100644
--- a/x-pack/test/api_integration/apis/security_solution/saved_objects/notes.ts
+++ b/x-pack/test/api_integration/apis/security_solution/saved_objects/notes.ts
@@ -10,12 +10,12 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
const supertest = getService('supertest');
describe('Note - Saved Objects', () => {
- beforeEach(() => esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
- afterEach(() => esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'));
+ before(() => kibanaServer.savedObjects.cleanStandardList());
+ after(() => kibanaServer.savedObjects.cleanStandardList());
describe('create a note', () => {
it('should return a timelineId, timelineVersion, noteId and version', async () => {
diff --git a/x-pack/test/api_integration/apis/security_solution/saved_objects/pinned_events.ts b/x-pack/test/api_integration/apis/security_solution/saved_objects/pinned_events.ts
index 8391f2f9ab18a2f..dcfe8a109b04e14 100644
--- a/x-pack/test/api_integration/apis/security_solution/saved_objects/pinned_events.ts
+++ b/x-pack/test/api_integration/apis/security_solution/saved_objects/pinned_events.ts
@@ -10,12 +10,12 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
const supertest = getService('supertest');
describe('Pinned Events - Saved Objects', () => {
- beforeEach(() => esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
- afterEach(() => esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'));
+ before(() => kibanaServer.savedObjects.cleanStandardList());
+ after(() => kibanaServer.savedObjects.cleanStandardList());
describe('Pinned an event', () => {
it('return a timelineId, timelineVersion, pinnedEventId and version', async () => {
diff --git a/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts b/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts
index 32d307ebc22d561..e3a79ba91b29c93 100644
--- a/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts
+++ b/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts
@@ -12,12 +12,12 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
import { createBasicTimeline } from './helpers';
export default function ({ getService }: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
const supertest = getService('supertest');
describe('Timeline - Saved Objects', () => {
- beforeEach(() => esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
- afterEach(() => esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'));
+ beforeEach(() => kibanaServer.savedObjects.cleanStandardList());
+ afterEach(() => kibanaServer.savedObjects.cleanStandardList());
describe('Persist a timeline', () => {
it('Create a timeline just with a title', async () => {
diff --git a/x-pack/test/common/services/spaces.ts b/x-pack/test/common/services/spaces.ts
index 24554e151135ced..c023d8da26ba580 100644
--- a/x-pack/test/common/services/spaces.ts
+++ b/x-pack/test/common/services/spaces.ts
@@ -24,7 +24,7 @@ export function SpacesServiceProvider({ getService }: FtrProviderContext) {
return new (class SpacesService {
public async create(space: any) {
- log.debug('creating space');
+ log.debug(`creating space ${space.name}`);
const { data, status, statusText } = await axios.post('/api/spaces/space', space);
if (status !== 200) {
@@ -32,19 +32,19 @@ export function SpacesServiceProvider({ getService }: FtrProviderContext) {
`Expected status code of 200, received ${status} ${statusText}: ${util.inspect(data)}`
);
}
- log.debug('created space');
+ log.debug(`created space ${space}`);
}
public async delete(spaceId: string) {
- log.debug(`deleting space: ${spaceId}`);
+ log.debug(`deleting space id: ${spaceId}`);
const { data, status, statusText } = await axios.delete(`/api/spaces/space/${spaceId}`);
if (status !== 204) {
- throw new Error(
+ log.debug(
`Expected status code of 204, received ${status} ${statusText}: ${util.inspect(data)}`
);
}
- log.debug(`deleted space: ${spaceId}`);
+ log.debug(`deleted space id: ${spaceId}`);
}
})();
}
diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts
index 6641867cadf2207..e71c14a8054c874 100644
--- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts
+++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts
@@ -23,7 +23,7 @@ export default function (providerContext: FtrProviderContext) {
let systemPkgVersion: string;
before(async () => {
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
setupFleetAndAgents(providerContext);
let packagePoliciesToDeleteIds: string[] = [];
@@ -41,7 +41,7 @@ export default function (providerContext: FtrProviderContext) {
}
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
it('should work with valid minimum required values', async () => {
const {
diff --git a/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts b/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts
index 4e5d2c60ae9323f..c48f5602f5b5207 100644
--- a/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts
+++ b/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts
@@ -14,11 +14,12 @@ export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
describe('fleet_download_sources_crud', async function () {
skipIfNoDockerRegistry(providerContext);
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
});
setupFleetAndAgents(providerContext);
@@ -38,7 +39,7 @@ export default function (providerContext: FtrProviderContext) {
});
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
});
diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts b/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts
index 9a49958d31d34c4..8906a7fa3ea37cf 100644
--- a/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts
+++ b/x-pack/test/fleet_api_integration/apis/epm/install_error_rollback.ts
@@ -13,10 +13,10 @@ import { setupFleetAndAgents } from '../agents/services';
export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
- const esArchiver = getService('esArchiver');
const pkgName = 'error_handling';
const goodPackageVersion = '0.1.0';
const badPackageVersion = '0.2.0';
+ const kibanaServer = getService('kibanaServer');
const installPackage = async (pkg: string, version: string) => {
await supertest
@@ -33,10 +33,10 @@ export default function (providerContext: FtrProviderContext) {
skipIfNoDockerRegistry(providerContext);
setupFleetAndAgents(providerContext);
beforeEach(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
afterEach(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
it('on a fresh install, it should uninstall a broken package during rollback', async function () {
diff --git a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts
index 88368e784dfa66d..d1e7cd8d999c689 100644
--- a/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts
+++ b/x-pack/test/fleet_api_integration/apis/fleet_telemetry.ts
@@ -14,20 +14,21 @@ export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
let agentCount = 0;
let pkgVersion: string;
describe('fleet_telemetry', () => {
skipIfNoDockerRegistry(providerContext);
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
});
setupFleetAndAgents(providerContext);
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
if (pkgVersion) {
await supertest.delete(`/api/fleet/epm/packages/fleet_server/${pkgVersion}`);
diff --git a/x-pack/test/fleet_api_integration/apis/outputs/crud.ts b/x-pack/test/fleet_api_integration/apis/outputs/crud.ts
index 43a3707a2196333..f48e17a70450429 100644
--- a/x-pack/test/fleet_api_integration/apis/outputs/crud.ts
+++ b/x-pack/test/fleet_api_integration/apis/outputs/crud.ts
@@ -14,11 +14,12 @@ export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
describe('fleet_output_crud', async function () {
skipIfNoDockerRegistry(providerContext);
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
});
setupFleetAndAgents(providerContext);
@@ -37,7 +38,7 @@ export default function (providerContext: FtrProviderContext) {
});
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
});
diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/create.ts b/x-pack/test/fleet_api_integration/apis/package_policy/create.ts
index c16815eee3168cb..46f716e1322460a 100644
--- a/x-pack/test/fleet_api_integration/apis/package_policy/create.ts
+++ b/x-pack/test/fleet_api_integration/apis/package_policy/create.ts
@@ -14,6 +14,7 @@ export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const es: Client = getService('es');
const supertest = getService('supertest');
+ const kibanaServer = getService('kibanaServer');
const getPackagePolicyById = async (id: string) => {
const { body } = await supertest.get(`/api/fleet/package_policies/${id}`);
@@ -27,13 +28,13 @@ export default function (providerContext: FtrProviderContext) {
skipIfNoDockerRegistry(providerContext);
let agentPolicyId: string;
before(async () => {
- await getService('esArchiver').load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await getService('esArchiver').load(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
});
after(async () => {
- await getService('esArchiver').unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await getService('esArchiver').unload(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/get.ts b/x-pack/test/fleet_api_integration/apis/package_policy/get.ts
index ef9eee75428381b..dbfb8109a2c1984 100644
--- a/x-pack/test/fleet_api_integration/apis/package_policy/get.ts
+++ b/x-pack/test/fleet_api_integration/apis/package_policy/get.ts
@@ -23,7 +23,8 @@ export default function (providerContext: FtrProviderContext) {
skipIfNoDockerRegistry(providerContext);
before(async () => {
- await getService('esArchiver').load('x-pack/test/functional/es_archives/empty_kibana');
+ await getService('kibanaServer').savedObjects.cleanStandardList();
+
await getService('esArchiver').load(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
@@ -33,7 +34,7 @@ export default function (providerContext: FtrProviderContext) {
await getService('esArchiver').unload(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
- await getService('esArchiver').unload('x-pack/test/functional/es_archives/empty_kibana');
+ await getService('kibanaServer').savedObjects.cleanStandardList();
});
describe('get by id', async function () {
diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts b/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts
index 6486579f41c7323..4a113714dc32457 100644
--- a/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts
+++ b/x-pack/test/fleet_api_integration/apis/package_policy/upgrade.ts
@@ -17,6 +17,7 @@ export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
function withTestPackageVersion(version: string) {
before(async function () {
@@ -42,12 +43,12 @@ export default function (providerContext: FtrProviderContext) {
let packagePolicyId: string;
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
});
after(async () => {
- await getService('esArchiver').unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await getService('esArchiver').unload(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
diff --git a/x-pack/test/fleet_api_integration/apis/preconfiguration/preconfiguration.ts b/x-pack/test/fleet_api_integration/apis/preconfiguration/preconfiguration.ts
index ee7679d2cef6565..83d2913e7aa5933 100644
--- a/x-pack/test/fleet_api_integration/apis/preconfiguration/preconfiguration.ts
+++ b/x-pack/test/fleet_api_integration/apis/preconfiguration/preconfiguration.ts
@@ -21,7 +21,8 @@ export default function (providerContext: FtrProviderContext) {
describe('Preconfiguration', async () => {
skipIfNoDockerRegistry(providerContext);
before(async () => {
- await getService('esArchiver').load('x-pack/test/functional/es_archives/empty_kibana');
+ await getService('kibanaServer').savedObjects.cleanStandardList();
+
await getService('esArchiver').load(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
@@ -31,7 +32,7 @@ export default function (providerContext: FtrProviderContext) {
await getService('esArchiver').unload(
'x-pack/test/functional/es_archives/fleet/empty_fleet_server'
);
- await getService('esArchiver').unload('x-pack/test/functional/es_archives/empty_kibana');
+ await getService('kibanaServer').savedObjects.cleanStandardList();
});
// Basic health check for the API; functionality is covered by the unit tests
diff --git a/x-pack/test/fleet_api_integration/apis/service_tokens.ts b/x-pack/test/fleet_api_integration/apis/service_tokens.ts
index e668caab8e98f28..bd13c3f5b8ca8ae 100644
--- a/x-pack/test/fleet_api_integration/apis/service_tokens.ts
+++ b/x-pack/test/fleet_api_integration/apis/service_tokens.ts
@@ -11,16 +11,16 @@ import { FtrProviderContext } from '../../api_integration/ftr_provider_context';
export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
- const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
const esClient = getService('es');
describe('fleet_service_tokens', async () => {
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
describe('POST /api/fleet/service_tokens', () => {
diff --git a/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts b/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts
index 142f6af98499409..5b10de7b3e036b9 100644
--- a/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts
+++ b/x-pack/test/functional_enterprise_search/apps/enterprise_search/with_host_configured/app_search/engines.ts
@@ -6,7 +6,6 @@
*/
import expect from '@kbn/expect';
-import { EsArchiver } from '@kbn/es-archiver';
import { AppSearchService, IEngine } from '../../../../services/app_search_service';
import { Browser } from '../../../../../../../test/functional/services/common';
import { FtrProviderContext } from '../../../../ftr_provider_context';
@@ -15,11 +14,10 @@ export default function enterpriseSearchSetupEnginesTests({
getService,
getPageObjects,
}: FtrProviderContext) {
- const esArchiver = getService('esArchiver') as EsArchiver;
const browser = getService('browser') as Browser;
const retry = getService('retry');
const appSearch = getService('appSearch') as AppSearchService;
-
+ const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['appSearch', 'security']);
describe('Engines Overview', function () {
@@ -28,14 +26,14 @@ export default function enterpriseSearchSetupEnginesTests({
let metaEngine: IEngine;
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
engine1 = await appSearch.createEngine();
engine2 = await appSearch.createEngine();
metaEngine = await appSearch.createMetaEngine([engine1.name, engine2.name]);
});
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
appSearch.destroyEngine(engine1.name);
appSearch.destroyEngine(engine2.name);
appSearch.destroyEngine(metaEngine.name);
diff --git a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts
index e7bec22936d1289..2995150d73d07c7 100644
--- a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts
+++ b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/app_search/setup_guide.ts
@@ -12,16 +12,17 @@ export default function enterpriseSearchSetupGuideTests({
getService,
getPageObjects,
}: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
const browser = getService('browser');
const retry = getService('retry');
-
+ const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['appSearch']);
describe('Setup Guide', function () {
- before(async () => await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
+ before(async () => {
+ await kibanaServer.savedObjects.cleanStandardList();
+ });
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
describe('when no enterpriseSearch.host is configured', () => {
diff --git a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts
index e1e78885e64014e..0be3156d29c0211 100644
--- a/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts
+++ b/x-pack/test/functional_enterprise_search/apps/enterprise_search/without_host_configured/workplace_search/setup_guide.ts
@@ -12,16 +12,17 @@ export default function enterpriseSearchSetupGuideTests({
getService,
getPageObjects,
}: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
const browser = getService('browser');
const retry = getService('retry');
-
+ const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['workplaceSearch']);
describe('Setup Guide', function () {
- before(async () => await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'));
+ before(async () => {
+ await kibanaServer.savedObjects.cleanStandardList();
+ });
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
describe('when no enterpriseSearch.host is configured', () => {
diff --git a/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts b/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts
index a7bcdf2ddc52cdd..961efb82a90d1a3 100644
--- a/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts
+++ b/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts
@@ -21,6 +21,7 @@ export default function ({ getService }: FtrProviderContext) {
const retry = getService('retry');
const spacesService = getService('spaces');
const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
describe('Event Log public API', () => {
before(async () => {
@@ -32,7 +33,7 @@ export default function ({ getService }: FtrProviderContext) {
});
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
for (const namespace of [undefined, 'namespace-a']) {
diff --git a/x-pack/test/reporting_functional/reporting_without_security/management.ts b/x-pack/test/reporting_functional/reporting_without_security/management.ts
index 36589d375b0e03d..f9444c7e4c72980 100644
--- a/x-pack/test/reporting_functional/reporting_without_security/management.ts
+++ b/x-pack/test/reporting_functional/reporting_without_security/management.ts
@@ -40,7 +40,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const supertest = getService('supertestWithoutAuth');
const kibanaServer = getService('kibanaServer');
const testSubjects = getService('testSubjects');
- const esArchiver = getService('esArchiver');
const reportingApi = getService('reportingAPI');
const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json';
@@ -55,12 +54,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
describe('Polling for jobs', () => {
beforeEach(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await kibanaServer.importExport.load(ecommerceSOPath);
});
afterEach(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await kibanaServer.importExport.unload(ecommerceSOPath);
await reportingApi.deleteAllReports();
});
diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_telemetry.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_telemetry.ts
index efc87330eb82286..3dc4f9fb3f3a43e 100644
--- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_telemetry.ts
+++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_telemetry.ts
@@ -11,17 +11,18 @@ import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const telemetryTestResources = getService('telemetryTestResources');
+ const kibanaServer = getService('kibanaServer');
// The source of the data for these tests have changed and need to be updated
// There are currently tests in the security_solution application being maintained
describe.skip('security solution endpoint telemetry', () => {
after(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
describe('when no agents are connected', () => {
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
it('reports no endpoints or policies', async () => {
diff --git a/x-pack/test/visual_regression/tests/login_page.ts b/x-pack/test/visual_regression/tests/login_page.ts
index 34e1132134744c4..3e2b41002403619 100644
--- a/x-pack/test/visual_regression/tests/login_page.ts
+++ b/x-pack/test/visual_regression/tests/login_page.ts
@@ -8,7 +8,7 @@
import { FtrProviderContext } from '../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
- const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
const visualTesting = getService('visualTesting');
const testSubjects = getService('testSubjects');
const retry = getService('retry');
@@ -17,12 +17,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe.skip('Security', () => {
describe('Login Page', () => {
before(async () => {
- await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
await PageObjects.security.forceLogout();
});
after(async () => {
- await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana');
+ await kibanaServer.savedObjects.cleanStandardList();
});
afterEach(async () => {
From 239def566c1d254b9d8831a43ded9d569934eb10 Mon Sep 17 00:00:00 2001
From: Catherine Liu
Date: Tue, 23 Aug 2022 12:49:35 -0700
Subject: [PATCH 07/18] [Controls] Removes timeslider in favor of new
timeslider control (#138931)
* Removed timeslider in favor of new timeslider control
* Removed time slider import
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* Fixed i18n errors
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
.../time_slider_persistable_state.ts | 47 ---
.../common/control_types/time_slider/types.ts | 15 -
src/plugins/controls/common/index.ts | 2 -
.../storybook_control_factories.ts | 6 -
.../time_slider.component.stories.tsx | 196 ----------
.../public/control_types/time_slider/index.ts | 11 -
.../time_slider/time_slider.component.scss | 47 ---
.../time_slider/time_slider.component.tsx | 343 ------------------
.../control_types/time_slider/time_slider.tsx | 79 ----
.../time_slider_embeddable.test.ts | 300 ---------------
.../time_slider/time_slider_embeddable.tsx | 334 -----------------
.../time_slider_embeddable_factory.tsx | 69 ----
.../time_slider/time_slider_reducers.ts | 20 -
.../time_slider/time_slider_strings.ts | 46 ---
.../public/control_types/time_slider/types.ts | 30 --
src/plugins/controls/public/index.ts | 7 +-
src/plugins/controls/public/plugin.ts | 24 --
.../control_group_telemetry.test.ts | 10 +-
.../time_slider_embeddable_factory.ts | 22 --
src/plugins/controls/server/plugin.ts | 8 +-
.../controls/replace_controls.ts | 47 +--
.../translations/translations/fr-FR.json | 7 -
.../translations/translations/ja-JP.json | 7 -
.../translations/translations/zh-CN.json | 7 -
24 files changed, 7 insertions(+), 1677 deletions(-)
delete mode 100644 src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts
delete mode 100644 src/plugins/controls/common/control_types/time_slider/types.ts
delete mode 100644 src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx
delete mode 100644 src/plugins/controls/public/control_types/time_slider/index.ts
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider.component.scss
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider.tsx
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts
delete mode 100644 src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts
delete mode 100644 src/plugins/controls/public/control_types/time_slider/types.ts
delete mode 100644 src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts
diff --git a/src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts b/src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts
deleted file mode 100644
index b8b3a5f16b51f6e..000000000000000
--- a/src/plugins/controls/common/control_types/time_slider/time_slider_persistable_state.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import {
- EmbeddableStateWithType,
- EmbeddablePersistableStateService,
-} from '@kbn/embeddable-plugin/common';
-import { SavedObjectReference } from '@kbn/core/types';
-import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';
-import { TimeSliderControlEmbeddableInput } from './types';
-
-type TimeSliderInputWithType = Partial & { type: string };
-const dataViewReferenceName = 'timeSliderDataView';
-
-export const createTimeSliderInject = (): EmbeddablePersistableStateService['inject'] => {
- return (state: EmbeddableStateWithType, references: SavedObjectReference[]) => {
- const workingState = { ...state } as EmbeddableStateWithType | TimeSliderInputWithType;
- references.forEach((reference) => {
- if (reference.name === dataViewReferenceName) {
- (workingState as TimeSliderInputWithType).dataViewId = reference.id;
- }
- });
- return workingState as EmbeddableStateWithType;
- };
-};
-
-export const createTimeSliderExtract = (): EmbeddablePersistableStateService['extract'] => {
- return (state: EmbeddableStateWithType) => {
- const workingState = { ...state } as EmbeddableStateWithType | TimeSliderInputWithType;
- const references: SavedObjectReference[] = [];
-
- if ('dataViewId' in workingState) {
- references.push({
- name: dataViewReferenceName,
- type: DATA_VIEW_SAVED_OBJECT_TYPE,
- id: workingState.dataViewId!,
- });
- delete workingState.dataViewId;
- }
- return { state: workingState as EmbeddableStateWithType, references };
- };
-};
diff --git a/src/plugins/controls/common/control_types/time_slider/types.ts b/src/plugins/controls/common/control_types/time_slider/types.ts
deleted file mode 100644
index 31272380becde90..000000000000000
--- a/src/plugins/controls/common/control_types/time_slider/types.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { DataControlInput } from '../../types';
-
-export const TIME_SLIDER_CONTROL = 'timeSlider';
-
-export interface TimeSliderControlEmbeddableInput extends DataControlInput {
- value?: [number | null, number | null];
-}
diff --git a/src/plugins/controls/common/index.ts b/src/plugins/controls/common/index.ts
index c3361c29232bd95..a201553c09ec12a 100644
--- a/src/plugins/controls/common/index.ts
+++ b/src/plugins/controls/common/index.ts
@@ -36,5 +36,3 @@ export {
// Control Type exports
export { OPTIONS_LIST_CONTROL, type OptionsListEmbeddableInput } from './options_list/types';
export { type RangeSliderEmbeddableInput, RANGE_SLIDER_CONTROL } from './range_slider/types';
-
-export { TIME_SLIDER_CONTROL } from './control_types/time_slider/types';
diff --git a/src/plugins/controls/public/__stories__/storybook_control_factories.ts b/src/plugins/controls/public/__stories__/storybook_control_factories.ts
index 9b0b41f6393e735..2e27339a9eaf876 100644
--- a/src/plugins/controls/public/__stories__/storybook_control_factories.ts
+++ b/src/plugins/controls/public/__stories__/storybook_control_factories.ts
@@ -8,7 +8,6 @@
import { OptionsListEmbeddableFactory } from '../options_list';
import { RangeSliderEmbeddableFactory } from '../range_slider';
-import { TimesliderEmbeddableFactory } from '../control_types/time_slider';
import { ControlsService } from '../services/controls';
import { ControlFactory } from '..';
@@ -26,9 +25,4 @@ export const populateStorybookControlFactories = (controlsServiceStub: ControlsS
const rangeSliderControlFactory = rangeSliderFactoryStub as unknown as ControlFactory;
rangeSliderControlFactory.getDefaultInput = () => ({});
controlsServiceStub.registerControlType(rangeSliderControlFactory);
-
- const timesliderFactoryStub = new TimesliderEmbeddableFactory();
- const timeSliderControlFactory = timesliderFactoryStub as unknown as ControlFactory;
- timeSliderControlFactory.getDefaultInput = () => ({});
- controlsServiceStub.registerControlType(timeSliderControlFactory);
};
diff --git a/src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx b/src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx
deleted file mode 100644
index 90ea07dc276bd56..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/__stories__/time_slider.component.stories.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-import React, { FC, useCallback, useState } from 'react';
-import moment from 'moment';
-import { EuiFormControlLayout } from '@elastic/eui';
-
-import { TimeSliderProps, TimeSlider } from '../time_slider.component';
-
-export default {
- title: 'Time Slider',
- description: '',
-};
-
-const TimeSliderWrapper: FC> = (props) => {
- const [value, setValue] = useState(props.value);
- const onChange = useCallback(
- (newValue: [number | null, number | null]) => {
- const lowValue = newValue[0];
- const highValue = newValue[1];
-
- setValue([lowValue, highValue]);
- },
- [setValue]
- );
-
- return (
-
-
-
-
-
- );
-};
-
-const undefinedValue: [null, null] = [null, null];
-const undefinedRange: [undefined, undefined] = [undefined, undefined];
-
-export const TimeSliderNoValuesOrRange = () => {
- // If range is undefined, that should be inndicate that we are loading the range
- return ;
-};
-
-export const TimeSliderUndefinedRangeNoValue = () => {
- // If a range is [undefined, undefined] then it was loaded, but no values were found.
- return ;
-};
-
-export const TimeSliderUndefinedRangeWithValue = () => {
- const lastWeek = moment().subtract(7, 'days');
- const now = moment();
-
- return (
-
- );
-};
-
-export const TimeSliderWithRangeAndNoValue = () => {
- const lastWeek = moment().subtract(7, 'days');
- const now = moment();
-
- return (
-
- );
-};
-
-export const TimeSliderWithRangeAndLowerValue = () => {
- const lastWeek = moment().subtract(7, 'days');
- const now = moment();
-
- const threeDays = moment().subtract(3, 'days');
-
- return (
-
- );
-};
-
-export const TimeSliderWithRangeAndUpperValue = () => {
- const lastWeek = moment().subtract(7, 'days');
- const now = moment();
-
- const threeDays = moment().subtract(3, 'days');
-
- return (
-
- );
-};
-
-export const TimeSliderWithLowRangeOverlap = () => {
- const lastWeek = moment().subtract(7, 'days');
- const now = moment();
-
- const threeDays = moment().subtract(3, 'days');
- const twoDays = moment().subtract(2, 'days');
-
- return (
-
- );
-};
-
-export const TimeSliderWithLowRangeOverlapAndIgnoredValidation = () => {
- const lastWeek = moment().subtract(7, 'days');
- const now = moment();
-
- const threeDays = moment().subtract(3, 'days');
- const twoDays = moment().subtract(2, 'days');
-
- return (
-
- );
-};
-
-export const TimeSliderWithRangeLowerThanValue = () => {
- const twoWeeksAgo = moment().subtract(14, 'days');
- const lastWeek = moment().subtract(7, 'days');
-
- const now = moment();
- const threeDays = moment().subtract(3, 'days');
-
- return (
-
- );
-};
-
-export const TimeSliderWithRangeHigherThanValue = () => {
- const twoWeeksAgo = moment().subtract(14, 'days');
- const lastWeek = moment().subtract(7, 'days');
-
- const now = moment();
- const threeDays = moment().subtract(3, 'days');
-
- return (
-
- );
-};
-
-export const PartialValueLowerThanRange = () => {
- // Selected value is March 8 -> March 9
- // Range is March 11 -> 25
- const eightDaysAgo = moment().subtract(8, 'days');
-
- const lastWeek = moment().subtract(7, 'days');
- const today = moment();
-
- return (
-
- );
-};
-
-export const PartialValueHigherThanRange = () => {
- // Selected value is March 8 -> March 9
- // Range is March 11 -> 25
- const eightDaysAgo = moment().subtract(8, 'days');
-
- const lastWeek = moment().subtract(7, 'days');
- const today = moment();
-
- return (
-
- );
-};
diff --git a/src/plugins/controls/public/control_types/time_slider/index.ts b/src/plugins/controls/public/control_types/time_slider/index.ts
deleted file mode 100644
index 1cd5900164676d2..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/index.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export { TimesliderEmbeddableFactory } from './time_slider_embeddable_factory';
-export { type TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types';
-export {} from '../../../common';
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider.component.scss b/src/plugins/controls/public/control_types/time_slider/time_slider.component.scss
deleted file mode 100644
index 3f8a37ec44d3705..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider.component.scss
+++ /dev/null
@@ -1,47 +0,0 @@
-.timeSlider__anchorOverride {
- display:block;
- >div {
- height: 100%;
- }
-}
-
-.timeSlider__popoverOverride {
- width: 100%;
- max-width: 100%;
- height: 100%;
-}
-
-.timeSlider__panelOverride {
- min-width: $euiSizeXXL * 15;
-}
-
-.timeSlider__anchor {
- text-decoration: none;
- width: 100%;
- background-color: $euiFormBackgroundColor;
- box-shadow: none;
- @include euiFormControlSideBorderRadius($euiFormControlBorderRadius, $side: 'right', $internal: true);
- overflow: hidden;
- height: 100%;
-
- &:enabled:focus {
- background-color: $euiFormBackgroundColor;
- }
-
- .euiText {
- background-color: $euiFormBackgroundColor;
- }
-
- .timeSlider__anchorText {
- font-weight: $euiFontWeightBold;
- }
-
- .timeSlider__anchorText--default {
- color: $euiColorMediumShade;
- }
-
- .timeSlider__anchorText--invalid {
- text-decoration: line-through;
- color: $euiColorMediumShade;
- }
-}
\ No newline at end of file
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx
deleted file mode 100644
index 1bb2f90b44121f4..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider.component.tsx
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React, { FC, useState, useMemo, useCallback } from 'react';
-import { isNil } from 'lodash';
-import {
- EuiText,
- EuiLoadingSpinner,
- EuiInputPopover,
- EuiPopoverTitle,
- EuiSpacer,
- EuiFlexItem,
- EuiFlexGroup,
- EuiToolTip,
- EuiButtonIcon,
-} from '@elastic/eui';
-import { EuiRangeTick } from '@elastic/eui/src/components/form/range/range_ticks';
-import moment from 'moment-timezone';
-import { calcAutoIntervalNear } from '@kbn/data-plugin/common';
-import { ValidatedDualRange } from '@kbn/kibana-react-plugin/public';
-import { TimeSliderStrings } from './time_slider_strings';
-import './time_slider.component.scss';
-
-function getScaledDateFormat(interval: number): string {
- if (interval >= moment.duration(1, 'y').asMilliseconds()) {
- return 'YYYY';
- }
-
- if (interval >= moment.duration(1, 'd').asMilliseconds()) {
- return 'MMM D';
- }
-
- if (interval >= moment.duration(6, 'h').asMilliseconds()) {
- return 'Do HH';
- }
-
- if (interval >= moment.duration(1, 'h').asMilliseconds()) {
- return 'HH:mm';
- }
-
- if (interval >= moment.duration(1, 'm').asMilliseconds()) {
- return 'HH:mm';
- }
-
- if (interval >= moment.duration(1, 's').asMilliseconds()) {
- return 'mm:ss';
- }
-
- return 'ss.SSS';
-}
-
-export function getInterval(min: number, max: number, steps = 6): number {
- const duration = max - min;
- let interval = calcAutoIntervalNear(steps, duration).asMilliseconds();
- // Sometimes auto interval is not quite right and returns 2X or 3X requested ticks
- // Adjust the interval to get closer to the requested number of ticks
- const actualSteps = duration / interval;
- if (actualSteps > steps * 1.5) {
- const factor = Math.round(actualSteps / steps);
- interval *= factor;
- } else if (actualSteps < 5) {
- interval *= 0.5;
- }
- return interval;
-}
-
-export interface TimeSliderProps {
- id: string;
- range?: [number | undefined, number | undefined];
- value: [number | null, number | null];
- onChange: (range: [number | null, number | null]) => void;
- dateFormat?: string;
- timezone?: string;
- fieldName: string;
- ignoreValidation?: boolean;
-}
-
-const isValidRange = (maybeRange: TimeSliderProps['range']): maybeRange is [number, number] => {
- return maybeRange !== undefined && !isNil(maybeRange[0]) && !isNil(maybeRange[1]);
-};
-
-const unselectedClass = 'timeSlider__anchorText--default';
-const validClass = 'timeSlider__anchorText';
-const invalidClass = 'timeSlider__anchorText--invalid';
-
-export const TimeSlider: FC = (props) => {
- const defaultProps = {
- dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS',
- ignoreValidation: false,
- timezone: 'Browser',
- ...props,
- };
- const { range, value, timezone, dateFormat, fieldName, ignoreValidation } = defaultProps;
- const [isPopoverOpen, setIsPopoverOpen] = useState(false);
- const togglePopover = useCallback(() => {
- setIsPopoverOpen(!isPopoverOpen);
- }, [isPopoverOpen, setIsPopoverOpen]);
-
- const getTimezone = useCallback(() => {
- const detectedTimezone = moment.tz.guess();
-
- return timezone === 'Browser' ? detectedTimezone : timezone;
- }, [timezone]);
-
- const epochToKbnDateFormat = useCallback(
- (epoch: number) => {
- const tz = getTimezone();
- return moment.tz(epoch, tz).format(dateFormat);
- },
- [dateFormat, getTimezone]
- );
-
- // If we don't have a range or we have is loading, show the loading state
- const hasRange = range !== undefined;
-
- // We have values if we have a range or value entry for both position
- const hasValues =
- (value[0] !== null || (hasRange && range[0] !== undefined)) &&
- (value[1] !== null || (hasRange && range[1] !== undefined));
-
- let valueText: JSX.Element | null = null;
- if (hasValues) {
- let lower = value[0] !== null ? value[0] : range![0]!;
- let upper = value[1] !== null ? value[1] : range![1]!;
-
- if (value[0] !== null && lower > upper) {
- upper = lower;
- } else if (value[1] !== null && lower > upper) {
- lower = upper;
- }
-
- const hasLowerValueInRange =
- value[0] !== null && isValidRange(range) && value[0] >= range[0] && value[0] <= range[1];
- // It's out of range if the upper value is above the upper range or below the lower range
- const hasUpperValueInRange =
- value[1] !== null && isValidRange(range) && value[1] <= range[1] && value[1] >= range[0];
-
- let lowClass = unselectedClass;
- let highClass = unselectedClass;
- if (value[0] !== null && (hasLowerValueInRange || ignoreValidation)) {
- lowClass = validClass;
- } else if (value[0] !== null) {
- lowClass = invalidClass;
- }
-
- if (value[1] !== null && (hasUpperValueInRange || ignoreValidation)) {
- highClass = validClass;
- } else if (value[1] !== null) {
- highClass = invalidClass;
- }
-
- // if no value then anchorText default
- // if hasLowerValueInRange || skipValidation then anchor text
- // else strikethrough
-
- valueText = (
-
- {epochToKbnDateFormat(lower)}
- →
- {epochToKbnDateFormat(upper)}
-
- );
- }
-
- const button = (
-
- );
-
- return (
- setIsPopoverOpen(false)}
- panelPaddingSize="s"
- anchorPosition="downCenter"
- disableFocusTrap
- attachToAnchor={false}
- >
- {isValidRange(range) ? (
-
- ) : (
-
- )}
-
- );
-};
-
-const TimeSliderComponentPopoverNoDocuments: FC = () => {
- return {TimeSliderStrings.noDocumentsPopover.getLabel()};
-};
-
-export const TimeSliderComponentPopover: FC<
- TimeSliderProps & {
- range: [number, number];
- getTimezone: () => string;
- epochToKbnDateFormat: (epoch: number) => string;
- }
-> = ({ range, value, onChange, getTimezone, epochToKbnDateFormat, fieldName }) => {
- const [lowerBound, upperBound] = range;
- let [lowerValue, upperValue] = value;
-
- if (lowerValue === null) {
- lowerValue = lowerBound;
- }
-
- if (upperValue === null) {
- upperValue = upperBound;
- }
-
- const fullRange = useMemo(
- () => [Math.min(lowerValue!, lowerBound), Math.max(upperValue!, upperBound)],
- [lowerValue, lowerBound, upperValue, upperBound]
- );
-
- const getTicks = useCallback(
- (min: number, max: number, interval: number): EuiRangeTick[] => {
- const format = getScaledDateFormat(interval);
- const tz = getTimezone();
-
- let tick = Math.ceil(min / interval) * interval;
- const ticks: EuiRangeTick[] = [];
- while (tick < max) {
- ticks.push({
- value: tick,
- label: moment.tz(tick, tz).format(format),
- });
- tick += interval;
- }
-
- return ticks;
- },
- [getTimezone]
- );
-
- const ticks = useMemo(() => {
- const interval = getInterval(fullRange[0], fullRange[1]);
- return getTicks(fullRange[0], fullRange[1], interval);
- }, [fullRange, getTicks]);
-
- const onChangeHandler = useCallback(
- ([_min, _max]: [number | string, number | string]) => {
- // If a value is undefined and the number that is given here matches the range bounds
- // then we will ignore it, becuase they probably didn't actually select that value
- const report: [number | null, number | null] = [null, null];
-
- let min: number;
- let max: number;
- if (typeof _min === 'string') {
- min = parseFloat(_min);
- min = isNaN(min) ? range[0] : min;
- } else {
- min = _min;
- }
-
- if (typeof _max === 'string') {
- max = parseFloat(_max);
- max = isNaN(max) ? range[0] : max;
- } else {
- max = _max;
- }
-
- if (value[0] !== null || min !== range[0]) {
- report[0] = min;
- }
- if (value[1] !== null || max !== range[1]) {
- report[1] = max;
- }
-
- onChange(report);
- },
- [onChange, value, range]
- );
-
- const levels = [{ min: range[0], max: range[1], color: 'success' }];
-
- return (
- <>
- {fieldName}
-
- {epochToKbnDateFormat(lowerValue)} - {epochToKbnDateFormat(upperValue)}
-
-
-
-
-
-
-
-
- onChange([null, null])}
- aria-label={TimeSliderStrings.resetButton.getLabel()}
- data-test-subj="timeSlider__clearRangeButton"
- />
-
-
-
-
- >
- );
-};
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider.tsx
deleted file mode 100644
index 0b519406ccf8d6e..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React, { FC, useCallback, useMemo } from 'react';
-import { BehaviorSubject } from 'rxjs';
-import { debounce } from 'lodash';
-import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public';
-
-import { timeSliderReducers } from './time_slider_reducers';
-import { TimeSlider as Component } from './time_slider.component';
-import { TimeSliderReduxState, TimeSliderSubjectState } from './types';
-
-interface TimeSliderProps {
- componentStateSubject: BehaviorSubject;
- dateFormat: string;
- timezone: string;
- fieldName: string;
- ignoreValidation: boolean;
-}
-
-export const TimeSlider: FC = ({
- componentStateSubject,
- dateFormat,
- timezone,
- fieldName,
- ignoreValidation,
-}) => {
- const {
- useEmbeddableDispatch,
- useEmbeddableSelector: select,
- actions: { selectRange },
- } = useReduxEmbeddableContext();
- const dispatch = useEmbeddableDispatch();
-
- const availableRange = select((state) => state.componentState.range);
- const value = select((state) => state.explicitInput.value);
- const id = select((state) => state.explicitInput.id);
-
- const { min, max } = availableRange
- ? availableRange
- : ({} as {
- min?: number;
- max?: number;
- });
-
- const dispatchChange = useCallback(
- (range: [number | null, number | null]) => {
- dispatch(selectRange(range));
- },
- [dispatch, selectRange]
- );
-
- const debouncedDispatchChange = useMemo(() => debounce(dispatchChange, 500), [dispatchChange]);
-
- const onChangeComplete = useCallback(
- (range: [number | null, number | null]) => {
- debouncedDispatchChange(range);
- },
- [debouncedDispatchChange]
- );
-
- return (
-
- );
-};
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts b/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts
deleted file mode 100644
index 4db5277a0e2f9db..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.test.ts
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { of } from 'rxjs';
-import { delay, map } from 'rxjs/operators';
-import { TimeSliderControlEmbeddableInput } from '.';
-import { TimeSliderControlEmbeddable } from './time_slider_embeddable';
-import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub';
-import { pluginServices } from '../../services';
-import { TestScheduler } from 'rxjs/testing';
-import { buildRangeFilter } from '@kbn/es-query';
-import { ReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public';
-
-const buildFilter = (range: [number | null, number | null]) => {
- const filterPieces: Record = {};
- if (range[0] !== null) {
- filterPieces.gte = range[0];
- }
- if (range[1] !== null) {
- filterPieces.lte = range[1];
- }
-
- const filter = buildRangeFilter(
- stubLogstashDataView.getFieldByName('bytes')!,
- filterPieces,
- stubLogstashDataView
- );
- filter.meta.key = 'bytes';
-
- return filter;
-};
-
-const rangeMin = 20;
-const rangeMax = 30;
-const range = { min: rangeMin, max: rangeMax };
-
-const lowerValue: [number, number] = [15, 25];
-const upperValue: [number, number] = [25, 35];
-const partialLowValue: [number, null] = [25, null];
-const partialHighValue: [null, number] = [null, 25];
-const withinRangeValue: [number, number] = [21, 29];
-const outOfRangeValue: [number, number] = [31, 40];
-
-const rangeFilter = buildFilter([rangeMin, rangeMax]);
-const lowerValueFilter = buildFilter(lowerValue);
-const lowerValuePartialFilter = buildFilter([20, 25]);
-const upperValueFilter = buildFilter(upperValue);
-const upperValuePartialFilter = buildFilter([25, 30]);
-
-const partialLowValueFilter = buildFilter(partialLowValue);
-const partialHighValueFilter = buildFilter(partialHighValue);
-const withinRangeValueFilter = buildFilter(withinRangeValue);
-const outOfRangeValueFilter = buildFilter(outOfRangeValue);
-
-const baseInput: TimeSliderControlEmbeddableInput = {
- id: 'id',
- fieldName: 'bytes',
- dataViewId: stubLogstashDataView.id!,
-};
-
-const mockReduxEmbeddablePackage = {
- createTools: () => {},
-} as unknown as ReduxEmbeddablePackage;
-
-describe('Time Slider Control Embeddable', () => {
- const services = pluginServices.getServices();
- const fetchRange = jest.spyOn(services.data, 'fetchFieldRange');
- const getDataView = jest.spyOn(services.data, 'getDataView');
- const fetchRange$ = jest.spyOn(services.data, 'fetchFieldRange$');
- const getDataView$ = jest.spyOn(services.data, 'getDataView$');
-
- beforeEach(() => {
- jest.resetAllMocks();
-
- fetchRange.mockResolvedValue(range);
- fetchRange$.mockReturnValue(of(range).pipe(delay(100)));
- getDataView.mockResolvedValue(stubLogstashDataView);
- getDataView$.mockReturnValue(of(stubLogstashDataView));
- });
-
- describe('outputting filters', () => {
- let testScheduler: TestScheduler;
- beforeEach(() => {
- testScheduler = new TestScheduler((actual, expected) => {
- expect(actual).toEqual(expected);
- });
- });
-
- const testFilterOutput = (
- input: any,
- expectedFilterAfterRangeFetch: any,
- mockRange: { min?: number; max?: number } = range
- ) => {
- testScheduler.run(({ expectObservable, cold }) => {
- fetchRange$.mockReturnValue(cold('--b', { b: mockRange }));
- const expectedMarbles = 'a-b';
- const expectedValues = {
- a: undefined,
- b: expectedFilterAfterRangeFetch ? [expectedFilterAfterRangeFetch] : undefined,
- };
-
- const embeddable = new TimeSliderControlEmbeddable(mockReduxEmbeddablePackage, input, {});
- const source$ = embeddable.getOutput$().pipe(map((o) => o.filters));
-
- expectObservable(source$).toBe(expectedMarbles, expectedValues);
- });
- };
-
- it('outputs no filter when no value is given', () => {
- testFilterOutput(baseInput, undefined);
- });
-
- it('outputs the value filter after the range is fetched', () => {
- testFilterOutput({ ...baseInput, value: withinRangeValue }, withinRangeValueFilter);
- });
-
- it('outputs a partial filter for a low partial value', () => {
- testFilterOutput({ ...baseInput, value: partialLowValue }, partialLowValueFilter);
- });
-
- it('outputs a partial filter for a high partial value', () => {
- testFilterOutput({ ...baseInput, value: partialHighValue }, partialHighValueFilter);
- });
-
- describe('with validation', () => {
- it('outputs a partial value filter if value is below range', () => {
- testFilterOutput({ ...baseInput, value: lowerValue }, lowerValuePartialFilter);
- });
-
- it('outputs a partial value filter if value is above range', () => {
- testFilterOutput({ ...baseInput, value: upperValue }, upperValuePartialFilter);
- });
-
- it('outputs range filter value if value is completely out of range', () => {
- testFilterOutput({ ...baseInput, value: outOfRangeValue }, rangeFilter);
- });
-
- it('outputs no filter when no range available', () => {
- testFilterOutput({ ...baseInput, value: withinRangeValue }, undefined, {});
- });
- });
-
- describe('with validation off', () => {
- it('outputs the lower value filter', () => {
- testFilterOutput(
- { ...baseInput, ignoreParentSettings: { ignoreValidations: true }, value: lowerValue },
- lowerValueFilter
- );
- });
-
- it('outputs the uppwer value filter', () => {
- testFilterOutput(
- { ...baseInput, ignoreParentSettings: { ignoreValidations: true }, value: upperValue },
- upperValueFilter
- );
- });
-
- it('outputs the out of range filter', () => {
- testFilterOutput(
- {
- ...baseInput,
- ignoreParentSettings: { ignoreValidations: true },
- value: outOfRangeValue,
- },
- outOfRangeValueFilter
- );
- });
-
- it('outputs the value filter when no range found', () => {
- testFilterOutput(
- {
- ...baseInput,
- ignoreParentSettings: { ignoreValidations: true },
- value: withinRangeValue,
- },
- withinRangeValueFilter,
- { min: undefined, max: undefined }
- );
- });
- });
- });
-
- describe('fetching range', () => {
- it('fetches range on init', () => {
- const testScheduler = new TestScheduler((actual, expected) => {
- expect(actual).toEqual(expected);
- });
-
- testScheduler.run(({ cold, expectObservable }) => {
- const mockRange = { min: 1, max: 2 };
- fetchRange$.mockReturnValue(cold('--b', { b: mockRange }));
-
- const expectedMarbles = 'a-b';
- const expectedValues = {
- a: undefined,
- b: mockRange,
- };
-
- const embeddable = new TimeSliderControlEmbeddable(
- mockReduxEmbeddablePackage,
- baseInput,
- {}
- );
- const source$ = embeddable.getComponentState$().pipe(map((state) => state.range));
-
- const { fieldName, ...inputForFetch } = baseInput;
-
- expectObservable(source$).toBe(expectedMarbles, expectedValues);
- expect(fetchRange$).toBeCalledWith(stubLogstashDataView, fieldName, {
- ...inputForFetch,
- filters: undefined,
- query: undefined,
- timeRange: undefined,
- viewMode: 'edit',
- });
- });
- });
-
- it('fetches range on input change', () => {
- const testScheduler = new TestScheduler((actual, expected) => {
- expect(actual).toEqual(expected);
- });
-
- testScheduler.run(({ cold, expectObservable, flush }) => {
- const mockRange = { min: 1, max: 2 };
- fetchRange$.mockReturnValue(cold('a', { a: mockRange }));
-
- const embeddable = new TimeSliderControlEmbeddable(
- mockReduxEmbeddablePackage,
- baseInput,
- {}
- );
- const updatedInput = { ...baseInput, fieldName: '@timestamp' };
-
- embeddable.updateInput(updatedInput);
-
- expect(fetchRange$).toBeCalledTimes(2);
- expect(fetchRange$.mock.calls[1][1]).toBe(updatedInput.fieldName);
- });
- });
-
- it('passes input to fetch range to build the query', () => {
- const testScheduler = new TestScheduler((actual, expected) => {
- expect(actual).toEqual(expected);
- });
-
- testScheduler.run(({ cold, expectObservable, flush }) => {
- const mockRange = { min: 1, max: 2 };
- fetchRange$.mockReturnValue(cold('a', { a: mockRange }));
-
- const input = {
- ...baseInput,
- query: {} as any,
- filters: {} as any,
- timeRange: {} as any,
- };
-
- new TimeSliderControlEmbeddable(mockReduxEmbeddablePackage, input, {});
-
- expect(fetchRange$).toBeCalledTimes(1);
- const args = fetchRange$.mock.calls[0][2];
- expect(args.query).toBe(input.query);
- expect(args.filters).toBe(input.filters);
- expect(args.timeRange).toBe(input.timeRange);
- });
- });
-
- it('does not pass ignored parent settings', () => {
- const testScheduler = new TestScheduler((actual, expected) => {
- expect(actual).toEqual(expected);
- });
-
- testScheduler.run(({ cold, expectObservable, flush }) => {
- const mockRange = { min: 1, max: 2 };
- fetchRange$.mockReturnValue(cold('a', { a: mockRange }));
-
- const input = {
- ...baseInput,
- query: '' as any,
- filters: {} as any,
- timeRange: {} as any,
- ignoreParentSettings: { ignoreFilters: true, ignoreQuery: true, ignoreTimerange: true },
- };
-
- new TimeSliderControlEmbeddable(mockReduxEmbeddablePackage, input, {});
-
- expect(fetchRange$).toBeCalledTimes(1);
- const args = fetchRange$.mock.calls[0][2];
- expect(args.query).not.toBe(input.query);
- expect(args.filters).not.toBe(input.filters);
- expect(args.timeRange).not.toBe(input.timeRange);
- });
- });
- });
-});
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx
deleted file mode 100644
index a4098a72dfe1ab7..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable.tsx
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { compareFilters, buildRangeFilter, RangeFilterParams } from '@kbn/es-query';
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { isEqual } from 'lodash';
-import deepEqual from 'fast-deep-equal';
-import { merge, Subscription, BehaviorSubject, Observable } from 'rxjs';
-import { map, distinctUntilChanged, skip, take, mergeMap } from 'rxjs/operators';
-
-import { Embeddable, IContainer } from '@kbn/embeddable-plugin/public';
-import { ReduxEmbeddableTools, ReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public';
-import { DataView } from '@kbn/data-views-plugin/public';
-
-import { TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types';
-import { TIME_SLIDER_CONTROL } from '../..';
-import { ControlsSettingsService } from '../../services/settings';
-import { ControlsDataService } from '../../services/data';
-import { ControlOutput } from '../..';
-import { pluginServices } from '../../services';
-
-import { TimeSlider as TimeSliderComponent } from './time_slider';
-import { timeSliderReducers } from './time_slider_reducers';
-import { TimeSliderReduxState, TimeSliderSubjectState } from './types';
-
-const diffDataFetchProps = (current?: any, last?: any) => {
- if (!current || !last) return false;
- const { filters: currentFilters, ...currentWithoutFilters } = current;
- const { filters: lastFilters, ...lastWithoutFilters } = last;
- if (!deepEqual(currentWithoutFilters, lastWithoutFilters)) return false;
- if (!compareFilters(lastFilters ?? [], currentFilters ?? [])) return false;
- return true;
-};
-
-export class TimeSliderControlEmbeddable extends Embeddable<
- TimeSliderControlEmbeddableInput,
- ControlOutput
-> {
- public readonly type = TIME_SLIDER_CONTROL;
- public deferEmbeddableLoad = true;
-
- private subscriptions: Subscription = new Subscription();
- private node?: HTMLElement;
-
- // Internal data fetching state for this input control.
- private dataView?: DataView;
-
- private componentState: TimeSliderSubjectState;
- private componentStateSubject$ = new BehaviorSubject({
- range: undefined,
- loading: false,
- });
-
- // Internal state subject will let us batch updates to the externally accessible state subject
- private internalComponentStateSubject$ = new BehaviorSubject({
- range: undefined,
- loading: false,
- });
-
- private internalOutput: ControlOutput;
-
- private fetchRange$: ControlsDataService['fetchFieldRange$'];
- private getDataView$: ControlsDataService['getDataView$'];
- private getDateFormat: ControlsSettingsService['getDateFormat'];
- private getTimezone: ControlsSettingsService['getTimezone'];
-
- private reduxEmbeddableTools: ReduxEmbeddableTools<
- TimeSliderReduxState,
- typeof timeSliderReducers
- >;
-
- constructor(
- reduxEmbeddablePackage: ReduxEmbeddablePackage,
- input: TimeSliderControlEmbeddableInput,
- output: ControlOutput,
- parent?: IContainer
- ) {
- super(input, output, parent); // get filters for initial output...
-
- const {
- data: { fetchFieldRange$, getDataView$ },
- settings: { getDateFormat, getTimezone },
- } = pluginServices.getServices();
- this.fetchRange$ = fetchFieldRange$;
- this.getDataView$ = getDataView$;
- this.getDateFormat = getDateFormat;
- this.getTimezone = getTimezone;
-
- this.componentState = { loading: true };
- this.updateComponentState(this.componentState, true);
-
- this.internalOutput = {};
-
- // build redux embeddable tools
- this.reduxEmbeddableTools = reduxEmbeddablePackage.createTools<
- TimeSliderReduxState,
- typeof timeSliderReducers
- >({
- embeddable: this,
- reducers: timeSliderReducers,
- });
-
- this.initialize();
- }
-
- private initialize() {
- // If value is undefined, then we can be finished with initialization because we're not going to output a filter
- if (this.getInput().value === undefined) {
- this.setInitializationFinished();
- }
-
- this.setupSubscriptions();
- }
-
- private setupSubscriptions() {
- // We need to fetch data when any of these values change
- const dataFetchPipe = this.getInput$().pipe(
- map((newInput) => ({
- lastReloadRequestTime: newInput.lastReloadRequestTime,
- dataViewId: newInput.dataViewId,
- fieldName: newInput.fieldName,
- timeRange: newInput.timeRange,
- filters: newInput.filters,
- query: newInput.query,
- })),
- distinctUntilChanged(diffDataFetchProps)
- );
-
- // When data fetch pipe emits, we start the fetch
- this.subscriptions.add(dataFetchPipe.subscribe(this.fetchAvailableTimerange));
-
- const availableRangePipe = this.internalComponentStateSubject$.pipe(
- map((state) => (state.range ? { min: state.range.min, max: state.range.max } : {})),
- distinctUntilChanged((a, b) => isEqual(a, b))
- );
-
- this.subscriptions.add(
- merge(
- this.getInput$().pipe(
- skip(1), // Skip the first input value
- distinctUntilChanged((a, b) => isEqual(a.value, b.value))
- ),
- availableRangePipe.pipe(skip(1))
- ).subscribe(() => {
- this.setInitializationFinished();
- this.buildFilter();
-
- this.componentStateSubject$.next(this.componentState);
- })
- );
- }
-
- private buildFilter = () => {
- const { fieldName, value, ignoreParentSettings } = this.getInput();
-
- const min = value ? value[0] : null;
- const max = value ? value[1] : null;
- const hasRange =
- this.componentState.range?.max !== undefined && this.componentState.range?.min !== undefined;
-
- this.getCurrentDataView$().subscribe((dataView) => {
- const range: RangeFilterParams = {};
- let filterMin: number | undefined;
- let filterMax: number | undefined;
- const field = dataView.getFieldByName(fieldName);
-
- if (ignoreParentSettings?.ignoreValidations) {
- if (min !== null) {
- range.gte = min;
- }
-
- if (max !== null) {
- range.lte = max;
- }
- } else {
- // If we have a value or a range use the min/max of those, otherwise undefined
- if (min !== null && this.componentState.range!.min !== undefined) {
- filterMin = Math.max(min || 0, this.componentState.range!.min || 0);
- }
-
- if (max !== null && this.componentState.range!.max) {
- filterMax = Math.min(
- max || Number.MAX_SAFE_INTEGER,
- this.componentState.range!.max || Number.MAX_SAFE_INTEGER
- );
- }
-
- // Last check, if the value is completely outside the range then we will just default to the range
- if (
- hasRange &&
- ((min !== null && min > this.componentState.range!.max!) ||
- (max !== null && max < this.componentState.range!.min!))
- ) {
- filterMin = this.componentState.range!.min;
- filterMax = this.componentState.range!.max;
- }
-
- if (hasRange && filterMin !== undefined) {
- range.gte = filterMin;
- }
- if (hasRange && filterMax !== undefined) {
- range.lte = filterMax;
- }
- }
-
- if (range.lte !== undefined || range.gte !== undefined) {
- const rangeFilter = buildRangeFilter(field!, range, dataView);
- rangeFilter.meta.key = field?.name;
-
- this.updateInternalOutput({ filters: [rangeFilter] }, true);
- this.updateComponentState({ loading: false });
- } else {
- this.updateInternalOutput({ filters: undefined, dataViewId: dataView.id }, true);
- this.updateComponentState({ loading: false });
- }
- });
- };
-
- private updateComponentState(changes: Partial, publish = false) {
- this.componentState = {
- ...this.componentState,
- ...changes,
- };
-
- this.internalComponentStateSubject$.next(this.componentState);
-
- if (publish) {
- this.componentStateSubject$.next(this.componentState);
- }
- }
-
- private updateInternalOutput(changes: Partial, publish = false) {
- this.internalOutput = {
- ...this.internalOutput,
- ...changes,
- };
-
- if (publish) {
- this.updateOutput(this.internalOutput);
- }
- }
-
- private getCurrentDataView$ = () => {
- const { dataViewId } = this.getInput();
- if (this.dataView && this.dataView.id === dataViewId)
- return new Observable((subscriber) => {
- subscriber.next(this.dataView);
- subscriber.complete();
- });
-
- return this.getDataView$(dataViewId);
- };
-
- private fetchAvailableTimerange = () => {
- this.updateComponentState({ loading: true }, true);
- this.updateInternalOutput({ loading: true }, true);
-
- const { fieldName, ignoreParentSettings, query, filters, timeRange, ...input } =
- this.getInput();
-
- const inputForFetch = {
- ...input,
- ...(ignoreParentSettings?.ignoreQuery ? {} : { query }),
- ...(ignoreParentSettings?.ignoreFilters ? {} : { filters }),
- ...(ignoreParentSettings?.ignoreTimerange ? {} : { timeRange }),
- };
-
- try {
- this.getCurrentDataView$()
- .pipe(
- mergeMap((dataView) => this.fetchRange$(dataView, fieldName, inputForFetch)),
- take(1)
- )
- .subscribe(({ min, max }) => {
- this.updateInternalOutput({ loading: false });
- this.updateComponentState({
- range: {
- min: min === null ? undefined : min,
- max: max === null ? undefined : max,
- },
- loading: false,
- });
- });
- } catch (e) {
- this.updateComponentState({ loading: false }, true);
- this.updateInternalOutput({ loading: false }, true);
- }
- };
-
- public getComponentState$ = () => {
- return this.componentStateSubject$;
- };
-
- public destroy = () => {
- super.destroy();
- this.subscriptions.unsubscribe();
- };
-
- public reload = () => {
- this.fetchAvailableTimerange();
- };
-
- public render = (node: HTMLElement) => {
- if (this.node) {
- ReactDOM.unmountComponentAtNode(this.node);
- }
- this.node = node;
-
- const { Wrapper: TimeSliderControlReduxWrapper } = this.reduxEmbeddableTools;
-
- ReactDOM.render(
-
-
- ,
- node
- );
- };
-}
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx b/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx
deleted file mode 100644
index 51048489ccae9b7..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider_embeddable_factory.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import deepEqual from 'fast-deep-equal';
-
-import { lazyLoadReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public';
-import { EmbeddableFactoryDefinition, IContainer } from '@kbn/embeddable-plugin/public';
-
-import { TIME_SLIDER_CONTROL } from '../..';
-import { ControlEmbeddable, DataControlField, IEditableControlFactory } from '../../types';
-import {
- createOptionsListExtract,
- createOptionsListInject,
-} from '../../../common/options_list/options_list_persistable_state';
-import { TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types';
-import { TimeSliderStrings } from './time_slider_strings';
-
-export class TimesliderEmbeddableFactory
- implements EmbeddableFactoryDefinition, IEditableControlFactory
-{
- public type = TIME_SLIDER_CONTROL;
- public canCreateNew = () => false;
-
- constructor() {}
-
- public async create(initialInput: TimeSliderControlEmbeddableInput, parent?: IContainer) {
- const reduxEmbeddablePackage = await lazyLoadReduxEmbeddablePackage();
- const { TimeSliderControlEmbeddable } = await import('./time_slider_embeddable');
-
- return Promise.resolve(
- new TimeSliderControlEmbeddable(reduxEmbeddablePackage, initialInput, {}, parent)
- );
- }
-
- public presaveTransformFunction = (
- newInput: Partial,
- embeddable?: ControlEmbeddable
- ) => {
- if (
- embeddable &&
- ((newInput.fieldName && !deepEqual(newInput.fieldName, embeddable.getInput().fieldName)) ||
- (newInput.dataViewId && !deepEqual(newInput.dataViewId, embeddable.getInput().dataViewId)))
- ) {
- // if the field name or data view id has changed in this editing session, selected options are invalid, so reset them.
- newInput.value = undefined;
- }
- return newInput;
- };
-
- public isFieldCompatible = (dataControlField: DataControlField) => {
- if (dataControlField.field.type === 'date') {
- dataControlField.compatibleControlTypes.push(this.type);
- }
- };
-
- public isEditable = () => Promise.resolve(false);
-
- public getDisplayName = () => TimeSliderStrings.getDisplayName();
- public getIconType = () => 'clock';
- public getDescription = () => TimeSliderStrings.getDescription();
-
- public inject = createOptionsListInject();
- public extract = createOptionsListExtract();
-}
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts b/src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts
deleted file mode 100644
index 95b8d87dc902e51..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider_reducers.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { PayloadAction } from '@reduxjs/toolkit';
-import { WritableDraft } from 'immer/dist/types/types-external';
-import { TimeSliderReduxState } from './types';
-
-export const timeSliderReducers = {
- selectRange: (
- state: WritableDraft,
- action: PayloadAction<[number | null, number | null]>
- ) => {
- state.explicitInput.value = action.payload;
- },
-};
diff --git a/src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts b/src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts
deleted file mode 100644
index 2c61d7d43a7976d..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/time_slider_strings.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export const TimeSliderStrings = {
- getDisplayName: () =>
- i18n.translate('controls.timeSlider.displayName', {
- defaultMessage: 'Time slider',
- }),
- getDescription: () =>
- i18n.translate('controls.timeSlider.description', {
- defaultMessage: 'Add a slider for selecting a time range',
- }),
- editor: {
- getDataViewTitle: () =>
- i18n.translate('controls.timeSlider.editor.dataViewTitle', {
- defaultMessage: 'Data view',
- }),
- getNoDataViewTitle: () =>
- i18n.translate('controls.timeSlider.editor.noDataViewTitle', {
- defaultMessage: 'Select data view',
- }),
- getFieldTitle: () =>
- i18n.translate('controls.timeSlider.editor.fieldTitle', {
- defaultMessage: 'Field',
- }),
- },
- resetButton: {
- getLabel: () =>
- i18n.translate('controls.timeSlider.resetButton.label', {
- defaultMessage: 'Reset selections',
- }),
- },
- noDocumentsPopover: {
- getLabel: () =>
- i18n.translate('controls.timeSlider.noDocuments.label', {
- defaultMessage: 'There were no documents found. Range selection unavailable.',
- }),
- },
-};
diff --git a/src/plugins/controls/public/control_types/time_slider/types.ts b/src/plugins/controls/public/control_types/time_slider/types.ts
deleted file mode 100644
index fc147dc3ba9596b..000000000000000
--- a/src/plugins/controls/public/control_types/time_slider/types.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { ReduxEmbeddableState } from '@kbn/presentation-util-plugin/public';
-
-import { ControlOutput } from '../../types';
-import { TimeSliderControlEmbeddableInput } from '../../../common/control_types/time_slider/types';
-
-export * from '../../../common/control_types/time_slider/types';
-
-// Component state is only used by public components.
-export interface TimeSliderSubjectState {
- range?: {
- min?: number;
- max?: number;
- };
- loading: boolean;
-}
-
-// public only - redux embeddable state type
-export type TimeSliderReduxState = ReduxEmbeddableState<
- TimeSliderControlEmbeddableInput,
- ControlOutput,
- TimeSliderSubjectState
->;
diff --git a/src/plugins/controls/public/index.ts b/src/plugins/controls/public/index.ts
index f55df5fa0f53a89..ecf430f6cc9277b 100644
--- a/src/plugins/controls/public/index.ts
+++ b/src/plugins/controls/public/index.ts
@@ -24,12 +24,7 @@ export type {
ControlInput,
} from '../common/types';
-export {
- CONTROL_GROUP_TYPE,
- OPTIONS_LIST_CONTROL,
- RANGE_SLIDER_CONTROL,
- TIME_SLIDER_CONTROL,
-} from '../common';
+export { CONTROL_GROUP_TYPE, OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '../common';
export {
ControlGroupContainer,
diff --git a/src/plugins/controls/public/plugin.ts b/src/plugins/controls/public/plugin.ts
index da45ba2e68684d0..01375b174a93496 100644
--- a/src/plugins/controls/public/plugin.ts
+++ b/src/plugins/controls/public/plugin.ts
@@ -14,7 +14,6 @@ import {
CONTROL_GROUP_TYPE,
OPTIONS_LIST_CONTROL,
RANGE_SLIDER_CONTROL,
- // TIME_SLIDER_CONTROL,
} from '.';
import { OptionsListEmbeddableFactory, OptionsListEmbeddableInput } from './options_list';
import { RangeSliderEmbeddableFactory, RangeSliderEmbeddableInput } from './range_slider';
@@ -29,13 +28,6 @@ import {
ControlInput,
} from './types';
-/*
-import {
- TimesliderEmbeddableFactory,
- TimeSliderControlEmbeddableInput,
-} from './control_types/time_slider';
-*/
-
export class ControlsPlugin
implements
Plugin<
@@ -101,22 +93,6 @@ export class ControlsPlugin
rangeSliderFactory
);
registerControlType(rangeSliderFactory);
-
- // Time Slider Control Factory Setup
- /* Temporary disabling Time Slider
- const timeSliderFactoryDef = new TimesliderEmbeddableFactory();
- const timeSliderFactory = embeddable.registerEmbeddableFactory(
- TIME_SLIDER_CONTROL,
- timeSliderFactoryDef
- )();
- this.transferEditorFunctions(
- timeSliderFactoryDef,
- timeSliderFactory
- );
-
-
- registerControlType(timeSliderFactory);
- */
});
return {
diff --git a/src/plugins/controls/server/control_group/control_group_telemetry.test.ts b/src/plugins/controls/server/control_group/control_group_telemetry.test.ts
index 140b58fd790fca0..1e66bb15fbc2bd4 100644
--- a/src/plugins/controls/server/control_group/control_group_telemetry.test.ts
+++ b/src/plugins/controls/server/control_group/control_group_telemetry.test.ts
@@ -24,7 +24,7 @@ const rawControlAttributes2: RawControlGroupAttributes = {
controlStyle: 'oneLine',
chainingSystem: 'NONE',
panelsJSON:
- '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"b47916fd-fc03-4dcd-bef1-5c3b7a315723":{"order":1,"width":"auto","type":"timeSlider","explicitInput":{"title":"timestamp","fieldName":"timestamp","id":"b47916fd-fc03-4dcd-bef1-5c3b7a315723","enhancements":{}}},"f6b076c6-9ef5-483e-b08d-d313d60d4b8c":{"order":2,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceMiles","fieldName":"DistanceMiles","id":"f6b076c6-9ef5-483e-b08d-d313d60d4b8c","enhancements":{}}}}',
+ '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"f6b076c6-9ef5-483e-b08d-d313d60d4b8c":{"order":2,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceMiles","fieldName":"DistanceMiles","id":"f6b076c6-9ef5-483e-b08d-d313d60d4b8c","enhancements":{}}}}',
ignoreParentSettingsJSON:
'{"ignoreFilters":true,"ignoreQuery":false,"ignoreTimerange":false,"ignoreValidations":false}',
};
@@ -34,7 +34,7 @@ const rawControlAttributes3: RawControlGroupAttributes = {
controlStyle: 'oneLine',
chainingSystem: 'HIERARCHICAL',
panelsJSON:
- '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"b47916fd-fc03-4dcd-bef1-5c3b7a315723":{"order":1,"width":"auto","type":"timeSlider","explicitInput":{"title":"timestamp","fieldName":"timestamp","id":"b47916fd-fc03-4dcd-bef1-5c3b7a315723","enhancements":{}}},"ee325e9e-6ec1-41f9-953f-423d59850d44":{"order":2,"width":"auto","type":"optionsListControl","explicitInput":{"title":"Carrier","fieldName":"Carrier","id":"ee325e9e-6ec1-41f9-953f-423d59850d44","enhancements":{}}},"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b":{"order":3,"width":"auto","type":"optionsListControl","explicitInput":{"title":"DestCityName","fieldName":"DestCityName","id":"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b","enhancements":{}}}}',
+ '{"9cf90205-e94d-43c9-a3aa-45f359a7522f":{"order":0,"width":"auto","type":"rangeSliderControl","explicitInput":{"title":"DistanceKilometers","fieldName":"DistanceKilometers","id":"9cf90205-e94d-43c9-a3aa-45f359a7522f","enhancements":{}}},"ee325e9e-6ec1-41f9-953f-423d59850d44":{"order":2,"width":"auto","type":"optionsListControl","explicitInput":{"title":"Carrier","fieldName":"Carrier","id":"ee325e9e-6ec1-41f9-953f-423d59850d44","enhancements":{}}},"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b":{"order":3,"width":"auto","type":"optionsListControl","explicitInput":{"title":"DestCityName","fieldName":"DestCityName","id":"cb0f5fcd-9ad9-4d4a-b489-b75bd060399b","enhancements":{}}}}',
ignoreParentSettingsJSON:
'{"ignoreFilters":false,"ignoreQuery":false,"ignoreTimerange":false,"ignoreValidations":false}',
};
@@ -97,7 +97,7 @@ describe('Control group telemetry function', () => {
});
test('counts all telemetry over multiple runs', () => {
- expect(finalTelemetry.total).toBe(10);
+ expect(finalTelemetry.total).toBe(8);
});
test('counts control types over multiple runs.', () => {
@@ -110,10 +110,6 @@ describe('Control group telemetry function', () => {
details: {},
total: 3,
},
- timeSlider: {
- details: {},
- total: 2,
- },
});
});
diff --git a/src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts b/src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts
deleted file mode 100644
index 8e8920f12f5545e..000000000000000
--- a/src/plugins/controls/server/control_types/time_slider/time_slider_embeddable_factory.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/server';
-import { TIME_SLIDER_CONTROL } from '../../../common';
-import {
- createTimeSliderExtract,
- createTimeSliderInject,
-} from '../../../common/control_types/time_slider/time_slider_persistable_state';
-
-export const timeSliderPersistableStateServiceFactory = (): EmbeddableRegistryDefinition => {
- return {
- id: TIME_SLIDER_CONTROL,
- extract: createTimeSliderExtract(),
- inject: createTimeSliderInject(),
- };
-};
diff --git a/src/plugins/controls/server/plugin.ts b/src/plugins/controls/server/plugin.ts
index 00d968881579631..019430166ff6fa9 100644
--- a/src/plugins/controls/server/plugin.ts
+++ b/src/plugins/controls/server/plugin.ts
@@ -14,7 +14,6 @@ import { setupOptionsListSuggestionsRoute } from './options_list/options_list_su
import { controlGroupContainerPersistableStateServiceFactory } from './control_group/control_group_container_factory';
import { optionsListPersistableStateServiceFactory } from './options_list/options_list_embeddable_factory';
import { rangeSliderPersistableStateServiceFactory } from './range_slider/range_slider_embeddable_factory';
-// import { timeSliderPersistableStateServiceFactory } from './control_types/time_slider/time_slider_embeddable_factory';
interface SetupDeps {
embeddable: EmbeddableSetup;
@@ -24,14 +23,11 @@ interface SetupDeps {
export class ControlsPlugin implements Plugin
,
- {
- KibanaLogic.values.navigateToUrl(APP_SEARCH_PLUGIN.URL + ENGINE_CREATION_PATH, {
- shouldNotCreateHref: true,
- });
- }}
- >
-
-
- {i18n.translate('xpack.enterpriseSearch.content.index.searchEngines.createEngine', {
- defaultMessage: 'Create a new App Search engine',
- })}
-
-
- ,
+ isHiddenIndex ? (
+
+
+
+ ) : (
+
+ ),
]}
/>
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts
index 6075f6e9822d3e8..fa9eb67cf9fe493 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/constants/index.ts
@@ -7,6 +7,7 @@
export * from './actions';
export * from './labels';
+export * from './query_params';
export * from './tables';
export * from './units';
export { DEFAULT_META } from './default_meta';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/constants/query_params.ts b/x-pack/plugins/enterprise_search/public/applications/shared/constants/query_params.ts
new file mode 100644
index 000000000000000..1a95b9734043e8b
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/constants/query_params.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export const ESINDEX_QUERY_PARAMETER = 'esindex';
diff --git a/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts b/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts
index 5305cc8ecdb5561..a860069af9e937e 100644
--- a/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts
+++ b/x-pack/plugins/enterprise_search/server/__mocks__/fetch_indices.mock.ts
@@ -15,6 +15,7 @@ export const mockSingleIndexStatsResponse = {
indices: {
'search-regular-index': {
health: 'green',
+ hidden: false,
status: 'open',
total: {
docs: {
@@ -115,6 +116,7 @@ export const getIndexReturnValue = (indexName: string) => {
alias: indexName.startsWith('alias') || indexName.startsWith('search-alias'),
count: 100,
name: indexName,
+ hidden: indexName.includes('hidden'),
privileges: { manage: true, read: true },
total: {
...mockMultiStatsResponse.indices[indexName].total,
diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts
index 9bf9f2b2d2f1d3e..49384f564a9885c 100644
--- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.test.ts
@@ -43,6 +43,7 @@ describe('fetchIndex lib function', () => {
indices: {
index_name: {
health: 'green',
+ hidden: false,
size: new ByteSizeValue(108000).toString(),
status: 'open',
total: {
@@ -63,6 +64,7 @@ describe('fetchIndex lib function', () => {
aliases: [],
count: 100,
health: 'green',
+ hidden: false,
name: 'index_name',
status: 'open',
total: {
diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts
index 1fc8f4cc071864d..4a01295fbeaa866 100644
--- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.test.ts
@@ -86,6 +86,7 @@ describe('fetchIndices lib function', () => {
alias: false,
count: 100,
health: 'green',
+ hidden: false,
name: 'search-regular-index',
privileges: { manage: true, read: true },
status: 'open',
@@ -135,6 +136,7 @@ describe('fetchIndices lib function', () => {
alias: false,
count: 100,
health: 'green',
+ hidden: false,
name: 'search-regular-index',
privileges: { manage: true, read: true },
status: 'open',
@@ -195,6 +197,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: 'green',
+ hidden: false,
name: 'index-without-prefix',
status: 'open',
alias: false,
@@ -213,6 +216,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: 'green',
+ hidden: false,
name: 'search-aliased',
status: 'open',
alias: true,
@@ -231,6 +235,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: 'green',
+ hidden: false,
name: 'search-double-aliased',
status: 'open',
alias: true,
@@ -249,6 +254,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: 'green',
+ hidden: false,
name: 'second-index',
status: 'open',
alias: false,
@@ -298,6 +304,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: 'green',
+ hidden: false,
name: 'index-without-prefix',
status: 'open',
alias: false,
@@ -316,6 +323,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: 'green',
+ hidden: false,
name: 'second-index',
status: 'open',
alias: false,
@@ -350,6 +358,7 @@ describe('fetchIndices lib function', () => {
{
count: 100,
health: undefined,
+ hidden: false,
name: 'search-regular-index',
status: undefined,
alias: false,
diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts
index 28a5373d50ac56a..5a1bfec87b9b713 100644
--- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_indices.ts
@@ -13,13 +13,16 @@ import {
import { ByteSizeValue } from '@kbn/config-schema';
import { IScopedClusterClient } from '@kbn/core/server';
-import { ElasticsearchIndexWithPrivileges } from '../../../common/types';
+import {
+ ElasticsearchIndex,
+ ElasticsearchIndexWithPrivileges,
+} from '../../../common/types/indices';
export const mapIndexStats = (
indexData: IndicesIndexState,
indexStats: IndicesStatsIndicesStats,
indexName: string
-) => {
+): Omit & { aliases: string[] } => {
const aliases = Object.keys(indexData.aliases!);
const sizeInBytes = new ByteSizeValue(indexStats?.total?.store?.size_in_bytes ?? 0).toString();
@@ -38,6 +41,7 @@ export const mapIndexStats = (
return {
aliases,
health: indexStats?.health,
+ hidden: Boolean(indexData.settings?.index?.hidden),
name: indexName,
status: indexStats?.status,
total,
@@ -132,17 +136,17 @@ export const fetchIndices = async (
return mapIndexStats(indexData, indexStats, indexName);
})
.flatMap(({ name, aliases, ...indexData }) => {
- const indicesAndAliases = [] as ElasticsearchIndexWithPrivileges[];
+ const indicesAndAliases: ElasticsearchIndexWithPrivileges[] = [];
if (includeAliases) {
aliases.forEach((alias) => {
if (alias.startsWith(alwaysShowSearchPattern)) {
indicesAndAliases.push({
+ ...indexData,
alias: true,
count: indexCounts[alias] ?? 0,
name: alias,
privileges: { manage: false, read: false, ...indexPrivileges[name] },
- ...indexData,
});
}
});
@@ -160,23 +164,23 @@ export const fetchIndices = async (
})
.flatMap(({ name, aliases, ...indexData }) => {
// expand aliases and add to results
- const indicesAndAliases = [] as ElasticsearchIndexWithPrivileges[];
+ const indicesAndAliases: ElasticsearchIndexWithPrivileges[] = [];
indicesAndAliases.push({
+ ...indexData,
alias: false,
count: indexCounts[name] ?? 0,
name,
privileges: { manage: false, read: false, ...indexPrivileges[name] },
- ...indexData,
});
if (includeAliases) {
aliases.forEach((alias) => {
indicesAndAliases.push({
+ ...indexData,
alias: true,
count: indexCounts[alias] ?? 0,
name: alias,
privileges: { manage: false, read: false, ...indexPrivileges[name] },
- ...indexData,
});
});
}
@@ -191,7 +195,7 @@ export const fetchIndices = async (
const itemsToInclude = alwaysShowIndices.filter(({ name }) => indexNamesToInclude.includes(name));
const indicesData = alwaysShowSearchPattern
- ? ([...regularIndexData, ...itemsToInclude] as ElasticsearchIndexWithPrivileges[])
+ ? [...regularIndexData, ...itemsToInclude]
: regularIndexData;
return indicesData.filter(
From 908a01b5a695ea50002c3a372031c90e3f37d66f Mon Sep 17 00:00:00 2001
From: Lukas Olson
Date: Tue, 23 Aug 2022 13:12:19 -0700
Subject: [PATCH 09/18] Update docs for KQL autocomplete when DLS is enabled
(#139248)
---
docs/management/advanced-options.asciidoc | 2 +-
src/plugins/data/server/ui_settings.ts | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc
index 7a1eaae67690664..e98561ce501082a 100644
--- a/docs/management/advanced-options.asciidoc
+++ b/docs/management/advanced-options.asciidoc
@@ -89,7 +89,7 @@ Set this property to `false` to prevent the filter editor and KQL autocomplete
from suggesting values for fields.
[[autocomplete-valuesuggestionmethod]]`autocomplete:valueSuggestionMethod`::
-When set to `terms_enum`, autocomplete uses the terms enum API for value suggestions. Kibana returns results faster, but suggestions are approximate, sorted alphabetically, and can be outside the selected time range.
+When set to `terms_enum`, autocomplete uses the terms enum API for value suggestions. Kibana returns results faster, but suggestions are approximate, sorted alphabetically, and can be outside the selected time range. (Note that this API is incompatible with {ref}/document-level-security.html[Document-Level-Security].)
When set to `terms_agg`, Kibana uses a terms aggregation for value suggestions, which is
slower, but suggestions include all values that optionally match your time range and are sorted by popularity.
diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts
index 31c360e76107896..fce2680f5fc030d 100644
--- a/src/plugins/data/server/ui_settings.ts
+++ b/src/plugins/data/server/ui_settings.ts
@@ -493,8 +493,9 @@ export function getUiSettings(
description: i18n.translate('data.advancedSettings.autocompleteValueSuggestionMethodText', {
defaultMessage:
'The method used for querying suggestions for values in KQL autocomplete. Select terms_enum to use the ' +
- 'Elasticsearch terms enum API for improved autocomplete suggestion performance. Select terms_agg to use an ' +
- 'Elasticsearch terms aggregation. {learnMoreLink}',
+ 'Elasticsearch terms enum API for improved autocomplete suggestion performance. (Note that terms_enum is ' +
+ 'incompatible with Document Level Security.) Select terms_agg to use an Elasticsearch terms aggregation. ' +
+ '{learnMoreLink}',
values: {
learnMoreLink:
`` +
From fe646b297dfe79d04dbe6275c319c648b25f9c1a Mon Sep 17 00:00:00 2001
From: Yuliia Naumenko
Date: Tue, 23 Aug 2022 14:21:37 -0700
Subject: [PATCH 10/18] [Security Solution][Tech debt] T-Grid cleanup (#138581)
* [Security Solution][Tech debt] T-Grid cleanup: removed unused logic
* Renamed folder to correspond the logic inside
* Fixed types for isEventViewer
* Fixed tests, corrected names
* Fixed due to comments
---
.../common/components/events_viewer/index.tsx | 2 -
.../additional_filters_action/index.test.tsx | 80 ++++
.../additional_filters_action/index.tsx | 94 ++++
.../additional_filters_action/translations.ts | 36 ++
.../alerts_utility_bar/index.test.tsx | 419 ------------------
.../alerts_table/alerts_utility_bar/index.tsx | 284 ------------
.../alerts_utility_bar/translations.ts | 85 ----
.../components/alerts_table/index.test.tsx | 4 +-
.../components/alerts_table/index.tsx | 210 +--------
.../components/take_action_dropdown/index.tsx | 2 +-
.../components/graph_overlay/index.tsx | 7 +-
.../public/components/t_grid/helpers.test.tsx | 22 +-
.../public/components/t_grid/helpers.tsx | 25 +-
.../t_grid/integrated/index.test.tsx | 3 -
.../components/t_grid/integrated/index.tsx | 51 +--
.../components/t_grid/standalone/index.tsx | 48 +-
.../translations/translations/fr-FR.json | 7 -
.../translations/translations/ja-JP.json | 7 -
.../translations/translations/zh-CN.json | 7 -
19 files changed, 259 insertions(+), 1134 deletions(-)
create mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx
create mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx
create mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts
delete mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx
delete mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx
delete mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
index 0556b3678d4dbc9..14921512819eee6 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
@@ -61,7 +61,6 @@ export interface Props {
onRuleChange?: () => void;
renderCellValue: (props: CellValueElementProps) => React.ReactNode;
rowRenderers: RowRenderer[];
- utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
additionalFilters?: React.ReactNode;
hasAlertsCrud?: boolean;
unit?: (n: number) => string;
@@ -86,7 +85,6 @@ const StatefulEventsViewerComponent: React.FC = ({
rowRenderers,
start,
scopeId,
- utilityBar,
additionalFilters,
hasAlertsCrud = false,
unit,
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx
new file mode 100644
index 000000000000000..ec4fdb5cb6e8d77
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx
@@ -0,0 +1,80 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+
+import { AdditionalFiltersAction } from '.';
+import { TestProviders } from '../../../../common/mock/test_providers';
+
+jest.useFakeTimers();
+jest.mock('../../../../common/lib/kibana');
+
+describe('AdditionalFiltersAction', () => {
+ describe('UtilityBarAdditionalFiltersContent', () => {
+ test('does not show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is false', async () => {
+ const onShowBuildingBlockAlertsChanged = jest.fn();
+ render(
+
+
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ const additionalFiltersButton = screen.findByTestId('additionalFilters-popover');
+ fireEvent.click(await additionalFiltersButton);
+
+ // The check box should be false
+ expect(await screen.findByTestId('showBuildingBlockAlertsCheckbox')).not.toBeChecked();
+ });
+
+ test('does not show the showOnlyThreatIndicatorAlerts checked if the showOnlyThreatIndicatorAlerts is true', async () => {
+ render(
+
+
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ const additionalFiltersButton = screen.findByTestId('additionalFilters-popover');
+ fireEvent.click(await additionalFiltersButton);
+
+ expect(await screen.findByTestId('showOnlyThreatIndicatorAlertsCheckbox')).toBeChecked();
+ });
+
+ test('does show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is true', async () => {
+ const onShowBuildingBlockAlertsChanged = jest.fn();
+ render(
+
+
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ const additionalFiltersButton = screen.findByTestId('additionalFilters-popover');
+ fireEvent.click(await additionalFiltersButton);
+
+ // The check box should be true
+ expect(await screen.findByTestId('showBuildingBlockAlertsCheckbox')).toBeChecked();
+ });
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx
new file mode 100644
index 000000000000000..ef780f783e92410
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.tsx
@@ -0,0 +1,94 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React, { useCallback } from 'react';
+
+import { EuiFlexGroup, EuiFlexItem, EuiCheckbox } from '@elastic/eui';
+import styled from 'styled-components';
+
+import { UtilityBarAction } from '../../../../common/components/utility_bar';
+import * as i18n from './translations';
+
+const UtilityBarFlexGroup = styled(EuiFlexGroup)`
+ min-width: 175px;
+`;
+
+const AdditionalFiltersItem = styled(EuiFlexItem)`
+ padding: ${({ theme }) => theme.eui.euiSizeS};
+`;
+
+const BuildingBlockContainer = styled(AdditionalFiltersItem)`
+ background: ${({ theme }) => theme.eui.euiColorHighlight};
+`;
+
+export const AdditionalFiltersAction = ({
+ areEventsLoading,
+ onShowBuildingBlockAlertsChanged,
+ showBuildingBlockAlerts,
+ onShowOnlyThreatIndicatorAlertsChanged,
+ showOnlyThreatIndicatorAlerts,
+}: {
+ areEventsLoading: boolean;
+ onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void;
+ showBuildingBlockAlerts: boolean;
+ onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void;
+ showOnlyThreatIndicatorAlerts: boolean;
+}) => {
+ const UtilityBarAdditionalFiltersContent = useCallback(
+ (closePopover: () => void) => (
+
+
+ ) => {
+ closePopover();
+ onShowBuildingBlockAlertsChanged(e.target.checked);
+ }}
+ checked={showBuildingBlockAlerts}
+ color="text"
+ data-test-subj="showBuildingBlockAlertsCheckbox"
+ label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK}
+ />
+
+
+ ) => {
+ closePopover();
+ onShowOnlyThreatIndicatorAlertsChanged(e.target.checked);
+ }}
+ checked={showOnlyThreatIndicatorAlerts}
+ color="text"
+ data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"
+ label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS}
+ />
+
+
+ ),
+ [
+ onShowBuildingBlockAlertsChanged,
+ onShowOnlyThreatIndicatorAlertsChanged,
+ showBuildingBlockAlerts,
+ showOnlyThreatIndicatorAlerts,
+ ]
+ );
+
+ return (
+
+ {i18n.ADDITIONAL_FILTERS_ACTIONS}
+
+ );
+};
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts
new file mode 100644
index 000000000000000..eb421c67ff39a54
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/translations.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+export const ADDITIONAL_FILTERS_ACTIONS = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle',
+ {
+ defaultMessage: 'Additional filters',
+ }
+);
+
+export const ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle',
+ {
+ defaultMessage: 'Include building block alerts',
+ }
+);
+
+export const ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts',
+ {
+ defaultMessage: 'Show only threat indicator alerts',
+ }
+);
+
+export const TAKE_ACTION = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle',
+ {
+ defaultMessage: 'Take action',
+ }
+);
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx
deleted file mode 100644
index f4372631cf0f45d..000000000000000
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import React from 'react';
-import { shallow, mount } from 'enzyme';
-
-import type { AlertsUtilityBarProps } from '.';
-import { AlertsUtilityBar } from '.';
-import { TestProviders } from '../../../../common/mock/test_providers';
-
-jest.useFakeTimers();
-jest.mock('../../../../common/lib/kibana');
-
-describe('AlertsUtilityBar', () => {
- test('renders correctly', () => {
- const wrapper = shallow(
-
- );
-
- expect(wrapper.find('[dataTestSubj="alertActionPopover"]')).toBeTruthy();
- });
-
- describe('UtilityBarAdditionalFiltersContent', () => {
- test('does not show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is false', () => {
- const onShowBuildingBlockAlertsChanged = jest.fn();
- const wrapper = mount(
-
-
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should be false
- expect(
- wrapper
- .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(false);
- });
-
- test('does not show the showOnlyThreatIndicatorAlerts checked if the showThreatMatchOnly is false', () => {
- const wrapper = mount(
-
-
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should be false
- expect(
- wrapper
- .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(false);
- });
-
- test('does show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is true', () => {
- const onShowBuildingBlockAlertsChanged = jest.fn();
- const wrapper = mount(
-
-
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should be true
- expect(
- wrapper
- .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(true);
- });
-
- test('does show the showOnlyThreatIndicatorAlerts checked if the showOnlyThreatIndicatorAlerts is true', () => {
- const wrapper = mount(
-
-
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should be true
- expect(
- wrapper
- .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(true);
- });
-
- test('calls the onShowBuildingBlockAlertsChanged when the check box is clicked', () => {
- const onShowBuildingBlockAlertsChanged = jest.fn();
- const wrapper = mount(
-
-
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // check the box
- wrapper
- .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input')
- .first()
- .simulate('change', { target: { checked: true } });
-
- // Make sure our callback is called
- expect(onShowBuildingBlockAlertsChanged).toHaveBeenCalled();
- });
-
- test('calls the onShowOnlyThreatIndicatorAlertsChanged when the check box is clicked', () => {
- const onShowOnlyThreatIndicatorAlertsChanged = jest.fn();
- const wrapper = mount(
-
-
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // check the box
- wrapper
- .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
- .first()
- .simulate('change', { target: { checked: true } });
-
- // Make sure our callback is called
- expect(onShowOnlyThreatIndicatorAlertsChanged).toHaveBeenCalled();
- });
-
- test('can update showBuildingBlockAlerts from false to true', () => {
- const Proxy = (props: AlertsUtilityBarProps) => (
-
-
-
- );
-
- const wrapper = mount(
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should false now since we initially set the showBuildingBlockAlerts to false
- expect(
- wrapper
- .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(false);
-
- wrapper.setProps({ showBuildingBlockAlerts: true });
- wrapper.update();
-
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should be true now since we changed the showBuildingBlockAlerts from false to true
- expect(
- wrapper
- .find('[data-test-subj="showBuildingBlockAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(true);
- });
-
- test('can update showOnlyThreatIndicatorAlerts from false to true', () => {
- const Proxy = (props: AlertsUtilityBarProps) => (
-
-
-
- );
-
- const wrapper = mount(
-
- );
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should false now since we initially set the showBuildingBlockAlerts to false
- expect(
- wrapper
- .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(false);
-
- wrapper.setProps({ showOnlyThreatIndicatorAlerts: true });
- wrapper.update();
-
- // click the filters button to popup the checkbox to make it visible
- wrapper
- .find('[data-test-subj="additionalFilters"] button')
- .first()
- .simulate('click')
- .update();
-
- // The check box should be true now since we changed the showBuildingBlockAlerts from false to true
- expect(
- wrapper
- .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
- .first()
- .prop('checked')
- ).toEqual(true);
- });
- });
-});
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx
deleted file mode 100644
index 91425ab90e60b67..000000000000000
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { isEmpty } from 'lodash/fp';
-import React, { useCallback } from 'react';
-import numeral from '@elastic/numeral';
-
-import { EuiFlexGroup, EuiFlexItem, EuiCheckbox } from '@elastic/eui';
-import styled from 'styled-components';
-
-import type { Status } from '../../../../../common/detection_engine/schemas/common/schemas';
-import { Link } from '../../../../common/components/link_icon';
-import { DEFAULT_NUMBER_FORMAT } from '../../../../../common/constants';
-import {
- UtilityBar,
- UtilityBarAction,
- UtilityBarGroup,
- UtilityBarSection,
- UtilityBarSpacer,
- UtilityBarText,
-} from '../../../../common/components/utility_bar';
-import * as i18n from './translations';
-import { useUiSetting$ } from '../../../../common/lib/kibana';
-import type { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline';
-import type { UpdateAlertsStatus } from '../types';
-import { FILTER_CLOSED, FILTER_ACKNOWLEDGED, FILTER_OPEN } from '../alerts_filter_group';
-
-export interface AlertsUtilityBarProps {
- areEventsLoading: boolean;
- clearSelection: () => void;
- currentFilter: Status;
- hasIndexMaintenance: boolean;
- hasIndexWrite: boolean;
- onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void;
- onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void;
- selectAll: () => void;
- selectedEventIds: Readonly>;
- showBuildingBlockAlerts: boolean;
- showClearSelection: boolean;
- showOnlyThreatIndicatorAlerts: boolean;
- totalCount: number;
- updateAlertsStatus: UpdateAlertsStatus;
-}
-
-const UtilityBarFlexGroup = styled(EuiFlexGroup)`
- min-width: 175px;
-`;
-
-const AdditionalFiltersItem = styled(EuiFlexItem)`
- padding: ${({ theme }) => theme.eui.euiSizeS};
-`;
-
-const BuildingBlockContainer = styled(AdditionalFiltersItem)`
- background: ${({ theme }) => theme.eui.euiColorHighlight};
-`;
-
-const AlertsUtilityBarComponent: React.FC = ({
- areEventsLoading,
- clearSelection,
- currentFilter,
- hasIndexMaintenance,
- hasIndexWrite,
- onShowBuildingBlockAlertsChanged,
- onShowOnlyThreatIndicatorAlertsChanged,
- selectAll,
- selectedEventIds,
- showBuildingBlockAlerts,
- showClearSelection,
- showOnlyThreatIndicatorAlerts,
- totalCount,
- updateAlertsStatus,
-}) => {
- const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT);
-
- const handleUpdateStatus = useCallback(
- async (selectedStatus: Status) => {
- await updateAlertsStatus({
- alertIds: Object.keys(selectedEventIds),
- status: currentFilter,
- selectedStatus,
- });
- },
- [currentFilter, selectedEventIds, updateAlertsStatus]
- );
-
- const formattedTotalCount = numeral(totalCount).format(defaultNumberFormat);
- const formattedSelectedEventsCount = numeral(Object.keys(selectedEventIds).length).format(
- defaultNumberFormat
- );
-
- const UtilityBarPopoverContent = (closePopover: () => void) => (
-
- {currentFilter !== FILTER_OPEN && (
-
- {
- closePopover();
- handleUpdateStatus('open');
- }}
- color="text"
- data-test-subj="openSelectedAlertsButton"
- >
- {i18n.BATCH_ACTION_OPEN_SELECTED}
-
-
- )}
-
- {currentFilter !== FILTER_CLOSED && (
-
- {
- closePopover();
- handleUpdateStatus('closed');
- }}
- color="text"
- data-test-subj="closeSelectedAlertsButton"
- >
- {i18n.BATCH_ACTION_CLOSE_SELECTED}
-
-
- )}
-
- {currentFilter !== FILTER_ACKNOWLEDGED && (
-
- {
- closePopover();
- handleUpdateStatus('acknowledged');
- }}
- color="text"
- data-test-subj="markSelectedAlertsAcknowledgedButton"
- >
- {i18n.BATCH_ACTION_ACKNOWLEDGED_SELECTED}
-
-
- )}
-
- );
-
- const handleSelectAllAlertsClick = useCallback(() => {
- if (!showClearSelection) {
- selectAll();
- } else {
- clearSelection();
- }
- }, [clearSelection, selectAll, showClearSelection]);
-
- return (
- <>
-
-
-
-
- {i18n.SHOWING_ALERTS(formattedTotalCount, totalCount)}
-
-
-
-
- {hasIndexWrite && hasIndexMaintenance && (
- <>
-
- {i18n.SELECTED_ALERTS(
- showClearSelection ? formattedTotalCount : formattedSelectedEventsCount,
- showClearSelection ? totalCount : Object.keys(selectedEventIds).length
- )}
-
-
-
- {i18n.TAKE_ACTION}
-
-
-
- {showClearSelection
- ? i18n.CLEAR_SELECTION
- : i18n.SELECT_ALL_ALERTS(formattedTotalCount, totalCount)}
-
- >
- )}
-
-
-
-
-
- >
- );
-};
-
-export const AlertsUtilityBar = React.memo(
- AlertsUtilityBarComponent,
- (prevProps, nextProps) =>
- prevProps.areEventsLoading === nextProps.areEventsLoading &&
- prevProps.selectedEventIds === nextProps.selectedEventIds &&
- prevProps.totalCount === nextProps.totalCount &&
- prevProps.showClearSelection === nextProps.showClearSelection &&
- prevProps.showBuildingBlockAlerts === nextProps.showBuildingBlockAlerts &&
- prevProps.showOnlyThreatIndicatorAlerts === nextProps.showOnlyThreatIndicatorAlerts
-);
-
-export const AditionalFiltersAction = ({
- areEventsLoading,
- onShowBuildingBlockAlertsChanged,
- showBuildingBlockAlerts,
- onShowOnlyThreatIndicatorAlertsChanged,
- showOnlyThreatIndicatorAlerts,
-}: {
- areEventsLoading: boolean;
- onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void;
- showBuildingBlockAlerts: boolean;
- onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void;
- showOnlyThreatIndicatorAlerts: boolean;
-}) => {
- const UtilityBarAdditionalFiltersContent = (closePopover: () => void) => (
-
-
- ) => {
- closePopover();
- onShowBuildingBlockAlertsChanged(e.target.checked);
- }}
- checked={showBuildingBlockAlerts}
- color="text"
- data-test-subj="showBuildingBlockAlertsCheckbox"
- label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK}
- />
-
-
- ) => {
- closePopover();
- onShowOnlyThreatIndicatorAlertsChanged(e.target.checked);
- }}
- checked={showOnlyThreatIndicatorAlerts}
- color="text"
- data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"
- label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS}
- />
-
-
- );
-
- return (
-
- {i18n.ADDITIONAL_FILTERS_ACTIONS}
-
- );
-};
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts
deleted file mode 100644
index 5da63a5ab95984d..000000000000000
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export const SHOWING_ALERTS = (totalAlertsFormatted: string, totalAlerts: number) =>
- i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle', {
- values: { totalAlertsFormatted, totalAlerts },
- defaultMessage:
- 'Showing {totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}',
- });
-
-export const SELECTED_ALERTS = (selectedAlertsFormatted: string, selectedAlerts: number) =>
- i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle', {
- values: { selectedAlertsFormatted, selectedAlerts },
- defaultMessage:
- 'Selected {selectedAlertsFormatted} {selectedAlerts, plural, =1 {alert} other {alerts}}',
- });
-
-export const SELECT_ALL_ALERTS = (totalAlertsFormatted: string, totalAlerts: number) =>
- i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle', {
- values: { totalAlertsFormatted, totalAlerts },
- defaultMessage:
- 'Select all {totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}',
- });
-
-export const ADDITIONAL_FILTERS_ACTIONS = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle',
- {
- defaultMessage: 'Additional filters',
- }
-);
-
-export const ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle',
- {
- defaultMessage: 'Include building block alerts',
- }
-);
-
-export const ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts',
- {
- defaultMessage: 'Show only threat indicator alerts',
- }
-);
-
-export const CLEAR_SELECTION = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle',
- {
- defaultMessage: 'Clear selection',
- }
-);
-
-export const TAKE_ACTION = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle',
- {
- defaultMessage: 'Take action',
- }
-);
-
-export const BATCH_ACTION_OPEN_SELECTED = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle',
- {
- defaultMessage: 'Open selected',
- }
-);
-
-export const BATCH_ACTION_CLOSE_SELECTED = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle',
- {
- defaultMessage: 'Close selected',
- }
-);
-
-export const BATCH_ACTION_ACKNOWLEDGED_SELECTED = i18n.translate(
- 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle',
- {
- defaultMessage: 'Mark as acknowledged',
- }
-);
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx
index 304f0ac1808214f..34378594a952dc2 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx
@@ -33,13 +33,11 @@ describe('AlertsTableComponent', () => {
loadingEventIds={[]}
selectedEventIds={{}}
isSelectAllChecked={false}
- clearSelected={jest.fn()}
- setEventsLoading={jest.fn()}
- setEventsDeleted={jest.fn()}
showBuildingBlockAlerts={false}
onShowBuildingBlockAlertsChanged={jest.fn()}
showOnlyThreatIndicatorAlerts={false}
onShowOnlyThreatIndicatorAlertsChanged={jest.fn()}
+ dispatch={jest.fn()}
/>
);
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
index 9c11f4499db95c7..d4dead20989a6e9 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
@@ -6,22 +6,15 @@
*/
import { isEmpty } from 'lodash/fp';
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import React, { useCallback, useEffect, useMemo } from 'react';
import type { ConnectedProps } from 'react-redux';
import { connect, useDispatch } from 'react-redux';
-import type { Dispatch } from 'redux';
import type { Filter } from '@kbn/es-query';
import { getEsQueryConfig } from '@kbn/data-plugin/common';
import type { Status } from '../../../../common/detection_engine/schemas/common/schemas';
import type { RowRendererId, TimelineIdLiteral } from '../../../../common/types/timeline';
import { StatefulEventsViewer } from '../../../common/components/events_viewer';
-import {
- displayErrorToast,
- displaySuccessToast,
- useStateToaster,
-} from '../../../common/components/toasters';
import { useSourcererDataView } from '../../../common/containers/sourcerer';
-import { useAppToasts } from '../../../common/hooks/use_app_toasts';
import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
import { useInvalidFilterQuery } from '../../../common/hooks/use_invalid_filter_query';
import { defaultCellActions } from '../../../common/lib/cell_actions/default_cell_actions';
@@ -29,7 +22,6 @@ import { useKibana } from '../../../common/lib/kibana';
import type { inputsModel, State } from '../../../common/store';
import { inputsSelectors } from '../../../common/store';
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
-import * as i18nCommon from '../../../common/translations';
import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants';
import { getDefaultControlColumn } from '../../../timelines/components/timeline/body/control_columns';
import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
@@ -38,8 +30,7 @@ import { timelineActions, timelineSelectors } from '../../../timelines/store/tim
import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
import type { TimelineModel } from '../../../timelines/store/timeline/model';
import { columns, RenderCellValue } from '../../configurations/security_solution_detections';
-import { updateAlertStatusAction } from './actions';
-import { AditionalFiltersAction, AlertsUtilityBar } from './alerts_utility_bar';
+import { AdditionalFiltersAction } from './additional_filters_action';
import {
alertsDefaultModel,
buildAlertStatusFilter,
@@ -47,13 +38,6 @@ import {
} from './default_config';
import { buildTimeRangeFilter } from './helpers';
import * as i18n from './translations';
-import type {
- SetEventsDeletedProps,
- SetEventsLoadingProps,
- UpdateAlertsStatusCallback,
- UpdateAlertsStatusProps,
-} from './types';
-
interface OwnProps {
defaultFilters?: Filter[];
from: string;
@@ -73,7 +57,6 @@ interface OwnProps {
type AlertsTableComponentProps = OwnProps & PropsFromRedux;
export const AlertsTableComponent: React.FC = ({
- clearSelected,
defaultFilters,
from,
globalFilters,
@@ -86,9 +69,6 @@ export const AlertsTableComponent: React.FC = ({
onRuleChange,
onShowBuildingBlockAlertsChanged,
onShowOnlyThreatIndicatorAlertsChanged,
- selectedEventIds,
- setEventsDeleted,
- setEventsLoading,
showBuildingBlockAlerts,
showOnlyThreatIndicatorAlerts,
timelineId,
@@ -96,15 +76,12 @@ export const AlertsTableComponent: React.FC = ({
filterGroup = 'open',
}) => {
const dispatch = useDispatch();
- const [showClearSelectionAction, setShowClearSelectionAction] = useState(false);
const {
browserFields,
indexPattern: indexPatterns,
selectedPatterns,
} = useSourcererDataView(SourcererScopeName.detections);
const kibana = useKibana();
- const [, dispatchToaster] = useStateToaster();
- const { addWarning } = useAppToasts();
const ACTION_BUTTON_COUNT = 5;
const getGlobalQuery = useCallback(
@@ -123,7 +100,6 @@ export const AlertsTableComponent: React.FC = ({
],
kqlQuery: globalQuery,
kqlMode: globalQuery.language,
- isEventViewer: true,
});
}
return null;
@@ -140,66 +116,6 @@ export const AlertsTableComponent: React.FC = ({
endDate: to,
});
- const setEventsLoadingCallback = useCallback(
- ({ eventIds, isLoading }: SetEventsLoadingProps) => {
- setEventsLoading({ id: timelineId, eventIds, isLoading });
- },
- [setEventsLoading, timelineId]
- );
-
- const setEventsDeletedCallback = useCallback(
- ({ eventIds, isDeleted }: SetEventsDeletedProps) => {
- setEventsDeleted({ id: timelineId, eventIds, isDeleted });
- },
- [setEventsDeleted, timelineId]
- );
-
- const onAlertStatusUpdateSuccess = useCallback(
- (updated: number, conflicts: number, status: Status) => {
- if (conflicts > 0) {
- // Partial failure
- addWarning({
- title: i18nCommon.UPDATE_ALERT_STATUS_FAILED(conflicts),
- text: i18nCommon.UPDATE_ALERT_STATUS_FAILED_DETAILED(updated, conflicts),
- });
- } else {
- let title = '';
- switch (status) {
- case 'closed':
- title = i18n.CLOSED_ALERT_SUCCESS_TOAST(updated);
- break;
- case 'open':
- title = i18n.OPENED_ALERT_SUCCESS_TOAST(updated);
- break;
- case 'acknowledged':
- case 'in-progress':
- title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated);
- }
- displaySuccessToast(title, dispatchToaster);
- }
- },
- [addWarning, dispatchToaster]
- );
-
- const onAlertStatusUpdateFailure = useCallback(
- (status: Status, error: Error) => {
- let title = '';
- switch (status) {
- case 'closed':
- title = i18n.CLOSED_ALERT_FAILED_TOAST;
- break;
- case 'open':
- title = i18n.OPENED_ALERT_FAILED_TOAST;
- break;
- case 'acknowledged':
- case 'in-progress':
- title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST;
- }
- displayErrorToast(title, [error.message], dispatchToaster);
- },
- [dispatchToaster]
- );
-
// Catches state change isSelectAllChecked->false upon user selection change to reset utility bar
useEffect(() => {
if (isSelectAllChecked) {
@@ -209,107 +125,12 @@ export const AlertsTableComponent: React.FC = ({
selectAll: false,
})
);
- } else {
- setShowClearSelectionAction(false);
}
}, [dispatch, isSelectAllChecked, timelineId]);
- // Callback for clearing entire selection from utility bar
- const clearSelectionCallback = useCallback(() => {
- clearSelected({ id: timelineId });
- dispatch(
- timelineActions.setTGridSelectAll({
- id: timelineId,
- selectAll: false,
- })
- );
- setShowClearSelectionAction(false);
- }, [clearSelected, dispatch, timelineId]);
-
- // Callback for selecting all events on all pages from utility bar
- // Dispatches to stateful_body's selectAll via TimelineTypeContext props
- // as scope of response data required to actually set selectedEvents
- const selectAllOnAllPagesCallback = useCallback(() => {
- dispatch(
- timelineActions.setTGridSelectAll({
- id: timelineId,
- selectAll: true,
- })
- );
- setShowClearSelectionAction(true);
- }, [dispatch, timelineId]);
-
- const updateAlertsStatusCallback: UpdateAlertsStatusCallback = useCallback(
- async (
- refetchQuery: inputsModel.Refetch,
- { status, selectedStatus }: UpdateAlertsStatusProps
- ) => {
- await updateAlertStatusAction({
- query: showClearSelectionAction
- ? getGlobalQuery(buildAlertStatusFilter(status))?.filterQuery
- : undefined,
- alertIds: Object.keys(selectedEventIds),
- selectedStatus,
- setEventsDeleted: setEventsDeletedCallback,
- setEventsLoading: setEventsLoadingCallback,
- onAlertStatusUpdateSuccess,
- onAlertStatusUpdateFailure,
- });
- refetchQuery();
- },
- [
- getGlobalQuery,
- selectedEventIds,
- setEventsDeletedCallback,
- setEventsLoadingCallback,
- showClearSelectionAction,
- onAlertStatusUpdateSuccess,
- onAlertStatusUpdateFailure,
- ]
- );
-
- // Callback for creating the AlertsUtilityBar which receives totalCount from EventsViewer component
- const utilityBarCallback = useCallback(
- (refetchQuery: inputsModel.Refetch, totalCount: number) => {
- return (
- 0}
- clearSelection={clearSelectionCallback}
- currentFilter={filterGroup}
- hasIndexMaintenance={hasIndexMaintenance}
- hasIndexWrite={hasIndexWrite}
- onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged}
- onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsChanged}
- selectAll={selectAllOnAllPagesCallback}
- selectedEventIds={selectedEventIds}
- showBuildingBlockAlerts={showBuildingBlockAlerts}
- showClearSelection={showClearSelectionAction}
- showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts}
- totalCount={totalCount}
- updateAlertsStatus={updateAlertsStatusCallback.bind(null, refetchQuery)}
- />
- );
- },
- [
- clearSelectionCallback,
- filterGroup,
- hasIndexMaintenance,
- hasIndexWrite,
- loadingEventIds.length,
- onShowBuildingBlockAlertsChanged,
- onShowOnlyThreatIndicatorAlertsChanged,
- selectAllOnAllPagesCallback,
- selectedEventIds,
- showBuildingBlockAlerts,
- showClearSelectionAction,
- showOnlyThreatIndicatorAlerts,
- updateAlertsStatusCallback,
- ]
- );
-
const additionalFiltersComponent = useMemo(
() => (
- 0}
onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged}
showBuildingBlockAlerts={showBuildingBlockAlerts}
@@ -387,7 +208,6 @@ export const AlertsTableComponent: React.FC = ({
rowRenderers={defaultRowRenderers}
scopeId={SourcererScopeName.detections}
start={from}
- utilityBar={utilityBarCallback}
/>
);
};
@@ -414,29 +234,7 @@ const makeMapStateToProps = () => {
return mapStateToProps;
};
-const mapDispatchToProps = (dispatch: Dispatch) => ({
- clearSelected: ({ id }: { id: string }) => dispatch(timelineActions.clearSelected({ id })),
- setEventsLoading: ({
- id,
- eventIds,
- isLoading,
- }: {
- id: string;
- eventIds: string[];
- isLoading: boolean;
- }) => dispatch(timelineActions.setEventsLoading({ id, eventIds, isLoading })),
- setEventsDeleted: ({
- id,
- eventIds,
- isDeleted,
- }: {
- id: string;
- eventIds: string[];
- isDeleted: boolean;
- }) => dispatch(timelineActions.setEventsDeleted({ id, eventIds, isDeleted })),
-});
-
-const connector = connect(makeMapStateToProps, mapDispatchToProps);
+const connector = connect(makeMapStateToProps);
type PropsFromRedux = ConnectedProps;
diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx
index ea66ebb132d8a6b..197d655d2420bfd 100644
--- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx
@@ -10,7 +10,7 @@ import { EuiButton, EuiContextMenuPanel, EuiPopover } from '@elastic/eui';
import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types';
import { useResponderActionItem } from '../endpoint_responder';
import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy';
-import { TAKE_ACTION } from '../alerts_table/alerts_utility_bar/translations';
+import { TAKE_ACTION } from '../alerts_table/additional_filters_action/translations';
import { useExceptionActions } from '../alerts_table/timeline_actions/use_add_exception_actions';
import { useAlertsActions } from '../alerts_table/timeline_actions/use_alerts_actions';
import { useInvestigateInTimeline } from '../alerts_table/timeline_actions/use_investigate_in_timeline';
diff --git a/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx
index 6ecaa56bc12db88..681de8ac4cb0c99 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/graph_overlay/index.tsx
@@ -84,11 +84,8 @@ const GraphOverlayComponent: React.FC = ({
const { timelineFullScreen } = useTimelineFullScreen();
const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []);
- const graphEventId = useDeepEqualSelector(
- (state) => (getTimeline(state, timelineId) ?? timelineDefaults).graphEventId
- );
- const sessionViewConfig = useDeepEqualSelector(
- (state) => (getTimeline(state, timelineId) ?? timelineDefaults).sessionViewConfig
+ const { graphEventId, sessionViewConfig } = useDeepEqualSelector(
+ (state) => getTimeline(state, timelineId) ?? timelineDefaults
);
const fullScreen = useMemo(
diff --git a/x-pack/plugins/timelines/public/components/t_grid/helpers.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/helpers.test.tsx
index 535c856d51e8fca..7d60cbc5d0e003f 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/helpers.test.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/helpers.test.tsx
@@ -225,7 +225,7 @@ describe('Combined Queries', () => {
ignoreFilterIfFieldNotInIndex: true,
dateFormatTZ: 'America/New_York',
};
- test('No Data Provider & No kqlQuery & and isEventViewer is false', () => {
+ test('No Data Provider & No kqlQuery', () => {
expect(
combineQueries({
config,
@@ -239,26 +239,7 @@ describe('Combined Queries', () => {
).toBeNull();
});
- test('No Data Provider & No kqlQuery & isEventViewer is true', () => {
- const isEventViewer = true;
- expect(
- combineQueries({
- config,
- dataProviders: [],
- indexPattern: mockIndexPattern,
- browserFields: mockBrowserFields,
- filters: [],
- kqlQuery: { query: '', language: 'kuery' },
- kqlMode: 'search',
- isEventViewer,
- })
- ).toEqual({
- filterQuery: '{"bool":{"must":[],"filter":[],"should":[],"must_not":[]}}',
- });
- });
-
test('No Data Provider & No kqlQuery & with Filters', () => {
- const isEventViewer = true;
expect(
combineQueries({
config,
@@ -293,7 +274,6 @@ describe('Combined Queries', () => {
],
kqlQuery: { query: '', language: 'kuery' },
kqlMode: 'search',
- isEventViewer,
})
).toEqual({
filterQuery:
diff --git a/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx b/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx
index 03830339761bc63..34fb215e708d566 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx
@@ -141,7 +141,6 @@ interface CombineQueries {
filters: Filter[];
kqlQuery: Query;
kqlMode: string;
- isEventViewer?: boolean;
}
export const combineQueries = ({
@@ -152,23 +151,10 @@ export const combineQueries = ({
filters = [],
kqlQuery,
kqlMode,
- isEventViewer,
}: CombineQueries): { filterQuery: string | undefined; kqlError: Error | undefined } | null => {
const kuery: Query = { query: '', language: kqlQuery.language };
- if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && isEmpty(filters) && !isEventViewer) {
+ if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && isEmpty(filters)) {
return null;
- } else if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && isEventViewer) {
- const [filterQuery, kqlError] = convertToBuildEsQuery({
- config,
- queries: [kuery],
- indexPattern,
- filters,
- });
-
- return {
- filterQuery,
- kqlError,
- };
} else if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && !isEmpty(filters)) {
const [filterQuery, kqlError] = convertToBuildEsQuery({
config,
@@ -229,15 +215,6 @@ export const combineQueries = ({
};
};
-export const buildCombinedQuery = (combineQueriesParams: CombineQueries) => {
- const combinedQuery = combineQueries(combineQueriesParams);
- return combinedQuery?.filterQuery
- ? {
- filterQuery: combinedQuery.filterQuery,
- }
- : null;
-};
-
export const buildTimeRangeFilter = (from: string, to: string): Filter =>
({
range: {
diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx
index 15fd4d2ce75cff7..d33d2fb5635b815 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.test.tsx
@@ -41,9 +41,6 @@ jest.mock('../helpers', () => {
filter: [],
},
}),
- buildCombinedQuery: () => ({
- filterQuery: '{"bool":{"must":[],"filter":[]}}',
- }),
};
});
const defaultProps: TGridIntegratedProps = tGridIntegratedProps;
diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
index 7183c164a24be9e..898611d073a95d6 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
@@ -39,7 +39,7 @@ import type {
import { useDeepEqualSelector } from '../../../hooks/use_selector';
import { defaultHeaders } from '../body/column_headers/default_headers';
-import { buildCombinedQuery, getCombinedFilterQuery, resolverIsShowing } from '../helpers';
+import { getCombinedFilterQuery, resolverIsShowing } from '../helpers';
import { tGridActions, tGridSelectors } from '../../../store/t_grid';
import { useTimelineEvents, InspectResponse, Refetch } from '../../../container';
import { StatefulBody } from '../body';
@@ -194,26 +194,32 @@ const TGridIntegratedComponent: React.FC = ({
}, [dispatch, id, isQueryLoading]);
const justTitle = useMemo(() => {title}, [title]);
+ const esQueryConfig = getEsQueryConfig(uiSettings);
- const combinedQueries = buildCombinedQuery({
- config: getEsQueryConfig(uiSettings),
- dataProviders,
- indexPattern,
- browserFields,
- filters,
- kqlQuery: query,
- kqlMode,
- isEventViewer: true,
- });
+ const filterQuery = useMemo(
+ () =>
+ getCombinedFilterQuery({
+ config: esQueryConfig,
+ browserFields,
+ dataProviders,
+ filters,
+ from: start,
+ indexPattern,
+ kqlMode,
+ kqlQuery: query,
+ to: end,
+ }),
+ [esQueryConfig, dataProviders, indexPattern, browserFields, filters, start, end, query, kqlMode]
+ );
const canQueryTimeline = useMemo(
() =>
- combinedQueries != null &&
+ filterQuery != null &&
isLoadingIndexPattern != null &&
!isLoadingIndexPattern &&
!isEmpty(start) &&
!isEmpty(end),
- [isLoadingIndexPattern, combinedQueries, start, end]
+ [isLoadingIndexPattern, filterQuery, start, end]
);
const fields = useMemo(
@@ -241,7 +247,7 @@ const TGridIntegratedComponent: React.FC = ({
endDate: end,
entityType,
fields,
- filterQuery: combinedQueries?.filterQuery,
+ filterQuery,
id,
indexNames,
limit: itemsPerPage,
@@ -251,23 +257,6 @@ const TGridIntegratedComponent: React.FC = ({
startDate: start,
});
- const filterQuery = useMemo(
- () =>
- getCombinedFilterQuery({
- config: getEsQueryConfig(uiSettings),
- browserFields,
- dataProviders,
- filters,
- from: start,
- indexPattern,
- isEventViewer: true,
- kqlMode,
- kqlQuery: query,
- to: end,
- }),
- [uiSettings, dataProviders, indexPattern, browserFields, filters, start, end, query, kqlMode]
- );
-
const totalCountMinusDeleted = useMemo(
() => (totalCount > 0 ? totalCount - deletedEventIds.length : 0),
[deletedEventIds.length, totalCount]
diff --git a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx
index 1eb327d95827a43..14a03e8bd5049e2 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx
@@ -30,7 +30,7 @@ import type {
} from '../../../../common/types/timeline';
import { useDeepEqualSelector } from '../../../hooks/use_selector';
import { defaultHeaders } from '../body/column_headers/default_headers';
-import { combineQueries, getCombinedFilterQuery } from '../helpers';
+import { getCombinedFilterQuery } from '../helpers';
import { tGridActions, tGridSelectors } from '../../../store/t_grid';
import type { State } from '../../../store/t_grid';
import { useTimelineEvents } from '../../../container';
@@ -170,25 +170,32 @@ const TGridStandaloneComponent: React.FC = ({
}, [dispatch, isQueryLoading]);
const justTitle = useMemo(() => {title}, [title]);
+ const esQueryConfig = getEsQueryConfig(uiSettings);
- const combinedQueries = useMemo(
+ const filterQuery = useMemo(
() =>
- combineQueries({
- config: getEsQueryConfig(uiSettings),
- dataProviders: EMPTY_DATA_PROVIDERS,
- indexPattern: indexPatterns,
+ getCombinedFilterQuery({
+ config: esQueryConfig,
browserFields,
+ dataProviders: EMPTY_DATA_PROVIDERS,
filters,
- kqlQuery: query,
+ from: start,
+ indexPattern: indexPatterns,
kqlMode: 'search',
- isEventViewer: true,
+ kqlQuery: query,
+ to: end,
}),
- [uiSettings, indexPatterns, browserFields, filters, query]
+ [esQueryConfig, indexPatterns, browserFields, filters, start, end, query]
);
const canQueryTimeline = useMemo(
- () => !indexPatternsLoading && combinedQueries != null && !isEmpty(start) && !isEmpty(end),
- [indexPatternsLoading, combinedQueries, start, end]
+ () =>
+ filterQuery != null &&
+ indexPatternsLoading != null &&
+ !indexPatternsLoading &&
+ !isEmpty(start) &&
+ !isEmpty(end),
+ [indexPatternsLoading, filterQuery, start, end]
);
const fields = useMemo(
@@ -221,7 +228,7 @@ const TGridStandaloneComponent: React.FC = ({
entityType,
excludeEcsData: true,
fields,
- filterQuery: combinedQueries?.filterQuery,
+ filterQuery,
id: STANDALONE_ID,
indexNames,
limit: itemsPerPageStore,
@@ -266,23 +273,6 @@ const TGridStandaloneComponent: React.FC = ({
[deletedEventIds, events]
);
- const filterQuery = useMemo(
- () =>
- getCombinedFilterQuery({
- config: getEsQueryConfig(uiSettings),
- dataProviders: EMPTY_DATA_PROVIDERS,
- indexPattern: indexPatterns,
- browserFields,
- filters,
- kqlQuery: query,
- kqlMode: 'search',
- isEventViewer: true,
- from: start,
- to: end,
- }),
- [uiSettings, indexPatterns, browserFields, filters, query, start, end]
- );
-
useEffect(() => {
setIsQueryLoading(loading);
}, [loading]);
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 0b2b72de830990e..d7053e47a137ade 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -25285,9 +25285,6 @@
"xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "Affichage de : {modifier}{totalAlertsFormatted} {totalAlerts, plural, =1 {alerte} other {alertes}}",
"xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "Premiers {fieldName}",
"xpack.securitySolution.detectionEngine.alerts.openedAlertSuccessToastMessage": "Ouverture réussie de {totalAlerts} {totalAlerts, plural, =1 {alerte} other {alertes}}.",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle": "Sélectionner un total de {totalAlertsFormatted} {totalAlerts, plural, =1 {alerte} other {alertes}}",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle": "{selectedAlertsFormatted} {selectedAlerts, plural, =1 {alerte} other {alertes}} sélectionnée(s)",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle": "Affichage de {totalAlertsFormatted} {totalAlerts, plural, =1 {alerte} other {alertes}}",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditConfirmation.confirmButtonLabel": "Modifier {customRulesCount, plural, =1 {# règle personnalisée} other {# règles personnalisées}}",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditFlyoutForm.setIndexPatternsWarningCallout": "Vous êtes sur le point d'écraser les modèles d'indexation pour {rulesCount, plural, one {# règle sélectionnée} other {# règles sélectionnées}}. Sélectionnez Enregistrer pour appliquer les modifications.",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditFlyoutForm.setTagsWarningCallout": "Vous êtes sur le point d'écraser les balises pour {rulesCount, plural, one {# règle sélectionnée} other {# règles sélectionnées}}. Sélectionnez Enregistrer pour appliquer les modifications.",
@@ -26167,10 +26164,6 @@
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle": "Inclure les alertes fondamentales",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts": "Afficher uniquement les alertes d'indicateur de menaces",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "Filtres supplémentaires",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle": "Marquer comme reconnue",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "Fermer la sélection",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "Ouvrir la sélection",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle": "Effacer la sélection",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle": "Entreprendre une action",
"xpack.securitySolution.detectionEngine.alertTitle": "Alertes",
"xpack.securitySolution.detectionEngine.buttonManageRules": "Gérer les règles",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 0e8650985261d66..f5361e3c867bd99 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -25264,9 +25264,6 @@
"xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "{modifier}{totalAlertsFormatted} {totalAlerts, plural, other {件のアラート}}を表示しています",
"xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "トップ{fieldName}",
"xpack.securitySolution.detectionEngine.alerts.openedAlertSuccessToastMessage": "{totalAlerts} {totalAlerts, plural, other {件のアラート}}を正常に開きました。",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle": "すべての{totalAlertsFormatted} {totalAlerts, plural, other {件のアラート}}を選択",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle": "Selected {selectedAlertsFormatted} {selectedAlerts, plural, other {件のアラート}}",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle": "すべての{totalAlertsFormatted} {totalAlerts, plural, other {件のアラート}}を表示しています",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditConfirmation.confirmButtonLabel": "{customRulesCount, plural, other {# 個のカスタムルール}}を編集",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditFlyoutForm.setIndexPatternsWarningCallout": "{rulesCount, plural, other {# 個の選択したルール}} のインデックスパターンを上書きしようとしています。[保存]をクリックすると、変更が適用されます。",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditFlyoutForm.setTagsWarningCallout": "{rulesCount, plural, other {# 個の選択したルール}}のタグを上書きしようとしています。[保存]をクリックすると、変更が適用されます。\n",
@@ -26144,10 +26141,6 @@
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle": "基本アラートを含める",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts": "脅威インジケーターアラートのみを表示",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "追加のフィルター",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle": "確認済みに設定",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "選択した項目を閉じる",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "選択した項目を開く",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle": "選択した項目をクリア",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle": "アクションを実行",
"xpack.securitySolution.detectionEngine.alertTitle": "アラート",
"xpack.securitySolution.detectionEngine.buttonManageRules": "ルールの管理",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 650d9f9b89da366..3082af48e77afe4 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -25293,9 +25293,6 @@
"xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "正在显示:{modifier}{totalAlertsFormatted} 个{totalAlerts, plural, other {告警}}",
"xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "排名靠前的{fieldName}",
"xpack.securitySolution.detectionEngine.alerts.openedAlertSuccessToastMessage": "已成功打开 {totalAlerts} 个{totalAlerts, plural, other {告警}}。",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle": "选择全部 {totalAlertsFormatted} 个{totalAlerts, plural, other {告警}}",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle": "已选择 {selectedAlertsFormatted} 个{selectedAlerts, plural, other {告警}}",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle": "正在显示 {totalAlertsFormatted} 个{totalAlerts, plural, other {告警}}",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditConfirmation.confirmButtonLabel": "编辑 {customRulesCount, plural, other {# 个定制规则}}",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditFlyoutForm.setIndexPatternsWarningCallout": "您即将覆盖 {rulesCount, plural, other {# 个选定规则}}的索引模式,按“保存”可应用更改。",
"xpack.securitySolution.detectionEngine.components.allRules.bulkActions.bulkEditFlyoutForm.setTagsWarningCallout": "您即将覆盖 {rulesCount, plural, other {# 个选定规则}}的标签,按“保存”可应用更改。",
@@ -26175,10 +26172,6 @@
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle": "包括构建块告警",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts": "仅显示威胁指标告警",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "其他筛选",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle": "标记为已确认",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "关闭所选",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "打开所选",
- "xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle": "清除所选内容",
"xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle": "采取操作",
"xpack.securitySolution.detectionEngine.alertTitle": "告警",
"xpack.securitySolution.detectionEngine.buttonManageRules": "管理规则",
From 6b0bd5b5709f2006617bd29ac2a1638b5bd88a41 Mon Sep 17 00:00:00 2001
From: Spencer
Date: Tue, 23 Aug 2022 14:46:52 -0700
Subject: [PATCH 11/18] [kbn/bazel-packages] convert to js (#139235)
---
packages/BUILD.bazel | 142 +++++++++---------
packages/kbn-bazel-packages/BUILD.bazel | 14 +-
packages/kbn-bazel-packages/src/async.js | 107 +++++++++++++
packages/kbn-bazel-packages/src/async.test.ts | 61 ++++++++
.../{bazel_package.ts => bazel_package.js} | 43 ++++--
..._package_dirs.ts => bazel_package_dirs.js} | 26 ++--
.../src/discover_packages.js | 44 ++++++
.../src/discover_packages.ts | 56 -------
packages/kbn-bazel-packages/src/find_files.js | 114 ++++++++++++++
packages/kbn-bazel-packages/src/index.js | 19 +++
packages/kbn-bazel-packages/src/index.ts | 11 --
..._package_json.ts => parse_package_json.js} | 40 ++---
packages/kbn-bazel-packages/src/types.ts | 31 ++++
packages/kbn-bazel-packages/tsconfig.json | 2 +
.../src/commands/package_command.ts | 2 +-
.../packages_build_manifest_command.ts | 2 +-
src/dev/build/tasks/build_packages_task.ts | 3 +-
src/dev/build/tasks/clean_tasks.ts | 3 +-
18 files changed, 509 insertions(+), 211 deletions(-)
create mode 100644 packages/kbn-bazel-packages/src/async.js
create mode 100644 packages/kbn-bazel-packages/src/async.test.ts
rename packages/kbn-bazel-packages/src/{bazel_package.ts => bazel_package.js} (67%)
rename packages/kbn-bazel-packages/src/{bazel_package_dirs.ts => bazel_package_dirs.js} (68%)
create mode 100644 packages/kbn-bazel-packages/src/discover_packages.js
delete mode 100644 packages/kbn-bazel-packages/src/discover_packages.ts
create mode 100644 packages/kbn-bazel-packages/src/find_files.js
create mode 100644 packages/kbn-bazel-packages/src/index.js
delete mode 100644 packages/kbn-bazel-packages/src/index.ts
rename packages/kbn-bazel-packages/src/{parse_package_json.ts => parse_package_json.js} (57%)
create mode 100644 packages/kbn-bazel-packages/src/types.ts
diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel
index b084fa8617929e3..812d73e82826f37 100644
--- a/packages/BUILD.bazel
+++ b/packages/BUILD.bazel
@@ -14,110 +14,110 @@ filegroup(
"//packages/analytics/shippers/elastic_v3/common:build",
"//packages/analytics/shippers/elastic_v3/server:build",
"//packages/analytics/shippers/fullstory:build",
+ "//packages/core/analytics/core-analytics-browser:build",
"//packages/core/analytics/core-analytics-browser-internal:build",
"//packages/core/analytics/core-analytics-browser-mocks:build",
- "//packages/core/analytics/core-analytics-browser:build",
+ "//packages/core/analytics/core-analytics-server:build",
"//packages/core/analytics/core-analytics-server-internal:build",
"//packages/core/analytics/core-analytics-server-mocks:build",
- "//packages/core/analytics/core-analytics-server:build",
"//packages/core/base/core-base-browser-internal:build",
"//packages/core/base/core-base-browser-mocks:build",
- "//packages/core/base/core-base-common-internal:build",
"//packages/core/base/core-base-common:build",
+ "//packages/core/base/core-base-common-internal:build",
"//packages/core/base/core-base-server-internal:build",
"//packages/core/base/core-base-server-mocks:build",
"//packages/core/capabilities/core-capabilities-common:build",
+ "//packages/core/capabilities/core-capabilities-server:build",
"//packages/core/capabilities/core-capabilities-server-internal:build",
"//packages/core/capabilities/core-capabilities-server-mocks:build",
- "//packages/core/capabilities/core-capabilities-server:build",
"//packages/core/config/core-config-server-internal:build",
+ "//packages/core/deprecations/core-deprecations-browser:build",
"//packages/core/deprecations/core-deprecations-browser-internal:build",
"//packages/core/deprecations/core-deprecations-browser-mocks:build",
- "//packages/core/deprecations/core-deprecations-browser:build",
"//packages/core/deprecations/core-deprecations-common:build",
+ "//packages/core/doc-links/core-doc-links-browser:build",
"//packages/core/doc-links/core-doc-links-browser-internal:build",
"//packages/core/doc-links/core-doc-links-browser-mocks:build",
- "//packages/core/doc-links/core-doc-links-browser:build",
+ "//packages/core/doc-links/core-doc-links-server:build",
"//packages/core/doc-links/core-doc-links-server-internal:build",
"//packages/core/doc-links/core-doc-links-server-mocks:build",
- "//packages/core/doc-links/core-doc-links-server:build",
"//packages/core/elasticsearch/core-elasticsearch-client-server-internal:build",
"//packages/core/elasticsearch/core-elasticsearch-client-server-mocks:build",
+ "//packages/core/elasticsearch/core-elasticsearch-server:build",
"//packages/core/elasticsearch/core-elasticsearch-server-internal:build",
"//packages/core/elasticsearch/core-elasticsearch-server-mocks:build",
- "//packages/core/elasticsearch/core-elasticsearch-server:build",
"//packages/core/environment/core-environment-server-internal:build",
"//packages/core/environment/core-environment-server-mocks:build",
+ "//packages/core/execution-context/core-execution-context-browser:build",
"//packages/core/execution-context/core-execution-context-browser-internal:build",
"//packages/core/execution-context/core-execution-context-browser-mocks:build",
- "//packages/core/execution-context/core-execution-context-browser:build",
"//packages/core/execution-context/core-execution-context-common:build",
+ "//packages/core/execution-context/core-execution-context-server:build",
"//packages/core/execution-context/core-execution-context-server-internal:build",
"//packages/core/execution-context/core-execution-context-server-mocks:build",
- "//packages/core/execution-context/core-execution-context-server:build",
+ "//packages/core/fatal-errors/core-fatal-errors-browser:build",
"//packages/core/fatal-errors/core-fatal-errors-browser-internal:build",
"//packages/core/fatal-errors/core-fatal-errors-browser-mocks:build",
- "//packages/core/fatal-errors/core-fatal-errors-browser:build",
+ "//packages/core/http/core-http-browser:build",
"//packages/core/http/core-http-browser-internal:build",
"//packages/core/http/core-http-browser-mocks:build",
- "//packages/core/http/core-http-browser:build",
"//packages/core/http/core-http-common:build",
"//packages/core/http/core-http-context-server-internal:build",
"//packages/core/http/core-http-context-server-mocks:build",
"//packages/core/http/core-http-router-server-internal:build",
"//packages/core/http/core-http-router-server-mocks:build",
+ "//packages/core/http/core-http-server:build",
"//packages/core/http/core-http-server-internal:build",
"//packages/core/http/core-http-server-mocks:build",
- "//packages/core/http/core-http-server:build",
+ "//packages/core/i18n/core-i18n-browser:build",
"//packages/core/i18n/core-i18n-browser-internal:build",
"//packages/core/i18n/core-i18n-browser-mocks:build",
- "//packages/core/i18n/core-i18n-browser:build",
+ "//packages/core/injected-metadata/core-injected-metadata-browser:build",
"//packages/core/injected-metadata/core-injected-metadata-browser-internal:build",
"//packages/core/injected-metadata/core-injected-metadata-browser-mocks:build",
- "//packages/core/injected-metadata/core-injected-metadata-browser:build",
"//packages/core/injected-metadata/core-injected-metadata-common-internal:build",
"//packages/core/integrations/core-integrations-browser-internal:build",
"//packages/core/integrations/core-integrations-browser-mocks:build",
+ "//packages/core/logging/core-logging-server:build",
"//packages/core/logging/core-logging-server-internal:build",
"//packages/core/logging/core-logging-server-mocks:build",
- "//packages/core/logging/core-logging-server:build",
"//packages/core/metrics/core-metrics-collectors-server-internal:build",
"//packages/core/metrics/core-metrics-collectors-server-mocks:build",
+ "//packages/core/metrics/core-metrics-server:build",
"//packages/core/metrics/core-metrics-server-internal:build",
"//packages/core/metrics/core-metrics-server-mocks:build",
- "//packages/core/metrics/core-metrics-server:build",
- "//packages/core/mount-utils/core-mount-utils-browser-internal:build",
"//packages/core/mount-utils/core-mount-utils-browser:build",
+ "//packages/core/mount-utils/core-mount-utils-browser-internal:build",
+ "//packages/core/node/core-node-server:build",
"//packages/core/node/core-node-server-internal:build",
"//packages/core/node/core-node-server-mocks:build",
- "//packages/core/node/core-node-server:build",
+ "//packages/core/notifications/core-notifications-browser:build",
"//packages/core/notifications/core-notifications-browser-internal:build",
"//packages/core/notifications/core-notifications-browser-mocks:build",
- "//packages/core/notifications/core-notifications-browser:build",
+ "//packages/core/overlays/core-overlays-browser:build",
"//packages/core/overlays/core-overlays-browser-internal:build",
"//packages/core/overlays/core-overlays-browser-mocks:build",
- "//packages/core/overlays/core-overlays-browser:build",
+ "//packages/core/preboot/core-preboot-server:build",
"//packages/core/preboot/core-preboot-server-internal:build",
"//packages/core/preboot/core-preboot-server-mocks:build",
- "//packages/core/preboot/core-preboot-server:build",
"//packages/core/saved-objects/core-saved-objects-api-browser:build",
"//packages/core/saved-objects/core-saved-objects-api-server:build",
"//packages/core/saved-objects/core-saved-objects-base-server-internal:build",
"//packages/core/saved-objects/core-saved-objects-base-server-mocks:build",
+ "//packages/core/saved-objects/core-saved-objects-browser:build",
"//packages/core/saved-objects/core-saved-objects-browser-internal:build",
"//packages/core/saved-objects/core-saved-objects-browser-mocks:build",
- "//packages/core/saved-objects/core-saved-objects-browser:build",
"//packages/core/saved-objects/core-saved-objects-common:build",
"//packages/core/saved-objects/core-saved-objects-server:build",
"//packages/core/saved-objects/core-saved-objects-utils-server:build",
"//packages/core/test-helpers/core-test-helpers-deprecations-getters:build",
"//packages/core/test-helpers/core-test-helpers-http-setup-browser:build",
+ "//packages/core/theme/core-theme-browser:build",
"//packages/core/theme/core-theme-browser-internal:build",
"//packages/core/theme/core-theme-browser-mocks:build",
- "//packages/core/theme/core-theme-browser:build",
+ "//packages/core/ui-settings/core-ui-settings-browser:build",
"//packages/core/ui-settings/core-ui-settings-browser-internal:build",
"//packages/core/ui-settings/core-ui-settings-browser-mocks:build",
- "//packages/core/ui-settings/core-ui-settings-browser:build",
"//packages/core/ui-settings/core-ui-settings-common:build",
"//packages/home/sample_data_card:build",
"//packages/home/sample_data_tab:build",
@@ -141,11 +141,11 @@ filegroup(
"//packages/kbn-ci-stats-reporter:build",
"//packages/kbn-cli-dev-mode:build",
"//packages/kbn-coloring:build",
+ "//packages/kbn-config:build",
"//packages/kbn-config-mocks:build",
"//packages/kbn-config-schema:build",
- "//packages/kbn-config:build",
- "//packages/kbn-crypto-browser:build",
"//packages/kbn-crypto:build",
+ "//packages/kbn-crypto-browser:build",
"//packages/kbn-datemath:build",
"//packages/kbn-dev-cli-errors:build",
"//packages/kbn-dev-cli-runner:build",
@@ -154,10 +154,10 @@ filegroup(
"//packages/kbn-doc-links:build",
"//packages/kbn-docs-utils:build",
"//packages/kbn-ebt-tools:build",
+ "//packages/kbn-es:build",
"//packages/kbn-es-archiver:build",
"//packages/kbn-es-errors:build",
"//packages/kbn-es-query:build",
- "//packages/kbn-es:build",
"//packages/kbn-eslint-config:build",
"//packages/kbn-eslint-plugin-disable:build",
"//packages/kbn-eslint-plugin-eslint:build",
@@ -170,8 +170,8 @@ filegroup(
"//packages/kbn-get-repo-files:build",
"//packages/kbn-handlebars:build",
"//packages/kbn-hapi-mocks:build",
- "//packages/kbn-i18n-react:build",
"//packages/kbn-i18n:build",
+ "//packages/kbn-i18n-react:build",
"//packages/kbn-import-resolver:build",
"//packages/kbn-interpreter:build",
"//packages/kbn-io-ts-utils:build",
@@ -179,21 +179,21 @@ filegroup(
"//packages/kbn-jsonc:build",
"//packages/kbn-kibana-manifest-parser:build",
"//packages/kbn-kibana-manifest-schema:build",
- "//packages/kbn-logging-mocks:build",
"//packages/kbn-logging:build",
- "//packages/kbn-managed-vscode-config-cli:build",
+ "//packages/kbn-logging-mocks:build",
"//packages/kbn-managed-vscode-config:build",
+ "//packages/kbn-managed-vscode-config-cli:build",
"//packages/kbn-mapbox-gl:build",
"//packages/kbn-monaco:build",
- "//packages/kbn-optimizer-webpack-helpers:build",
"//packages/kbn-optimizer:build",
+ "//packages/kbn-optimizer-webpack-helpers:build",
"//packages/kbn-performance-testing-dataset-extractor:build",
"//packages/kbn-plugin-discovery:build",
"//packages/kbn-plugin-generator:build",
"//packages/kbn-plugin-helpers:build",
"//packages/kbn-react-field:build",
- "//packages/kbn-repo-source-classifier-cli:build",
"//packages/kbn-repo-source-classifier:build",
+ "//packages/kbn-repo-source-classifier-cli:build",
"//packages/kbn-rule-data-utils:build",
"//packages/kbn-safer-lodash-set:build",
"//packages/kbn-securitysolution-autocomplete:build",
@@ -222,23 +222,23 @@ filegroup(
"//packages/kbn-storybook:build",
"//packages/kbn-synthetic-package-map:build",
"//packages/kbn-telemetry-tools:build",
+ "//packages/kbn-test:build",
"//packages/kbn-test-jest-helpers:build",
"//packages/kbn-test-subj-selector:build",
- "//packages/kbn-test:build",
"//packages/kbn-timelion-grammar:build",
"//packages/kbn-tinymath:build",
"//packages/kbn-tooling-log:build",
+ "//packages/kbn-type-summarizer:build",
"//packages/kbn-type-summarizer-cli:build",
"//packages/kbn-type-summarizer-core:build",
- "//packages/kbn-type-summarizer:build",
"//packages/kbn-typed-react-router-config:build",
"//packages/kbn-ui-framework:build",
"//packages/kbn-ui-shared-deps-npm:build",
"//packages/kbn-ui-shared-deps-src:build",
"//packages/kbn-ui-theme:build",
"//packages/kbn-user-profile-components:build",
- "//packages/kbn-utility-types-jest:build",
"//packages/kbn-utility-types:build",
+ "//packages/kbn-utility-types-jest:build",
"//packages/kbn-utils:build",
"//packages/kbn-yarn-lock-validator:build",
"//packages/shared-ux/avatar/solution:build",
@@ -290,110 +290,110 @@ filegroup(
"//packages/analytics/shippers/elastic_v3/common:build_types",
"//packages/analytics/shippers/elastic_v3/server:build_types",
"//packages/analytics/shippers/fullstory:build_types",
+ "//packages/core/analytics/core-analytics-browser:build_types",
"//packages/core/analytics/core-analytics-browser-internal:build_types",
"//packages/core/analytics/core-analytics-browser-mocks:build_types",
- "//packages/core/analytics/core-analytics-browser:build_types",
+ "//packages/core/analytics/core-analytics-server:build_types",
"//packages/core/analytics/core-analytics-server-internal:build_types",
"//packages/core/analytics/core-analytics-server-mocks:build_types",
- "//packages/core/analytics/core-analytics-server:build_types",
"//packages/core/base/core-base-browser-internal:build_types",
"//packages/core/base/core-base-browser-mocks:build_types",
- "//packages/core/base/core-base-common-internal:build_types",
"//packages/core/base/core-base-common:build_types",
+ "//packages/core/base/core-base-common-internal:build_types",
"//packages/core/base/core-base-server-internal:build_types",
"//packages/core/base/core-base-server-mocks:build_types",
"//packages/core/capabilities/core-capabilities-common:build_types",
+ "//packages/core/capabilities/core-capabilities-server:build_types",
"//packages/core/capabilities/core-capabilities-server-internal:build_types",
"//packages/core/capabilities/core-capabilities-server-mocks:build_types",
- "//packages/core/capabilities/core-capabilities-server:build_types",
"//packages/core/config/core-config-server-internal:build_types",
+ "//packages/core/deprecations/core-deprecations-browser:build_types",
"//packages/core/deprecations/core-deprecations-browser-internal:build_types",
"//packages/core/deprecations/core-deprecations-browser-mocks:build_types",
- "//packages/core/deprecations/core-deprecations-browser:build_types",
"//packages/core/deprecations/core-deprecations-common:build_types",
+ "//packages/core/doc-links/core-doc-links-browser:build_types",
"//packages/core/doc-links/core-doc-links-browser-internal:build_types",
"//packages/core/doc-links/core-doc-links-browser-mocks:build_types",
- "//packages/core/doc-links/core-doc-links-browser:build_types",
+ "//packages/core/doc-links/core-doc-links-server:build_types",
"//packages/core/doc-links/core-doc-links-server-internal:build_types",
"//packages/core/doc-links/core-doc-links-server-mocks:build_types",
- "//packages/core/doc-links/core-doc-links-server:build_types",
"//packages/core/elasticsearch/core-elasticsearch-client-server-internal:build_types",
"//packages/core/elasticsearch/core-elasticsearch-client-server-mocks:build_types",
+ "//packages/core/elasticsearch/core-elasticsearch-server:build_types",
"//packages/core/elasticsearch/core-elasticsearch-server-internal:build_types",
"//packages/core/elasticsearch/core-elasticsearch-server-mocks:build_types",
- "//packages/core/elasticsearch/core-elasticsearch-server:build_types",
"//packages/core/environment/core-environment-server-internal:build_types",
"//packages/core/environment/core-environment-server-mocks:build_types",
+ "//packages/core/execution-context/core-execution-context-browser:build_types",
"//packages/core/execution-context/core-execution-context-browser-internal:build_types",
"//packages/core/execution-context/core-execution-context-browser-mocks:build_types",
- "//packages/core/execution-context/core-execution-context-browser:build_types",
"//packages/core/execution-context/core-execution-context-common:build_types",
+ "//packages/core/execution-context/core-execution-context-server:build_types",
"//packages/core/execution-context/core-execution-context-server-internal:build_types",
"//packages/core/execution-context/core-execution-context-server-mocks:build_types",
- "//packages/core/execution-context/core-execution-context-server:build_types",
+ "//packages/core/fatal-errors/core-fatal-errors-browser:build_types",
"//packages/core/fatal-errors/core-fatal-errors-browser-internal:build_types",
"//packages/core/fatal-errors/core-fatal-errors-browser-mocks:build_types",
- "//packages/core/fatal-errors/core-fatal-errors-browser:build_types",
+ "//packages/core/http/core-http-browser:build_types",
"//packages/core/http/core-http-browser-internal:build_types",
"//packages/core/http/core-http-browser-mocks:build_types",
- "//packages/core/http/core-http-browser:build_types",
"//packages/core/http/core-http-common:build_types",
"//packages/core/http/core-http-context-server-internal:build_types",
"//packages/core/http/core-http-context-server-mocks:build_types",
"//packages/core/http/core-http-router-server-internal:build_types",
"//packages/core/http/core-http-router-server-mocks:build_types",
+ "//packages/core/http/core-http-server:build_types",
"//packages/core/http/core-http-server-internal:build_types",
"//packages/core/http/core-http-server-mocks:build_types",
- "//packages/core/http/core-http-server:build_types",
+ "//packages/core/i18n/core-i18n-browser:build_types",
"//packages/core/i18n/core-i18n-browser-internal:build_types",
"//packages/core/i18n/core-i18n-browser-mocks:build_types",
- "//packages/core/i18n/core-i18n-browser:build_types",
+ "//packages/core/injected-metadata/core-injected-metadata-browser:build_types",
"//packages/core/injected-metadata/core-injected-metadata-browser-internal:build_types",
"//packages/core/injected-metadata/core-injected-metadata-browser-mocks:build_types",
- "//packages/core/injected-metadata/core-injected-metadata-browser:build_types",
"//packages/core/injected-metadata/core-injected-metadata-common-internal:build_types",
"//packages/core/integrations/core-integrations-browser-internal:build_types",
"//packages/core/integrations/core-integrations-browser-mocks:build_types",
+ "//packages/core/logging/core-logging-server:build_types",
"//packages/core/logging/core-logging-server-internal:build_types",
"//packages/core/logging/core-logging-server-mocks:build_types",
- "//packages/core/logging/core-logging-server:build_types",
"//packages/core/metrics/core-metrics-collectors-server-internal:build_types",
"//packages/core/metrics/core-metrics-collectors-server-mocks:build_types",
+ "//packages/core/metrics/core-metrics-server:build_types",
"//packages/core/metrics/core-metrics-server-internal:build_types",
"//packages/core/metrics/core-metrics-server-mocks:build_types",
- "//packages/core/metrics/core-metrics-server:build_types",
- "//packages/core/mount-utils/core-mount-utils-browser-internal:build_types",
"//packages/core/mount-utils/core-mount-utils-browser:build_types",
+ "//packages/core/mount-utils/core-mount-utils-browser-internal:build_types",
+ "//packages/core/node/core-node-server:build_types",
"//packages/core/node/core-node-server-internal:build_types",
"//packages/core/node/core-node-server-mocks:build_types",
- "//packages/core/node/core-node-server:build_types",
+ "//packages/core/notifications/core-notifications-browser:build_types",
"//packages/core/notifications/core-notifications-browser-internal:build_types",
"//packages/core/notifications/core-notifications-browser-mocks:build_types",
- "//packages/core/notifications/core-notifications-browser:build_types",
+ "//packages/core/overlays/core-overlays-browser:build_types",
"//packages/core/overlays/core-overlays-browser-internal:build_types",
"//packages/core/overlays/core-overlays-browser-mocks:build_types",
- "//packages/core/overlays/core-overlays-browser:build_types",
+ "//packages/core/preboot/core-preboot-server:build_types",
"//packages/core/preboot/core-preboot-server-internal:build_types",
"//packages/core/preboot/core-preboot-server-mocks:build_types",
- "//packages/core/preboot/core-preboot-server:build_types",
"//packages/core/saved-objects/core-saved-objects-api-browser:build_types",
"//packages/core/saved-objects/core-saved-objects-api-server:build_types",
"//packages/core/saved-objects/core-saved-objects-base-server-internal:build_types",
"//packages/core/saved-objects/core-saved-objects-base-server-mocks:build_types",
+ "//packages/core/saved-objects/core-saved-objects-browser:build_types",
"//packages/core/saved-objects/core-saved-objects-browser-internal:build_types",
"//packages/core/saved-objects/core-saved-objects-browser-mocks:build_types",
- "//packages/core/saved-objects/core-saved-objects-browser:build_types",
"//packages/core/saved-objects/core-saved-objects-common:build_types",
"//packages/core/saved-objects/core-saved-objects-server:build_types",
"//packages/core/saved-objects/core-saved-objects-utils-server:build_types",
"//packages/core/test-helpers/core-test-helpers-deprecations-getters:build_types",
"//packages/core/test-helpers/core-test-helpers-http-setup-browser:build_types",
+ "//packages/core/theme/core-theme-browser:build_types",
"//packages/core/theme/core-theme-browser-internal:build_types",
"//packages/core/theme/core-theme-browser-mocks:build_types",
- "//packages/core/theme/core-theme-browser:build_types",
+ "//packages/core/ui-settings/core-ui-settings-browser:build_types",
"//packages/core/ui-settings/core-ui-settings-browser-internal:build_types",
"//packages/core/ui-settings/core-ui-settings-browser-mocks:build_types",
- "//packages/core/ui-settings/core-ui-settings-browser:build_types",
"//packages/core/ui-settings/core-ui-settings-common:build_types",
"//packages/home/sample_data_card:build_types",
"//packages/home/sample_data_tab:build_types",
@@ -412,11 +412,11 @@ filegroup(
"//packages/kbn-ci-stats-reporter:build_types",
"//packages/kbn-cli-dev-mode:build_types",
"//packages/kbn-coloring:build_types",
+ "//packages/kbn-config:build_types",
"//packages/kbn-config-mocks:build_types",
"//packages/kbn-config-schema:build_types",
- "//packages/kbn-config:build_types",
- "//packages/kbn-crypto-browser:build_types",
"//packages/kbn-crypto:build_types",
+ "//packages/kbn-crypto-browser:build_types",
"//packages/kbn-datemath:build_types",
"//packages/kbn-dev-cli-errors:build_types",
"//packages/kbn-dev-cli-runner:build_types",
@@ -436,8 +436,8 @@ filegroup(
"//packages/kbn-get-repo-files:build_types",
"//packages/kbn-handlebars:build_types",
"//packages/kbn-hapi-mocks:build_types",
- "//packages/kbn-i18n-react:build_types",
"//packages/kbn-i18n:build_types",
+ "//packages/kbn-i18n-react:build_types",
"//packages/kbn-import-resolver:build_types",
"//packages/kbn-interpreter:build_types",
"//packages/kbn-io-ts-utils:build_types",
@@ -445,21 +445,21 @@ filegroup(
"//packages/kbn-jsonc:build_types",
"//packages/kbn-kibana-manifest-parser:build_types",
"//packages/kbn-kibana-manifest-schema:build_types",
- "//packages/kbn-logging-mocks:build_types",
"//packages/kbn-logging:build_types",
- "//packages/kbn-managed-vscode-config-cli:build_types",
+ "//packages/kbn-logging-mocks:build_types",
"//packages/kbn-managed-vscode-config:build_types",
+ "//packages/kbn-managed-vscode-config-cli:build_types",
"//packages/kbn-mapbox-gl:build_types",
"//packages/kbn-monaco:build_types",
- "//packages/kbn-optimizer-webpack-helpers:build_types",
"//packages/kbn-optimizer:build_types",
+ "//packages/kbn-optimizer-webpack-helpers:build_types",
"//packages/kbn-performance-testing-dataset-extractor:build_types",
"//packages/kbn-plugin-discovery:build_types",
"//packages/kbn-plugin-generator:build_types",
"//packages/kbn-plugin-helpers:build_types",
"//packages/kbn-react-field:build_types",
- "//packages/kbn-repo-source-classifier-cli:build_types",
"//packages/kbn-repo-source-classifier:build_types",
+ "//packages/kbn-repo-source-classifier-cli:build_types",
"//packages/kbn-rule-data-utils:build_types",
"//packages/kbn-safer-lodash-set:build_types",
"//packages/kbn-securitysolution-autocomplete:build_types",
@@ -486,19 +486,19 @@ filegroup(
"//packages/kbn-stdio-dev-helpers:build_types",
"//packages/kbn-storybook:build_types",
"//packages/kbn-telemetry-tools:build_types",
- "//packages/kbn-test-jest-helpers:build_types",
"//packages/kbn-test:build_types",
+ "//packages/kbn-test-jest-helpers:build_types",
"//packages/kbn-tooling-log:build_types",
+ "//packages/kbn-type-summarizer:build_types",
"//packages/kbn-type-summarizer-cli:build_types",
"//packages/kbn-type-summarizer-core:build_types",
- "//packages/kbn-type-summarizer:build_types",
"//packages/kbn-typed-react-router-config:build_types",
"//packages/kbn-ui-shared-deps-npm:build_types",
"//packages/kbn-ui-shared-deps-src:build_types",
"//packages/kbn-ui-theme:build_types",
"//packages/kbn-user-profile-components:build_types",
- "//packages/kbn-utility-types-jest:build_types",
"//packages/kbn-utility-types:build_types",
+ "//packages/kbn-utility-types-jest:build_types",
"//packages/kbn-utils:build_types",
"//packages/kbn-yarn-lock-validator:build_types",
"//packages/shared-ux/avatar/solution:build_types",
diff --git a/packages/kbn-bazel-packages/BUILD.bazel b/packages/kbn-bazel-packages/BUILD.bazel
index e3a3545be167d61..9c7a793459623ed 100644
--- a/packages/kbn-bazel-packages/BUILD.bazel
+++ b/packages/kbn-bazel-packages/BUILD.bazel
@@ -7,6 +7,7 @@ PKG_REQUIRE_NAME = "@kbn/bazel-packages"
SOURCE_FILES = glob(
[
+ "src/**/*.js",
"src/**/*.ts",
],
exclude = [
@@ -37,11 +38,6 @@ NPM_MODULE_EXTRA_FILES = [
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
- "//packages/kbn-utils",
- "//packages/kbn-std",
- "//packages/kbn-synthetic-package-map",
- "@npm//globby",
- "@npm//normalize-path",
]
# In this array place dependencies necessary to build the types, which will include the
@@ -55,13 +51,8 @@ RUNTIME_DEPS = [
# References to NPM packages work the same as RUNTIME_DEPS:
# eg. "@npm//@types/babel__core"
TYPES_DEPS = [
- "//packages/kbn-utils:npm_module_types",
- "//packages/kbn-std:npm_module_types",
- "//packages/kbn-synthetic-package-map:npm_module_types",
"@npm//@types/node",
- "@npm//@types/normalize-path",
- "@npm//globby",
- "@npm//normalize-path",
+ "@npm//@types/jest",
]
jsts_transpiler(
@@ -87,6 +78,7 @@ ts_project(
deps = TYPES_DEPS,
declaration = True,
declaration_map = True,
+ allow_js = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
diff --git a/packages/kbn-bazel-packages/src/async.js b/packages/kbn-bazel-packages/src/async.js
new file mode 100644
index 000000000000000..38b535447953f38
--- /dev/null
+++ b/packages/kbn-bazel-packages/src/async.js
@@ -0,0 +1,107 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+/**
+ *
+ * @template T
+ * @template T2
+ * @param {(v: T) => Promise} fn
+ * @param {T} item
+ * @returns {Promise>}
+ */
+const settle = async (fn, item) => {
+ const [result] = await Promise.allSettled([(async () => fn(item))()]);
+ return result;
+};
+
+/**
+ * @template T
+ * @template T2
+ * @param {Array} source
+ * @param {number} limit
+ * @param {(v: T) => Promise} mapFn
+ * @returns {Promise}
+ */
+function asyncMapWithLimit(source, limit, mapFn) {
+ return new Promise((resolve, reject) => {
+ if (limit < 1) {
+ reject(new Error('invalid limit, must be greater than 0'));
+ return;
+ }
+
+ let failed = false;
+ let inProgress = 0;
+ const queue = [...source.entries()];
+
+ /** @type {T2[]} */
+ const results = new Array(source.length);
+
+ /**
+ * this is run for each item, manages the inProgress state,
+ * calls the mapFn with that item, writes the map result to
+ * the result array, and calls runMore() after each item
+ * completes to either start another item or resolve the
+ * returned promise.
+ *
+ * @param {number} index
+ * @param {T} item
+ */
+ function run(index, item) {
+ inProgress += 1;
+ settle(mapFn, item).then((result) => {
+ inProgress -= 1;
+
+ if (failed) {
+ return;
+ }
+
+ if (result.status === 'fulfilled') {
+ results[index] = result.value;
+ runMore();
+ return;
+ }
+
+ // when an error occurs we update the state to prevent
+ // holding onto old results and ignore future results
+ // from in-progress promises
+ failed = true;
+ results.length = 0;
+ reject(result.reason);
+ });
+ }
+
+ /**
+ * If there is work in the queue, schedule it, if there isn't
+ * any work to be scheduled and there isn't anything in progress
+ * then we're done. This function is called every time a mapFn
+ * promise resolves and once after initialization
+ */
+ function runMore() {
+ if (!queue.length) {
+ if (inProgress === 0) {
+ resolve(results);
+ }
+
+ return;
+ }
+
+ while (inProgress < limit) {
+ const entry = queue.shift();
+ if (!entry) {
+ break;
+ }
+
+ run(...entry);
+ }
+ }
+
+ runMore();
+ });
+}
+
+module.exports = { asyncMapWithLimit };
diff --git a/packages/kbn-bazel-packages/src/async.test.ts b/packages/kbn-bazel-packages/src/async.test.ts
new file mode 100644
index 000000000000000..b238783f74fb856
--- /dev/null
+++ b/packages/kbn-bazel-packages/src/async.test.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { setTimeout } from 'timers/promises';
+import { asyncMapWithLimit } from './async';
+
+const NUMS = [1, 2, 3, 4];
+const ident = jest.fn(async function ident(x: T) {
+ return await x;
+});
+const double = jest.fn(async function double(x: number) {
+ return x * 2;
+});
+
+beforeEach(() => {
+ jest.clearAllMocks();
+});
+
+it('resolves with an empty array', async () => {
+ const result = await asyncMapWithLimit([], 10, ident);
+ expect(ident).not.toHaveBeenCalled();
+ expect(result).toEqual([]);
+});
+
+it('resolves with a mapped array', async () => {
+ const result = await asyncMapWithLimit(NUMS, 10, double);
+ expect(double).toHaveBeenCalledTimes(NUMS.length);
+ expect(result.join(',')).toMatchInlineSnapshot(`"2,4,6,8"`);
+});
+
+it('rejects when limit it not >= 1', async () => {
+ await expect(() => asyncMapWithLimit([], -1, ident)).rejects.toMatchInlineSnapshot(
+ `[Error: invalid limit, must be greater than 0]`
+ );
+ await expect(() => asyncMapWithLimit([], 0, ident)).rejects.toMatchInlineSnapshot(
+ `[Error: invalid limit, must be greater than 0]`
+ );
+ await expect(() => asyncMapWithLimit([], -Infinity, ident)).rejects.toMatchInlineSnapshot(
+ `[Error: invalid limit, must be greater than 0]`
+ );
+});
+
+it('rejects with the first error produced and stops calling mapFn', async () => {
+ const map = jest.fn(async (num) => {
+ if (num % 2 === 0) {
+ throw new Error('even numbers are not supported');
+ }
+ return num * 2;
+ });
+
+ await expect(() => asyncMapWithLimit(NUMS, 1, map)).rejects.toMatchInlineSnapshot(
+ `[Error: even numbers are not supported]`
+ );
+ await setTimeout(10);
+ expect(map).toHaveBeenCalledTimes(2);
+});
diff --git a/packages/kbn-bazel-packages/src/bazel_package.ts b/packages/kbn-bazel-packages/src/bazel_package.js
similarity index 67%
rename from packages/kbn-bazel-packages/src/bazel_package.ts
rename to packages/kbn-bazel-packages/src/bazel_package.js
index 91e411770175bdf..c6a31ccc0dbc1f9 100644
--- a/packages/kbn-bazel-packages/src/bazel_package.ts
+++ b/packages/kbn-bazel-packages/src/bazel_package.js
@@ -6,27 +6,31 @@
* Side Public License, v 1.
*/
-import { inspect } from 'util';
-import Path from 'path';
-import Fsp from 'fs/promises';
+const { inspect } = require('util');
+const Path = require('path');
+const Fsp = require('fs/promises');
-import normalizePath from 'normalize-path';
-import { REPO_ROOT } from '@kbn/utils';
-
-import { readPackageJson, ParsedPackageJson } from './parse_package_json';
+/** @typedef {import('./types').ParsedPackageJson} ParsedPackageJson */
+const { readPackageJson } = require('./parse_package_json');
const BUILD_RULE_NAME = /(^|\s)name\s*=\s*"build"/;
const BUILD_TYPES_RULE_NAME = /(^|\s)name\s*=\s*"build_types"/;
/**
* Representation of a Bazel Package in the Kibana repository
+ * @class
+ * @property {string} normalizedRepoRelativeDir
+ * @property {import('./types').ParsedPackageJson} pkg
+ * @property {string | undefined} buildBazelContent
*/
-export class BazelPackage {
+class BazelPackage {
/**
* Create a BazelPackage object from a package directory. Reads some files from the package and returns
* a Promise for a BazelPackage instance.
+ * @param {string} repoRoot
+ * @param {string} dir
*/
- static async fromDir(dir: string) {
+ static async fromDir(repoRoot, dir) {
const pkg = readPackageJson(Path.resolve(dir, 'package.json'));
let buildBazelContent;
@@ -36,23 +40,30 @@ export class BazelPackage {
throw new Error(`unable to read BUILD.bazel file in [${dir}]: ${error.message}`);
}
- return new BazelPackage(normalizePath(Path.relative(REPO_ROOT, dir)), pkg, buildBazelContent);
+ return new BazelPackage(Path.relative(repoRoot, dir), pkg, buildBazelContent);
}
constructor(
/**
* Relative path from the root of the repository to the package directory
+ * @type {string}
*/
- public readonly normalizedRepoRelativeDir: string,
+ normalizedRepoRelativeDir,
/**
* Parsed package.json file from the package
+ * @type {import('./types').ParsedPackageJson}
*/
- public readonly pkg: ParsedPackageJson,
+ pkg,
/**
* Content of the BUILD.bazel file
+ * @type {string | undefined}
*/
- private readonly buildBazelContent?: string
- ) {}
+ buildBazelContent = undefined
+ ) {
+ this.normalizedRepoRelativeDir = normalizedRepoRelativeDir;
+ this.pkg = pkg;
+ this.buildBazelContent = buildBazelContent;
+ }
/**
* Returns true if the package includes a `:build` bazel rule
@@ -83,3 +94,7 @@ export class BazelPackage {
return `BazelPackage<${this.normalizedRepoRelativeDir}>`;
}
}
+
+module.exports = {
+ BazelPackage,
+};
diff --git a/packages/kbn-bazel-packages/src/bazel_package_dirs.ts b/packages/kbn-bazel-packages/src/bazel_package_dirs.js
similarity index 68%
rename from packages/kbn-bazel-packages/src/bazel_package_dirs.ts
rename to packages/kbn-bazel-packages/src/bazel_package_dirs.js
index 755ef614c045619..7e3f728a21ca72e 100644
--- a/packages/kbn-bazel-packages/src/bazel_package_dirs.ts
+++ b/packages/kbn-bazel-packages/src/bazel_package_dirs.js
@@ -6,10 +6,7 @@
* Side Public License, v 1.
*/
-import globby from 'globby';
-import Path from 'path';
-
-import { REPO_ROOT } from '@kbn/utils';
+const { expandWildcards } = require('./find_files');
/**
* This is a list of repo-relative paths to directories containing packages. Do not
@@ -19,7 +16,7 @@ import { REPO_ROOT } from '@kbn/utils';
* eg. src/vis_editors => would find a package at src/vis_editors/foo/package.json
* src/vis_editors/* => would find a package at src/vis_editors/foo/bar/package.json
*/
-export const BAZEL_PACKAGE_DIRS = [
+const BAZEL_PACKAGE_DIRS = [
'packages',
'packages/shared-ux',
'packages/shared-ux/*',
@@ -34,18 +31,13 @@ export const BAZEL_PACKAGE_DIRS = [
/**
* Resolve all the BAZEL_PACKAGE_DIRS to absolute paths
+ * @param {string} repoRoot
*/
-export function getAllBazelPackageDirs() {
- return globby.sync(BAZEL_PACKAGE_DIRS, {
- cwd: REPO_ROOT,
- onlyDirectories: true,
- expandDirectories: false,
- });
+function getAllBazelPackageDirs(repoRoot) {
+ return expandWildcards(repoRoot, BAZEL_PACKAGE_DIRS);
}
-/**
- * Resolve all the BAZEL_PACKAGE_DIRS to repo-relative paths
- */
-export function getAllRepoRelativeBazelPackageDirs() {
- return getAllBazelPackageDirs().map((path) => Path.relative(REPO_ROOT, path));
-}
+module.exports = {
+ BAZEL_PACKAGE_DIRS,
+ getAllBazelPackageDirs,
+};
diff --git a/packages/kbn-bazel-packages/src/discover_packages.js b/packages/kbn-bazel-packages/src/discover_packages.js
new file mode 100644
index 000000000000000..17678115c74526b
--- /dev/null
+++ b/packages/kbn-bazel-packages/src/discover_packages.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+const Path = require('path');
+
+const { BazelPackage } = require('./bazel_package');
+const { getAllBazelPackageDirs } = require('./bazel_package_dirs');
+const { findPackages } = require('./find_files');
+const { asyncMapWithLimit } = require('./async');
+
+/**
+ * @param {string} repoRoot
+ */
+function discoverBazelPackageLocations(repoRoot) {
+ const packagesWithBuildBazel = getAllBazelPackageDirs(repoRoot)
+ .flatMap((packageDir) => findPackages(packageDir, 'BUILD.bazel'))
+ .map((path) => Path.dirname(path));
+
+ // NOTE: only return as discovered packages with a package.json + BUILD.bazel file.
+ // In the future we should change this to only discover the ones with kibana.jsonc.
+ return getAllBazelPackageDirs(repoRoot)
+ .flatMap((packageDir) => findPackages(packageDir, 'package.json'))
+ .map((path) => Path.dirname(path))
+ .filter((pkg) => packagesWithBuildBazel.includes(pkg))
+ .sort((a, b) => a.localeCompare(b));
+}
+
+/**
+ * @param {string} repoRoot
+ */
+async function discoverBazelPackages(repoRoot) {
+ return await asyncMapWithLimit(
+ discoverBazelPackageLocations(repoRoot),
+ 100,
+ async (dir) => await BazelPackage.fromDir(repoRoot, dir)
+ );
+}
+
+module.exports = { discoverBazelPackageLocations, discoverBazelPackages };
diff --git a/packages/kbn-bazel-packages/src/discover_packages.ts b/packages/kbn-bazel-packages/src/discover_packages.ts
deleted file mode 100644
index 8b78e4e29311886..000000000000000
--- a/packages/kbn-bazel-packages/src/discover_packages.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import Path from 'path';
-
-import globby from 'globby';
-import normalizePath from 'normalize-path';
-import { REPO_ROOT } from '@kbn/utils';
-import { asyncMapWithLimit } from '@kbn/std';
-
-import { BazelPackage } from './bazel_package';
-import { BAZEL_PACKAGE_DIRS } from './bazel_package_dirs';
-
-export function discoverBazelPackageLocations(repoRoot: string) {
- const packagesWithPackageJson = globby
- .sync(
- BAZEL_PACKAGE_DIRS.map((dir) => `${dir}/*/package.json`),
- {
- cwd: repoRoot,
- absolute: true,
- }
- )
- // NOTE: removing x-pack by default for now to prevent a situation where a BUILD.bazel file
- // needs to be added at the root of the folder which will make x-pack to be wrongly recognized
- // as a Bazel package in that case
- .filter((path) => !normalizePath(path).includes('x-pack/package.json'))
- .sort((a, b) => a.localeCompare(b))
- .map((path) => Path.dirname(path));
-
- const packagesWithBuildBazel = globby
- .sync(
- BAZEL_PACKAGE_DIRS.map((dir) => `${dir}/*/BUILD.bazel`),
- {
- cwd: repoRoot,
- absolute: true,
- }
- )
- .map((path) => Path.dirname(path));
-
- // NOTE: only return as discovered packages the ones with a package.json + BUILD.bazel file.
- // In the future we should change this to only discover the ones declaring kibana.json.
- return packagesWithPackageJson.filter((pkg) => packagesWithBuildBazel.includes(pkg));
-}
-
-export async function discoverBazelPackages(repoRoot: string = REPO_ROOT) {
- return await asyncMapWithLimit(
- discoverBazelPackageLocations(repoRoot),
- 100,
- async (dir) => await BazelPackage.fromDir(dir)
- );
-}
diff --git a/packages/kbn-bazel-packages/src/find_files.js b/packages/kbn-bazel-packages/src/find_files.js
new file mode 100644
index 000000000000000..9be6c2e25607905
--- /dev/null
+++ b/packages/kbn-bazel-packages/src/find_files.js
@@ -0,0 +1,114 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+const Path = require('path');
+const Fs = require('fs');
+
+/**
+ * @param {string} path
+ */
+function safeIsFile(path) {
+ try {
+ return Fs.statSync(path).isFile();
+ } catch (error) {
+ if (error.code === 'ENOENT') {
+ return false;
+ }
+
+ throw error;
+ }
+}
+
+/**
+ * @param {string} path
+ */
+function safeReadDir(path) {
+ try {
+ return Fs.readdirSync(path, {
+ withFileTypes: true,
+ });
+ } catch (error) {
+ if (error.code === 'ENOENT' || error.code === 'ENOTDIR') {
+ return [];
+ }
+
+ throw error;
+ }
+}
+
+/**
+ * Search for `name` files in directories within `packageDir`
+ *
+ * @param {string} packageDir
+ * @param {string} name
+ * @returns {string[]}
+ */
+function findPackages(packageDir, name) {
+ return (
+ // get the directories within the "package dir"
+ safeReadDir(packageDir)
+ // if this directory has a file with the name, it's a match
+ .flatMap((e) => {
+ if (!e.isDirectory()) {
+ return [];
+ }
+
+ const path = Path.resolve(packageDir, e.name, name);
+ return safeIsFile(path) ? path : [];
+ })
+ );
+}
+
+/**
+ * Expand simple `*` wildcards in patterns, which are otherwise expected to be
+ * paths relative to `cwd`.
+ *
+ * @param {string} cwd
+ * @param {string[]} patterns
+ */
+function expandWildcards(cwd, patterns) {
+ /** @type {Set} */
+ const results = new Set();
+
+ /** @type {Set} */
+ const queue = new Set(patterns.map((p) => Path.resolve(cwd, p)));
+
+ for (const pattern of queue) {
+ let length = 3;
+ let index = pattern.indexOf('/*/');
+ if (index === -1 && pattern.endsWith('/*')) {
+ length = 2;
+ index = pattern.length - length;
+ }
+
+ if (index === -1) {
+ results.add(pattern);
+ continue;
+ }
+
+ const left = pattern.slice(0, index + 1);
+ const right = pattern.slice(index + length);
+ for (const ent of safeReadDir(left)) {
+ if (!ent.isDirectory()) {
+ continue;
+ }
+
+ const path = Path.resolve(left, ent.name);
+
+ if (right) {
+ queue.add(Path.resolve(path, right));
+ } else {
+ results.add(path);
+ }
+ }
+ }
+
+ return [...results];
+}
+
+module.exports = { findPackages, expandWildcards };
diff --git a/packages/kbn-bazel-packages/src/index.js b/packages/kbn-bazel-packages/src/index.js
new file mode 100644
index 000000000000000..254b8bb9da44c6c
--- /dev/null
+++ b/packages/kbn-bazel-packages/src/index.js
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+/** @typedef {import('./bazel_package').BazelPackage} BazelPackage */
+
+const { BAZEL_PACKAGE_DIRS, getAllBazelPackageDirs } = require('./bazel_package_dirs');
+const { discoverBazelPackageLocations, discoverBazelPackages } = require('./discover_packages');
+
+module.exports = {
+ BAZEL_PACKAGE_DIRS,
+ getAllBazelPackageDirs,
+ discoverBazelPackageLocations,
+ discoverBazelPackages,
+};
diff --git a/packages/kbn-bazel-packages/src/index.ts b/packages/kbn-bazel-packages/src/index.ts
deleted file mode 100644
index 55d5db9bb3adb21..000000000000000
--- a/packages/kbn-bazel-packages/src/index.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export * from './bazel_package_dirs';
-export * from './discover_packages';
-export type { BazelPackage } from './bazel_package';
diff --git a/packages/kbn-bazel-packages/src/parse_package_json.ts b/packages/kbn-bazel-packages/src/parse_package_json.js
similarity index 57%
rename from packages/kbn-bazel-packages/src/parse_package_json.ts
rename to packages/kbn-bazel-packages/src/parse_package_json.js
index b060656c0c51256..27a78f91a446613 100644
--- a/packages/kbn-bazel-packages/src/parse_package_json.ts
+++ b/packages/kbn-bazel-packages/src/parse_package_json.js
@@ -6,40 +6,22 @@
* Side Public License, v 1.
*/
-import Fs from 'fs';
+const Fs = require('fs');
/**
- * Simple parsed representation of a package.json file, validated
- * by `assertParsedPackageJson()` and extensible as needed in the future
+ * @param {unknown} v
+ * @returns {v is Record}
*/
-export interface ParsedPackageJson {
- /** The name of the package, usually `@kbn/`+something */
- name: string;
- /** "dependenices" property from package.json */
- dependencies?: Record;
- /** "devDependenices" property from package.json */
- devDependencies?: Record;
- /** Some kibana specific properties about this package */
- kibana?: {
- /** Is this package only intended for dev? */
- devOnly?: boolean;
- };
- /** Scripts defined in the package.json file */
- scripts?: {
- [key: string]: string | undefined;
- };
- /** All other fields in the package.json are typed as unknown as we don't care what they are */
- [key: string]: unknown;
-}
-
-function isObj(v: unknown): v is Record {
+function isObj(v) {
return !!(typeof v === 'object' && v);
}
/**
* Asserts that given value looks like a parsed package.json file
+ * @param {unknown} v
+ * @returns {asserts v is import('./types').ParsedPackageJson}
*/
-export function assertParsedPackageJson(v: unknown): asserts v is ParsedPackageJson {
+function validateParsedPackageJson(v) {
if (!isObj(v) || typeof v.name !== 'string') {
throw new Error('Expected at least a "name" property');
}
@@ -66,14 +48,18 @@ export function assertParsedPackageJson(v: unknown): asserts v is ParsedPackageJ
/**
* Reads a given package.json file from disk and parses it
+ * @param {string} path
+ * @returns {import('./types').ParsedPackageJson}
*/
-export function readPackageJson(path: string): ParsedPackageJson {
+function readPackageJson(path) {
let pkg;
try {
pkg = JSON.parse(Fs.readFileSync(path, 'utf8'));
- assertParsedPackageJson(pkg);
+ validateParsedPackageJson(pkg);
} catch (error) {
throw new Error(`unable to parse package.json at [${path}]: ${error.message}`);
}
return pkg;
}
+
+module.exports = { readPackageJson, validateParsedPackageJson };
diff --git a/packages/kbn-bazel-packages/src/types.ts b/packages/kbn-bazel-packages/src/types.ts
new file mode 100644
index 000000000000000..dc77d35bc206af9
--- /dev/null
+++ b/packages/kbn-bazel-packages/src/types.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+/**
+ * Simple parsed representation of a package.json file, validated
+ * by `assertParsedPackageJson()` and extensible as needed in the future
+ */
+export interface ParsedPackageJson {
+ /** The name of the package, usually `@kbn/`+something */
+ name: string;
+ /** "dependenices" property from package.json */
+ dependencies?: Record;
+ /** "devDependenices" property from package.json */
+ devDependencies?: Record;
+ /** Some kibana specific properties about this package */
+ kibana?: {
+ /** Is this package only intended for dev? */
+ devOnly?: boolean;
+ };
+ /** Scripts defined in the package.json file */
+ scripts?: {
+ [key: string]: string | undefined;
+ };
+ /** All other fields in the package.json are typed as unknown as we don't care what they are */
+ [key: string]: unknown;
+}
diff --git a/packages/kbn-bazel-packages/tsconfig.json b/packages/kbn-bazel-packages/tsconfig.json
index 789c6b3111115dd..9f78bc243ac66cb 100644
--- a/packages/kbn-bazel-packages/tsconfig.json
+++ b/packages/kbn-bazel-packages/tsconfig.json
@@ -4,6 +4,8 @@
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
+ "allowJs": true,
+ "checkJs": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
diff --git a/packages/kbn-generate/src/commands/package_command.ts b/packages/kbn-generate/src/commands/package_command.ts
index 4f5d58184aeac73..32d5ff008c79f48 100644
--- a/packages/kbn-generate/src/commands/package_command.ts
+++ b/packages/kbn-generate/src/commands/package_command.ts
@@ -162,7 +162,7 @@ ${BAZEL_PACKAGE_DIRS.map((dir) => ` ./${dir}/*\n`).join
Path.resolve(TEMPLATE_DIR, 'packages_BUILD.bazel.ejs'),
Path.resolve(REPO_ROOT, 'packages/BUILD.bazel'),
{
- packages: await discoverBazelPackages(),
+ packages: await discoverBazelPackages(REPO_ROOT),
}
);
log.info('Updated packages/BUILD.bazel');
diff --git a/packages/kbn-generate/src/commands/packages_build_manifest_command.ts b/packages/kbn-generate/src/commands/packages_build_manifest_command.ts
index 9103d56d42a1dbf..9b05c1aed332de4 100644
--- a/packages/kbn-generate/src/commands/packages_build_manifest_command.ts
+++ b/packages/kbn-generate/src/commands/packages_build_manifest_command.ts
@@ -31,7 +31,7 @@ export const PackagesBuildManifestCommand: GenerateCommand = {
async run({ log, render, flags }) {
const validate = !!flags.validate;
- const packages = await discoverBazelPackages();
+ const packages = await discoverBazelPackages(REPO_ROOT);
const dest = Path.resolve(REPO_ROOT, 'packages/BUILD.bazel');
const relDest = Path.relative(process.cwd(), dest);
diff --git a/src/dev/build/tasks/build_packages_task.ts b/src/dev/build/tasks/build_packages_task.ts
index 607e0ac0f08bafd..521b1299f423d0d 100644
--- a/src/dev/build/tasks/build_packages_task.ts
+++ b/src/dev/build/tasks/build_packages_task.ts
@@ -8,6 +8,7 @@
import Path from 'path';
+import { REPO_ROOT } from '@kbn/utils';
import { discoverBazelPackages } from '@kbn/bazel-packages';
import { runBazel } from '@kbn/bazel-runner';
@@ -16,7 +17,7 @@ import { Task, scanCopy, write } from '../lib';
export const BuildBazelPackages: Task = {
description: 'Building distributable versions of Bazel packages',
async run(config, log, build) {
- const packages = (await discoverBazelPackages()).filter((pkg) => !pkg.isDevOnly());
+ const packages = (await discoverBazelPackages(REPO_ROOT)).filter((pkg) => !pkg.isDevOnly());
log.info(`Preparing Bazel projects production build non-devOnly packages`);
await runBazel(['build', '//packages:build']);
diff --git a/src/dev/build/tasks/clean_tasks.ts b/src/dev/build/tasks/clean_tasks.ts
index 15b20e712334c40..409f6a77b50bfca 100644
--- a/src/dev/build/tasks/clean_tasks.ts
+++ b/src/dev/build/tasks/clean_tasks.ts
@@ -8,6 +8,7 @@
import minimatch from 'minimatch';
import { discoverBazelPackages } from '@kbn/bazel-packages';
+import { REPO_ROOT } from '@kbn/utils';
import { deleteAll, deleteEmptyFolders, scanDelete, Task, GlobalTask } from '../lib';
export const Clean: GlobalTask = {
@@ -259,7 +260,7 @@ export const DeleteBazelPackagesFromBuildRoot: Task = {
'Deleting bazel packages outputs from build folder root as they are now installed as node_modules',
async run(config, log, build) {
- const bazelPackagesOnBuildRoot = (await discoverBazelPackages()).map((pkg) =>
+ const bazelPackagesOnBuildRoot = (await discoverBazelPackages(REPO_ROOT)).map((pkg) =>
build.resolvePath(pkg.normalizedRepoRelativeDir)
);
From d4fad94368b504928103aa5a3f78ea2c4e25f817 Mon Sep 17 00:00:00 2001
From: James Garside
Date: Tue, 23 Aug 2022 22:47:46 +0100
Subject: [PATCH 12/18] Updated for Human readable Dataview names (#139308)
* Updated for Human readable dataview names
* Update docs/maps/asset-tracking-tutorial.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
* Update docs/maps/asset-tracking-tutorial.asciidoc
* Update docs/maps/asset-tracking-tutorial.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
---
docs/maps/asset-tracking-tutorial.asciidoc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/maps/asset-tracking-tutorial.asciidoc b/docs/maps/asset-tracking-tutorial.asciidoc
index 85629e0e611f6c2..4e6efff35b3a35f 100644
--- a/docs/maps/asset-tracking-tutorial.asciidoc
+++ b/docs/maps/asset-tracking-tutorial.asciidoc
@@ -318,9 +318,9 @@ cloud.auth:
. In {kib}, open the main menu, and click *Stack Management > Data Views*.
. Click *Create data view*.
. Give the data view a name: *tri_met_tracks**.
-. Click *Next step*.
-. Set the *Time field* to *trimet.time*.
-. Click *Create data view*.
+. Set the index pattern as: *tri_met_tracks**.
+. Set the *Timestamp field* to *trimet.time*.
+. Click *Save data view to Kibana*.
{kib} shows the fields in your data view.
From 368eba6ee9d3e8620c262386a5b51a2b34651571 Mon Sep 17 00:00:00 2001
From: Nicolas Chaulet
Date: Tue, 23 Aug 2022 18:19:11 -0400
Subject: [PATCH 13/18] [Fleet] Remove field package_policies from agent policy
(#138677)
---
.../server/deprecations/deprecations.test.ts | 2 +-
.../server/lib/fleet_util.ts | 5 +-
.../server/routes/benchmarks/benchmarks.ts | 11 +-
x-pack/plugins/fleet/common/index.ts | 2 +
.../fleet/common/services/limited_package.ts | 6 +-
.../plugins/fleet/common/services/routes.ts | 4 +
.../fleet/common/types/models/agent_policy.ts | 2 +-
.../fleet/cypress/downloads/downloads.html | Bin 0 -> 4956 bytes
x-pack/plugins/fleet/cypress/tasks/fleet.ts | 6 +
.../components/package_policies/index.tsx | 6 +-
.../sections/agent_policy/list_page/index.tsx | 1 +
.../sections/agents/agent_list_page/index.tsx | 15 +-
.../epm/screens/detail/index.test.tsx | 8 +-
.../use_package_policies_with_agent_policy.ts | 35 ++---
.../hooks/use_package_installations.tsx | 4 +-
.../fleet/public/services/has_fleet_server.ts | 9 +-
.../reset_preconfiguration.test.ts | 5 +-
x-pack/plugins/fleet/server/mocks/index.ts | 1 +
.../server/routes/agent_policy/handlers.ts | 1 +
.../fleet/server/saved_objects/index.ts | 3 +-
.../saved_objects/migrations/to_v7_10_0.ts | 9 +-
.../saved_objects/migrations/to_v8_5_0.ts | 22 +++
...kage_policies_to_agent_permissions.test.ts | 6 +-
.../package_policies_to_agent_permissions.ts | 12 +-
.../server/services/agent_policy.test.ts | 11 +-
.../fleet/server/services/agent_policy.ts | 92 ++----------
.../fleet/server/services/package_policy.ts | 102 +++++++++----
.../server/services/preconfiguration.test.ts | 11 +-
.../fleet_agent_policy_generator.ts | 1 -
.../common/endpoint/generate_data.ts | 1 -
.../public/management/mocks/fleet_mocks.ts | 141 +++++++++++++++++-
.../management/pages/endpoint_hosts/mocks.ts | 6 +
.../endpoint_hosts/store/middleware.test.ts | 1 +
.../pages/endpoint_hosts/store/middleware.ts | 20 +--
.../store/mock_endpoint_result_list.ts | 22 ++-
.../pages/endpoint_hosts/view/index.test.tsx | 2 +
.../pages/policy/view/policy_list.test.tsx | 20 +--
.../pages/policy/view/policy_list.tsx | 24 +--
.../management/services/policies/hooks.ts | 16 +-
.../management/services/policies/ingest.ts | 41 +++++
.../metadata/endpoint_metadata_service.ts | 9 +-
41 files changed, 445 insertions(+), 250 deletions(-)
create mode 100644 x-pack/plugins/fleet/cypress/downloads/downloads.html
create mode 100644 x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_5_0.ts
diff --git a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
index b57628a3f326b74..1843affb9bfc327 100644
--- a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
+++ b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
@@ -54,7 +54,7 @@ describe('getDeprecations', () => {
get: () =>
({
id: 'foo',
- package_policies: [''],
+ package_policies: [{ package: { name: 'system' } }],
} as AgentPolicy),
},
}),
diff --git a/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts b/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts
index 42e11f08d9d80e7..9ef90e4175a6c02 100644
--- a/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts
+++ b/x-pack/plugins/cloud_security_posture/server/lib/fleet_util.ts
@@ -58,7 +58,10 @@ export const getCspAgentPolicies = async (
packagePolicies: PackagePolicy[],
agentPolicyService: AgentPolicyServiceInterface
): Promise =>
- agentPolicyService.getByIds(soClient, uniq(map(packagePolicies, 'policy_id')));
+ agentPolicyService.getByIds(soClient, uniq(map(packagePolicies, 'policy_id')), {
+ withPackagePolicies: true,
+ ignoreMissing: true,
+ });
export const getCspPackagePolicies = (
soClient: SavedObjectsClientContract,
diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts
index 8ffeb38b6b57619..4bc00f5e0209d39 100644
--- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts
+++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts
@@ -111,11 +111,12 @@ const createBenchmarks = (
);
return Promise.all(
agentPolicies.flatMap((agentPolicy) => {
- const cspPackagesOnAgent = agentPolicy.package_policies
- .map((pckPolicyId) => {
- if (typeof pckPolicyId === 'string') return cspPackagePoliciesMap.get(pckPolicyId);
- })
- .filter(isNonNullable);
+ const cspPackagesOnAgent =
+ agentPolicy.package_policies
+ ?.map(({ id: pckPolicyId }) => {
+ return cspPackagePoliciesMap.get(pckPolicyId);
+ })
+ .filter(isNonNullable) ?? [];
const benchmarks = cspPackagesOnAgent.map(async (cspPackage) => {
const cspRulesStatus = await addPackagePolicyCspRules(soClient, cspPackage);
const agentPolicyStatus = {
diff --git a/x-pack/plugins/fleet/common/index.ts b/x-pack/plugins/fleet/common/index.ts
index ced5c17f55f6ffe..d514d5b56469018 100644
--- a/x-pack/plugins/fleet/common/index.ts
+++ b/x-pack/plugins/fleet/common/index.ts
@@ -101,6 +101,8 @@ export type {
UpgradePackagePolicyResponseItem,
UpgradePackagePolicyBaseResponse,
UpgradePackagePolicyDryRunResponseItem,
+ BulkGetPackagePoliciesResponse,
+ BulkGetAgentPoliciesResponse,
// Models
Agent,
AgentStatus,
diff --git a/x-pack/plugins/fleet/common/services/limited_package.ts b/x-pack/plugins/fleet/common/services/limited_package.ts
index 601f680c8bf0390..e4e9dd090941d7b 100644
--- a/x-pack/plugins/fleet/common/services/limited_package.ts
+++ b/x-pack/plugins/fleet/common/services/limited_package.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import type { PackageInfo, AgentPolicy, PackagePolicy } from '../types';
+import type { PackageInfo, AgentPolicy } from '../types';
export const isPackageLimited = (packageInfo: PackageInfo): boolean => {
return (packageInfo.policy_templates || []).some(
@@ -17,10 +17,10 @@ export const doesAgentPolicyAlreadyIncludePackage = (
agentPolicy: AgentPolicy,
packageName: string
): boolean => {
- if (agentPolicy.package_policies.length && typeof agentPolicy.package_policies[0] === 'string') {
+ if (!agentPolicy.package_policies) {
throw new Error('Unable to read full package policy information');
}
- return (agentPolicy.package_policies as PackagePolicy[])
+ return agentPolicy.package_policies
.map((packagePolicy) => packagePolicy.package?.name || '')
.includes(packageName);
};
diff --git a/x-pack/plugins/fleet/common/services/routes.ts b/x-pack/plugins/fleet/common/services/routes.ts
index 95551ddeea7c0f3..323d7d1f8b3786a 100644
--- a/x-pack/plugins/fleet/common/services/routes.ts
+++ b/x-pack/plugins/fleet/common/services/routes.ts
@@ -118,6 +118,10 @@ export const agentPolicyRouteService = {
return AGENT_POLICY_API_ROUTES.LIST_PATTERN;
},
+ getBulkGetPath: () => {
+ return AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN;
+ },
+
getInfoPath: (agentPolicyId: string) => {
return AGENT_POLICY_API_ROUTES.INFO_PATTERN.replace('{agentPolicyId}', agentPolicyId);
},
diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts
index 44e6b35c02eec59..ea22f73a2e5f973 100644
--- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts
+++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts
@@ -35,7 +35,7 @@ export interface NewAgentPolicy {
export interface AgentPolicy extends Omit {
id: string;
status: ValueOf;
- package_policies: string[] | PackagePolicy[];
+ package_policies?: PackagePolicy[];
is_managed: boolean; // required for created policy
updated_at: string;
updated_by: string;
diff --git a/x-pack/plugins/fleet/cypress/downloads/downloads.html b/x-pack/plugins/fleet/cypress/downloads/downloads.html
new file mode 100644
index 0000000000000000000000000000000000000000..772778ea352e58515ffdccdd56b8f8f73a6b15c5
GIT binary patch
literal 4956
zcmZ{ncQhPMzs9kwzDkrJiQapnu1*M1qeSnW6+~}~RfAQcBw1mJAX-Fp37h=1=!>W;
zNc6BaYOuT9yM(MZ&s%afTO$e&Q>A@ijShd
z!f<=H?XlS^EC~H%_Q5KP?7oFJ(xb$KM{a_)k#cl8Lq0Hgbc
z+Zx;#mn@L8Pm|}|<`ut5W2@lbOZ^z$aO==d`SDT;3UjxG3{h~5*?-_$qshD%g{L`E
zgNRDytK~u*3Yy7t<+jTTCm!$$c&@AcTsqTvBKtwm~LtS*NB_G12xX!3_Z7eXe5?^nGxg`>0pGscpEhhY%)h7Bb5vvJ&y=OT`xk*kJ`~^+j?YYwhyef@fZ7LbVsW2)|)5e!~k9j
zDW^n!uTfz=KE@u_XEz|BUo#o=fa(R0x!`kXy7H~y#S%Q5{Z
z9=k8Ze#o+GkLZ1<@Ksb|;I4^9KR;SRf&K1=vX!wla0{YNALQC(eQzC}=EN~#BvC)4
zz4?{2hA*hcHi^2gBOzb)qy))81|TINWlkW6w`$H^$dhH)KXt4$r2lU8)8Rzh2IafJ
zM!7A@V;<=`xN!LM{RZvu3k=ZfFe!v@n2|N1I
z)!eug$neEAjs)%PHN!AB+|R5Ge0rf$Bky;oFxTvy=*rb}`SB6as(tkqI;UpOoB42W
z6?(tSU&@uc3`MG2@rZXG#Fg#+r>$)REabBw*5WLZHyr+1dR$Y+{vXyK^x|YV-F^$q
zg{?EkD5Ur&%js{76HS~p$$CYsL>x>b5)ooL@Qg55wi{=oPD9u0_7WLMO*yrZTSyG^
zqOX3#1teuVm#l`{{DHdCu|{WfX5&HfqgeEigz>_1#Fw9mA?Pmdn&Gy}5$uOC3yL8+ya}&s;u`7BaVszCU7gT130CE-*Dk>@x
zO&KbyKR?TVi~f%b2=wrTNcukV3X}?RTU%wBKMU_I-T>auG9ocEq@-d19xZ_WT%-Fl
z|No%B)qe#^g?d4JLp@uI;~|z-Y=eR21!SysmJ(C_e;zpbqIP0NN?S_`tn#aQUfAT0
z3nf^lWGB38UOri_O4b-+bj2ez#5@g2_s!Z>NPYgc>%KzYF+-6ho9$AAlv@KU(*yCZ
z=3u-Uu5_*wH)wf1)j+)@sxe~xd^u!a4cEh+FO>Yo&bduh_jRURo|yUF_xk_z+-1s{
zAj1o2nK4S=rTAjQ+vmaSoUaM`^k|ZuCS~~iNW!e8GS=Q;V-{{dTvBXUOOr`kN8_q!
z&|H#!75H#*HY#>JRnHl1u@$}_qDZa^Mb5*BYC)lNp-EC`YVapsG{{ctjt|*M8JlH-
z>MDt-0Eg*k9LcALyCssg{Rl8cUl9{q^aAjU6D?d?_CYJVI!{i1g|wRdB&
z8ntMWtc_jeQ6dK=fr7|GVTxMpN;F-c@vGOBK+&J5(X=K>&1DQP0Yn!@2l8j18LtB?
zGzr(DHTm?(hIlAm!{l;7w-W#oKwBQlb(rcZS01taa=)`n;%X#k#s28kd))N$g?v26
z8D`Nsio3~kKPIYC90UJQMIhev#E)`&Z^XZbI7dd|(!2`-R=C8EC=0Oos|(9ZR!_{q
zP(2~p|2vjHe(~r##1r2u{BTp+vdy$GaKgC;!rxzhGJHxxl2Ol@A
zp!eX?Fg1YJshcg^Al(^nnyNikM$rOOK!ZRqomH7_l6#uMk=K?CLV6(Xp3!+LY09@k
z=OktZY%?}JHzQBVWtH-OTVRJuQqSo=PQR`KKO4NaVxt{G@d~UZ`Q?5AUrd#oQ-WVE
zMXGFijHb#PAV@});)uEhARUz8dR>Da1d#qh_N0vaWGxO2%+NaYur&mCLd~#2Mo&Lu
zH=^GGJQAi=O?PX!Z%i-rUa!90GQF*4wX616HbWMEW?^(|OSyx(o}nH2wjBkK=#~m8
zZ|A4x(h`m2C6v7K$QGPAdFiwO<;PUFHKt+4(U@_PnWeUZfIyOn#Qf_F1`d=}%_Z~@
zjhhlA94@?Y?{`!ZLft&}U)K6Lf3mj{J(nV0?HBKzGzI$U2!13VT{~!(B$RYsL{#OK
z=4?dVw~?Mv;|!5b!8A^;-P7q;WXnc6@n?28-%%dGWvAl7g{`c?80}n!+29q*f;Q@<
z@SFa&BiL$ZhV~c#1kjv!C%9D-G@KS1F=bZ)TpYLwv2G2P3P*Q2=-t>GyBTY^dak@M
zq;?}_TtyJyT@+x^g98TU%y0FMVCUX7s{Y~{AN-Uarw%?-iP~F}9jBaWmK&$+t`1TE
z>i)F!*`N}r&N!;(M)Rhpe0yb78?);00a(UsY^0*zm!kdZ=()UfC!vRi;693YW|cvI
zu~Hd?dbmSGs4h3wAOh7i#20{ZzX|gG(2Gk!JPHs|dj6`0>Jrltr+}}n{OoXQ`tzhqy~MrJZ|KKwql|KR
zkycyD(29YFCujtKSg;OnY08V<<84R7)eL
zaSEsYokSgoMkzM_*5^y!N2pw^29;McF<;>{rh}LSiNB3;=6c_*F^av@fd#DIYD39+
zwBpX%Ay*_AWZ$WCrc1m^yYr{ht)r_im*NVi_MOC7rd!hy{>K0KBRGZ;1AC2WDCGF%
zKKtQI{qd3)b}BQef>+)fzj5AIFyiiRy1+7fb>Fkc`fJGpeDDZ_h1{SobgHS0j*d4m
zpp1l$SNUcci-X=OL!xRBr&a)fqKuZ*5YRx?CjxHfR{BIuB@Pe{B9Z>Htcn1?iI~~0
zQqkygDrFfUXh3ea1z|#T7g}_qV(28&0$On1wk0~NjE+yAbyWmh3`8_3aop7$)?^3C
z?UYfFa{WWvOMAhXZjOe7suFm>m^2giBq{Pwq#%<*(t{}k6X`HX0M#rbtPOC?mk^b|
z9_8ZnQdQ&Vv8wo0#m)G&uSZ@P?xceyhX%NB$W(2)+3s6N%uKHBZupGHtYU}1>I6mb
zBG)JHE0Z~soVjbq9f0BIuYN~BV$HHMjn${n3z>#=2N&Vj_k~>$Mi?|dUoG!jI0V($YXo7Q1&)K`;TVmZ+mbss~wRE>`BePf&@2xj#`1m*Rno@hNkx
zOB;c2#1B5B2Gb-uV3)w8dPqfS@WDn6uhvsp@4NQGDdeYZ@eJLK}bBf
zysZ~)&L%DiMPh7st4Hh+NG09r4_mLREOoDq-9hYc#^~MG?M97mbSzWrdOS>Qx
zH=L8@ch1G!j8B$Q;4erLqRl%Vw
zUExboj*Ib2MRun@qUw6IYoxVi?qTaL*=f{5J{%X~lLS$Lp;0Na)r}`NT*=
zB3@*Ln=Z8!(eG=%Yx=AfJS4Ym8@F7WHlA5$?A{HCR_N1bC^QN)iVs@0liry(I+vX@
zq+C?L#eXxpQ*LfJv9aELQ}))KP1P`Dj$^4&aqI2&V>{c7gUisY+$25*Y_mzqwB}%?A%+Qo;>&W*s?zCv5{yI6`W!$&IimQT41}0wSwL}oRYdu
zIT-f(LrTZx3}C!toQ%vQ;&7+2!EU?DvejTj)<^V7N)ey6CQ@Z>caL_KAhAXG`aHA%
zdebRpS*tgilcDP^o7~QJN;bCrb?-N`EoyZ4G?ne`0iP+whmH#h?p5J32zNqq
zS4&on9h+0jW@ezYU#s2B9Xd7BfrmNZhO90r8}|a={0|C!hwX|DH9;$nM8)fU)*c~I
zpB;B-x`Z8)VqGdS-$o$Z3lqaJZuR2k^tFW9THhze^RYd_%X#%=){@P;x}ATkVj{YdVComeXNr}?@;~l
zhbFGDSMTa*KAvDYnKj{z+T=I7G<`vsZe|F*#2i}4xvyG}R~xw}l&)FCRR>@8o5>A+
z;8J&%*<5+;Dm9T-RDQi-gYSmbXxNV(riyI55}Sd>;P!l=b3Z+&x}xv%-X@n{KJ_w(Gj76brN%n2M(W;m
zQoWTe;~t#r3T5N+)S{T%CcS^%uHK61o=TL`=^+16)K=B*fPc{OOEUR#{|W3bl)&DV
zHBQ;P3!zGS9@hjJofnRVCcfo3>D|;}y0{x*U1AR5X(L{9I-`*ehqZd_`f2
zODm_eT4lX0yxVuM)o1_1x7F5&h7RRcdq8v_TWbApv9r#SGdiXoYuUbu0{5pSt(p*&fui@oCTT&~Xe)!b7%=Fn1pf=RAp?B9GPTQ^oCR2(o@IsW7!OYJy7
zLE)N_!o=rI)tKVpU~Suqh56UsAK$YSEBoA0gc-lRT03P+u0L&A5fM4Ha|tZ+Gkvmp
zb`r>?l5ZStk~P%ip+-YH(qV~3H~BWX38x@;npIxa9?bc}(q*KqxPyfnj8~6dL`TyX5$
zeB^Gl&fyF0kN0=l9g8=%#*)rHYD1k8H{#Q`uq^^u4&CyTgxLCL__-_Yzu34MKPf@{
zgO?r(f3cC2j0NyN1p1#y`IkWdEm9Hz(!cJ1@#z0;{m(({ agentPolicy }) => {
useBreadcrumbs('policy_details', { policyName: agentPolicy.name });
- if (agentPolicy.package_policies.length === 0) {
+ if (!agentPolicy.package_policies || agentPolicy.package_policies.length === 0) {
return ;
}
return (
);
});
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx
index ba6b7f4ad31c4ba..9b0d9051a32ed80 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/list_page/index.tsx
@@ -89,6 +89,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => {
sortField: sorting?.field,
sortOrder: sorting?.direction,
kuery: search,
+ full: true,
});
// Some policies retrieved, set up table props
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx
index a9e3429732b3cd8..6bf9506d6ba28b9 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx
@@ -19,7 +19,7 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedRelative } from '@kbn/i18n-react';
-import type { Agent, AgentPolicy, PackagePolicy, SimplifiedAgentStatus } from '../../../types';
+import type { Agent, AgentPolicy, SimplifiedAgentStatus } from '../../../types';
import {
usePagination,
useAuthz,
@@ -35,8 +35,12 @@ import {
sendGetAgentTags,
} from '../../../hooks';
import { AgentEnrollmentFlyout, AgentPolicySummaryLine } from '../../../components';
-import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services';
-import { AGENTS_PREFIX, FLEET_SERVER_PACKAGE, SO_SEARCH_LIMIT } from '../../../constants';
+import {
+ AgentStatusKueryHelper,
+ isAgentUpgradeable,
+ policyHasFleetServer,
+} from '../../../services';
+import { AGENTS_PREFIX, SO_SEARCH_LIMIT } from '../../../constants';
import {
AgentReassignAgentPolicyModal,
AgentHealth,
@@ -389,10 +393,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
return false;
}
- return agentPolicy.package_policies.some(
- (ap: string | PackagePolicy) =>
- typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE
- );
+ return policyHasFleetServer(agentPolicy);
}, [agentToUnenroll, agentPoliciesIndexedById]);
// Fleet server unhealthy status
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx
index a77c45a6b5110a8..693dee99ebf69ae 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx
@@ -717,11 +717,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos
namespace: 'default',
description: 'Default agent policy created by Kibana',
status: 'active',
- package_policies: [
- '4d09bd78-b0ad-4238-9fa3-d87d3c887c73',
- '2babac18-eb8e-4ce4-b53b-4b7c5f507019',
- 'e8a37031-2907-44f6-89d2-98bd493f60dc',
- ],
+ package_policies: [],
is_managed: false,
monitoring_enabled: ['logs', 'metrics'],
revision: 6,
@@ -735,7 +731,7 @@ On Windows, the module was tested with Nginx installed from the Chocolatey repos
namespace: 'default',
description: 'Protect EU from COVID',
status: 'active',
- package_policies: ['e8a37031-2907-44f6-89d2-98bd493f60cd'],
+ package_policies: [],
is_managed: false,
monitoring_enabled: ['logs', 'metrics'],
revision: 2,
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts
index 4f6f456bf82cdfd..399016ebf204269 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/policies/use_package_policies_with_agent_policy.ts
@@ -14,7 +14,6 @@ import type {
GetPackagePoliciesResponse,
} from '../../../../../types';
import { agentPolicyRouteService } from '../../../../../services';
-import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '../../../../../constants';
import { useGetPackagePolicies, useConditionalRequest } from '../../../../../hooks';
import type { SendConditionalRequestConfig } from '../../../../../hooks';
@@ -52,37 +51,31 @@ export const usePackagePoliciesWithAgentPolicy = (
resendRequest,
} = useGetPackagePolicies(query);
- const agentPoliciesFilter = useMemo(() => {
+ const agentPoliciesIds = useMemo(() => {
if (!packagePoliciesData?.items.length) {
- return '';
+ return [];
}
// Build a list of package_policies for which we need Agent Policies for. Since some package
// policies can exist within the same Agent Policy, we don't need to (in some cases) include
// the entire list of package_policy ids.
- const includedAgentPolicies = new Set();
-
- return `${AGENT_POLICY_SAVED_OBJECT_TYPE}.package_policies: (${packagePoliciesData.items
- .filter((packagePolicy) => {
- if (includedAgentPolicies.has(packagePolicy.policy_id)) {
- return false;
- }
- includedAgentPolicies.add(packagePolicy.policy_id);
- return true;
- })
- .map((packagePolicy) => packagePolicy.id)
- .join(' or ')}) `;
+ return Array.from(
+ new Set(
+ packagePoliciesData.items.map((packagePolicy) => packagePolicy.policy_id)
+ ).values()
+ );
}, [packagePoliciesData]);
const { data: agentPoliciesData, isLoading: isLoadingAgentPolicies } =
useConditionalRequest({
- path: agentPolicyRouteService.getListPath(),
- method: 'get',
- query: {
- perPage: 100,
- kuery: agentPoliciesFilter,
+ path: agentPolicyRouteService.getBulkGetPath(),
+ method: 'post',
+ body: {
+ ids: agentPoliciesIds,
+ full: true,
+ ignoreMissing: true,
},
- shouldSendRequest: !!packagePoliciesData?.items.length,
+ shouldSendRequest: agentPoliciesIds.length > 0,
} as SendConditionalRequestConfig);
const [enrichedData, setEnrichedData] = useState();
diff --git a/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx b/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx
index 4789770b7046f38..5a0b6285c71db1a 100644
--- a/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx
+++ b/x-pack/plugins/fleet/public/hooks/use_package_installations.tsx
@@ -52,8 +52,8 @@ export const usePackageInstallations = () => {
const updatableIntegrations = useMemo