@@ -121,6 +121,21 @@ var alertTests = []struct {
121121 }` ,
122122 `[alert-name-camelcase] Alert 'test Alert' name is not in camel case` ,
123123 },
124+ {
125+ `{
126+ alert: 'TestAlertNameIsLongerThan40CharactersLong',
127+ expr: 'up == 0',
128+ labels: {
129+ severity: 'warning',
130+ },
131+ annotations: {
132+ description: '{{ $labels.instance }} has been unready for more than 15 minutes.',
133+ summary: 'Instance is not ready.',
134+ },
135+ 'for': '15m',
136+ }` ,
137+ `[alert-name-length] Alert 'TestAlertNameIsLongerThan40CharactersLong' name exceeds 40 characters` ,
138+ },
124139
125140 // severity
126141 {
@@ -265,6 +280,147 @@ func TestLintPrometheusAlertsGuidelines(t *testing.T) {
265280
266281}
267282
283+ func TestLintPrometheusAlertGroupsGuidelines_ValidGroup (t * testing.T ) {
284+ expectedLintErr := ""
285+ var validAlert = `{
286+ alert: 'TestAlert',
287+ expr: 'up == 0',
288+ labels: {
289+ severity: 'warning',
290+ },
291+ annotations: {
292+ description: '{{ $labels.instance }} has been unready for more than 15 minutes.',
293+ summary: 'Instance is not ready.',
294+ },
295+ 'for': '15m',
296+ }`
297+
298+ alertsStr := fmt .Sprintf (`
299+ {
300+ _config+:: {},
301+ prometheusAlerts+: {
302+ groups+: [
303+ {
304+ name: 'test',
305+ rules: [
306+ %s,
307+ ],
308+ },
309+ ],
310+ },
311+ }
312+ ` , validAlert )
313+
314+ filename , delete := writeTempFile (t , "alerts.jsonnet" , alertsStr )
315+ defer delete ()
316+
317+ vm := jsonnet .MakeVM ()
318+ errs := make (chan error )
319+ go lintPrometheus (filename , vm , errs )
320+ for err := range errs {
321+ if err .Error () != expectedLintErr {
322+ t .Errorf ("linting wrote unexpected output, expected '%s', got: %v" , expectedLintErr , err )
323+ }
324+ }
325+ }
326+
327+ func TestLintPrometheusAlertGroupsGuidelines_InvalidGroupName (t * testing.T ) {
328+ expectedLintErr := "[alert-group-name-length] Alert Group 'InvalidAlertGroupNameHasMoreThanFourtyCharacters' name exceeds 40 characters"
329+ var validAlert = `{
330+ alert: 'TestAlert',
331+ expr: 'up == 0',
332+ labels: {
333+ severity: 'warning',
334+ },
335+ annotations: {
336+ description: '{{ $labels.instance }} has been unready for more than 15 minutes.',
337+ summary: 'Instance is not ready.',
338+ },
339+ 'for': '15m',
340+ }`
341+
342+ alertsStr := fmt .Sprintf (`
343+ {
344+ _config+:: {},
345+ prometheusAlerts+: {
346+ groups+: [
347+ {
348+ name: 'InvalidAlertGroupNameHasMoreThanFourtyCharacters',
349+ rules: [
350+ %s,
351+ ],
352+ },
353+ ],
354+ },
355+ }
356+ ` , validAlert )
357+
358+ filename , delete := writeTempFile (t , "alerts.jsonnet" , alertsStr )
359+ defer delete ()
360+
361+ vm := jsonnet .MakeVM ()
362+ errs := make (chan error )
363+ go lintPrometheus (filename , vm , errs )
364+ for err := range errs {
365+ if err .Error () != expectedLintErr {
366+ t .Errorf ("linting wrote unexpected output, expected '%s', got: %v" , expectedLintErr , err )
367+ }
368+ }
369+ }
370+
371+ func TestLintPrometheusAlertGroupsGuidelines_TooManyAlerts (t * testing.T ) {
372+ invalidNumAlerts := 21
373+ expectedLintErr := "[alert-group-rule-count] Group 'test' contains more than 20 rules (21)"
374+ var validAlert = `{
375+ alert: 'TestAlert',
376+ expr: 'up == 0',
377+ labels: {
378+ severity: 'warning',
379+ },
380+ annotations: {
381+ description: '{{ $labels.instance }} has been unready for more than 15 minutes.',
382+ summary: 'Instance is not ready.',
383+ },
384+ 'for': '15m',
385+ }`
386+
387+ var joinedAlerts = ""
388+ for i := 0 ; i < invalidNumAlerts ; i ++ {
389+ if i > 0 {
390+ joinedAlerts += ","
391+ }
392+ joinedAlerts += validAlert
393+ }
394+
395+ alertsStr := fmt .Sprintf (`
396+ {
397+ _config+:: {},
398+ prometheusAlerts+: {
399+ groups+: [
400+ {
401+ name: 'test',
402+ rules: [
403+ %s,
404+ ],
405+ },
406+ ],
407+ },
408+ }
409+ ` , joinedAlerts )
410+
411+ filename , delete := writeTempFile (t , "alerts.jsonnet" , alertsStr )
412+ defer delete ()
413+
414+ vm := jsonnet .MakeVM ()
415+ errs := make (chan error )
416+ go lintPrometheus (filename , vm , errs )
417+ for err := range errs {
418+ if err .Error () != expectedLintErr {
419+ t .Errorf ("linting wrote unexpected output, expected '%s', got: %v" , expectedLintErr , err )
420+ }
421+ }
422+ }
423+
268424func TestLintPrometheusRules (t * testing.T ) {
269425 filename , delete := writeTempFile (t , "rules.jsonnet" , rules )
270426 defer delete ()
0 commit comments