mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[RAM][Maintenance Window] Improve Maintenance Window Backend Integration Testing (#157120)
## Summary Resolves: https://github.com/elastic/kibana/issues/155902 Improves backend integration testing for maintenance windows, tests the following: # API: - Add more tests around create/update, ensuring events are generated correctly - Add more tests around `/_active`, ensuring the query we use is solid - Add more tests around cancelling/archiving - Verify functionality of the 3 MW scenarios - Verify summarized actions and security rules function correctly ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
556ba07452
commit
9910615a3d
11 changed files with 674 additions and 10 deletions
|
@ -33,8 +33,7 @@ export default function activeMaintenanceWindowTests({ getService }: FtrProvider
|
|||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
describe(scenario.id, () => {
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
it('should handle update maintenance window request appropriately', async () => {
|
||||
it('should handle get active maintenance window request appropriately', async () => {
|
||||
// Create 2 active and 1 inactive maintenance window
|
||||
const { body: createdMaintenanceWindow1 } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/internal/alerting/rules/maintenance_window`)
|
||||
|
|
|
@ -27,7 +27,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider
|
|||
freq: 2, // weekly
|
||||
},
|
||||
};
|
||||
after(() => objectRemover.removeAll());
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
|
||||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
|
@ -84,5 +84,103 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('can archive and unarchive a maintenance window', async () => {
|
||||
const space1 = UserAtSpaceScenarios[1].space.id;
|
||||
const { body: createdMaintenanceWindow } = await supertest
|
||||
.post(`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send(createParams)
|
||||
.expect(200);
|
||||
|
||||
objectRemover.add(
|
||||
space1,
|
||||
createdMaintenanceWindow.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
expect(createdMaintenanceWindow.status).eql('running');
|
||||
|
||||
const { body: archive } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_archive`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({ archive: true })
|
||||
.expect(200);
|
||||
|
||||
expect(archive.status).eql('archived');
|
||||
|
||||
const { body: unarchived } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_archive`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({ archive: false })
|
||||
.expect(200);
|
||||
|
||||
expect(unarchived.status).eql('running');
|
||||
});
|
||||
|
||||
it('archiving a finished maintenance window does not change the events', async () => {
|
||||
const space1 = UserAtSpaceScenarios[1].space.id;
|
||||
const { body: createdMaintenanceWindow } = await supertest
|
||||
.post(`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
...createParams,
|
||||
r_rule: {
|
||||
...createParams.r_rule,
|
||||
dtstart: moment.utc().subtract(1, 'day').toISOString(),
|
||||
freq: 3, // daily
|
||||
count: 4,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
objectRemover.add(
|
||||
space1,
|
||||
createdMaintenanceWindow.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
const { body: finish } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_finish`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send()
|
||||
.expect(200);
|
||||
|
||||
// The finished maintenance window has a different end date for the first event
|
||||
expect(finish.events[0].lte).eql(createdMaintenanceWindow.events[0].lte);
|
||||
expect(finish.events[1].lte).not.eql(createdMaintenanceWindow.events[1].lte);
|
||||
expect(finish.events[2].lte).eql(createdMaintenanceWindow.events[2].lte);
|
||||
expect(finish.events[3].lte).eql(createdMaintenanceWindow.events[3].lte);
|
||||
|
||||
const { body: archive } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_archive`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({ archive: true })
|
||||
.expect(200);
|
||||
|
||||
// Archiving should not change the events
|
||||
expect(finish.events[0].lte).eql(archive.events[0].lte);
|
||||
expect(finish.events[1].lte).eql(archive.events[1].lte);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function createMaintenanceWindowTests({ getService }: FtrProvider
|
|||
freq: 2, // weekly
|
||||
},
|
||||
};
|
||||
after(() => objectRemover.removeAll());
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
|
||||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function deleteMaintenanceWindowTests({ getService }: FtrProvider
|
|||
freq: 2, // weekly
|
||||
},
|
||||
};
|
||||
after(() => objectRemover.removeAll());
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
|
||||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
|
|
|
@ -26,13 +26,12 @@ export default function findMaintenanceWindowTests({ getService }: FtrProviderCo
|
|||
freq: 2, // weekly
|
||||
},
|
||||
};
|
||||
after(() => objectRemover.removeAll());
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
|
||||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
describe(scenario.id, () => {
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
it('should handle update maintenance window request appropriately', async () => {
|
||||
it('should handle find maintenance window request appropriately', async () => {
|
||||
const { body: createdMaintenanceWindow1 } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
|
|
|
@ -80,5 +80,99 @@ export default function findMaintenanceWindowTests({ getService }: FtrProviderCo
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('should error when trying to finish a finished maintenance window', async () => {
|
||||
const space1 = UserAtSpaceScenarios[1].space.id;
|
||||
const { body: createdMaintenanceWindow } = await supertest
|
||||
.post(`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
...createParams,
|
||||
r_rule: {
|
||||
...createParams.r_rule,
|
||||
count: 1,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
objectRemover.add(
|
||||
space1,
|
||||
createdMaintenanceWindow.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
const { body: finish } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_finish`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send()
|
||||
.expect(200);
|
||||
expect(finish.status).eql('finished');
|
||||
|
||||
// Cant finish a finished maintenance window
|
||||
await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_finish`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send()
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
it('should error when trying to finish a upcoming maintenance window', async () => {
|
||||
const space1 = UserAtSpaceScenarios[1].space.id;
|
||||
const { body: createdMaintenanceWindow } = await supertest
|
||||
.post(`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
...createParams,
|
||||
r_rule: {
|
||||
...createParams.r_rule,
|
||||
count: 2, // 2 occurrences
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
objectRemover.add(
|
||||
space1,
|
||||
createdMaintenanceWindow.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
const { body: finish } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_finish`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send()
|
||||
.expect(200);
|
||||
|
||||
// Status now upcoming, new start and end dates reflect the upcoming event
|
||||
expect(finish.status).eql('upcoming');
|
||||
expect(finish.event_start_time).eql(createdMaintenanceWindow.events[1].gte);
|
||||
expect(finish.event_end_time).eql(createdMaintenanceWindow.events[1].lte);
|
||||
|
||||
// Cannot finish an upcoming maintenance window
|
||||
await supertest
|
||||
.post(
|
||||
`${getUrlPrefix(space1)}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}/_finish`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send()
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function getMaintenanceWindowTests({ getService }: FtrProviderCon
|
|||
freq: 2, // weekly
|
||||
},
|
||||
};
|
||||
after(() => objectRemover.removeAll());
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
|
||||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
|
|
|
@ -27,7 +27,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider
|
|||
freq: 2, // weekly
|
||||
},
|
||||
};
|
||||
after(() => objectRemover.removeAll());
|
||||
afterEach(() => objectRemover.removeAll());
|
||||
|
||||
for (const scenario of UserAtSpaceScenarios) {
|
||||
const { user, space } = scenario;
|
||||
|
@ -90,6 +90,58 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider
|
|||
});
|
||||
}
|
||||
|
||||
it('should update fields correctly', async () => {
|
||||
const { body: createdMaintenanceWindow } = await supertest
|
||||
.post(`${getUrlPrefix('space1')}/internal/alerting/rules/maintenance_window`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
title: 'test-maintenance-window',
|
||||
duration: 60 * 60 * 1000, // 1 hr
|
||||
r_rule: {
|
||||
dtstart: new Date().toISOString(),
|
||||
tzid: 'UTC',
|
||||
freq: 2, // weekly
|
||||
count: 1,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
objectRemover.add(
|
||||
'space1',
|
||||
createdMaintenanceWindow.id,
|
||||
'rules/maintenance_window',
|
||||
'alerting',
|
||||
true
|
||||
);
|
||||
|
||||
const newRRule = {
|
||||
dtstart: moment.utc().add(1, 'day').toISOString(),
|
||||
tzid: 'CET',
|
||||
freq: 3,
|
||||
count: 5,
|
||||
};
|
||||
|
||||
const { body: updatedMW } = await supertest
|
||||
.post(
|
||||
`${getUrlPrefix('space1')}/internal/alerting/rules/maintenance_window/${
|
||||
createdMaintenanceWindow.id
|
||||
}`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
title: 'test-maintenance-window-new',
|
||||
duration: 60 * 1000,
|
||||
r_rule: newRRule,
|
||||
enabled: false,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(updatedMW.title).eql('test-maintenance-window-new');
|
||||
expect(updatedMW.duration).eql(60 * 1000);
|
||||
expect(updatedMW.r_rule).eql(newRRule);
|
||||
expect(updatedMW.title).eql('test-maintenance-window-new');
|
||||
});
|
||||
|
||||
it('should update RRule correctly when removing fields', async () => {
|
||||
const { body: createdMaintenanceWindow } = await supertest
|
||||
.post(`${getUrlPrefix('space1')}/internal/alerting/rules/maintenance_window`)
|
||||
|
|
|
@ -1308,6 +1308,104 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fire summary actions during maintenance window', async () => {
|
||||
const { body: window } = await supertest
|
||||
.post(`${getUrlPrefix(space.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,
|
||||
},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(space.id, window.id, 'rules/maintenance_window', 'alerting', true);
|
||||
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name: 'Test conn',
|
||||
connector_type_id: 'test.noop',
|
||||
config: {},
|
||||
secrets: {},
|
||||
})
|
||||
.expect(200);
|
||||
objectRemover.add(space.id, createdAction.id, 'action', 'actions');
|
||||
|
||||
const { body: createdRule } = await supertest
|
||||
.post(`${getUrlPrefix(space.id)}/api/alerting/rule`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send(
|
||||
getTestRuleData({
|
||||
rule_type_id: 'test.always-firing-alert-as-data',
|
||||
schedule: { interval: '24h' },
|
||||
throttle: undefined,
|
||||
notify_when: undefined,
|
||||
params: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
reference: 'test',
|
||||
},
|
||||
actions: [
|
||||
{
|
||||
id: createdAction.id,
|
||||
group: 'default',
|
||||
params: {
|
||||
index: ES_TEST_INDEX_NAME,
|
||||
reference: 'test',
|
||||
message: '',
|
||||
},
|
||||
frequency: {
|
||||
summary: true,
|
||||
throttle: null,
|
||||
notify_when: 'onActiveAlert',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
)
|
||||
.expect(200);
|
||||
objectRemover.add(space.id, createdRule.id, 'rule', 'alerting');
|
||||
|
||||
// get the events we're expecting
|
||||
await retry.try(async () => {
|
||||
return await getEventLog({
|
||||
getService,
|
||||
spaceId: space.id,
|
||||
type: 'alert',
|
||||
id: createdRule.id,
|
||||
provider: 'alerting',
|
||||
actions: new Map([
|
||||
['execute-start', { equal: 1 }],
|
||||
['execute', { equal: 1 }],
|
||||
['active-instance', { equal: 2 }],
|
||||
]),
|
||||
});
|
||||
});
|
||||
|
||||
// Try to get actions, should fail
|
||||
let hasActions = false;
|
||||
try {
|
||||
await getEventLog({
|
||||
getService,
|
||||
spaceId: space.id,
|
||||
type: 'alert',
|
||||
id: createdRule.id,
|
||||
provider: 'alerting',
|
||||
actions: new Map([['execute-action', { equal: 1 }]]),
|
||||
});
|
||||
hasActions = true;
|
||||
} catch (e) {
|
||||
hasActions = false;
|
||||
}
|
||||
|
||||
expect(hasActions).eql(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -15,5 +15,6 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC
|
|||
after(async () => await tearDown(getService));
|
||||
|
||||
loadTestFile(require.resolve('./builtin_alert_types'));
|
||||
loadTestFile(require.resolve('./maintenance_window_flows'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* 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 { 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function maintenanceWindowFlowsTests({ getService }: FtrProviderContext) {
|
||||
const supertestWithoutAuth = getService('supertestWithoutAuth');
|
||||
const supertest = getService('supertest');
|
||||
const retry = getService('retry');
|
||||
|
||||
describe('maintenanceWindowFlows', () => {
|
||||
const objectRemover = new ObjectRemover(supertestWithoutAuth);
|
||||
|
||||
afterEach(async () => {
|
||||
await objectRemover.removeAll();
|
||||
});
|
||||
|
||||
it('alerts triggered before a MW should fire actions when active or recovered during a MW', async () => {
|
||||
const pattern = {
|
||||
instance: [true, true, false, true],
|
||||
};
|
||||
|
||||
// Create action and rule
|
||||
const action = await createAction();
|
||||
const rule = await createRule({ actionId: action.id, pattern });
|
||||
|
||||
// Run the first time - active
|
||||
await getRuleEvents({
|
||||
id: rule.id,
|
||||
action: 1,
|
||||
activeInstance: 1,
|
||||
});
|
||||
|
||||
// Run again - active, 2 action
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({
|
||||
id: rule.id,
|
||||
action: 2,
|
||||
activeInstance: 2,
|
||||
});
|
||||
|
||||
// Create active maintenance window
|
||||
const maintenanceWindow = await createMaintenanceWindow();
|
||||
const activeMaintenanceWindows = await getActiveMaintenanceWindows();
|
||||
expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id);
|
||||
|
||||
// Run again - recovered, 3 actions, fired in MW
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({
|
||||
id: rule.id,
|
||||
action: 3,
|
||||
activeInstance: 2,
|
||||
recoveredInstance: 1,
|
||||
});
|
||||
|
||||
// Run again - active, 3 actions, new active action NOT fired in MW
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({
|
||||
id: rule.id,
|
||||
action: 3,
|
||||
activeInstance: 3,
|
||||
recoveredInstance: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('alerts triggered within a MW should not fire actions if active or recovered during a MW', async () => {
|
||||
const pattern = {
|
||||
instance: [true, true, false, true],
|
||||
};
|
||||
|
||||
// Create active maintenance window
|
||||
const maintenanceWindow = await createMaintenanceWindow();
|
||||
const activeMaintenanceWindows = await getActiveMaintenanceWindows();
|
||||
expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id);
|
||||
|
||||
// Create action and rule
|
||||
const action = await createAction();
|
||||
const rule = await createRule({ actionId: action.id, pattern });
|
||||
|
||||
// Run the first time - active
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 1 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
|
||||
// Run again - active
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 2 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
|
||||
// Run again - recovered
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 2, recoveredInstance: 1 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
|
||||
// Run again - active again
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 3, recoveredInstance: 1 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
});
|
||||
|
||||
it('alerts triggered within a MW should not fire actions if active or recovered outside a MW', async () => {
|
||||
const pattern = {
|
||||
instance: [true, true, false, true],
|
||||
};
|
||||
|
||||
// Create active maintenance window
|
||||
const maintenanceWindow = await createMaintenanceWindow();
|
||||
const activeMaintenanceWindows = await getActiveMaintenanceWindows();
|
||||
expect(activeMaintenanceWindows[0].id).eql(maintenanceWindow.id);
|
||||
|
||||
// Create action and rule
|
||||
const action = await createAction();
|
||||
const rule = await createRule({ actionId: action.id, pattern });
|
||||
|
||||
// Run the first time - active
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 1 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
|
||||
// End the maintenance window
|
||||
await finishMaintenanceWindow(maintenanceWindow.id);
|
||||
const empty = await getActiveMaintenanceWindows();
|
||||
expect(empty).eql([]);
|
||||
|
||||
// Run again - active
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 2 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
|
||||
// Run again - recovered
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({ id: rule.id, activeInstance: 2, recoveredInstance: 1 });
|
||||
|
||||
await expectNoActionsFired(rule.id);
|
||||
|
||||
// Run again - active again, this time fire the action since its a new alert instance
|
||||
await runSoon(rule.id);
|
||||
await getRuleEvents({
|
||||
id: rule.id,
|
||||
action: 1,
|
||||
activeInstance: 3,
|
||||
recoveredInstance: 1,
|
||||
});
|
||||
});
|
||||
|
||||
// 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() {
|
||||
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,
|
||||
},
|
||||
})
|
||||
.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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue