From e4a039b70a7cb7fd07cad1f7151005a63aa4d8f9 Mon Sep 17 00:00:00 2001 From: Vitalii Dmyterko <92328789+vitaliidm@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:07:20 +0000 Subject: [PATCH] [Security Solution][Detection engine] fix deduplication ES|QL test (#170772) ## Summary - fixes https://github.com/elastic/security-team/issues/7928 by changing test to use real rule executions and explicitly refreshing alerts index between the runs --------- Co-authored-by: Ievgen Sorokopud --- .../rule_execution_logic/esql.ts | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/esql.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/esql.ts index 9ae0bf9773de6..51db00fc1ed6b 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/esql.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/esql.ts @@ -11,6 +11,7 @@ import { orderBy } from 'lodash'; import { EsqlRuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine/model/rule_schema'; import { getCreateEsqlRulesSchemaMock } from '@kbn/security-solution-plugin/common/api/detection_engine/model/rule_schema/mocks'; +import { RuleExecutionStatusEnum } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_monitoring'; import { getMaxSignalsWarning } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/utils/utils'; import { @@ -26,6 +27,7 @@ import { previewRuleWithExceptionEntries } from '../../utils/preview_rule_with_e import { deleteAllExceptions } from '../../../lists_api_integration/utils'; import { dataGeneratorFactory } from '../../utils/data_generator'; import { removeRandomValuedProperties } from './utils'; +import { patchRule } from '../../utils/patch_rule'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { @@ -710,18 +712,22 @@ export default ({ getService }: FtrProviderContext) => { expect(previewAlerts.length).toBe(150); }); - // as per https://github.com/elastic/kibana/pull/170034, test is failing on CI and flaky locally - // skipping it for now for further investigation - it.skip('should generate alerts when docs overlap execution intervals and alerts number reached max_signals in one of the executions', async () => { + // we use actual rule executions, not preview, because for preview API alerts index refresh=false for non suppressed alerts + // first rule execution catches 130 documents and generates 100 alerts + // second rule execution catches 150 docs, 120 of which were captured during the first execution and generates only 60 alerts. Because rest are deduplicated + // so in total 160 alerts should be generated + it('should generate alerts when docs overlap execution intervals and alerts number reached max_signals in one of the real executions', async () => { const id = uuidv4(); const rule: EsqlRuleCreateProps = { - ...getCreateEsqlRulesSchemaMock('rule-1', true), + ...getCreateEsqlRulesSchemaMock(`rule-${id}`, true), query: `from ecs_compliant [metadata _id] ${internalIdPipe( id )} | keep _id, agent.name | sort agent.name`, - from: 'now-45m', - interval: '30m', + from: '2020-10-28T05:15:00.000Z', + to: '2020-10-28T06:00:00.000Z', + interval: '45m', max_signals: 100, + enabled: true, }; // docs fall in first rule executions @@ -772,20 +778,46 @@ export default ({ getService }: FtrProviderContext) => { }), }); - const { previewId } = await previewRule({ + const createdRule = await createRule(supertest, log, rule); + + // first rule run should generate 100 alerts from first 3 batches of index documents + const alertsResponseFromFirstRuleExecution = await getOpenAlerts( supertest, - rule, - timeframeEnd: new Date('2020-10-28T06:30:00.000Z'), - invocationCount: 2, - }); - const previewAlerts = await getPreviewAlerts({ + log, es, - previewId, - size: 200, + createdRule, + // rule has warning, alerts were truncated, thus "partial failure" status + RuleExecutionStatusEnum['partial failure'], + 200 + ); + + // should return 100 alerts + expect(alertsResponseFromFirstRuleExecution.hits.hits.length).toBe(100); + + // re-trigger rule execution with new interval + await patchRule(supertest, log, { + id: createdRule.id, + enabled: false, + }); + await patchRule(supertest, log, { + id: createdRule.id, + from: '2020-10-28T05:45:00.000Z', + to: '2020-10-28T06:30:00.000Z', + enabled: true, }); - // should generate 160 alerts - expect(previewAlerts.length).toBe(160); + const alertsResponse = await getOpenAlerts( + supertest, + log, + es, + createdRule, + RuleExecutionStatusEnum.succeeded, + 200, + new Date() + ); + + // should return 160 alerts + expect(alertsResponse.hits.hits.length).toBe(160); }); });