Add flapping state object and interface in AAD index and Event Log (#143920)

* move flapping to kibana.alerting in event log

* move flapping back to under kibana.alert. Add integration tests

* add default flapping state to alert logs
This commit is contained in:
Ersin Erdal 2022-11-07 18:15:30 +01:00 committed by GitHub
parent 5e7989844d
commit c5bcfd6762
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 192 additions and 30 deletions

View file

@ -30,6 +30,7 @@ const ALERT_DURATION = `${ALERT_NAMESPACE}.duration.us` as const;
const ALERT_END = `${ALERT_NAMESPACE}.end` as const;
const ALERT_EVALUATION_THRESHOLD = `${ALERT_NAMESPACE}.evaluation.threshold` as const;
const ALERT_EVALUATION_VALUE = `${ALERT_NAMESPACE}.evaluation.value` as const;
const ALERT_FLAPPING = `${ALERT_NAMESPACE}.flapping` as const;
const ALERT_INSTANCE_ID = `${ALERT_NAMESPACE}.instance.id` as const;
const ALERT_REASON = `${ALERT_NAMESPACE}.reason` as const;
const ALERT_RISK_SCORE = `${ALERT_NAMESPACE}.risk_score` as const;
@ -115,6 +116,7 @@ const fields = {
ALERT_END,
ALERT_EVALUATION_THRESHOLD,
ALERT_EVALUATION_VALUE,
ALERT_FLAPPING,
ALERT_INSTANCE_ID,
ALERT_RULE_CONSUMER,
ALERT_RULE_PRODUCER,
@ -176,6 +178,7 @@ export {
ALERT_END,
ALERT_EVALUATION_THRESHOLD,
ALERT_EVALUATION_VALUE,
ALERT_FLAPPING,
ALERT_INSTANCE_ID,
ALERT_NAMESPACE,
ALERT_RULE_NAMESPACE,

View file

@ -36,4 +36,5 @@ export interface AlertStatus {
muted: boolean;
actionGroupId?: string;
activeStartDate?: string;
flapping: boolean;
}

View file

@ -122,12 +122,14 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": true,
"status": "OK",
},
"alert-2": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": true,
"status": "OK",
},
@ -232,6 +234,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": false,
"status": "OK",
},
@ -272,6 +275,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": false,
"status": "OK",
},
@ -311,6 +315,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": false,
"status": "OK",
},
@ -351,6 +356,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": "action group A",
"activeStartDate": "2020-06-18T00:00:00.000Z",
"flapping": false,
"muted": false,
"status": "Active",
},
@ -391,6 +397,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": undefined,
"activeStartDate": "2020-06-18T00:00:00.000Z",
"flapping": false,
"muted": false,
"status": "Active",
},
@ -431,6 +438,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": "action group B",
"activeStartDate": "2020-06-18T00:00:00.000Z",
"flapping": false,
"muted": false,
"status": "Active",
},
@ -469,6 +477,7 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": "action group A",
"activeStartDate": undefined,
"flapping": false,
"muted": false,
"status": "Active",
},
@ -511,12 +520,14 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": "action group A",
"activeStartDate": "2020-06-18T00:00:00.000Z",
"flapping": false,
"muted": true,
"status": "Active",
},
"alert-2": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": true,
"status": "OK",
},
@ -566,12 +577,14 @@ describe('alertSummaryFromEventLog', () => {
"alert-1": Object {
"actionGroupId": "action group B",
"activeStartDate": "2020-06-18T00:00:00.000Z",
"flapping": false,
"muted": false,
"status": "Active",
},
"alert-2": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": false,
"status": "OK",
},
@ -584,6 +597,43 @@ describe('alertSummaryFromEventLog', () => {
testExecutionDurations(eventsFactory.getExecutionDurations(), executionDuration);
});
test('rule with currently active alert, flapping', async () => {
const rule = createRule({});
const eventsFactory = new EventsFactory();
const events = eventsFactory
.addExecute()
.addActiveAlert('alert-1', 'action group A', true)
.getEvents();
const executionEvents = eventsFactory.getEvents();
const summary: AlertSummary = alertSummaryFromEventLog({
rule,
events,
executionEvents,
dateStart,
dateEnd,
});
const { lastRun, status, alerts, executionDuration } = summary;
expect({ lastRun, status, alerts }).toMatchInlineSnapshot(`
Object {
"alerts": Object {
"alert-1": Object {
"actionGroupId": "action group A",
"activeStartDate": undefined,
"flapping": true,
"muted": false,
"status": "Active",
},
},
"lastRun": "2020-06-18T00:00:00.000Z",
"status": "Active",
}
`);
testExecutionDurations(eventsFactory.getExecutionDurations(), executionDuration);
});
const testExecutionDurations = (
actualDurations: Record<string, number>,
executionDuration?: {
@ -642,7 +692,11 @@ export class EventsFactory {
return this;
}
addActiveAlert(alertId: string, actionGroupId: string | undefined): EventsFactory {
addActiveAlert(
alertId: string,
actionGroupId: string | undefined,
flapping = false
): EventsFactory {
const kibanaAlerting = actionGroupId
? { instance_id: alertId, action_group_id: actionGroupId }
: { instance_id: alertId };
@ -652,7 +706,7 @@ export class EventsFactory {
provider: EVENT_LOG_PROVIDER,
action: EVENT_LOG_ACTIONS.activeInstance,
},
kibana: { alerting: kibanaAlerting },
kibana: { alerting: kibanaAlerting, alert: { flapping } },
});
return this;
}

View file

@ -80,6 +80,11 @@ export function alertSummaryFromEventLog(params: AlertSummaryFromEventLogParams)
if (alertId === undefined) continue;
const status = getAlertStatus(alerts, alertId);
if (event?.kibana?.alert?.flapping) {
status.flapping = true;
}
switch (action) {
case EVENT_LOG_ACTIONS.newInstance:
status.activeStartDate = timeStamp;
@ -152,6 +157,7 @@ function getAlertStatus(alerts: Map<string, AlertStatus>, alertId: string): Aler
muted: false,
actionGroupId: undefined,
activeStartDate: undefined,
flapping: false,
};
alerts.set(alertId, status);
return status;

View file

@ -66,6 +66,7 @@ const alert = {
end: '2020-01-01T03:00:00.000Z',
duration: '2343252346',
},
flapping: false,
};
const action = {

View file

@ -48,6 +48,7 @@ interface AlertOpts {
message: string;
group?: string;
state?: AlertInstanceState;
flapping: boolean;
}
interface ActionOpts {
@ -247,6 +248,7 @@ export function createAlertRecord(context: RuleContextOpts, alert: AlertOpts) {
},
],
ruleName: context.ruleName,
flapping: alert.flapping,
});
}

View file

@ -35,6 +35,7 @@ interface CreateAlertEventLogRecordParams {
typeId: string;
relation?: string;
}>;
flapping?: boolean;
}
export function createAlertEventLogRecordObject(params: CreateAlertEventLogRecordParams): Event {
@ -50,6 +51,7 @@ export function createAlertEventLogRecordObject(params: CreateAlertEventLogRecor
namespace,
consumer,
spaceId,
flapping,
} = params;
const alerting =
params.instanceId || group
@ -72,6 +74,7 @@ export function createAlertEventLogRecordObject(params: CreateAlertEventLogRecor
},
kibana: {
alert: {
...(flapping !== undefined ? { flapping } : {}),
rule: {
rule_type_id: ruleType.id,
...(consumer ? { consumer } : {}),

View file

@ -128,7 +128,7 @@ describe('getAlertSummary()', () => {
.advanceTime(10000)
.addExecute()
.addRecoveredAlert('alert-previously-active')
.addActiveAlert('alert-currently-active', 'action group A')
.addActiveAlert('alert-currently-active', 'action group A', true)
.getEvents();
const eventsResult = {
...AlertSummaryFindEventsResult,
@ -157,18 +157,21 @@ describe('getAlertSummary()', () => {
"alert-currently-active": Object {
"actionGroupId": "action group A",
"activeStartDate": "2019-02-12T21:01:22.479Z",
"flapping": true,
"muted": false,
"status": "Active",
},
"alert-muted-no-activity": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": true,
"status": "OK",
},
"alert-previously-active": Object {
"actionGroupId": undefined,
"activeStartDate": undefined,
"flapping": false,
"muted": false,
"status": "OK",
},

View file

@ -198,6 +198,7 @@ export const generateAlertOpts = ({ action, group, state, id }: GeneratorParams
message,
state,
...(group ? { group } : {}),
flapping: false,
};
};

View file

@ -158,48 +158,56 @@ describe('logAlerts', () => {
id: '7',
message: "test-rule-type-id:123: 'test rule' alert '7' has recovered",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(2, {
action: 'recovered-instance',
id: '8',
message: "test-rule-type-id:123: 'test rule' alert '8' has recovered",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(3, {
action: 'recovered-instance',
id: '9',
message: "test-rule-type-id:123: 'test rule' alert '9' has recovered",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(4, {
action: 'recovered-instance',
id: '10',
message: "test-rule-type-id:123: 'test rule' alert '10' has recovered",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(5, {
action: 'new-instance',
id: '4',
message: "test-rule-type-id:123: 'test rule' created new alert: '4'",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(6, {
action: 'active-instance',
id: '1',
message: "test-rule-type-id:123: 'test rule' active alert: '1' in actionGroup: 'undefined'",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(7, {
action: 'active-instance',
id: '2',
message: "test-rule-type-id:123: 'test rule' active alert: '2' in actionGroup: 'undefined'",
state: {},
flapping: false,
});
expect(alertingEventLogger.logAlert).toHaveBeenNthCalledWith(8, {
action: 'active-instance',
id: '4',
message: "test-rule-type-id:123: 'test rule' active alert: '4' in actionGroup: 'undefined'",
state: {},
flapping: false,
});
});

View file

@ -102,6 +102,7 @@ export function logAlerts<
group: actionGroup,
message,
state,
flapping: false,
});
}
@ -115,6 +116,7 @@ export function logAlerts<
group: actionGroup,
message,
state,
flapping: false,
});
}
@ -128,6 +130,7 @@ export function logAlerts<
group: actionGroup,
message,
state,
flapping: false,
});
}
}

View file

@ -276,6 +276,9 @@
},
"alert": {
"properties": {
"flapping": {
"type": "boolean"
},
"rule": {
"properties": {
"consumer": {

View file

@ -120,6 +120,7 @@ export const EventSchema = schema.maybe(
),
alert: schema.maybe(
schema.object({
flapping: ecsBoolean(),
rule: schema.maybe(
schema.object({
consumer: ecsString(),
@ -199,6 +200,10 @@ function ecsDate() {
return schema.maybe(schema.string({ validate: validateDate }));
}
function ecsBoolean() {
return schema.maybe(schema.boolean());
}
const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
function validateDate(isoDate: string) {

View file

@ -161,6 +161,11 @@ function generateSchemaLines(lineWriter, prop, mappings) {
return;
}
if (mappings.type === 'boolean') {
lineWriter.addLine(`${propKey}: ecsBoolean(),`);
return;
}
// only handling objects for the rest of this function
if (mappings.properties == null) {
logError(`unknown properties to map: ${prop}: ${JSON.stringify(mappings)}`);
@ -324,6 +329,10 @@ function ecsDate() {
return schema.maybe(schema.string({ validate: validateDate }));
}
function ecsBoolean() {
return schema.maybe(schema.boolean());
}
const ISO_DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;
function validateDate(isoDate: string) {

View file

@ -58,6 +58,9 @@ exports.EcsCustomPropertyMappings = {
},
alert: {
properties: {
flapping: {
type: 'boolean',
},
rule: {
properties: {
consumer: {

View file

@ -43,6 +43,9 @@ it('matches snapshot', () => {
"kibana.alert.end": Object {
"type": "date",
},
"kibana.alert.flapping": Object {
"type": "boolean",
},
"kibana.alert.instance.id": Object {
"required": true,
"type": "keyword",

View file

@ -33,6 +33,7 @@ export const technicalRuleFieldMap = {
[Fields.ALERT_DURATION]: { type: 'long' },
[Fields.ALERT_SEVERITY]: { type: 'keyword' },
[Fields.ALERT_STATUS]: { type: 'keyword', required: true },
[Fields.ALERT_FLAPPING]: { type: 'boolean' },
[Fields.VERSION]: {
type: 'version',
array: false,

View file

@ -37,6 +37,7 @@ import {
TAGS,
TIMESTAMP,
VERSION,
// ALERT_FLAPPING,
} from '../../common/technical_rule_data_field_names';
import { CommonAlertFieldNameLatest, CommonAlertIdFieldNameLatest } from '../../common/schemas';
import { IRuleDataClient } from '../rule_data_client';

View file

@ -14,7 +14,13 @@ const http = httpServiceMock.createStartContract();
describe('loadRuleSummary', () => {
test('should call rule summary API', async () => {
const resolvedValue: RuleSummary = {
alerts: {},
alerts: {
'1': {
flapping: true,
status: 'OK',
muted: false,
},
},
consumer: 'alerts',
enabled: true,
errorMessages: [],
@ -35,7 +41,13 @@ describe('loadRuleSummary', () => {
};
http.get.mockResolvedValueOnce({
alerts: {},
alerts: {
'1': {
flapping: true,
status: 'OK',
muted: false,
},
},
consumer: 'alerts',
enabled: true,
error_messages: [],

View file

@ -72,11 +72,13 @@ describe('rules', () => {
status: 'OK',
muted: false,
actionGroupId: 'default',
flapping: false,
},
second_rule: {
status: 'Active',
muted: false,
actionGroupId: 'action group id unknown',
flapping: false,
},
},
});
@ -134,10 +136,12 @@ describe('rules', () => {
['us-central']: {
status: 'OK',
muted: false,
flapping: false,
},
['us-east']: {
status: 'OK',
muted: false,
flapping: false,
},
};
@ -169,8 +173,8 @@ describe('rules', () => {
mutedInstanceIds: ['us-west', 'us-east'],
});
const ruleType = mockRuleType();
const ruleUsWest: AlertStatus = { status: 'OK', muted: false };
const ruleUsEast: AlertStatus = { status: 'OK', muted: false };
const ruleUsWest: AlertStatus = { status: 'OK', muted: false, flapping: false };
const ruleUsEast: AlertStatus = { status: 'OK', muted: false, flapping: false };
const wrapper = mountWithIntl(
<RuleComponent
@ -183,10 +187,12 @@ describe('rules', () => {
'us-west': {
status: 'OK',
muted: false,
flapping: false,
},
'us-east': {
status: 'OK',
muted: false,
flapping: false,
},
},
})}
@ -219,6 +225,7 @@ describe('alertToListItem', () => {
muted: false,
activeStartDate: fake2MinutesAgo.toISOString(),
actionGroupId: 'testing',
flapping: false,
};
expect(alertToListItem(fakeNow.getTime(), ruleType, 'id', alert)).toEqual({
@ -238,6 +245,7 @@ describe('alertToListItem', () => {
status: 'Active',
muted: false,
activeStartDate: fake2MinutesAgo.toISOString(),
flapping: false,
};
expect(alertToListItem(fakeNow.getTime(), ruleType, 'id', alert)).toEqual({
@ -258,6 +266,7 @@ describe('alertToListItem', () => {
muted: true,
activeStartDate: fake2MinutesAgo.toISOString(),
actionGroupId: 'default',
flapping: false,
};
expect(alertToListItem(fakeNow.getTime(), ruleType, 'id', alert)).toEqual({
@ -276,6 +285,7 @@ describe('alertToListItem', () => {
status: 'Active',
muted: false,
actionGroupId: 'default',
flapping: false,
};
expect(alertToListItem(fakeNow.getTime(), ruleType, 'id', alert)).toEqual({
@ -294,6 +304,7 @@ describe('alertToListItem', () => {
status: 'OK',
muted: true,
actionGroupId: 'default',
flapping: false,
};
expect(alertToListItem(fakeNow.getTime(), ruleType, 'id', alert)).toEqual({
alert: 'id',
@ -389,11 +400,13 @@ describe('tabbed content', () => {
status: 'OK',
muted: false,
actionGroupId: 'default',
flapping: false,
},
second_rule: {
status: 'Active',
muted: false,
actionGroupId: 'action group id unknown',
flapping: false,
},
},
});
@ -473,6 +486,7 @@ function mockRuleSummary(overloads: Partial<RuleSummary> = {}): RuleSummary {
status: 'OK',
muted: false,
actionGroupId: 'testActionGroup',
flapping: false,
},
},
executionDuration: {

View file

@ -167,6 +167,7 @@ function mockRuleSummary(overloads: Partial<any> = {}): any {
foo: {
status: 'OK',
muted: false,
flapping: false,
},
},
executionDuration: {

View file

@ -101,6 +101,7 @@ export function mockRuleSummary(overloads: Partial<RuleSummary> = {}): RuleSumma
status: 'OK',
muted: false,
actionGroupId: 'testActionGroup',
flapping: false,
},
},
executionDuration: {

View file

@ -193,6 +193,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
event,
`created new alert: 'instance'`,
false,
false,
currentExecutionId
);
break;
@ -202,6 +203,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
event,
`alert 'instance' has recovered`,
true,
false,
currentExecutionId
);
break;
@ -211,6 +213,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
event,
`active alert: 'instance' in actionGroup: 'default'`,
false,
false,
currentExecutionId
);
break;
@ -259,33 +262,11 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
});
});
for (const event of actionEvents) {
switch (event?.event?.action) {
case 'execute':
expect(event?.kibana?.alert?.rule?.execution?.uuid).not.to.be(undefined);
expect(
executionIds.indexOf(event?.kibana?.alert?.rule?.execution?.uuid)
).to.be.greaterThan(-1);
validateEvent(event, {
spaceId: space.id,
savedObjects: [
{ type: 'action', id: createdAction.id, rel: 'primary', type_id: 'test.noop' },
],
message: `action executed: test.noop:${createdAction.id}: MY action`,
outcome: 'success',
shouldHaveTask: true,
ruleTypeId: response.body.rule_type_id,
rule: undefined,
consumer: 'alertsFixture',
});
break;
}
}
function validateInstanceEvent(
event: IValidatedEvent,
subMessage: string,
shouldHaveEventEnd: boolean,
flapping: boolean,
executionId?: string
) {
validateEvent(event, {
@ -307,8 +288,32 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
name: response.body.name,
},
consumer: 'alertsFixture',
flapping,
});
}
for (const event of actionEvents) {
switch (event?.event?.action) {
case 'execute':
expect(event?.kibana?.alert?.rule?.execution?.uuid).not.to.be(undefined);
expect(
executionIds.indexOf(event?.kibana?.alert?.rule?.execution?.uuid)
).to.be.greaterThan(-1);
validateEvent(event, {
spaceId: space.id,
savedObjects: [
{ type: 'action', id: createdAction.id, rel: 'primary', type_id: 'test.noop' },
],
message: `action executed: test.noop:${createdAction.id}: MY action`,
outcome: 'success',
shouldHaveTask: true,
ruleTypeId: response.body.rule_type_id,
rule: undefined,
consumer: 'alertsFixture',
});
break;
}
}
});
it('should generate expected events for rules with multiple searches', async () => {
@ -567,6 +572,7 @@ interface ValidateEventLogParams {
ruleset?: string;
namespace?: string;
};
flapping?: boolean;
}
export function validateEvent(event: IValidatedEvent, params: ValidateEventLogParams): void {
@ -585,6 +591,7 @@ export function validateEvent(event: IValidatedEvent, params: ValidateEventLogPa
numRecoveredAlerts,
consumer,
ruleTypeId,
flapping,
} = params;
const { status, actionGroupId, instanceId, reason, shouldHaveEventEnd } = params;
@ -634,6 +641,10 @@ export function validateEvent(event: IValidatedEvent, params: ValidateEventLogPa
expect(event?.kibana?.alert?.rule?.execution?.metrics?.alert_counts?.new).to.be(numNewAlerts);
}
if (flapping !== undefined) {
expect(event?.kibana?.alert?.flapping).to.be(flapping);
}
expect(event?.kibana?.alert?.rule?.rule_type_id).to.be(ruleTypeId);
expect(event?.kibana?.space_ids?.[0]).to.equal(spaceId);

View file

@ -93,10 +93,12 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) {
start?: string;
durationToDate?: string;
} = {};
for (let i = 0; i < instanceEvents.length; ++i) {
switch (instanceEvents[i]?.event?.action) {
case 'new-instance':
expect(instanceEvents[i]?.kibana?.alerting?.instance_id).to.equal('instance');
expect(instanceEvents[i]?.kibana?.alert?.flapping).to.equal(false);
// a new alert should generate a unique UUID for the duration of its activeness
expect(instanceEvents[i]?.event?.end).to.be(undefined);
@ -107,6 +109,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) {
case 'active-instance':
expect(instanceEvents[i]?.kibana?.alerting?.instance_id).to.equal('instance');
expect(instanceEvents[i]?.kibana?.alert?.flapping).to.equal(false);
expect(instanceEvents[i]?.event?.start).to.equal(currentAlertSpan.start);
expect(instanceEvents[i]?.event?.end).to.be(undefined);
@ -121,6 +124,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) {
case 'recovered-instance':
expect(instanceEvents[i]?.kibana?.alerting?.instance_id).to.equal('instance');
expect(instanceEvents[i]?.kibana?.alert?.flapping).to.equal(false);
expect(instanceEvents[i]?.event?.start).to.equal(currentAlertSpan.start);
expect(instanceEvents[i]?.event?.end).not.to.be(undefined);
expect(

View file

@ -180,6 +180,7 @@ export default function createGetAlertSummaryTests({ getService }: FtrProviderCo
'1': {
status: 'OK',
muted: true,
flapping: false,
},
});
});
@ -239,20 +240,24 @@ export default function createGetAlertSummaryTests({ getService }: FtrProviderCo
muted: false,
actionGroupId: 'default',
activeStartDate: actualAlerts.alertA.activeStartDate,
flapping: false,
},
alertB: {
status: 'OK',
muted: false,
flapping: false,
},
alertC: {
status: 'Active',
muted: true,
actionGroupId: 'default',
activeStartDate: actualAlerts.alertC.activeStartDate,
flapping: false,
},
alertD: {
status: 'OK',
muted: true,
flapping: false,
},
};
expect(actualAlerts).to.eql(expectedAlerts);
@ -294,20 +299,24 @@ export default function createGetAlertSummaryTests({ getService }: FtrProviderCo
muted: false,
actionGroupId: 'default',
activeStartDate: actualAlerts.alertA.activeStartDate,
flapping: false,
},
alertB: {
status: 'OK',
muted: false,
flapping: false,
},
alertC: {
status: 'Active',
muted: true,
actionGroupId: 'default',
activeStartDate: actualAlerts.alertC.activeStartDate,
flapping: false,
},
alertD: {
status: 'OK',
muted: true,
flapping: false,
},
};
expect(actualAlerts).to.eql(expectedAlerts);