cloudflare/pint
Publicmirrored fromhttps://github.com/cloudflare/pintAvailable
internal/parser/fuzz_test.go
285lines · modecode
| 1 | package parser_test |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | |
| 7 | "github.com/cloudflare/pint/internal/parser" |
| 8 | ) |
| 9 | |
| 10 | func FuzzParse(f *testing.F) { |
| 11 | testcases := []string{ |
| 12 | `# head comment |
| 13 | - record: foo # record comment |
| 14 | expr: foo offset 10m # expr comment |
| 15 | # pre-labels comment |
| 16 | labels: |
| 17 | # pre-foo comment |
| 18 | foo: bar |
| 19 | # post-foo comment |
| 20 | bob: alice |
| 21 | # foot comment |
| 22 | `, |
| 23 | ` |
| 24 | - alert: foo |
| 25 | annotations: {} |
| 26 | expr: bar |
| 27 | annotations: {} |
| 28 | `, |
| 29 | `- record: name |
| 30 | expr: sum(foo) |
| 31 | labels: |
| 32 | foo: bar |
| 33 | bob: alice |
| 34 | `, |
| 35 | ` |
| 36 | groups: |
| 37 | - name: custom_rules |
| 38 | rules: |
| 39 | - record: name |
| 40 | expr: sum(foo) |
| 41 | labels: |
| 42 | foo: bar |
| 43 | bob: alice |
| 44 | `, |
| 45 | `- alert: Down |
| 46 | expr: | |
| 47 | up == 0 |
| 48 | for: |+ |
| 49 | 11m |
| 50 | labels: |
| 51 | severity: critical |
| 52 | annotations: |
| 53 | uri: https://docs.example.com/down.html |
| 54 | |
| 55 | - record: > |
| 56 | foo |
| 57 | expr: |- |
| 58 | bar |
| 59 | / |
| 60 | baz > 1 |
| 61 | labels: {} |
| 62 | `, |
| 63 | `- alert: Foo |
| 64 | expr: |
| 65 | ( |
| 66 | xxx |
| 67 | - |
| 68 | yyy |
| 69 | ) * bar > 0 |
| 70 | and on(instance, device) baz |
| 71 | for: 30m |
| 72 | `, |
| 73 | ` |
| 74 | # pint ignore/begin |
| 75 | {%- set foo = 1 %} |
| 76 | {% set bar = 2 -%} |
| 77 | {# comment #} |
| 78 | {# |
| 79 | comment |
| 80 | #} |
| 81 | # pint ignore/end |
| 82 | |
| 83 | - record: colo_job:up:count |
| 84 | expr: sum(foo) without(job) |
| 85 | |
| 86 | - record: invalid |
| 87 | expr: sum(foo) by ()) |
| 88 | |
| 89 | # pint ignore/begin |
| 90 | - record: colo_job:down:count |
| 91 | expr: up == {{ foo }} |
| 92 | # pint ignore/end |
| 93 | |
| 94 | - record: colo:multiline |
| 95 | expr: | |
| 96 | sum( |
| 97 | multiline |
| 98 | ) without(job, instance) |
| 99 | |
| 100 | - record: colo:multiline:sum |
| 101 | expr: | |
| 102 | sum(sum) without(job) |
| 103 | + |
| 104 | sum(sum) without(job) |
| 105 | |
| 106 | - record: colo:multiline2 |
| 107 | expr: >- |
| 108 | sum( |
| 109 | multiline2 |
| 110 | ) without(job, instance) |
| 111 | |
| 112 | - record: colo_job:up:byinstance |
| 113 | expr: sum(byinstance) by(instance) |
| 114 | |
| 115 | - record: instance_mode:node_cpu:rate4m |
| 116 | expr: sum(rate(node_cpu_seconds_total[4m])) without (cpu) |
| 117 | |
| 118 | - record: instance_mode:node_cpu:rate4m |
| 119 | expr: sum(rate(node_cpu_seconds_total[5m])) without (cpu) |
| 120 | |
| 121 | - record: instance_mode:node_cpu:rate5min |
| 122 | expr: sum(irate(node_cpu_seconds_total[5m])) without (cpu) |
| 123 | |
| 124 | - alert: Instance Is Down |
| 125 | expr: up == 0 |
| 126 | `, |
| 127 | ` |
| 128 | - record: colo_job:down:count |
| 129 | expr: up{job=~"foo"} == 0 |
| 130 | |
| 131 | - record: colo_job:down:count |
| 132 | expr: up{job!~"foo"} == 0 |
| 133 | `, |
| 134 | ` |
| 135 | - record: colo_job:fl_cf_html_bytes_in:rate10m |
| 136 | expr: sum(rate(fl_cf_html_bytes_in[10m])) WITHOUT (colo_id, instance, node_type, region, node_status, job, colo_name) |
| 137 | - record: colo_job:foo:rate1m |
| 138 | expr: sum(rate(foo[1m])) WITHOUT (instance) |
| 139 | - record: colo_job:foo:irate3m |
| 140 | expr: sum(irate(foo[3m])) WITHOUT (colo_id) |
| 141 | `, |
| 142 | ` |
| 143 | xxx: |
| 144 | xxx: |
| 145 | xxx: |
| 146 | |
| 147 | - xx |
| 148 | - yyy |
| 149 | `, |
| 150 | ` |
| 151 | - record: "colo:test1" |
| 152 | expr: topk(6, sum(rate(edgeworker_subrequest_errorCount{cordon="free"}[5m])) BY (zoneId,job)) |
| 153 | - record: "colo:test2" |
| 154 | expr: topk(6, sum(rate(edgeworker_subrequest_errorCount{cordon="free"}[10m])) without (instance)) |
| 155 | `, |
| 156 | `- alert: Always |
| 157 | expr: up |
| 158 | - alert: AlwaysIgnored |
| 159 | expr: up # pint disable alerts/comparison |
| 160 | labels: |
| 161 | severity: warning |
| 162 | annotations: |
| 163 | url: "https://wiki.example.com/page/ServiceIsDown.html" |
| 164 | - alert: ServiceIsDown |
| 165 | expr: up == 0 |
| 166 | - alert: ServiceIsDown |
| 167 | expr: up == 0 |
| 168 | labels: |
| 169 | severity: bad |
| 170 | annotations: |
| 171 | url: bad |
| 172 | - alert: ServiceIsDown |
| 173 | expr: up == 0 |
| 174 | labels: |
| 175 | severity: warning |
| 176 | annotations: |
| 177 | url: "https://wiki.example.com/page/ServiceIsDown.html" |
| 178 | `, |
| 179 | ` |
| 180 | - alert: Foo Is Down |
| 181 | expr: up{job="foo"} == 0 |
| 182 | annotations: |
| 183 | url: "https://wiki.example.com/page/ServiceIsDown.html" |
| 184 | summary: 'Instance {{ $label.instance }} down' |
| 185 | func: '{{ $valuexx | xxx }}' |
| 186 | labels: |
| 187 | severity: warning |
| 188 | summary: 'Instance {{ $label.instance }} down' |
| 189 | func: '{{ $value | xxx }}' |
| 190 | bar: 'Some {{$value}} value' |
| 191 | val: '{{ .Value|humanizeDuration }}' |
| 192 | ignore: '$value is not a variable' |
| 193 | `, |
| 194 | `groups: |
| 195 | - name: example |
| 196 | rules: |
| 197 | |
| 198 | # Alert for any instance that is unreachable for >5 minutes. |
| 199 | - alert: InstanceDown |
| 200 | expr: up == 0 |
| 201 | for: 5m |
| 202 | labels: |
| 203 | severity: page |
| 204 | annotations: |
| 205 | summary: "Instance {{ $labels.instance }} down" |
| 206 | description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." |
| 207 | |
| 208 | # Alert for any instance that has a median request latency >1s. |
| 209 | - alert: APIHighRequestLatency |
| 210 | expr: sum by (instance) (http_inprogress_requests) > 0 |
| 211 | for: 10m |
| 212 | annotations: |
| 213 | summary: "High request latency on {{ $labels.instance }}" |
| 214 | description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)" |
| 215 | `, |
| 216 | `- alert: Good |
| 217 | expr: up == 0 |
| 218 | for: 2m |
| 219 | labels: |
| 220 | component: foo |
| 221 | |
| 222 | alert: Bad |
| 223 | expr: up == 0 |
| 224 | for: 2m |
| 225 | labels: |
| 226 | component: foo |
| 227 | `, |
| 228 | ` |
| 229 | - record: disabled |
| 230 | expr: sum(errors_total) by ) # pint disable promql/syntax |
| 231 | |
| 232 | - record: active |
| 233 | expr: sum(errors_total) by ) |
| 234 | |
| 235 | - record: disabled |
| 236 | # pint disable promql/aggregate(job:true) |
| 237 | expr: sum(errors_total) without(job) |
| 238 | |
| 239 | - record: disabled |
| 240 | # pint disable promql/aggregate |
| 241 | expr: sum(errors_total) without(job) |
| 242 | |
| 243 | - record: active |
| 244 | expr: sum(errors_total) without(job) |
| 245 | |
| 246 | - alert: disabled |
| 247 | expr: sum(errors_total) by ) # pint disable promql/syntax |
| 248 | |
| 249 | - alert: active |
| 250 | expr: sum(errors_total) by ) |
| 251 | |
| 252 | - alert: disabled |
| 253 | # pint disable promql/aggregate(job:true) |
| 254 | expr: sum(errors_total) without(job) > 0 |
| 255 | |
| 256 | - alert: disabled |
| 257 | # pint disable promql/aggregate |
| 258 | expr: sum(errors_total) without(job) > 0 |
| 259 | |
| 260 | - alert: active |
| 261 | expr: sum(errors_total) without(job) |
| 262 | `, |
| 263 | `groups: |
| 264 | - name: "haproxy.api_server.rules" |
| 265 | rules: |
| 266 | - alert: HaproxyServerHealthcheckFailure |
| 267 | expr: increase(haproxy_server_check_failures_total[15m]) > 100 |
| 268 | for: 5m |
| 269 | labels: |
| 270 | severity: 24x7 |
| 271 | annotations: |
| 272 | summary: "HAProxy server healthcheck failure (instance {{ $labels.instance }})" |
| 273 | description: "Some server healthcheck are failing on {{ $labels.server }}\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" |
| 274 | |
| 275 | `, |
| 276 | } |
| 277 | for _, tc := range testcases { |
| 278 | f.Add(tc) |
| 279 | } |
| 280 | p := parser.NewParser(parser.DefaultOptions) |
| 281 | f.Fuzz(func(t *testing.T, s string) { |
| 282 | t.Logf("Parsing: [%s]\n", s) |
| 283 | _ = p.Parse(strings.NewReader(s)) |
| 284 | }) |
| 285 | } |
| 286 | |