Skip to content

Commit

Permalink
feat(config): add missing duration pattern validations (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreDemailly authored Oct 30, 2023
1 parent 09fc460 commit a01f61e
Show file tree
Hide file tree
Showing 5 changed files with 319 additions and 8 deletions.
12 changes: 8 additions & 4 deletions src/config/src/schemas/configSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@
"interval": {
"title": "The interval of time to pause alert",
"description": "A duration string (e.g. '1m', '1h', '1d').",
"type": "string"
"type": "string",
"pattern": "^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$"
},
"activationThreshold": {
"title": "The number of alert before activating the throttle",
Expand Down Expand Up @@ -203,7 +204,8 @@
"interval": {
"title": "Defines the maximum interval, default one day",
"description": "A duration string (e.g. '1m', '1h', '1d').",
"type": "string"
"type": "string",
"pattern": "^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$"
},
"template": {
"title": "The template used to send the alert",
Expand Down Expand Up @@ -240,7 +242,8 @@
"interval": {
"title": "The interval of time to pause alert",
"description": "A duration string (e.g. '1m', '1h', '1d').",
"type": "string"
"type": "string",
"pattern": "^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$"
}
},
"required": ["interval"],
Expand All @@ -252,7 +255,8 @@
},
"muteDuration": {
"title": "Defines the duration for which rules should be muted",
"type": "string"
"type": "string",
"pattern": "^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$"
}
},
"additionalProperties": false,
Expand Down
6 changes: 4 additions & 2 deletions src/config/src/schemas/rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@
"interval": {
"title": "The interval of time in which the logs will be counted",
"description": "A duration string (e.g. '1m', '1h', '1d').",
"type": "string"
"type": "string",
"pattern": "^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$"
},
"label": {
"title": "The label to watch",
Expand Down Expand Up @@ -321,7 +322,8 @@
"interval": {
"title": "The interval of time to pause alert",
"description": "A duration string (e.g. '1m', '1h', '1d').",
"type": "string"
"type": "string",
"pattern": "^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$"
},
"activationThreshold": {
"title": "The number of alert before activating the throttle",
Expand Down
172 changes: 171 additions & 1 deletion src/config/test/compositeRules.validation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-lines */
// Import Node.js Dependencies
import assert from "node:assert";
import { describe, it } from "node:test";
Expand All @@ -6,6 +7,22 @@ import { describe, it } from "node:test";
import { validateConfig } from "../src/validate";
import { VALID_CONFIG } from "./helpers";

// CONSTANTS
const kDurations = [
"20milliseconds", "20 milliseconds",
"20msecs", "20 msecs",
"20ms", "20 ms",
"20seconds", "20 seconds",
"20secs", "20 secs",
"20s", "20 s",
"20minutes", "20 minutes",
"20mins", "20 mins",
"20m", "20 m",
"20hours", "20 hours",
"20hrs", "20 hrs",
"20h", "20 h"
];

describe("Composite rules validations", () => {
it("property 'compositeRules' should be optional", () => {
assert.doesNotThrow(() => {
Expand Down Expand Up @@ -378,7 +395,7 @@ describe("Composite rules validations", () => {
});
});

it("compositeRules property 'interval' can must be string", () => {
it("compositeRules property 'interval' must be string", () => {
assert.throws(() => {
validateConfig({
...VALID_CONFIG,
Expand All @@ -399,6 +416,48 @@ describe("Composite rules validations", () => {
});
});

it("compositeRules property 'interval' must be a duration", () => {
assert.throws(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
interval: "foo"
}
]
});
}, {
name: "Error",
// eslint-disable-next-line max-len
message: "Invalid config: /compositeRules/0/interval: must match pattern \"^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$\""
});
});

for (const duration of kDurations) {
it(`compositeRules property 'interval' can be '${duration}'`, () => {
assert.doesNotThrow(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
interval: duration
}
]
});
});
});
}

it("compositeRules property 'throttle' can be set", () => {
assert.doesNotThrow(() => {
validateConfig({
Expand Down Expand Up @@ -511,6 +570,75 @@ describe("Composite rules validations", () => {
});
});

it("compositeRules property 'throttle.interval' must be string", () => {
assert.throws(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
throttle: {
interval: true as any
}
}
]
});
}, {
name: "Error",
message: "Invalid config: /compositeRules/0/throttle/interval: must be string"
});
});

it("compositeRules property 'throttle.interval' must be a duration", () => {
assert.throws(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
throttle: {
interval: "foo"
}
}
]
});
}, {
name: "Error",
// eslint-disable-next-line max-len
message: "Invalid config: /compositeRules/0/throttle/interval: must match pattern \"^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$\""
});
});

for (const duration of kDurations) {
it(`compositeRules property 'throttle.interval' can be '${duration}'`, () => {
assert.doesNotThrow(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
throttle: {
interval: duration
}
}
]
});
});
});
}

it("compositeRules property 'throttle.count' must be an integer", () => {
assert.throws(() => {
validateConfig({
Expand Down Expand Up @@ -613,6 +741,48 @@ describe("Composite rules validations", () => {
});
});

it("compositeRules property 'muteDuration' must be a duration", () => {
assert.throws(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
muteDuration: "foo"
}
]
});
}, {
name: "Error",
// eslint-disable-next-line max-len
message: "Invalid config: /compositeRules/0/muteDuration: must match pattern \"^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$\""
});
});

for (const duration of kDurations) {
it(`compositeRules property 'muteDuration' can be '${duration}'`, () => {
assert.doesNotThrow(() => {
validateConfig({
...VALID_CONFIG,
compositeRules: [
{
notifCount: 12,
template: {
title: "title"
},
name: "foo",
muteDuration: duration
}
]
});
});
});
}

it("compositeRules cannot have additional property", () => {
assert.throws(() => {
validateConfig({
Expand Down
84 changes: 83 additions & 1 deletion src/config/test/rule.alert.validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ import { PartialSigynAlert } from "../src/types";

// CONSTANTS
const kValidRule = VALID_CONFIG.rules[0];
const kDurations = [
"20milliseconds", "20 milliseconds",
"20msecs", "20 msecs",
"20ms", "20 ms",
"20seconds", "20 seconds",
"20secs", "20 secs",
"20s", "20 s",
"20minutes", "20 minutes",
"20mins", "20 mins",
"20m", "20 m",
"20hours", "20 hours",
"20hrs", "20 hrs",
"20h", "20 h"
];

function mergeAlert(alert: Partial<PartialSigynAlert>) {
return {
Expand Down Expand Up @@ -206,6 +220,48 @@ describe("Rule alert validations", () => {
});
});

it("rule alert property 'on.interval' must be string", () => {
assert.throws(() => {
validateConfig(mergeAlert({
on: {
...kValidRule.alert.on,
interval: true as any
}
}));
}, {
name: "Error",
message: "Invalid config: /rules/0/alert/on/interval: must be string"
});
});

it("rule alert property 'on.interval' must be a duration", () => {
assert.throws(() => {
validateConfig(mergeAlert({
on: {
...kValidRule.alert.on,
interval: "foo"
}
}));
}, {
name: "Error",
// eslint-disable-next-line max-len
message: "Invalid config: /rules/0/alert/on/interval: must match pattern \"^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$\""
});
});

for (const duration of kDurations) {
it(`rule alert property 'on.interval' can be '${duration}'`, () => {
assert.doesNotThrow(() => {
validateConfig(mergeAlert({
on: {
...kValidRule.alert.on,
interval: duration
}
}));
});
});
}

it("rule alert property 'on.interval' or 'on.minimumLabelCount' should be required when rule is label percent threhsold based (value)", () => {
assert.throws(() => {
validateConfig(mergeAlert({
Expand Down Expand Up @@ -475,7 +531,7 @@ describe("Rule alert validations", () => {
});
});

it("rule alert property 'throttle.interval' must be a duration", () => {
it("rule alert property 'throttle.interval' must be string", () => {
assert.throws(() => {
validateConfig(mergeAlert({
throttle: {
Expand All @@ -488,6 +544,32 @@ describe("Rule alert validations", () => {
});
});

it("rule alert property 'throttle.interval' must be a duration", () => {
assert.throws(() => {
validateConfig(mergeAlert({
throttle: {
interval: "foo"
}
}));
}, {
name: "Error",
// eslint-disable-next-line max-len
message: "Invalid config: /rules/0/alert/throttle/interval: must match pattern \"^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$\""
});
});

for (const duration of kDurations) {
it(`rule alert property 'throttle.interval' can be '${duration}'`, () => {
assert.doesNotThrow(() => {
validateConfig(mergeAlert({
throttle: {
interval: duration
}
}));
});
});
}

it("rule alert property 'throttle.count' must be an integer", () => {
assert.throws(() => {
validateConfig(mergeAlert({
Expand Down
Loading

0 comments on commit a01f61e

Please sign in to comment.