From 96b9c5082a7362d651ca3109f141cf4f95b91f1b Mon Sep 17 00:00:00 2001 From: Jiawei Wu Date: Thu, 30 Nov 2023 18:24:45 -0800 Subject: [PATCH] Add E2E tests --- .../server/task_runner/task_runner.ts | 5 +- .../plugins/alerts/server/alert_types.ts | 2 +- .../tests/alerting/group3/index.ts | 1 + .../group3/maintenance_window_flows.ts | 457 ++++++++++-------- .../group3/maintenance_window_scoped_query.ts | 156 ++++++ .../tests/alerting/group3/test_helpers.ts | 227 +++++++++ 6 files changed, 631 insertions(+), 217 deletions(-) create mode 100644 x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_scoped_query.ts create mode 100644 x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/test_helpers.ts diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index a8d30f25397051..fcf1b2e8662f4a 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -434,9 +434,6 @@ export class TaskRunner< return false; }); - const maintenanceWindowsWithScopedQuery = maintenanceWindows.filter( - ({ scopedQuery }) => scopedQuery - ); const maintenanceWindowsWithoutScopedQuery = maintenanceWindows.filter( ({ scopedQuery }) => !scopedQuery ); @@ -598,7 +595,7 @@ export class TaskRunner< ruleId: rule.id, spaceId, executionUuid: this.executionId, - maintenanceWindows: maintenanceWindowsWithScopedQuery, + maintenanceWindows, }); } catch (e) { this.logger.debug( diff --git a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/alert_types.ts b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/alert_types.ts index 8bd5ebfad1b21a..34367ce2d8b4da 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/alert_types.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/alert_types.ts @@ -552,7 +552,7 @@ function getPatternFiringAlertsAsDataRuleType() { id: 'test.patternFiringAad', name: 'Test: Firing on a Pattern and writing Alerts as Data', actionGroups: [{ id: 'default', name: 'Default' }], - category: 'kibana', + category: 'management', producer: 'alertsFixture', defaultActionGroupId: 'default', minimumLicenseRequired: 'basic', diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/index.ts index 0b8e43039c33a3..47157e8d55d05f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/index.ts @@ -16,5 +16,6 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./builtin_alert_types')); loadTestFile(require.resolve('./maintenance_window_flows')); + loadTestFile(require.resolve('./maintenance_window_scoped_query')); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_flows.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_flows.ts index ac92bb080f5509..d0b8c7e8825a2d 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_flows.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_flows.ts @@ -5,12 +5,19 @@ * 2.0. */ -import { IValidatedEvent } from '@kbn/event-log-plugin/server'; -import moment from 'moment'; import expect from '@kbn/expect'; -import { Spaces } from '../../../scenarios'; -import { getUrlPrefix, getTestRuleData, ObjectRemover, getEventLog } from '../../../../common/lib'; +import { ObjectRemover } from '../../../../common/lib'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { + createRule, + createAction, + createMaintenanceWindow, + getActiveMaintenanceWindows, + finishMaintenanceWindow, + getRuleEvents, + expectNoActionsFired, + runSoon, +} from './test_helpers'; // eslint-disable-next-line import/no-default-export export default function maintenanceWindowFlowsTests({ getService }: FtrProviderContext) { @@ -31,45 +38,78 @@ export default function maintenanceWindowFlowsTests({ getService }: FtrProviderC }; // Create action and rule - const action = await createAction(); - const rule = await createRule({ actionId: action.id, pattern }); + const action = await createAction({ + supertest, + objectRemover, + }); + const rule = await createRule({ + actionId: action.id, + pattern, + supertest, + objectRemover, + }); // Run the first time - active await getRuleEvents({ id: rule.id, action: 1, activeInstance: 1, + retry, + getService, }); // Run again - active, 2 action - await runSoon(rule.id); + await runSoon({ + id: rule.id, + supertest, + retry, + }); await getRuleEvents({ id: rule.id, action: 2, activeInstance: 2, + retry, + getService, }); // Create active maintenance window - const maintenanceWindow = await createMaintenanceWindow(); - const activeMaintenanceWindows = await getActiveMaintenanceWindows(); + const maintenanceWindow = await createMaintenanceWindow({ + supertest, + objectRemover, + }); + const activeMaintenanceWindows = await getActiveMaintenanceWindows({ + supertest, + }); expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id); // Run again - recovered, 3 actions, fired in MW - await runSoon(rule.id); + await runSoon({ + id: rule.id, + supertest, + retry, + }); await getRuleEvents({ id: rule.id, action: 3, activeInstance: 2, recoveredInstance: 1, + retry, + getService, }); // Run again - active, 3 actions, new active action NOT fired in MW - await runSoon(rule.id); + await runSoon({ + id: rule.id, + supertest, + retry, + }); await getRuleEvents({ id: rule.id, action: 3, activeInstance: 3, recoveredInstance: 1, + retry, + getService, }); }); @@ -79,36 +119,99 @@ export default function maintenanceWindowFlowsTests({ getService }: FtrProviderC }; // Create active maintenance window - const maintenanceWindow = await createMaintenanceWindow(); - const activeMaintenanceWindows = await getActiveMaintenanceWindows(); + const maintenanceWindow = await createMaintenanceWindow({ + supertest, + objectRemover, + }); + const activeMaintenanceWindows = await getActiveMaintenanceWindows({ + supertest, + }); expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id); // Create action and rule - const action = await createAction(); - const rule = await createRule({ actionId: action.id, pattern }); + const action = await createAction({ + supertest, + objectRemover, + }); + const rule = await createRule({ + actionId: action.id, + pattern, + supertest, + objectRemover, + }); // Run the first time - active - await getRuleEvents({ id: rule.id, activeInstance: 1 }); + await getRuleEvents({ + id: rule.id, + activeInstance: 1, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); // Run again - active - await runSoon(rule.id); - await getRuleEvents({ id: rule.id, activeInstance: 2 }); + await runSoon({ + id: rule.id, + supertest, + retry, + }); + await getRuleEvents({ + id: rule.id, + activeInstance: 2, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); // Run again - recovered - await runSoon(rule.id); - await getRuleEvents({ id: rule.id, activeInstance: 2, recoveredInstance: 1 }); + await runSoon({ + id: rule.id, + supertest, + retry, + }); + await getRuleEvents({ + id: rule.id, + activeInstance: 2, + recoveredInstance: 1, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); // Run again - active again - await runSoon(rule.id); - await getRuleEvents({ id: rule.id, activeInstance: 3, recoveredInstance: 1 }); + await runSoon({ + id: rule.id, + supertest, + retry, + }); + await getRuleEvents({ + id: rule.id, + activeInstance: 3, + recoveredInstance: 1, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); }); it('alerts triggered within a MW should not fire actions if active or recovered outside a MW', async () => { @@ -117,43 +220,103 @@ export default function maintenanceWindowFlowsTests({ getService }: FtrProviderC }; // Create active maintenance window - const maintenanceWindow = await createMaintenanceWindow(); - const activeMaintenanceWindows = await getActiveMaintenanceWindows(); + const maintenanceWindow = await createMaintenanceWindow({ + supertest, + objectRemover, + }); + const activeMaintenanceWindows = await getActiveMaintenanceWindows({ + supertest, + }); expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id); // Create action and rule - const action = await createAction(); - const rule = await createRule({ actionId: action.id, pattern }); + const action = await createAction({ + supertest, + objectRemover, + }); + const rule = await createRule({ + actionId: action.id, + pattern, + supertest, + objectRemover, + }); // Run the first time - active - await getRuleEvents({ id: rule.id, activeInstance: 1 }); + await getRuleEvents({ + id: rule.id, + activeInstance: 1, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); // End the maintenance window - await finishMaintenanceWindow(maintenanceWindow.id); - const empty = await getActiveMaintenanceWindows(); + await finishMaintenanceWindow({ + id: maintenanceWindow.id, + supertest, + }); + const empty = await getActiveMaintenanceWindows({ + supertest, + }); expect(empty).eql([]); // Run again - active - await runSoon(rule.id); - await getRuleEvents({ id: rule.id, activeInstance: 2 }); + await runSoon({ + id: rule.id, + supertest, + retry, + }); + await getRuleEvents({ + id: rule.id, + activeInstance: 2, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); // Run again - recovered - await runSoon(rule.id); - await getRuleEvents({ id: rule.id, activeInstance: 2, recoveredInstance: 1 }); + await runSoon({ + id: rule.id, + supertest, + retry, + }); + await getRuleEvents({ + id: rule.id, + activeInstance: 2, + recoveredInstance: 1, + retry, + getService, + }); - await expectNoActionsFired(rule.id); + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); // Run again - active again, this time fire the action since its a new alert instance - await runSoon(rule.id); + await runSoon({ + id: rule.id, + supertest, + retry, + }); await getRuleEvents({ id: rule.id, action: 1, activeInstance: 3, recoveredInstance: 1, + retry, + getService, }); }); @@ -164,208 +327,78 @@ export default function maintenanceWindowFlowsTests({ getService }: FtrProviderC // Create active maintenance window const maintenanceWindow = await createMaintenanceWindow({ - category_ids: ['observability'], + overwrites: { + category_ids: ['observability'], + }, + supertest, + objectRemover, + }); + const activeMaintenanceWindows = await getActiveMaintenanceWindows({ + supertest, }); - const activeMaintenanceWindows = await getActiveMaintenanceWindows(); expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id); expect(activeMaintenanceWindows[0].category_ids).eql(['observability']); // Create action and rule - const action = await createAction(); - const rule = await createRule({ actionId: action.id, pattern }); + const action = await await createAction({ + supertest, + objectRemover, + }); + const rule = await createRule({ + actionId: action.id, + pattern, + supertest, + objectRemover, + }); // Run 4 times - firing each time await getRuleEvents({ id: rule.id, action: 1, activeInstance: 1, + retry, + getService, + }); + await runSoon({ + id: rule.id, + supertest, + retry, }); - await runSoon(rule.id); await getRuleEvents({ id: rule.id, action: 2, activeInstance: 2, + retry, + getService, }); - await runSoon(rule.id); + await runSoon({ + id: rule.id, + supertest, + retry, + }); await getRuleEvents({ id: rule.id, action: 3, activeInstance: 2, recoveredInstance: 1, + retry, + getService, }); - await runSoon(rule.id); + await runSoon({ + id: rule.id, + supertest, + retry, + }); await getRuleEvents({ id: rule.id, action: 4, activeInstance: 3, recoveredInstance: 1, + retry, + getService, }); }); - - // Helper functions: - async function createRule({ - actionId, - pattern, - }: { - actionId: string; - pattern: { instance: boolean[] }; - }) { - const { body: createdRule } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - name: 'test-rule', - rule_type_id: 'test.patternFiring', - schedule: { interval: '24h' }, - throttle: null, - notify_when: 'onActiveAlert', - params: { - pattern, - }, - actions: [ - { - id: actionId, - group: 'default', - params: {}, - }, - { - id: actionId, - group: 'recovered', - params: {}, - }, - ], - }) - ) - .expect(200); - - objectRemover.add(Spaces.space1.id, createdRule.id, 'rule', 'alerting'); - return createdRule; - } - - async function createAction() { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'MY action', - connector_type_id: 'test.noop', - config: {}, - secrets: {}, - }) - .expect(200); - - objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); - return createdAction; - } - - async function createMaintenanceWindow(overwrites?: any) { - const { body: window } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/maintenance_window`) - .set('kbn-xsrf', 'foo') - .send({ - title: 'test-maintenance-window-1', - duration: 60 * 60 * 1000, // 1 hr - r_rule: { - dtstart: moment.utc().toISOString(), - tzid: 'UTC', - freq: 0, // yearly - count: 1, - }, - ...overwrites, - }) - .expect(200); - - objectRemover.add(Spaces.space1.id, window.id, 'rules/maintenance_window', 'alerting', true); - return window; - } - - async function getActiveMaintenanceWindows() { - const { body: activeMaintenanceWindows } = await supertest - .get(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/maintenance_window/_active`) - .set('kbn-xsrf', 'foo') - .expect(200); - - return activeMaintenanceWindows; - } - - function finishMaintenanceWindow(id: string) { - return supertest - .post( - `${getUrlPrefix( - Spaces.space1.id - )}/internal/alerting/rules/maintenance_window/${id}/_finish` - ) - .set('kbn-xsrf', 'foo') - .expect(200); - } - - async function getRuleEvents({ - id, - action, - newInstance, - activeInstance, - recoveredInstance, - }: { - id: string; - action?: number; - newInstance?: number; - activeInstance?: number; - recoveredInstance?: number; - }) { - const actions: Array<[string, { equal: number }]> = []; - if (action) { - actions.push(['execute-action', { equal: action }]); - } - if (newInstance) { - actions.push(['new-instance', { equal: newInstance }]); - } - if (activeInstance) { - actions.push(['active-instance', { equal: activeInstance }]); - } - if (recoveredInstance) { - actions.push(['recovered-instance', { equal: recoveredInstance }]); - } - return retry.try(async () => { - return await getEventLog({ - getService, - spaceId: Spaces.space1.id, - type: 'alert', - id, - provider: 'alerting', - actions: new Map(actions), - }); - }); - } - - async function expectNoActionsFired(id: string) { - const events = await retry.try(async () => { - const { body: result } = await supertest - .get(`${getUrlPrefix(Spaces.space1.id)}/_test/event_log/alert/${id}/_find?per_page=5000`) - .expect(200); - - if (!result.total) { - throw new Error('no events found yet'); - } - return result.data as IValidatedEvent[]; - }); - - const actionEvents = events.filter((event) => { - return event?.event?.action === 'execute-action'; - }); - - expect(actionEvents.length).eql(0); - } - - function runSoon(id: string) { - return retry.try(async () => { - await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${id}/_run_soon`) - .set('kbn-xsrf', 'foo') - .expect(204); - }); - } }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_scoped_query.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_scoped_query.ts new file mode 100644 index 00000000000000..b5e31940124b30 --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/maintenance_window_scoped_query.ts @@ -0,0 +1,156 @@ +/* + * 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 { ObjectRemover } from '../../../../common/lib'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { + createRule, + createAction, + createMaintenanceWindow, + getRuleEvents, + expectNoActionsFired, + runSoon, +} from './test_helpers'; + +// eslint-disable-next-line import/no-default-export +export default function maintenanceWindowScopedQueryTests({ getService }: FtrProviderContext) { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const supertest = getService('supertest'); + const retry = getService('retry'); + + describe('maintenanceWindowScopedQuery', () => { + const objectRemover = new ObjectRemover(supertestWithoutAuth); + + afterEach(async () => { + await objectRemover.removeAll(); + }); + + it('should associate alerts muted by maintenance window scoped query', async () => { + const pattern = { + instance: [true, true, false, true], + }; + // Create active maintenance window + await createMaintenanceWindow({ + supertest, + objectRemover, + overwrites: { + scoped_query: { + kql: 'kibana.alert.rule.name: "test-rule"', + filters: [], + }, + category_ids: ['management'], + }, + }); + + // Create action and rule + const action = await await createAction({ + supertest, + objectRemover, + }); + + const rule = await createRule({ + actionId: action.id, + pattern, + supertest, + objectRemover, + overwrites: { + rule_type_id: 'test.patternFiringAad', + }, + }); + + // Run the first time - active + await getRuleEvents({ + id: rule.id, + activeInstance: 1, + retry, + getService, + }); + + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); + + await runSoon({ + id: rule.id, + supertest, + retry, + }); + + await getRuleEvents({ + id: rule.id, + activeInstance: 2, + retry, + getService, + }); + + await expectNoActionsFired({ + id: rule.id, + supertest, + retry, + }); + }); + + it('should not associate alerts if scoped query does not match the alert', async () => { + const pattern = { + instance: [true, true, false, true], + }; + // Create active maintenance window + await createMaintenanceWindow({ + supertest, + objectRemover, + overwrites: { + scoped_query: { + kql: 'kibana.alert.rule.name: "wrong-rule"', + filters: [], + }, + category_ids: ['management'], + }, + }); + + // Create action and rule + const action = await await createAction({ + supertest, + objectRemover, + }); + + const rule = await createRule({ + actionId: action.id, + pattern, + supertest, + objectRemover, + overwrites: { + rule_type_id: 'test.patternFiringAad', + }, + }); + + // Run the first time - active - has action + await getRuleEvents({ + id: rule.id, + action: 1, + activeInstance: 1, + retry, + getService, + }); + + await runSoon({ + id: rule.id, + supertest, + retry, + }); + + await getRuleEvents({ + id: rule.id, + action: 2, + activeInstance: 2, + retry, + getService, + }); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/test_helpers.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/test_helpers.ts new file mode 100644 index 00000000000000..a898cc14b9104a --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/test_helpers.ts @@ -0,0 +1,227 @@ +/* + * 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 moment from 'moment'; +import type { RetryService } from '@kbn/ftr-common-functional-services'; +import type { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import type { SuperTest, Test } from 'supertest'; +import expect from '@kbn/expect'; +import type { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { getUrlPrefix, getTestRuleData, ObjectRemover, getEventLog } from '../../../../common/lib'; +import { Spaces } from '../../../scenarios'; + +export const createRule = async ({ + actionId, + pattern, + supertest, + objectRemover, + overwrites, +}: { + actionId: string; + pattern: { instance: boolean[] }; + supertest: SuperTest; + objectRemover: ObjectRemover; + overwrites?: any; +}) => { + const { body: createdRule } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + name: 'test-rule', + rule_type_id: 'test.patternFiring', + schedule: { interval: '24h' }, + throttle: null, + notify_when: 'onActiveAlert', + params: { + pattern, + }, + actions: [ + { + id: actionId, + group: 'default', + params: {}, + }, + { + id: actionId, + group: 'recovered', + params: {}, + }, + ], + ...overwrites, + }) + ) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdRule.id, 'rule', 'alerting'); + return createdRule; +}; + +export const createAction = async ({ + supertest, + objectRemover, +}: { + supertest: SuperTest; + objectRemover: ObjectRemover; +}) => { + const { body: createdAction } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'MY action', + connector_type_id: 'test.noop', + config: {}, + secrets: {}, + }) + .expect(200); + + objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); + return createdAction; +}; + +export const createMaintenanceWindow = async ({ + overwrites, + supertest, + objectRemover, +}: { + overwrites?: any; + supertest: SuperTest; + objectRemover: ObjectRemover; +}) => { + const { body: window } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/maintenance_window`) + .set('kbn-xsrf', 'foo') + .send({ + title: 'test-maintenance-window-1', + duration: 60 * 60 * 1000, // 1 hr + r_rule: { + dtstart: moment.utc().toISOString(), + tzid: 'UTC', + freq: 0, // yearly + count: 1, + }, + ...overwrites, + }) + .expect(200); + + objectRemover.add(Spaces.space1.id, window.id, 'rules/maintenance_window', 'alerting', true); + return window; +}; + +export const getActiveMaintenanceWindows = async ({ + supertest, +}: { + supertest: SuperTest; +}) => { + const { body: activeMaintenanceWindows } = await supertest + .get(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/maintenance_window/_active`) + .set('kbn-xsrf', 'foo') + .expect(200); + + return activeMaintenanceWindows; +}; + +export const finishMaintenanceWindow = async ({ + id, + supertest, +}: { + id: string; + supertest: SuperTest; +}) => { + return supertest + .post( + `${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/maintenance_window/${id}/_finish` + ) + .set('kbn-xsrf', 'foo') + .expect(200); +}; + +export const getRuleEvents = async ({ + id, + action, + newInstance, + activeInstance, + recoveredInstance, + retry, + getService, +}: { + id: string; + action?: number; + newInstance?: number; + activeInstance?: number; + recoveredInstance?: number; + retry: RetryService; + getService: FtrProviderContext['getService']; +}) => { + const actions: Array<[string, { equal: number }]> = []; + if (action) { + actions.push(['execute-action', { equal: action }]); + } + if (newInstance) { + actions.push(['new-instance', { equal: newInstance }]); + } + if (activeInstance) { + actions.push(['active-instance', { equal: activeInstance }]); + } + if (recoveredInstance) { + actions.push(['recovered-instance', { equal: recoveredInstance }]); + } + return retry.try(async () => { + return await getEventLog({ + getService, + spaceId: Spaces.space1.id, + type: 'alert', + id, + provider: 'alerting', + actions: new Map(actions), + }); + }); +}; + +export const expectNoActionsFired = async ({ + id, + supertest, + retry, +}: { + id: string; + supertest: SuperTest; + retry: RetryService; +}) => { + const events = await retry.try(async () => { + const { body: result } = await supertest + .get(`${getUrlPrefix(Spaces.space1.id)}/_test/event_log/alert/${id}/_find?per_page=5000`) + .expect(200); + + if (!result.total) { + throw new Error('no events found yet'); + } + return result.data as IValidatedEvent[]; + }); + + const actionEvents = events.filter((event) => { + return event?.event?.action === 'execute-action'; + }); + + expect(actionEvents.length).eql(0); +}; + +export const runSoon = async ({ + id, + supertest, + retry, +}: { + id: string; + supertest: SuperTest; + retry: RetryService; +}) => { + return retry.try(async () => { + await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${id}/_run_soon`) + .set('kbn-xsrf', 'foo') + .expect(204); + }); +};