cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.4.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/checks/alerts_template_test.go

417lines · modecode

1package checks_test
2
3import (
4 "testing"
5
6 "github.com/cloudflare/pint/internal/checks"
7)
8
9func TestTemplateCheck(t *testing.T) {
10 testCases := []checkTest{
11 {
12 description: "skips recording rule",
13 content: "- record: foo\n expr: sum(foo)\n",
14 checker: checks.NewTemplateCheck(checks.Bug),
15 },
16 {
17 description: "invalid syntax in annotations",
18 content: "- alert: Foo Is Down\n expr: up{job=\"foo\"} == 0\n annotations:\n summary: 'Instance {{ $label.instance }} down'\n",
19 checker: checks.NewTemplateCheck(checks.Bug),
20 problems: []checks.Problem{
21 {
22 Fragment: `summary: Instance {{ $label.instance }} down`,
23 Lines: []int{4},
24 Reporter: "alerts/template",
25 Text: "template parse error: undefined variable \"$label\"",
26 Severity: checks.Bug,
27 },
28 },
29 },
30 {
31 description: "invalid function in annotations",
32 content: "- alert: Foo Is Down\n expr: up{job=\"foo\"} == 0\n annotations:\n summary: '{{ $value | xxx }}'\n",
33 checker: checks.NewTemplateCheck(checks.Bug),
34 problems: []checks.Problem{
35 {
36 Fragment: `summary: {{ $value | xxx }}`,
37 Lines: []int{4},
38 Reporter: "alerts/template",
39 Text: "template parse error: function \"xxx\" not defined",
40 Severity: checks.Bug,
41 },
42 },
43 },
44 {
45 description: "valid syntax in annotations",
46 content: "- alert: Foo Is Down\n expr: up{job=\"foo\"} == 0\n annotations:\n summary: 'Instance {{ $labels.instance }} down'\n",
47 checker: checks.NewTemplateCheck(checks.Bug),
48 },
49 {
50 description: "invalid syntax in labels",
51 content: "- alert: Foo Is Down\n expr: up{job=\"foo\"} == 0\n labels:\n summary: 'Instance {{ $label.instance }} down'\n",
52 checker: checks.NewTemplateCheck(checks.Bug),
53 problems: []checks.Problem{
54 {
55 Fragment: `summary: Instance {{ $label.instance }} down`,
56 Lines: []int{4},
57 Reporter: "alerts/template",
58 Text: "template parse error: undefined variable \"$label\"",
59 Severity: checks.Bug,
60 },
61 },
62 },
63 {
64 description: "invalid function in annotations",
65 content: "- alert: Foo Is Down\n expr: up{job=\"foo\"} == 0\n labels:\n summary: '{{ $value | xxx }}'\n",
66 checker: checks.NewTemplateCheck(checks.Bug),
67 problems: []checks.Problem{
68 {
69 Fragment: `summary: {{ $value | xxx }}`,
70 Lines: []int{4},
71 Reporter: "alerts/template",
72 Text: "template parse error: function \"xxx\" not defined",
73 Severity: checks.Bug,
74 },
75 },
76 },
77 {
78 description: "valid syntax in labels",
79 content: "- alert: Foo Is Down\n expr: up{job=\"foo\"} == 0\n labels:\n summary: 'Instance {{ $labels.instance }} down'\n",
80 checker: checks.NewTemplateCheck(checks.Bug),
81 },
82 {
83 description: "{{ $value}} in label key",
84 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n '{{ $value}}': bar\n",
85 checker: checks.NewTemplateCheck(checks.Bug),
86 problems: []checks.Problem{
87 {
88 Fragment: "{{ $value}}: bar",
89 Lines: []int{5},
90 Reporter: "alerts/template",
91 Text: "using $value in labels will generate a new alert on every value change, move it to annotations",
92 Severity: checks.Bug,
93 },
94 },
95 },
96 {
97 description: "{{ $value }} in label key",
98 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n '{{ $value }}': bar\n",
99 checker: checks.NewTemplateCheck(checks.Bug),
100 problems: []checks.Problem{
101 {
102 Fragment: "{{ $value }}: bar",
103 Lines: []int{5},
104 Reporter: "alerts/template",
105 Text: "using $value in labels will generate a new alert on every value change, move it to annotations",
106 Severity: checks.Bug,
107 },
108 },
109 },
110 {
111 description: "{{$value}} in label value",
112 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: '{{$value}}'\n",
113 checker: checks.NewTemplateCheck(checks.Fatal),
114 problems: []checks.Problem{
115 {
116 Fragment: "baz: {{$value}}",
117 Lines: []int{5},
118 Reporter: "alerts/template",
119 Text: "using $value in labels will generate a new alert on every value change, move it to annotations",
120 Severity: checks.Fatal,
121 },
122 },
123 },
124 {
125 description: "{{$value}} in multiple labels",
126 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: '{{ .Value }}'\n baz: '{{$value}}'\n",
127 checker: checks.NewTemplateCheck(checks.Fatal),
128 problems: []checks.Problem{
129 {
130 Fragment: "foo: {{ .Value }}",
131 Lines: []int{4},
132 Reporter: "alerts/template",
133 Text: "using .Value in labels will generate a new alert on every value change, move it to annotations",
134 Severity: checks.Fatal,
135 },
136 {
137 Fragment: "baz: {{$value}}",
138 Lines: []int{5},
139 Reporter: "alerts/template",
140 Text: "using $value in labels will generate a new alert on every value change, move it to annotations",
141 Severity: checks.Fatal,
142 },
143 },
144 },
145 {
146 description: "{{ $value }} in label value",
147 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: |\n foo is {{ $value | humanizePercentage }}%\n",
148 checker: checks.NewTemplateCheck(checks.Bug),
149 problems: []checks.Problem{
150 {
151 Fragment: "baz: foo is {{ $value | humanizePercentage }}%\n",
152 Lines: []int{5, 6},
153 Reporter: "alerts/template",
154 Text: "using $value in labels will generate a new alert on every value change, move it to annotations",
155 Severity: checks.Bug,
156 },
157 },
158 },
159 {
160 description: "{{ $value }} in label value",
161 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: |\n foo is {{$value|humanizePercentage}}%\n",
162 checker: checks.NewTemplateCheck(checks.Bug),
163 problems: []checks.Problem{
164 {
165 Fragment: "baz: foo is {{$value|humanizePercentage}}%\n",
166 Lines: []int{5, 6},
167 Reporter: "alerts/template",
168 Text: "using $value in labels will generate a new alert on every value change, move it to annotations",
169 Severity: checks.Bug,
170 },
171 },
172 },
173 {
174 description: "{{ .Value }} in label value",
175 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: 'value {{ .Value }}'\n",
176 checker: checks.NewTemplateCheck(checks.Bug),
177 problems: []checks.Problem{
178 {
179 Fragment: "baz: value {{ .Value }}",
180 Lines: []int{5},
181 Reporter: "alerts/template",
182 Text: "using .Value in labels will generate a new alert on every value change, move it to annotations",
183 Severity: checks.Bug,
184 },
185 },
186 },
187 {
188 description: "{{ .Value|humanize }} in label value",
189 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: '{{ .Value|humanize }}'\n",
190 checker: checks.NewTemplateCheck(checks.Bug),
191 problems: []checks.Problem{
192 {
193 Fragment: "baz: {{ .Value|humanize }}",
194 Lines: []int{5},
195 Reporter: "alerts/template",
196 Text: "using .Value in labels will generate a new alert on every value change, move it to annotations",
197 Severity: checks.Bug,
198 },
199 },
200 },
201 {
202 description: "{{ $foo := $value }} in label value",
203 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: '{{ $foo := $value }}{{ $foo }}'\n",
204 checker: checks.NewTemplateCheck(checks.Bug),
205 problems: []checks.Problem{
206 {
207 Fragment: "baz: {{ $foo := $value }}{{ $foo }}",
208 Lines: []int{5},
209 Reporter: "alerts/template",
210 Text: "using $foo in labels will generate a new alert on every value change, move it to annotations",
211 Severity: checks.Bug,
212 },
213 },
214 },
215 {
216 description: "{{ $foo := .Value }} in label value",
217 content: "- alert: foo\n expr: sum(foo)\n labels:\n foo: bar\n baz: '{{ $foo := .Value }}{{ $foo }}'\n",
218 checker: checks.NewTemplateCheck(checks.Bug),
219 problems: []checks.Problem{
220 {
221 Fragment: "baz: {{ $foo := .Value }}{{ $foo }}",
222 Lines: []int{5},
223 Reporter: "alerts/template",
224 Text: "using $foo in labels will generate a new alert on every value change, move it to annotations",
225 Severity: checks.Bug,
226 },
227 },
228 },
229 {
230 description: "annotation label missing from metrics (by)",
231 content: "- alert: Foo Is Down\n expr: sum(foo) > 0\n annotations:\n summary: '{{ $labels.job }}'\n",
232 checker: checks.NewTemplateCheck(checks.Bug),
233 problems: []checks.Problem{
234 {
235 Fragment: `summary: {{ $labels.job }}`,
236 Lines: []int{4},
237 Reporter: "alerts/template",
238 Text: `template is using "job" label but the query removes it`,
239 Severity: checks.Bug,
240 },
241 },
242 },
243 {
244 description: "annotation label missing from metrics (by)",
245 content: "- alert: Foo Is Down\n expr: sum(foo) > 0\n annotations:\n summary: '{{ .Labels.job }}'\n",
246 checker: checks.NewTemplateCheck(checks.Bug),
247 problems: []checks.Problem{
248 {
249 Fragment: `summary: {{ .Labels.job }}`,
250 Lines: []int{4},
251 Reporter: "alerts/template",
252 Text: `template is using "job" label but the query removes it`,
253 Severity: checks.Bug,
254 },
255 },
256 },
257 {
258 description: "annotation label missing from metrics (without)",
259 content: "- alert: Foo Is Down\n expr: sum(foo) without(job) > 0\n annotations:\n summary: '{{ $labels.job }}'\n",
260 checker: checks.NewTemplateCheck(checks.Bug),
261 problems: []checks.Problem{
262 {
263 Fragment: `summary: {{ $labels.job }}`,
264 Lines: []int{4},
265 Reporter: "alerts/template",
266 Text: `template is using "job" label but the query removes it`,
267 Severity: checks.Bug,
268 },
269 },
270 },
271 {
272 description: "annotation label missing from metrics (without)",
273 content: "- alert: Foo Is Down\n expr: sum(foo) without(job) > 0\n annotations:\n summary: '{{ .Labels.job }}'\n",
274 checker: checks.NewTemplateCheck(checks.Bug),
275 problems: []checks.Problem{
276 {
277 Fragment: `summary: {{ .Labels.job }}`,
278 Lines: []int{4},
279 Reporter: "alerts/template",
280 Text: `template is using "job" label but the query removes it`,
281 Severity: checks.Bug,
282 },
283 },
284 },
285 {
286 description: "annotation label missing from metrics (or)",
287 content: "- alert: Foo Is Down\n expr: sum(foo) by(job) or sum(bar)\n annotations:\n summary: '{{ .Labels.job }}'\n",
288 checker: checks.NewTemplateCheck(checks.Bug),
289 problems: []checks.Problem{
290 {
291 Fragment: `summary: {{ .Labels.job }}`,
292 Lines: []int{4},
293 Reporter: "alerts/template",
294 Text: `template is using "job" label but the query removes it`,
295 Severity: checks.Bug,
296 },
297 },
298 },
299 {
300 description: "annotation label missing from metrics (1+)",
301 content: "- alert: Foo Is Down\n expr: 1 + sum(foo) by(job) + sum(foo) by(notjob)\n annotations:\n summary: '{{ .Labels.job }}'\n",
302 checker: checks.NewTemplateCheck(checks.Bug),
303 problems: []checks.Problem{
304 {
305 Fragment: `summary: {{ .Labels.job }}`,
306 Lines: []int{4},
307 Reporter: "alerts/template",
308 Text: `template is using "job" label but the query removes it`,
309 Severity: checks.Bug,
310 },
311 },
312 },
313 {
314 description: "annotation label missing from metrics (group_left)",
315 content: `
316- alert: Foo Is Down
317 expr: count(build_info) by (instance, version) != ignoring(package) group_left(foo) count(package_installed) by (instance, version, package)
318 annotations:
319 summary: '{{ $labels.instance }} on {{ .Labels.foo }} is down'
320 help: '{{ $labels.ixtance }}'
321`,
322 checker: checks.NewTemplateCheck(checks.Bug),
323 problems: []checks.Problem{
324 {
325 Fragment: `help: {{ $labels.ixtance }}`,
326 Lines: []int{6},
327 Reporter: "alerts/template",
328 Text: `template is using "ixtance" label but the query removes it`,
329 Severity: checks.Bug,
330 },
331 },
332 },
333 {
334 description: "annotation label present on metrics (absent)",
335 content: `
336- alert: Foo Is Missing
337 expr: absent(foo{job="bar", instance="server1"})
338 annotations:
339 summary: '{{ $labels.instance }} on {{ .Labels.job }} is missing'
340`,
341 checker: checks.NewTemplateCheck(checks.Bug),
342 },
343 {
344 description: "annotation label missing from metrics (absent)",
345 content: `
346- alert: Foo Is Missing
347 expr: absent(foo{job="bar"}) AND on(job) foo
348 labels:
349 instance: '{{ $labels.instance }}'
350 annotations:
351 summary: '{{ $labels.instance }} on {{ .Labels.foo }} is missing'
352 help: '{{ $labels.xxx }}'
353`,
354 checker: checks.NewTemplateCheck(checks.Warning),
355 problems: []checks.Problem{
356 {
357 Fragment: "instance: {{ $labels.instance }}",
358 Lines: []int{5},
359 Reporter: "alerts/template",
360 Text: `template is using "instance" label but absent() is not passing it`,
361 Severity: checks.Warning,
362 },
363 {
364 Fragment: `summary: {{ $labels.instance }} on {{ .Labels.foo }} is missing`,
365 Lines: []int{7},
366 Reporter: "alerts/template",
367 Text: `template is using "instance" label but absent() is not passing it`,
368 Severity: checks.Warning,
369 },
370 {
371 Fragment: `summary: {{ $labels.instance }} on {{ .Labels.foo }} is missing`,
372 Lines: []int{7},
373 Reporter: "alerts/template",
374 Text: `template is using "foo" label but absent() is not passing it`,
375 Severity: checks.Warning,
376 },
377 {
378 Fragment: "help: {{ $labels.xxx }}",
379 Lines: []int{8},
380 Reporter: "alerts/template",
381 Text: `template is using "xxx" label but absent() is not passing it`,
382 Severity: checks.Warning,
383 },
384 },
385 },
386 {
387 description: "annotation label present on metrics (absent(sum))",
388 content: `
389- alert: Foo Is Missing
390 expr: absent(sum(foo) by(job, instance))
391 annotations:
392 summary: '{{ $labels.instance }} on {{ .Labels.job }} is missing'
393`,
394 checker: checks.NewTemplateCheck(checks.Bug),
395 },
396 {
397 description: "annotation label missing from metrics (absent(sum))",
398 content: `
399- alert: Foo Is Missing
400 expr: absent(sum(foo) by(job))
401 annotations:
402 summary: '{{ $labels.instance }} on {{ .Labels.job }} is missing'
403`,
404 checker: checks.NewTemplateCheck(checks.Information),
405 problems: []checks.Problem{
406 {
407 Fragment: `summary: {{ $labels.instance }} on {{ .Labels.job }} is missing`,
408 Lines: []int{5},
409 Reporter: "alerts/template",
410 Text: `template is using "instance" label but the query removes it`,
411 Severity: checks.Information,
412 },
413 },
414 },
415 }
416 runTests(t, testCases)
417}
418