diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index 5e05b4276209d..4a2f50f9e3a29 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -225,7 +225,6 @@ enabled: - x-pack/test/dataset_quality_api_integration/basic/config.ts - x-pack/test/detection_engine_api_integration/basic/config.ts - x-pack/test/detection_engine_api_integration/security_and_spaces/group1/config.ts - - x-pack/test/detection_engine_api_integration/security_and_spaces/group4/config.ts - x-pack/test/detection_engine_api_integration/security_and_spaces/group10/config.ts - x-pack/test/disable_ems/config.ts - x-pack/test/encrypted_saved_objects_api_integration/config.ts @@ -477,3 +476,5 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/user_roles/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/user_roles/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/ess.config.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3900fc90d9bca..a17c788699938 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1410,7 +1410,7 @@ x-pack/test/security_solution_api_integration/test_suites/detections_response/de /x-pack/plugins/security_solution/server/routes @elastic/security-detections-response @elastic/security-threat-hunting /x-pack/plugins/security_solution/server/utils @elastic/security-detections-response @elastic/security-threat-hunting x-pack/test/security_solution_api_integration/test_suites/detections_response/utils @elastic/security-detections-response - +x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry @elastic/security-detections-response ## Security Solution sub teams - security-defend-workflows /x-pack/plugins/security_solution/public/management/ @elastic/security-defend-workflows diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/index.ts deleted file mode 100644 index 9394e81017aba..0000000000000 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/index.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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FtrProviderContext } from '../../common/ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default ({ loadTestFile }: FtrProviderContext): void => { - describe('detection engine api security and spaces enabled - Group 4', function () { - loadTestFile(require.resolve('./telemetry')); - }); -}; diff --git a/x-pack/test/detection_engine_api_integration/utils/create_new_action.ts b/x-pack/test/detection_engine_api_integration/utils/create_new_action.ts deleted file mode 100644 index d5093d8d5d39b..0000000000000 --- a/x-pack/test/detection_engine_api_integration/utils/create_new_action.ts +++ /dev/null @@ -1,34 +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 type { ToolingLog } from '@kbn/tooling-log'; -import type SuperTest from 'supertest'; - -import { getWebHookAction } from './get_web_hook_action'; - -/** - * Helper to cut down on the noise in some of the tests. This - * creates a new action and expects a 200 and does not do any retries. - * @param supertest The supertest deps - */ -export const createNewAction = async ( - supertest: SuperTest.SuperTest, - log: ToolingLog -) => { - const response = await supertest - .post('/api/actions/action') - .set('kbn-xsrf', 'true') - .send(getWebHookAction()); - if (response.status !== 200) { - log.error( - `Did not get an expected 200 "ok" when creating a new action. CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify( - response.body - )}, status: ${JSON.stringify(response.status)}` - ); - } - return response.body; -}; diff --git a/x-pack/test/detection_engine_api_integration/utils/index.ts b/x-pack/test/detection_engine_api_integration/utils/index.ts index 770906789f328..a1373f03a1817 100644 --- a/x-pack/test/detection_engine_api_integration/utils/index.ts +++ b/x-pack/test/detection_engine_api_integration/utils/index.ts @@ -13,7 +13,6 @@ export * from './create_container_with_entries'; export * from './create_exception_list'; export * from './create_exception_list_item'; export * from './create_legacy_rule_action'; -export * from './create_new_action'; export * from './create_rule'; export * from './create_rule_with_exception_entries'; export * from './create_rule_saved_object'; @@ -25,12 +24,10 @@ export * from './delete_all_alerts'; export * from './delete_all_timelines'; export * from './delete_exception_list'; export * from './delete_rule'; -export * from './downgrade_immutable_rule'; export * from './finalize_signals_migration'; export * from './find_immutable_rule_by_id'; export * from './get_complex_rule'; export * from './get_complex_rule_output'; -export * from './get_detection_metrics_from_body'; export * from './get_eql_rule_for_signal_testing'; export * from './get_event_log_execute_complete_by_id'; export * from './get_legacy_action_notification_so'; @@ -47,7 +44,6 @@ export * from './get_rule_for_signal_testing_with_timestamp_override'; export * from './get_rule_with_web_hook_action'; export * from './get_rule_with_legacy_investigation_fields'; export * from './get_saved_query_rule_for_signal_testing'; -export * from './get_security_telemetry_stats'; export * from './get_signal_status'; export * from './get_signals_by_id'; export * from './get_signals_by_ids'; @@ -62,9 +58,6 @@ export * from './get_simple_rule_output_without_rule_id'; export * from './get_simple_rule_update'; export * from './get_simple_rule_without_rule_id'; export * from './get_simple_saved_query_rule'; -export * from './get_simple_threat_match'; -export * from './get_stats'; -export * from './get_stats_url'; export * from './get_threat_match_rule_for_signal_testing'; export * from './get_threshold_rule_for_signal_testing'; export * from './get_slack_action'; @@ -76,7 +69,6 @@ export * from './preview_rule_with_exception_entries'; export * from './preview_rule'; export * from './refresh_index'; export * from './route_with_namespace'; -export * from './remove_time_fields_from_telemetry_stats'; export * from './remove_server_generated_properties'; export * from './remove_server_generated_properties_including_rule_id'; export * from './resolve_simple_rule_output'; diff --git a/x-pack/test/security_solution_api_integration/package.json b/x-pack/test/security_solution_api_integration/package.json index 0b2fb7c4416c4..50dc47f95b1b3 100644 --- a/x-pack/test/security_solution_api_integration/package.json +++ b/x-pack/test/security_solution_api_integration/package.json @@ -93,6 +93,11 @@ "user_roles:runner:serverless": "npm run run-tests:dr:default user_roles serverless serverlessEnv", "user_roles:qa:serverless": "npm run run-tests:dr:default user_roles serverless qaEnv", "user_roles:server:ess": "npm run initialize-server:dr:default user_roles ess", - "user_roles:runner:ess": "npm run run-tests:dr:default user_roles ess essEnv" + "user_roles:runner:ess": "npm run run-tests:dr:default user_roles ess essEnv", + "telemetry:server:serverless": "npm run initialize-server:dr:default telemetry serverless", + "telemetry:runner:serverless": "npm run run-tests:dr:default telemetry serverless serverlessEnv", + "telemetry:qa:serverless": "npm run run-tests:dr:default telemetry serverless qaEnv", + "telemetry:server:ess": "npm run initialize-server:dr:default telemetry ess", + "telemetry:runner:ess": "npm run run-tests:dr:default telemetry ess essEnv" } } diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/bundled_prebuilt_rules_package/install_latest_bundled_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/bundled_prebuilt_rules_package/install_latest_bundled_prebuilt_rules.ts index bd306b0d65654..556e689514d7f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/bundled_prebuilt_rules_package/install_latest_bundled_prebuilt_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/bundled_prebuilt_rules_package/install_latest_bundled_prebuilt_rules.ts @@ -66,7 +66,7 @@ export default ({ getService }: FtrProviderContext): void => { expect(bundledInstallResponse._meta.install_source).toBe('bundled'); // Refresh ES indices to avoid race conditions between write and reading of indeces - // See implementation utility function at x-pack/test/detection_engine_api_integration/utils/prebuilt_rules/install_prebuilt_rules_fleet_package.ts + // See implementation utility function at x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_prebuilt_rules_fleet_package.ts await es.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES }); // Verify that status is updated after package installation diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/README.md b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/README.md similarity index 100% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/README.md rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/README.md diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/ess.config.ts similarity index 63% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/config.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/ess.config.ts index 2430b8f2148d9..787542036e084 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/ess.config.ts @@ -7,12 +7,16 @@ import { FtrConfigProviderContext } from '@kbn/test'; -// eslint-disable-next-line import/no-default-export export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const functionalConfig = await readConfigFile(require.resolve('../config.base.ts')); + const functionalConfig = await readConfigFile( + require.resolve('../../../../../config/ess/config.base.trial') + ); return { ...functionalConfig.getAll(), - testFiles: [require.resolve('.')], + testFiles: [require.resolve('..')], + junit: { + reportName: 'Detection Engine API Integration Tests - ESS - Telemetry', + }, }; } diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/serverless.config.ts new file mode 100644 index 0000000000000..99bd2458c69a4 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/serverless.config.ts @@ -0,0 +1,18 @@ +/* + * 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 { createTestConfig } from '../../../../../config/serverless/config.base'; + +export default createTestConfig({ + testFiles: [require.resolve('..')], + junit: { + reportName: 'Detection Engine API Integration Tests - Serverless - Telemetry', + }, + kbnTestServerArgs: [ + `--xpack.securitySolution.enableExperimental=${JSON.stringify(['previewTelemetryUrlEnabled'])}`, + ], +}); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/index.ts similarity index 83% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/index.ts index 4e180f73dc742..5fef7869ba7c8 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/index.ts @@ -4,15 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { FtrProviderContext } from '../../../../ftr_provider_context'; -import { FtrProviderContext } from '../../../common/ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export export default ({ loadTestFile }: FtrProviderContext): void => { describe('Detection rule type telemetry', function () { loadTestFile(require.resolve('./usage_collector/all_types')); loadTestFile(require.resolve('./usage_collector/detection_rules')); loadTestFile(require.resolve('./usage_collector/detection_rule_status')); + loadTestFile(require.resolve('./usage_collector/detection_rules_legacy_action')); loadTestFile(require.resolve('./task_based/all_types')); loadTestFile(require.resolve('./task_based/detection_rules')); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/all_types.ts similarity index 82% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/all_types.ts index 576f00b563724..26ac4627a0260 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/all_types.ts @@ -6,17 +6,18 @@ */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../../common/ftr_provider_context'; + import { - createSignalsIndex, + createAlertsIndex, deleteAllRules, deleteAllAlerts, getSecurityTelemetryStats, removeTimeFieldsFromTelemetryStats, -} from '../../../../utils'; -import { deleteAllExceptions } from '../../../../../lists_api_integration/utils'; +} from '../../../utils'; +import { deleteAllExceptions } from '../../../../../../lists_api_integration/utils'; + +import { FtrProviderContext } from '../../../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); @@ -24,7 +25,7 @@ export default ({ getService }: FtrProviderContext) => { const retry = getService('retry'); const es = getService('es'); - describe('All task telemetry types generically', async () => { + describe('@ess @serverless All task telemetry types generically', async () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry'); }); @@ -34,7 +35,7 @@ export default ({ getService }: FtrProviderContext) => { }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { @@ -43,7 +44,7 @@ export default ({ getService }: FtrProviderContext) => { await deleteAllExceptions(supertest, log); }); - it('should only have task metric values when no rules are running', async () => { + it('@skipInQA should only have task metric values when no rules are running', async () => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); removeTimeFieldsFromTelemetryStats(stats); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/detection_rules.ts similarity index 92% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/detection_rules.ts index 684fc752c152e..bed9457c34707 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/detection_rules.ts @@ -10,23 +10,22 @@ import expect from '@kbn/expect'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common'; -import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { createRule, - createSignalsIndex, + createAlertsIndex, deleteAllRules, deleteAllAlerts, - getRule, - getRuleForSignalTesting, + fetchRule, + getRuleForAlertTesting, installMockPrebuiltRules, getSecurityTelemetryStats, createExceptionList, createExceptionListItem, removeTimeFieldsFromTelemetryStats, -} from '../../../../utils'; -import { deleteAllExceptions } from '../../../../../lists_api_integration/utils'; +} from '../../../utils'; +import { deleteAllExceptions } from '../../../../../../lists_api_integration/utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const es = getService('es'); const supertest = getService('supertest'); @@ -34,7 +33,7 @@ export default ({ getService }: FtrProviderContext) => { const log = getService('log'); const retry = getService('retry'); - describe('Detection rule task telemetry', async () => { + describe('@ess @serverless Detection rule task telemetry', async () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry'); }); @@ -44,7 +43,7 @@ export default ({ getService }: FtrProviderContext) => { }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { @@ -54,8 +53,8 @@ export default ({ getService }: FtrProviderContext) => { }); describe('custom rules should never show any detection_rules telemetry data for each list type', () => { - it('should NOT give telemetry/stats for an exception list of type "detection"', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@skipInQA should NOT give telemetry/stats for an exception list of type "detection"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); // create an exception list container of type "detection" const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { @@ -110,8 +109,8 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should NOT give telemetry/stats for an exception list of type "endpoint"', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); // create an exception list container of type "detection" const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { @@ -166,8 +165,8 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should NOT give telemetry/stats for an exception list of type "endpoint_trusted_apps"', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint_trusted_apps"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); // create an exception list container of type "detection" const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { @@ -222,8 +221,8 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should NOT give telemetry/stats for an exception list of type "endpoint_events"', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint_events"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); // create an exception list container of type "detection" const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { @@ -278,8 +277,8 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should NOT give telemetry/stats for an exception list of type "endpoint_host_isolation_exceptions"', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint_host_isolation_exceptions"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); // create an exception list container of type "detection" const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, { @@ -335,7 +334,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - describe('pre-built/immutable/elastic rules should show detection_rules telemetry data for each list type', () => { + describe('@skipInQA pre-built/immutable/elastic rules should show detection_rules telemetry data for each list type', () => { beforeEach(async () => { // install prepackaged rules to get immutable rules for testing await installMockPrebuiltRules(supertest, es); @@ -368,7 +367,9 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule using "PATCH" endpoint - const { exceptions_list } = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const { exceptions_list } = await fetchRule(supertest, { + ruleId: ELASTIC_SECURITY_RULE_ID, + }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') @@ -427,7 +428,7 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') @@ -504,7 +505,7 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') @@ -581,7 +582,7 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') @@ -658,7 +659,7 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') @@ -735,7 +736,7 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') @@ -786,7 +787,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - describe('pre-built/immutable/elastic rules should show detection_rules telemetry data for multiple list items and types', () => { + describe('@skipInQA pre-built/immutable/elastic rules should show detection_rules telemetry data for multiple list items and types', () => { beforeEach(async () => { // install prepackaged rules to get immutable rules for testing await installMockPrebuiltRules(supertest, es); @@ -836,7 +837,7 @@ export default ({ getService }: FtrProviderContext) => { }); // add the exception list to the pre-built/immutable/elastic rule - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); await supertest .patch(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/security_lists.ts similarity index 97% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/security_lists.ts index 50661a537472d..d654cba35902f 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/task_based/security_lists.ts @@ -11,19 +11,18 @@ import { ENDPOINT_LIST_ID, ENDPOINT_TRUSTED_APPS_LIST_ID, } from '@kbn/securitysolution-list-constants'; -import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { - createSignalsIndex, + createAlertsIndex, deleteAllRules, deleteAllAlerts, getSecurityTelemetryStats, createExceptionListItem, createExceptionList, removeTimeFieldsFromTelemetryStats, -} from '../../../../utils'; -import { deleteAllExceptions } from '../../../../../lists_api_integration/utils'; +} from '../../../utils'; +import { deleteAllExceptions } from '../../../../../../lists_api_integration/utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); @@ -32,7 +31,7 @@ export default ({ getService }: FtrProviderContext) => { const es = getService('es'); // Failing: See https://github.com/elastic/kibana/issues/164334 - describe.skip('Security lists task telemetry', async () => { + describe.skip('@ess @serverless Security lists task telemetry', async () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry'); }); @@ -42,7 +41,7 @@ export default ({ getService }: FtrProviderContext) => { }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); // Calling stats endpoint once like this guarantees that the trusted applications and exceptions lists are created for us. await getSecurityTelemetryStats(supertest, log); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/all_types.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/all_types.ts similarity index 80% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/all_types.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/all_types.ts index 503fcc3c1a5da..93e16cefa19ff 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/all_types.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/all_types.ts @@ -7,10 +7,10 @@ import expect from '@kbn/expect'; import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage'; -import type { FtrProviderContext } from '../../../../common/ftr_provider_context'; -import { createSignalsIndex, deleteAllRules, deleteAllAlerts, getStats } from '../../../../utils'; -// eslint-disable-next-line import/no-default-export +import { createAlertsIndex, deleteAllRules, deleteAllAlerts, getStats } from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; + export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); @@ -18,7 +18,7 @@ export default ({ getService }: FtrProviderContext) => { const retry = getService('retry'); const es = getService('es'); - describe('Detection rule telemetry', async () => { + describe('@ess @serverless @skipInQA Detection rule telemetry', async () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry'); }); @@ -28,7 +28,7 @@ export default ({ getService }: FtrProviderContext) => { }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rule_status.ts similarity index 96% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rule_status.ts index 233244ff5a05d..fb21ccdcb166a 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rule_status.ts @@ -22,21 +22,20 @@ import { } from '@kbn/security-solution-plugin/server/usage/detections/rules/get_initial_usage'; import { createRule, - createSignalsIndex, + createAlertsIndex, deleteAllRules, deleteAllAlerts, - getEqlRuleForSignalTesting, - getRuleForSignalTesting, + getEqlRuleForAlertTesting, + getRuleForAlertTesting, getSimpleThreatMatch, getStats, - getThresholdRuleForSignalTesting, + getThresholdRuleForAlertTesting, waitForRuleSuccess, - waitForSignalsToBePresent, + waitForAlertsToBePresent, deleteAllEventLogExecutionEvents, -} from '../../../../utils'; -import type { FtrProviderContext } from '../../../../common/ftr_provider_context'; +} from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); @@ -46,7 +45,7 @@ export default ({ getService }: FtrProviderContext) => { // Note: We don't actually find signals well with ML tests at the moment so there are not tests for ML rule type for telemetry // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/132856 - describe('Detection rule status telemetry', async () => { + describe('@ess @serverless Detection rule status telemetry', async () => { before(async () => { // Just in case other tests do not clean up the event logs, let us clear them now and here only once. await deleteAllEventLogExecutionEvents(es, log); @@ -58,7 +57,7 @@ export default ({ getService }: FtrProviderContext) => { }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { @@ -70,10 +69,10 @@ export default ({ getService }: FtrProviderContext) => { describe('"kql" rule type', () => { let stats: DetectionMetrics | undefined; before(async () => { - const rule = getRuleForSignalTesting(['telemetry']); + const rule = getRuleForAlertTesting(['telemetry']); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); // get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed await retry.try(async () => { stats = await getStats(supertest, log); @@ -120,7 +119,7 @@ export default ({ getService }: FtrProviderContext) => { expect(stats?.detection_rules.detection_rule_usage).to.eql(expectedRuleUsage); }); - it('should have zero values for "detection_rule_status.all_rules" rules that are not query based', () => { + it('@skipInQA should have zero values for "detection_rule_status.all_rules" rules that are not query based', () => { expect(stats?.detection_rules.detection_rule_status.all_rules.eql).to.eql( getInitialSingleEventMetric() ); @@ -172,7 +171,7 @@ export default ({ getService }: FtrProviderContext) => { ); }); - it('should have non zero values for "index_duration"', () => { + it('@skipInQA should have non zero values for "index_duration"', () => { expect( stats?.detection_rules.detection_rule_status.custom_rules.query.index_duration.max ).to.be.above(1); @@ -205,11 +204,11 @@ export default ({ getService }: FtrProviderContext) => { ).to.be.above(1); }); - it('should have non zero values for "succeeded"', () => { + it('@skipInQA should have non zero values for "succeeded"', () => { expect(stats?.detection_rules.detection_rule_status.custom_rules.query.succeeded).to.eql(1); }); - it('should have non zero values for "succeeded", "index_duration", "search_duration" and "enrichment_duration"', () => { + it('@skipInQA should have non zero values for "succeeded", "index_duration", "search_duration" and "enrichment_duration"', () => { expect( stats?.detection_rules.detection_rule_status.custom_rules.query.index_duration.max ).to.be.above(1); @@ -257,10 +256,10 @@ export default ({ getService }: FtrProviderContext) => { describe('"eql" rule type', () => { let stats: DetectionMetrics | undefined; before(async () => { - const rule = getEqlRuleForSignalTesting(['telemetry']); + const rule = getEqlRuleForAlertTesting(['telemetry']); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); // get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed await retry.try(async () => { stats = await getStats(supertest, log); @@ -445,7 +444,7 @@ export default ({ getService }: FtrProviderContext) => { let stats: DetectionMetrics | undefined; before(async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry']), + ...getThresholdRuleForAlertTesting(['telemetry']), threshold: { field: 'keyword', value: 1, @@ -453,7 +452,7 @@ export default ({ getService }: FtrProviderContext) => { }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); // get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed await retry.try(async () => { stats = await getStats(supertest, log); @@ -662,7 +661,7 @@ export default ({ getService }: FtrProviderContext) => { }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); // get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed await retry.try(async () => { stats = await getStats(supertest, log); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rules.ts similarity index 86% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rules.ts index 652d13fd32a53..b81ced41b2511 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rules.ts @@ -14,34 +14,34 @@ import type { import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage'; import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common'; import { RulesTypeUsage } from '@kbn/security-solution-plugin/server/usage/detections/rules/types'; -import type { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { createLegacyRuleAction, - createNewAction, + createWebHookRuleAction, createRule, - createSignalsIndex, + createAlertsIndex, deleteAllRules, deleteAllAlerts, - getEqlRuleForSignalTesting, - getRule, - getRuleForSignalTesting, + getEqlRuleForAlertTesting, + fetchRule, + getRuleForAlertTesting, getRuleWithWebHookAction, getSimpleMlRule, getSimpleRule, getSimpleThreatMatch, getStats, - getThresholdRuleForSignalTesting, + getThresholdRuleForAlertTesting, installMockPrebuiltRules, waitForRuleSuccess, - waitForSignalsToBePresent, + waitForAlertsToBePresent, updateRule, deleteAllEventLogExecutionEvents, getRuleSavedObjectWithLegacyInvestigationFields, getRuleSavedObjectWithLegacyInvestigationFieldsEmptyArray, createRuleThroughAlertingEndpoint, -} from '../../../../utils'; +} from '../../../utils'; + +import { FtrProviderContext } from '../../../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); @@ -49,7 +49,7 @@ export default ({ getService }: FtrProviderContext) => { const retry = getService('retry'); const es = getService('es'); - describe('Detection rule telemetry', async () => { + describe('@ess @serverless Detection rule telemetry', async () => { before(async () => { // Just in case other tests do not clean up the event logs, let us clear them now and here only once. await deleteAllEventLogExecutionEvents(es, log); @@ -61,7 +61,7 @@ export default ({ getService }: FtrProviderContext) => { }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { @@ -72,7 +72,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"kql" rule type', () => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); await createRule(supertest, log, rule); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -102,10 +102,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => { - const rule = getRuleForSignalTesting(['telemetry']); + const rule = getRuleForAlertTesting(['telemetry']); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); const expected: RulesTypeUsage = { @@ -136,8 +136,8 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { - const rule = getRuleForSignalTesting(['telemetry']); - const hookAction = await createNewAction(supertest, log); + const rule = getRuleForAlertTesting(['telemetry']); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule); await createRule(supertest, log, ruleToCreate); @@ -160,13 +160,13 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { - const rule = getRuleForSignalTesting(['telemetry']); - const hookAction = await createNewAction(supertest, log); + it('@brokenInServerless should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { + const rule = getRuleForAlertTesting(['telemetry']); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule); const { id } = await createRule(supertest, log, ruleToCreate); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -189,10 +189,10 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { - const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await retry.try(async () => { @@ -215,13 +215,13 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { - const rule = getRuleForSignalTesting(['telemetry']); + it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule = getRuleForAlertTesting(['telemetry']); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -244,7 +244,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - describe('legacy investigation fields', () => { + describe('@brokenInServerless legacy investigation fields', () => { beforeEach(async () => { await deleteAllRules(supertest, log); await createRuleThroughAlertingEndpoint( @@ -294,7 +294,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"eql" rule type', () => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => { - const rule = getEqlRuleForSignalTesting(['telemetry'], 'rule-1', false); + const rule = getEqlRuleForAlertTesting(['telemetry'], 'rule-1', false); await createRule(supertest, log, rule); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -322,10 +322,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => { - const rule = getEqlRuleForSignalTesting(['telemetry']); + const rule = getEqlRuleForAlertTesting(['telemetry']); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); const expected: RulesTypeUsage = { @@ -356,8 +356,8 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { - const rule = getEqlRuleForSignalTesting(['telemetry']); - const hookAction = await createNewAction(supertest, log); + const rule = getEqlRuleForAlertTesting(['telemetry']); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule); await createRule(supertest, log, ruleToCreate); @@ -381,12 +381,12 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { - const rule = getEqlRuleForSignalTesting(['telemetry']); - const hookAction = await createNewAction(supertest, log); + const rule = getEqlRuleForAlertTesting(['telemetry']); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule); const { id } = await createRule(supertest, log, ruleToCreate); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -409,10 +409,10 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { - const rule = getEqlRuleForSignalTesting(['telemetry'], 'rule-1', false); + it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule = getEqlRuleForAlertTesting(['telemetry'], 'rule-1', false); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await retry.try(async () => { @@ -434,13 +434,13 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { - const rule = getEqlRuleForSignalTesting(['telemetry']); + it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule = getEqlRuleForAlertTesting(['telemetry']); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -467,7 +467,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"threshold" rule type', () => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false), + ...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false), threshold: { field: 'keyword', value: 1, @@ -503,7 +503,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry']), + ...getThresholdRuleForAlertTesting(['telemetry']), threshold: { field: 'keyword', value: 1, @@ -511,7 +511,7 @@ export default ({ getService }: FtrProviderContext) => { }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); const expected: RulesTypeUsage = { @@ -543,13 +543,13 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false), + ...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false), threshold: { field: 'keyword', value: 1, }, }; - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule); await createRule(supertest, log, ruleToCreate); @@ -574,17 +574,17 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry']), + ...getThresholdRuleForAlertTesting(['telemetry']), threshold: { field: 'keyword', value: 1, }, }; - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule); const { id } = await createRule(supertest, log, ruleToCreate); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -607,16 +607,16 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false), + ...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false), threshold: { field: 'keyword', value: 1, }, }; const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await retry.try(async () => { @@ -638,19 +638,19 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { const rule: ThresholdRuleCreateProps = { - ...getThresholdRuleForSignalTesting(['telemetry']), + ...getThresholdRuleForAlertTesting(['telemetry']), threshold: { field: 'keyword', value: 1, }, }; const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -738,7 +738,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { const rule = getSimpleMlRule(); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule); await createRule(supertest, log, ruleToCreate); @@ -763,7 +763,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { const rule = getSimpleMlRule('rule-1', true); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule); await createRule(supertest, log, ruleToCreate); @@ -786,10 +786,10 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { const rule = getSimpleMlRule(); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await retry.try(async () => { @@ -811,10 +811,10 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { const rule = getSimpleMlRule('rule-1', true); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await retry.try(async () => { @@ -887,7 +887,7 @@ export default ({ getService }: FtrProviderContext) => { }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); const expected: RulesTypeUsage = { @@ -919,7 +919,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { const rule = getSimpleThreatMatch(); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule); await createRule(supertest, log, ruleToCreate); @@ -959,11 +959,11 @@ export default ({ getService }: FtrProviderContext) => { }, ], }; - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule); const { id } = await createRule(supertest, log, ruleToCreate); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -986,10 +986,10 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { const rule = getSimpleThreatMatch(); const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await retry.try(async () => { @@ -1011,7 +1011,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { const rule: ThreatMatchRuleCreateProps = { ...getSimpleThreatMatch('rule-1', true), index: ['telemetry'], @@ -1029,10 +1029,10 @@ export default ({ getService }: FtrProviderContext) => { ], }; const { id } = await createRule(supertest, log, rule); - const hookAction = await createNewAction(supertest, log); + const hookAction = await createWebHookRuleAction(supertest); await createLegacyRuleAction(supertest, id, hookAction.id); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 4, [id]); + await waitForAlertsToBePresent(supertest, log, 4, [id]); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -1057,7 +1057,7 @@ export default ({ getService }: FtrProviderContext) => { }); describe('"pre-packaged"/"immutable" rules', async () => { - it('should show stats for totals for in-active pre-packaged rules', async () => { + it('@skipInQA should show stats for totals for in-active pre-packaged rules', async () => { await installMockPrebuiltRules(supertest, es); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -1090,7 +1090,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show stats for the detection_rule_details for a specific pre-packaged rule', async () => { + it('@skipInQA should show stats for the detection_rule_details for a specific pre-packaged rule', async () => { await installMockPrebuiltRules(supertest, es); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -1121,13 +1121,13 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "notifications_disabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { + it('@skipInQA should show "notifications_disabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { await installMockPrebuiltRules(supertest, es); - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); - const hookAction = await createNewAction(supertest, log); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); + const hookAction = await createWebHookRuleAction(supertest); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id); const ruleToUpdate = getRuleWithWebHookAction(hookAction.id, false, newRuleToUpdate); - await updateRule(supertest, log, ruleToUpdate); + await updateRule(supertest, ruleToUpdate); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -1174,13 +1174,13 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "notifications_enabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { + it('@skipInQA should show "notifications_enabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { await installMockPrebuiltRules(supertest, es); - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); - const hookAction = await createNewAction(supertest, log); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); + const hookAction = await createWebHookRuleAction(supertest); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id); const ruleToUpdate = getRuleWithWebHookAction(hookAction.id, true, newRuleToUpdate); - await updateRule(supertest, log, ruleToUpdate); + await updateRule(supertest, ruleToUpdate); await retry.try(async () => { const stats = await getStats(supertest, log); @@ -1227,12 +1227,12 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { + it('@brokenInServerless should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { await installMockPrebuiltRules(supertest, es); - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); - const hookAction = await createNewAction(supertest, log); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); + const hookAction = await createWebHookRuleAction(supertest); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, false); - await updateRule(supertest, log, newRuleToUpdate); + await updateRule(supertest, newRuleToUpdate); await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id); await retry.try(async () => { @@ -1280,12 +1280,12 @@ export default ({ getService }: FtrProviderContext) => { }); }); - it('should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { + it('@brokenInServerless should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { await installMockPrebuiltRules(supertest, es); - const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID); - const hookAction = await createNewAction(supertest, log); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); + const hookAction = await createWebHookRuleAction(supertest); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, true); - await updateRule(supertest, log, newRuleToUpdate); + await updateRule(supertest, newRuleToUpdate); await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id); await retry.try(async () => { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rules_legacy_action.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rules_legacy_action.ts new file mode 100644 index 0000000000000..b0e40253bb8c2 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/usage_collector/detection_rules_legacy_action.ts @@ -0,0 +1,512 @@ +/* + * 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 expect from '@kbn/expect'; + +import type { + ThreatMatchRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage'; +import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common'; +import { RulesTypeUsage } from '@kbn/security-solution-plugin/server/usage/detections/rules/types'; +import { + createLegacyRuleAction, + createWebHookRuleAction, + createRule, + createAlertsIndex, + deleteAllRules, + deleteAllAlerts, + getEqlRuleForAlertTesting, + fetchRule, + getRuleForAlertTesting, + getRuleWithWebHookAction, + getSimpleMlRule, + getSimpleRule, + getSimpleThreatMatch, + getStats, + getThresholdRuleForAlertTesting, + installMockPrebuiltRules, + waitForRuleSuccess, + waitForAlertsToBePresent, + updateRule, + deleteAllEventLogExecutionEvents, +} from '../../../utils'; + +import { FtrProviderContext } from '../../../../../ftr_provider_context'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + const log = getService('log'); + const retry = getService('retry'); + const es = getService('es'); + + describe('@ess Detection rule legacy actions telemetry', async () => { + before(async () => { + // Just in case other tests do not clean up the event logs, let us clear them now and here only once. + await deleteAllEventLogExecutionEvents(es, log); + await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/security_solution/telemetry'); + }); + + beforeEach(async () => { + await createAlertsIndex(supertest, log); + }); + + afterEach(async () => { + await deleteAllAlerts(supertest, log, es); + await deleteAllRules(supertest, log); + await deleteAllEventLogExecutionEvents(es, log); + }); + + describe('"kql" rule type', () => { + it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { + const rule = getRuleForAlertTesting(['telemetry']); + const hookAction = await createWebHookRuleAction(supertest); + const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule); + const { id } = await createRule(supertest, log, ruleToCreate); + await waitForRuleSuccess({ supertest, log, id }); + await waitForAlertsToBePresent(supertest, log, 4, [id]); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + query: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.query, + enabled: 1, + alerts: 4, + notifications_enabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + enabled: 1, + alerts: 4, + notifications_enabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + + it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + query: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.query, + disabled: 1, + legacy_notifications_disabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + disabled: 1, + legacy_notifications_disabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + + it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule = getRuleForAlertTesting(['telemetry']); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + await waitForRuleSuccess({ supertest, log, id }); + await waitForAlertsToBePresent(supertest, log, 4, [id]); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + query: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.query, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + }); + + describe('"eql" rule type', () => { + it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule = getEqlRuleForAlertTesting(['telemetry'], 'rule-1', false); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + eql: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.eql, + disabled: 1, + legacy_notifications_disabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + disabled: 1, + legacy_notifications_disabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + + it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule = getEqlRuleForAlertTesting(['telemetry']); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + await waitForRuleSuccess({ supertest, log, id }); + await waitForAlertsToBePresent(supertest, log, 4, [id]); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + eql: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.eql, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + }); + + describe('"threshold" rule type', () => { + it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule: ThresholdRuleCreateProps = { + ...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false), + threshold: { + field: 'keyword', + value: 1, + }, + }; + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + threshold: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threshold, + disabled: 1, + legacy_notifications_disabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + disabled: 1, + legacy_notifications_disabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + + it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule: ThresholdRuleCreateProps = { + ...getThresholdRuleForAlertTesting(['telemetry']), + threshold: { + field: 'keyword', + value: 1, + }, + }; + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + await waitForRuleSuccess({ supertest, log, id }); + await waitForAlertsToBePresent(supertest, log, 4, [id]); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + threshold: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threshold, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + }); + + // Note: We don't actually find signals with these tests as we don't have a good way of signal finding with ML rules. + describe('"ml" rule type', () => { + it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule = getSimpleMlRule(); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + machine_learning: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.machine_learning, + disabled: 1, + legacy_notifications_disabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + disabled: 1, + legacy_notifications_disabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + + it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule = getSimpleMlRule('rule-1', true); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + machine_learning: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.machine_learning, + enabled: 1, + legacy_notifications_enabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + enabled: 1, + legacy_notifications_enabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + }); + + describe('"indicator_match/threat_match" rule type', () => { + it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { + const rule = getSimpleThreatMatch(); + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + threat_match: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threat_match, + disabled: 1, + legacy_notifications_disabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + disabled: 1, + legacy_notifications_disabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + + it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { + const rule: ThreatMatchRuleCreateProps = { + ...getSimpleThreatMatch('rule-1', true), + index: ['telemetry'], + threat_index: ['telemetry'], + threat_mapping: [ + { + entries: [ + { + field: 'keyword', + value: 'keyword', + type: 'mapping', + }, + ], + }, + ], + }; + const { id } = await createRule(supertest, log, rule); + const hookAction = await createWebHookRuleAction(supertest); + await createLegacyRuleAction(supertest, id, hookAction.id); + await waitForRuleSuccess({ supertest, log, id }); + await waitForAlertsToBePresent(supertest, log, 4, [id]); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + const expected: RulesTypeUsage = { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage, + threat_match: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threat_match, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + custom_total: { + ...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total, + alerts: 4, + enabled: 1, + legacy_notifications_enabled: 1, + }, + }; + expect(stats.detection_rules.detection_rule_usage).to.eql(expected); + }); + }); + }); + + describe('"pre-packaged"/"immutable" rules', async () => { + it('should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { + await installMockPrebuiltRules(supertest, es); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); + const hookAction = await createWebHookRuleAction(supertest); + const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, false); + await updateRule(supertest, newRuleToUpdate); + await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + // We have to search by "rule_name" since the "rule_id" it is storing is the Saved Object ID and not the rule_id + const foundRule = stats.detection_rules.detection_rule_detail.find( + (rule) => rule.rule_id === ELASTIC_SECURITY_RULE_ID + ); + if (foundRule == null) { + throw new Error('Found rule should not be null. Please change this end to end test.'); + } + const { + created_on: createdOn, + updated_on: updatedOn, + rule_id: ruleId, + rule_version: ruleVersion, + ...omittedFields + } = foundRule; + expect(omittedFields).to.eql({ + rule_name: 'Simple Rule Query', + rule_type: 'query', + enabled: false, + elastic_rule: true, + alert_count_daily: 0, + cases_count_total: 0, + has_notification: false, + has_legacy_notification: true, + has_legacy_investigation_field: false, + }); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.notifications_disabled + ).to.eql(0); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_enabled + ).to.eql(0); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_disabled + ).to.eql(1); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.notifications_enabled + ).to.eql(0); + expect(stats.detection_rules.detection_rule_usage.custom_total).to.eql( + getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total + ); + }); + }); + + it('should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { + await installMockPrebuiltRules(supertest, es); + const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID }); + const hookAction = await createWebHookRuleAction(supertest); + const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, true); + await updateRule(supertest, newRuleToUpdate); + await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id); + + await retry.try(async () => { + const stats = await getStats(supertest, log); + // We have to search by "rule_name" since the "rule_id" it is storing is the Saved Object ID and not the rule_id + const foundRule = stats.detection_rules.detection_rule_detail.find( + (rule) => rule.rule_id === ELASTIC_SECURITY_RULE_ID + ); + if (foundRule == null) { + throw new Error('Found rule should not be null. Please change this end to end test.'); + } + const { + created_on: createdOn, + updated_on: updatedOn, + rule_id: ruleId, + rule_version: ruleVersion, + ...omittedFields + } = foundRule; + expect(omittedFields).to.eql({ + rule_name: 'Simple Rule Query', + rule_type: 'query', + enabled: true, + elastic_rule: true, + alert_count_daily: 0, + cases_count_total: 0, + has_notification: false, + has_legacy_notification: true, + has_legacy_investigation_field: false, + }); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.notifications_disabled + ).to.eql(0); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_enabled + ).to.eql(1); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_disabled + ).to.eql(0); + expect( + stats.detection_rules.detection_rule_usage.elastic_total.notifications_enabled + ).to.eql(0); + expect(stats.detection_rules.detection_rule_usage.custom_total).to.eql( + getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total + ); + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/create_new_action.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/create_new_webhook_action.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/create_new_action.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/create_new_webhook_action.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/index.ts index f91323f94de59..9accb2b089280 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/actions/index.ts @@ -6,5 +6,5 @@ */ export * from './get_slack_action'; export * from './get_web_hook_action'; -export * from './create_new_action'; +export * from './create_new_webhook_action'; export * from './legacy_actions'; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/event_log/delete_all_event_log_execution_events.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/event_log/delete_all_event_log_execution_events.ts new file mode 100644 index 0000000000000..998033d185486 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/event_log/delete_all_event_log_execution_events.ts @@ -0,0 +1,39 @@ +/* + * 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 type { ToolingLog } from '@kbn/tooling-log'; +import type { Client } from '@elastic/elasticsearch'; + +import { countDownES } from '../count_down_es'; + +/** + * Remove all .kibana-event-log-* documents with an execution.uuid + * This will retry 50 times before giving up and hopefully still not interfere with other tests + * @param es The ElasticSearch handle + * @param log The tooling logger + */ +export const deleteAllEventLogExecutionEvents = async ( + es: Client, + log: ToolingLog +): Promise => { + return countDownES( + async () => { + return es.deleteByQuery( + { + index: '.kibana-event-log-*', + q: '_exists_:kibana.alert.rule.execution.uuid', + wait_for_completion: true, + refresh: true, + body: {}, + }, + { meta: true } + ); + }, + 'deleteAllEventLogExecutionEvents', + log + ); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/event_log/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/event_log/index.ts new file mode 100644 index 0000000000000..c10ed51052bc3 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/event_log/index.ts @@ -0,0 +1,7 @@ +/* + * 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 * from './delete_all_event_log_execution_events'; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_detection_metrics_from_body.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_detection_metrics_from_body.ts similarity index 59% rename from x-pack/test/detection_engine_api_integration/utils/get_detection_metrics_from_body.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_detection_metrics_from_body.ts index 92e17ba61fe03..20febd5e9180f 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_detection_metrics_from_body.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_detection_metrics_from_body.ts @@ -6,7 +6,6 @@ */ import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types'; -import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types'; /** * Given a body this will return the detection metrics from it. @@ -24,20 +23,3 @@ export const getDetectionMetricsFromBody = ( ): DetectionMetrics => { return body[0].stats.stack_stats.kibana.plugins.security_solution.detectionMetrics; }; - -/** - * Given a body this will return the risk engine metrics from it. - * @param body The Stats body - * @returns Detection metrics - */ -export const getRiskEngineMetricsFromBody = ( - body: Array<{ - stats: { - stack_stats: { - kibana: { plugins: { security_solution: { riskEngineMetrics: {} } } }; - }; - }; - }> -): RiskEngineMetrics => { - return body[0].stats.stack_stats.kibana.plugins.security_solution.riskEngineMetrics; -}; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_stats.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_stats.ts similarity index 57% rename from x-pack/test/detection_engine_api_integration/utils/get_stats.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_stats.ts index d042bdc4d53f7..9415f6900a54f 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_stats.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_stats.ts @@ -8,17 +8,13 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types'; -import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types'; import { ELASTIC_HTTP_VERSION_HEADER, X_ELASTIC_INTERNAL_ORIGIN_REQUEST, } from '@kbn/core-http-common'; import { getStatsUrl } from './get_stats_url'; -import { - getDetectionMetricsFromBody, - getRiskEngineMetricsFromBody, -} from './get_detection_metrics_from_body'; +import { getDetectionMetricsFromBody } from './get_detection_metrics_from_body'; /** * Gets the stats from the stats endpoint. @@ -45,29 +41,3 @@ export const getStats = async ( return getDetectionMetricsFromBody(response.body); }; - -/** - * Gets the stats from the stats endpoint. - * @param supertest The supertest agent. - * @returns The detection metrics - */ -export const getRiskEngineStats = async ( - supertest: SuperTest.SuperTest, - log: ToolingLog -): Promise => { - const response = await supertest - .post(getStatsUrl()) - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '2') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send({ unencrypted: true, refreshCache: true }); - if (response.status !== 200) { - log.error( - `Did not get an expected 200 "ok" when getting the stats for risk engine. CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify( - response.body - )}, status: ${JSON.stringify(response.status)}` - ); - } - - return getRiskEngineMetricsFromBody(response.body); -}; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_stats_url.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_stats_url.ts similarity index 100% rename from x-pack/test/detection_engine_api_integration/utils/get_stats_url.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/get_stats_url.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/index.ts index 87fd3c61d54e7..0b7c66f57cb2a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/index.ts @@ -9,13 +9,11 @@ export * from './exception_list_and_item'; export * from './alerts'; export * from './actions'; export * from './data_generator'; +export * from './telemetry'; +export * from './event_log'; export * from './machine_learning'; -export * from './rules/get_rule_so_by_id'; -export * from './rules/create_rule_saved_object'; -export * from './rules/get_rule_with_legacy_investigation_fields'; export * from './get_index_name_from_load'; - export * from './count_down_test'; export * from './count_down_es'; export * from './update_username'; @@ -23,3 +21,6 @@ export * from './refresh_index'; export * from './wait_for'; export * from './route_with_namespace'; export * from './wait_for_index_to_populate'; +export * from './get_stats'; +export * from './get_detection_metrics_from_body'; +export * from './get_stats_url'; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/create_legacy_rule_action.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/create_legacy_rule_action.ts new file mode 100644 index 0000000000000..8e0cb59d5ee90 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/create_legacy_rule_action.ts @@ -0,0 +1,35 @@ +/* + * 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 type SuperTest from 'supertest'; + +import { UPDATE_OR_CREATE_LEGACY_ACTIONS } from '@kbn/security-solution-plugin/common/constants'; + +export const createLegacyRuleAction = async ( + supertest: SuperTest.SuperTest, + alertId: string, + connectorId: string +): Promise => + supertest + .post(UPDATE_OR_CREATE_LEGACY_ACTIONS) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', '1') + .query({ alert_id: alertId }) + .send({ + name: 'Legacy notification with one action', + interval: '1h', + actions: [ + { + id: connectorId, + group: 'default', + params: { + message: 'Hourly\nRule {{context.rule.name}} generated {{state.signals_count}} alerts', + }, + actionTypeId: '.slack', + }, + ], + }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_ml_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_ml_rule.ts new file mode 100644 index 0000000000000..a8fe28d54f24e --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_ml_rule.ts @@ -0,0 +1,25 @@ +/* + * 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 type { RuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine'; + +/** + * This is a representative ML rule payload as expected by the server + * @param ruleId The rule id + * @param enabled Set to tru to enable it, by default it is off + */ +export const getSimpleMlRule = (ruleId = 'rule-1', enabled = false): RuleCreateProps => ({ + name: 'Simple ML Rule', + description: 'Simple Machine Learning Rule', + enabled, + anomaly_threshold: 44, + risk_score: 1, + rule_id: ruleId, + severity: 'high', + machine_learning_job_id: ['some_job_id'], + type: 'machine_learning', +}); diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_threat_match.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_threat_match.ts similarity index 100% rename from x-pack/test/detection_engine_api_integration/utils/get_simple_threat_match.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_threat_match.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts index 00e5fa399bd04..db5ccb307395e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts @@ -36,5 +36,8 @@ export * from './preview_rule'; export * from './preview_rule_with_exception_entries'; export * from './patch_rule'; export * from './generate_event'; +export * from './create_legacy_rule_action'; +export * from './get_simple_threat_match'; +export * from './get_simple_ml_rule'; export * from './prebuilt_rules'; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_security_telemetry_stats.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/get_security_telemetry_stats.ts similarity index 86% rename from x-pack/test/detection_engine_api_integration/utils/get_security_telemetry_stats.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/get_security_telemetry_stats.ts index 7eb00b7ff3138..462cdecbb498d 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_security_telemetry_stats.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/get_security_telemetry_stats.ts @@ -9,6 +9,10 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; import { SECURITY_TELEMETRY_URL } from '@kbn/security-solution-plugin/common/constants'; +import { + ELASTIC_HTTP_VERSION_HEADER, + X_ELASTIC_INTERNAL_ORIGIN_REQUEST, +} from '@kbn/core-http-common'; /** * Gets the stats from the stats endpoint within specifically the security_solutions application. @@ -23,7 +27,8 @@ export const getSecurityTelemetryStats = async ( const response = await supertest .get(SECURITY_TELEMETRY_URL) .set('kbn-xsrf', 'true') - .set('elastic-api-version', '1') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send({ unencrypted: true, refreshCache: true }); if (response.status !== 200) { log.error( diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/index.ts new file mode 100644 index 0000000000000..c784edd7f618b --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/index.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 * from './get_security_telemetry_stats'; +export * from './remove_time_fields_from_telemetry_stats'; diff --git a/x-pack/test/detection_engine_api_integration/utils/remove_time_fields_from_telemetry_stats.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/remove_time_fields_from_telemetry_stats.ts similarity index 100% rename from x-pack/test/detection_engine_api_integration/utils/remove_time_fields_from_telemetry_stats.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/telemetry/remove_time_fields_from_telemetry_stats.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/wait_for_index_to_populate.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/wait_for_index_to_populate.ts index 74e3e8a253769..ceba42efd1793 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/wait_for_index_to_populate.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/wait_for_index_to_populate.ts @@ -7,7 +7,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type { Client } from '@elastic/elasticsearch'; -import { waitFor } from '../../../../detection_engine_api_integration/utils/wait_for'; +import { waitFor } from './wait_for'; /** * Waits for the given index to contain documents diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_metrics_from_body.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_metrics_from_body.ts new file mode 100644 index 0000000000000..c8ec19e448402 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_metrics_from_body.ts @@ -0,0 +1,24 @@ +/* + * 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 type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types'; + +/** + * Given a body this will return the risk engine metrics from it. + * @param body The Stats body + * @returns Detection metrics + */ +export const getRiskEngineMetricsFromBody = ( + body: Array<{ + stats: { + stack_stats: { + kibana: { plugins: { security_solution: { riskEngineMetrics: {} } } }; + }; + }; + }> +): RiskEngineMetrics => { + return body[0].stats.stack_stats.kibana.plugins.security_solution.riskEngineMetrics; +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_stats.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_stats.ts index c5343372ce99a..5629e0da9a89d 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_stats.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/get_risk_engine_stats.ts @@ -7,44 +7,14 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; -import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types'; import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types'; import { ELASTIC_HTTP_VERSION_HEADER, X_ELASTIC_INTERNAL_ORIGIN_REQUEST, } from '@kbn/core-http-common'; -import { getStatsUrl } from '../../../../detection_engine_api_integration/utils/get_stats_url'; -import { - getDetectionMetricsFromBody, - getRiskEngineMetricsFromBody, -} from '../../../../detection_engine_api_integration/utils/get_detection_metrics_from_body'; - -/** - * Gets the stats from the stats endpoint. - * @param supertest The supertest agent. - * @returns The detection metrics - */ -export const getStats = async ( - supertest: SuperTest.SuperTest, - log: ToolingLog -): Promise => { - const response = await supertest - .post(getStatsUrl()) - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '2') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send({ unencrypted: true, refreshCache: true }); - if (response.status !== 200) { - log.error( - `Did not get an expected 200 "ok" when getting the stats for detections. CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify( - response.body - )}, status: ${JSON.stringify(response.status)}` - ); - } - - return getDetectionMetricsFromBody(response.body); -}; +import { getStatsUrl } from '../../detections_response/utils/get_stats_url'; +import { getRiskEngineMetricsFromBody } from './get_risk_engine_metrics_from_body'; /** * Gets the stats from the stats endpoint.