[AO] Add testing action variables to the Custom threshold rule API integration tests (#167757)

Closes #162950
Closes #161237

## Summary

This PR adds testing action variables to the Custom threshold rule API
integration tests.
This commit is contained in:
Maryam Saeidi 2023-10-04 16:35:45 +02:00 committed by GitHub
parent ad0c38d75d
commit 8a2843e281
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 152 additions and 30 deletions

View file

@ -51,10 +51,10 @@ export const generateEvent = (index: number, timestamp: Moment, interval: number
},
},
user: {
pct: randomBetween(1, 4),
pct: 2.5,
},
system: {
pct: randomBetween(1, 4),
pct: 3,
},
},
},

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import moment from 'moment';
import { cleanup, generate } from '@kbn/infra-forge';
import {
Aggregators,
@ -15,8 +16,13 @@ import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
import { createDataView, deleteDataView } from '../helpers/data_view';
import { waitForAlertInIndex, waitForRuleStatus } from '../helpers/alerting_wait_for_helpers';
import {
waitForAlertInIndex,
waitForDocumentInIndex,
waitForRuleStatus,
} from '../helpers/alerting_wait_for_helpers';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { ActionDocument } from './typings';
// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
@ -35,6 +41,8 @@ export default function ({ getService }: FtrProviderContext) {
let infraDataIndex: string;
let actionId: string;
let ruleId: string;
let alertId: string;
let startedAt: string;
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
@ -110,6 +118,10 @@ export default function ({ getService }: FtrProviderContext) {
documents: [
{
ruleType: '{{rule.type}}',
alertDetailsUrl: '{{context.alertDetailsUrl}}',
reason: '{{context.reason}}',
value: '{{context.value}}',
host: '{{context.host}}',
},
],
},
@ -140,6 +152,8 @@ export default function ({ getService }: FtrProviderContext) {
indexName: CUSTOM_THRESHOLD_RULE_ALERT_INDEX,
ruleId,
});
alertId = (resp.hits.hits[0]._source as any)['kibana.alert.uuid'];
startedAt = (resp.hits.hits[0]._source as any)['kibana.alert.start'];
expect(resp.hits.hits[0]._source).property(
'kibana.alert.rule.category',
@ -186,6 +200,23 @@ export default function ({ getService }: FtrProviderContext) {
searchConfiguration: { index: 'data-view-id', query: { query: '', language: 'kuery' } },
});
});
it('should set correct action variables', async () => {
const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString();
const resp = await waitForDocumentInIndex<ActionDocument>({
esClient,
indexName: ALERT_ACTION_INDEX,
});
expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold');
expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql(
`https://localhost:5601/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)`
);
expect(resp.hits.hits[0]._source?.reason).eql(
'Custom equation is 2.5 in the last 5 mins. Alert when > 0.5.'
);
expect(resp.hits.hits[0]._source?.value).eql('2.5');
});
});
});
}

View file

@ -5,23 +5,30 @@
* 2.0.
*/
import moment from 'moment';
import {
Aggregators,
Comparator,
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/custom_threshold/custom_threshold_executor';
import { NO_DATA_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/custom_threshold/custom_threshold_executor';
import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
import { createDataView, deleteDataView } from '../helpers/data_view';
import { waitForAlertInIndex, waitForRuleStatus } from '../helpers/alerting_wait_for_helpers';
import {
waitForAlertInIndex,
waitForDocumentInIndex,
waitForRuleStatus,
} from '../helpers/alerting_wait_for_helpers';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { ActionDocument } from './typings';
// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
const supertest = getService('supertest');
const esDeleteAllIndices = getService('esDeleteAllIndices');
describe('Custom Threshold rule - AVG - PCT - NoData', () => {
const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default';
@ -29,6 +36,8 @@ export default function ({ getService }: FtrProviderContext) {
const DATA_VIEW_ID = 'data-view-id-no-data';
let actionId: string;
let ruleId: string;
let alertId: string;
let startedAt: string;
before(async () => {
await createDataView({
@ -54,6 +63,7 @@ export default function ({ getService }: FtrProviderContext) {
supertest,
id: DATA_VIEW_ID,
});
await esDeleteAllIndices([ALERT_ACTION_INDEX]);
});
describe('Rule creation', () => {
@ -95,12 +105,15 @@ export default function ({ getService }: FtrProviderContext) {
},
actions: [
{
group: FIRED_ACTIONS_ID,
group: NO_DATA_ACTIONS_ID,
id: actionId,
params: {
documents: [
{
ruleType: '{{rule.type}}',
alertDetailsUrl: '{{context.alertDetailsUrl}}',
reason: '{{context.reason}}',
value: '{{context.value}}',
},
],
},
@ -131,6 +144,8 @@ export default function ({ getService }: FtrProviderContext) {
indexName: CUSTOM_THRESHOLD_RULE_ALERT_INDEX,
ruleId,
});
alertId = (resp.hits.hits[0]._source as any)['kibana.alert.uuid'];
startedAt = (resp.hits.hits[0]._source as any)['kibana.alert.start'];
expect(resp.hits.hits[0]._source).property(
'kibana.alert.rule.category',
@ -180,6 +195,23 @@ export default function ({ getService }: FtrProviderContext) {
},
});
});
it('should set correct action variables', async () => {
const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString();
const resp = await waitForDocumentInIndex<ActionDocument>({
esClient,
indexName: ALERT_ACTION_INDEX,
});
expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold');
expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql(
`https://localhost:5601/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)`
);
expect(resp.hits.hits[0]._source?.reason).eql(
'Custom equation reported no data in the last 5m'
);
expect(resp.hits.hits[0]._source?.value).eql('[NO DATA]');
});
});
});
}

View file

@ -24,6 +24,7 @@ import {
waitForDocumentInIndex,
waitForRuleStatus,
} from '../helpers/alerting_wait_for_helpers';
import { ActionDocument } from './typings';
// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
@ -206,12 +207,7 @@ export default function ({ getService }: FtrProviderContext) {
it('should set correct action parameter: ruleType', async () => {
const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString();
const resp = await waitForDocumentInIndex<{
ruleType: string;
alertDetailsUrl: string;
reason: string;
value: string;
}>({
const resp = await waitForDocumentInIndex<ActionDocument>({
esClient,
indexName: ALERT_ACTION_INDEX,
});

View file

@ -11,6 +11,7 @@
* 2.0.
*/
import moment from 'moment';
import { cleanup, generate } from '@kbn/infra-forge';
import {
Aggregators,
@ -21,8 +22,13 @@ import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
import { createDataView, deleteDataView } from '../helpers/data_view';
import { waitForAlertInIndex, waitForRuleStatus } from '../helpers/alerting_wait_for_helpers';
import {
waitForAlertInIndex,
waitForDocumentInIndex,
waitForRuleStatus,
} from '../helpers/alerting_wait_for_helpers';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { ActionDocument } from './typings';
// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
@ -41,6 +47,8 @@ export default function ({ getService }: FtrProviderContext) {
let infraDataIndex: string;
let actionId: string;
let ruleId: string;
let alertId: string;
let startedAt: string;
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
@ -118,6 +126,9 @@ export default function ({ getService }: FtrProviderContext) {
documents: [
{
ruleType: '{{rule.type}}',
alertDetailsUrl: '{{context.alertDetailsUrl}}',
reason: '{{context.reason}}',
value: '{{context.value}}',
},
],
},
@ -148,6 +159,8 @@ export default function ({ getService }: FtrProviderContext) {
indexName: CUSTOM_THRESHOLD_RULE_ALERT_INDEX,
ruleId,
});
alertId = (resp.hits.hits[0]._source as any)['kibana.alert.uuid'];
startedAt = (resp.hits.hits[0]._source as any)['kibana.alert.start'];
expect(resp.hits.hits[0]._source).property(
'kibana.alert.rule.category',
@ -198,6 +211,23 @@ export default function ({ getService }: FtrProviderContext) {
searchConfiguration: { index: 'data-view-id', query: { query: '', language: 'kuery' } },
});
});
it('should set correct action variables', async () => {
const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString();
const resp = await waitForDocumentInIndex<ActionDocument>({
esClient,
indexName: ALERT_ACTION_INDEX,
});
expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold');
expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql(
`https://localhost:5601/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)`
);
expect(resp.hits.hits[0]._source?.reason).eql(
'Custom equation is 1 in the last 1 min. Alert when > 0.9.'
);
expect(resp.hits.hits[0]._source?.value).eql('1');
});
});
});
}

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import moment from 'moment';
import { cleanup, generate } from '@kbn/infra-forge';
import {
Aggregators,
@ -15,8 +16,13 @@ import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
import { createDataView, deleteDataView } from '../helpers/data_view';
import { waitForAlertInIndex, waitForRuleStatus } from '../helpers/alerting_wait_for_helpers';
import {
waitForAlertInIndex,
waitForDocumentInIndex,
waitForRuleStatus,
} from '../helpers/alerting_wait_for_helpers';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { ActionDocument } from './typings';
// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
@ -35,6 +41,8 @@ export default function ({ getService }: FtrProviderContext) {
let infraDataIndex: string;
let actionId: string;
let ruleId: string;
let alertId: string;
let startedAt: string;
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
@ -108,6 +116,9 @@ export default function ({ getService }: FtrProviderContext) {
documents: [
{
ruleType: '{{rule.type}}',
alertDetailsUrl: '{{context.alertDetailsUrl}}',
reason: '{{context.reason}}',
value: '{{context.value}}',
},
],
},
@ -138,6 +149,8 @@ export default function ({ getService }: FtrProviderContext) {
indexName: CUSTOM_THRESHOLD_RULE_ALERT_INDEX,
ruleId,
});
alertId = (resp.hits.hits[0]._source as any)['kibana.alert.uuid'];
startedAt = (resp.hits.hits[0]._source as any)['kibana.alert.start'];
expect(resp.hits.hits[0]._source).property(
'kibana.alert.rule.category',
@ -186,6 +199,23 @@ export default function ({ getService }: FtrProviderContext) {
searchConfiguration: { index: 'data-view-id', query: { query: '', language: 'kuery' } },
});
});
it('should set correct action variables', async () => {
const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString();
const resp = await waitForDocumentInIndex<ActionDocument>({
esClient,
indexName: ALERT_ACTION_INDEX,
});
expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold');
expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql(
`https://localhost:5601/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)`
);
expect(resp.hits.hits[0]._source?.reason).eql(
'Custom equation is 3 in the last 1 min. Alert when > 2.'
);
expect(resp.hits.hits[0]._source?.value).eql('3');
});
});
});
}

View file

@ -4,12 +4,6 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.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 moment from 'moment';
import { cleanup, generate } from '@kbn/infra-forge';
@ -28,6 +22,7 @@ import {
waitForRuleStatus,
} from '../helpers/alerting_wait_for_helpers';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { ActionDocument } from './typings';
// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
@ -35,8 +30,6 @@ export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const esDeleteAllIndices = getService('esDeleteAllIndices');
const logger = getService('log');
let alertId: string;
let startedAt: string;
describe('Custom Threshold rule - GROUP_BY - FIRED', () => {
const CUSTOM_THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default';
@ -48,6 +41,8 @@ export default function ({ getService }: FtrProviderContext) {
let infraDataIndex: string;
let actionId: string;
let ruleId: string;
let alertId: string;
let startedAt: string;
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
@ -235,14 +230,7 @@ export default function ({ getService }: FtrProviderContext) {
it('should set correct action variables', async () => {
const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString();
const resp = await waitForDocumentInIndex<{
ruleType: string;
alertDetailsUrl: string;
reason: string;
value: string;
host: string;
group: string;
}>({
const resp = await waitForDocumentInIndex<ActionDocument>({
esClient,
indexName: ALERT_ACTION_INDEX,
});

View file

@ -0,0 +1,15 @@
/*
* 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 interface ActionDocument {
ruleType: string;
alertDetailsUrl: string;
reason: string;
value: string;
host?: string;
group?: string;
}