Skip to content

Commit

Permalink
[Alerting] Allow rule to execute if the value is 0 and that mets the …
Browse files Browse the repository at this point in the history
…condition (#105626)

* Allow rule to execute if the value is 0 and that mets the condition

* PR feedback

* Fix type issue

* PR feedback

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
chrisronline and kibanamachine authored Jul 19, 2021
1 parent 3b921ce commit 887a149
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,28 @@
* 2.0.
*/

import uuid from 'uuid';
import type { Writable } from '@kbn/utility-types';
import { loggingSystemMock } from '../../../../../../src/core/server/mocks';
import { getAlertType } from './alert_type';
import { AlertServices } from '../../../../alerting/server';
import { getAlertType, ActionGroupId } from './alert_type';
import { ActionContext } from './action_context';
import { Params } from './alert_type_params';
import { AlertServicesMock, alertsMock } from '../../../../alerting/server/mocks';

describe('alertType', () => {
const logger = loggingSystemMock.create().get();
const data = {
timeSeriesQuery: jest.fn(),
};
const alertServices: AlertServicesMock = alertsMock.createAlertServices();

const alertType = getAlertType(logger, Promise.resolve(data));

afterEach(() => {
data.timeSeriesQuery.mockReset();
});

it('alert type creation structure is the expected value', async () => {
expect(alertType.id).toBe('.index-threshold');
expect(alertType.name).toBe('Index threshold');
Expand Down Expand Up @@ -135,4 +144,198 @@ describe('alertType', () => {
`"[aggType]: invalid aggType: \\"foo\\""`
);
});

it('should ensure 0 results fires actions if it passes the comparator check', async () => {
data.timeSeriesQuery.mockImplementation((...args) => {
return {
results: [
{
group: 'all documents',
metrics: [['2021-07-14T14:49:30.978Z', 0]],
},
],
};
});
const params: Params = {
index: 'index-name',
timeField: 'time-field',
aggType: 'foo',
groupBy: 'all',
timeWindowSize: 5,
timeWindowUnit: 'm',
thresholdComparator: '<',
threshold: [1],
};

await alertType.executor({
alertId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
services: (alertServices as unknown) as AlertServices<
{},
ActionContext,
typeof ActionGroupId
>,
params,
state: {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});

expect(alertServices.alertInstanceFactory).toHaveBeenCalledWith('all documents');
});

it('should ensure a null result does not fire actions', async () => {
const customAlertServices: AlertServicesMock = alertsMock.createAlertServices();
data.timeSeriesQuery.mockImplementation((...args) => {
return {
results: [
{
group: 'all documents',
metrics: [['2021-07-14T14:49:30.978Z', null]],
},
],
};
});
const params: Params = {
index: 'index-name',
timeField: 'time-field',
aggType: 'foo',
groupBy: 'all',
timeWindowSize: 5,
timeWindowUnit: 'm',
thresholdComparator: '<',
threshold: [1],
};

await alertType.executor({
alertId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
services: (customAlertServices as unknown) as AlertServices<
{},
ActionContext,
typeof ActionGroupId
>,
params,
state: {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});

expect(customAlertServices.alertInstanceFactory).not.toHaveBeenCalled();
});

it('should ensure an undefined result does not fire actions', async () => {
const customAlertServices: AlertServicesMock = alertsMock.createAlertServices();
data.timeSeriesQuery.mockImplementation((...args) => {
return {
results: [
{
group: 'all documents',
metrics: [['2021-07-14T14:49:30.978Z', undefined]],
},
],
};
});
const params: Params = {
index: 'index-name',
timeField: 'time-field',
aggType: 'foo',
groupBy: 'all',
timeWindowSize: 5,
timeWindowUnit: 'm',
thresholdComparator: '<',
threshold: [1],
};

await alertType.executor({
alertId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
services: (customAlertServices as unknown) as AlertServices<
{},
ActionContext,
typeof ActionGroupId
>,
params,
state: {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});

expect(customAlertServices.alertInstanceFactory).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
import { ComparatorFns, getHumanReadableComparator } from '../lib';

export const ID = '.index-threshold';
const ActionGroupId = 'threshold met';
export const ActionGroupId = 'threshold met';

export function getAlertType(
logger: Logger,
Expand Down Expand Up @@ -180,7 +180,7 @@ export function getAlertType(
groupResult.metrics && groupResult.metrics.length > 0 ? groupResult.metrics[0] : null;
const value = metric && metric.length === 2 ? metric[1] : null;

if (!value) {
if (value === null || value === undefined) {
logger.debug(
`alert ${ID}:${alertId} "${name}": no metrics found for group ${instanceId}} from groupResult ${JSON.stringify(
groupResult
Expand Down

0 comments on commit 887a149

Please sign in to comment.