cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.63.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/discovery/discovery_test.go

355lines · modecode

1package discovery
2
3import (
4 "bytes"
5 "encoding/json"
6 "errors"
7 "fmt"
8 "io"
9 "strings"
10 "testing"
11
12 "github.com/stretchr/testify/require"
13
14 "github.com/cloudflare/pint/internal/parser"
15)
16
17type failingReader struct {
18 err error
19}
20
21func (r failingReader) Read(_ []byte) (int, error) {
22 return 0, r.err
23}
24
25func TestReadRules(t *testing.T) {
26 mustParse := func(offset int, s string) parser.Rule {
27 p := parser.NewParser(false)
28 r, err := p.Parse([]byte(strings.Repeat("\n", offset) + s))
29 if err != nil {
30 panic(fmt.Sprintf("failed to parse rule:\n---\n%s\n---\nerror: %s", s, err))
31 }
32 if len(r) != 1 {
33 panic(fmt.Sprintf("wrong number of rules returned: %d\n---\n%s\n---", len(r), s))
34 }
35 return r[0]
36 }
37
38 type testCaseT struct {
39 sourceFunc func(t *testing.T) io.Reader
40 title string
41 reportedPath string
42 sourcePath string
43 err string
44 entries []Entry
45 isStrict bool
46 }
47
48 testCases := []testCaseT{
49 {
50 title: "nil input",
51 reportedPath: "rules.yml",
52 sourcePath: "rules.yml",
53 sourceFunc: func(_ *testing.T) io.Reader {
54 return bytes.NewBuffer(nil)
55 },
56 isStrict: false,
57 },
58 {
59 title: "nil input",
60 reportedPath: "rules.yml",
61 sourcePath: "rules.yml",
62 sourceFunc: func(_ *testing.T) io.Reader {
63 return bytes.NewBuffer(nil)
64 },
65 isStrict: true,
66 },
67 {
68 title: "empty input",
69 reportedPath: "rules.yml",
70 sourcePath: "rules.yml",
71 sourceFunc: func(_ *testing.T) io.Reader {
72 return bytes.NewBuffer([]byte(" "))
73 },
74 isStrict: false,
75 },
76 {
77 title: "empty input",
78 reportedPath: "rules.yml",
79 sourcePath: "rules.yml",
80 sourceFunc: func(_ *testing.T) io.Reader {
81 return bytes.NewBuffer([]byte(" "))
82 },
83 isStrict: true,
84 },
85 {
86 title: "reader error",
87 reportedPath: "rules.yml",
88 sourcePath: "rules.yml",
89 sourceFunc: func(_ *testing.T) io.Reader {
90 return failingReader{
91 err: io.ErrClosedPipe,
92 }
93 },
94 isStrict: false,
95 err: io.ErrClosedPipe.Error(),
96 },
97 {
98 title: "reader error",
99 reportedPath: "rules.yml",
100 sourcePath: "rules.yml",
101 sourceFunc: func(_ *testing.T) io.Reader {
102 return failingReader{
103 err: io.ErrClosedPipe,
104 }
105 },
106 isStrict: true,
107 err: io.ErrClosedPipe.Error(),
108 },
109 {
110 title: "no rules, just a comment",
111 reportedPath: "rules.yml",
112 sourcePath: "rules.yml",
113 sourceFunc: func(_ *testing.T) io.Reader {
114 return bytes.NewBuffer([]byte("\n\n # pint file/disable xxx \n\n"))
115 },
116 isStrict: false,
117 },
118 {
119 title: "file/disable comment",
120 reportedPath: "rules.yml",
121 sourcePath: "rules.yml",
122 sourceFunc: func(_ *testing.T) io.Reader {
123 return bytes.NewBuffer([]byte(`
124# pint file/disable promql/series
125
126- record: foo
127 expr: bar
128`))
129 },
130 isStrict: false,
131 entries: []Entry{
132 {
133 State: Unknown,
134 Path: Path{
135 Name: "rules.yml",
136 SymlinkTarget: "rules.yml",
137 },
138 ModifiedLines: []int{4, 5},
139 Rule: mustParse(3, "- record: foo\n expr: bar\n"),
140 DisabledChecks: []string{"promql/series"},
141 },
142 },
143 },
144 {
145 title: "file/disable comment",
146 reportedPath: "rules.yml",
147 sourcePath: "rules.yml",
148 sourceFunc: func(_ *testing.T) io.Reader {
149 return bytes.NewBuffer([]byte(`
150# pint file/disable promql/series
151
152groups:
153- name: foo
154 rules:
155 - record: foo
156 expr: bar
157`))
158 },
159 isStrict: true,
160 entries: []Entry{
161 {
162 State: Unknown,
163 Path: Path{
164 Name: "rules.yml",
165 SymlinkTarget: "rules.yml",
166 },
167 ModifiedLines: []int{7, 8},
168 Rule: mustParse(6, "- record: foo\n expr: bar\n"),
169 DisabledChecks: []string{"promql/series"},
170 },
171 },
172 },
173 {
174 title: "single expired snooze comment",
175 reportedPath: "rules.yml",
176 sourcePath: "rules.yml",
177 sourceFunc: func(_ *testing.T) io.Reader {
178 return bytes.NewBuffer([]byte(`
179# pint file/snooze 2000-01-01T00:00:00Z promql/series
180
181- record: foo
182 expr: bar
183`))
184 },
185 isStrict: false,
186 entries: []Entry{
187 {
188 State: Unknown,
189 Path: Path{
190 Name: "rules.yml",
191 SymlinkTarget: "rules.yml",
192 },
193 ModifiedLines: []int{4, 5},
194 Rule: mustParse(3, "- record: foo\n expr: bar\n"),
195 },
196 },
197 },
198 {
199 title: "single expired snooze comment",
200 reportedPath: "rules.yml",
201 sourcePath: "rules.yml",
202 sourceFunc: func(_ *testing.T) io.Reader {
203 return bytes.NewBuffer([]byte(`
204# pint file/snooze 2000-01-01T00:00:00Z promql/series
205
206groups:
207- name: foo
208 rules:
209 - record: foo
210 expr: bar
211`))
212 },
213 isStrict: true,
214 entries: []Entry{
215 {
216 State: Unknown,
217 Path: Path{
218 Name: "rules.yml",
219 SymlinkTarget: "rules.yml",
220 },
221 ModifiedLines: []int{7, 8},
222 Rule: mustParse(6, "- record: foo\n expr: bar\n"),
223 },
224 },
225 },
226 {
227 title: "single valid snooze comment",
228 reportedPath: "rules.yml",
229 sourcePath: "rules.yml",
230 sourceFunc: func(_ *testing.T) io.Reader {
231 return bytes.NewBuffer([]byte(`
232# pint file/snooze 2099-01-01T00:00:00Z promql/series
233
234- record: foo
235 expr: bar
236`))
237 },
238 isStrict: false,
239 entries: []Entry{
240 {
241 State: Unknown,
242 Path: Path{
243 Name: "rules.yml",
244 SymlinkTarget: "rules.yml",
245 },
246 ModifiedLines: []int{4, 5},
247 Rule: mustParse(3, "- record: foo\n expr: bar\n"),
248 DisabledChecks: []string{"promql/series"},
249 },
250 },
251 },
252 {
253 title: "single valid snooze comment",
254 reportedPath: "rules.yml",
255 sourcePath: "rules.yml",
256 sourceFunc: func(_ *testing.T) io.Reader {
257 return bytes.NewBuffer([]byte(`
258# pint file/snooze 2099-01-01T00:00:00Z promql/series
259
260groups:
261- name: foo
262 rules:
263 - record: foo
264 expr: bar
265`))
266 },
267 isStrict: true,
268 entries: []Entry{
269 {
270 State: Unknown,
271 Path: Path{
272 Name: "rules.yml",
273 SymlinkTarget: "rules.yml",
274 },
275 ModifiedLines: []int{7, 8},
276 Rule: mustParse(6, "- record: foo\n expr: bar\n"),
277 DisabledChecks: []string{"promql/series"},
278 },
279 },
280 },
281 {
282 title: "ignore/file",
283 reportedPath: "rules.yml",
284 sourcePath: "rules.yml",
285 sourceFunc: func(_ *testing.T) io.Reader {
286 return bytes.NewBuffer([]byte(`
287# pint ignore/file
288
289- record: foo
290 expr: bar
291`))
292 },
293 isStrict: false,
294 entries: []Entry{
295 {
296 State: Unknown,
297 Path: Path{
298 Name: "rules.yml",
299 SymlinkTarget: "rules.yml",
300 },
301 ModifiedLines: []int{1, 2, 3, 4, 5},
302 PathError: FileIgnoreError{Line: 2, Err: errors.New("file was ignored")},
303 },
304 },
305 },
306 {
307 title: "ignore/file",
308 reportedPath: "rules.yml",
309 sourcePath: "rules.yml",
310 sourceFunc: func(_ *testing.T) io.Reader {
311 return bytes.NewBuffer([]byte(`
312# pint ignore/file
313
314groups:
315- name: foo
316 rules:
317 - record: foo
318 expr: bar
319`))
320 },
321 isStrict: true,
322 entries: []Entry{
323 {
324 State: Unknown,
325 Path: Path{
326 Name: "rules.yml",
327 SymlinkTarget: "rules.yml",
328 },
329 ModifiedLines: []int{1, 2, 3, 4, 5, 6, 7, 8},
330 PathError: FileIgnoreError{Line: 2, Err: errors.New("file was ignored")},
331 },
332 },
333 },
334 }
335
336 for _, tc := range testCases {
337 t.Run(
338 fmt.Sprintf("rPath=%s sPath=%s strict=%v title=%s", tc.reportedPath, tc.sourcePath, tc.isStrict, tc.title),
339 func(t *testing.T) {
340 r := tc.sourceFunc(t)
341 entries, err := readRules(tc.reportedPath, tc.sourcePath, r, tc.isStrict)
342 if tc.err != "" {
343 require.EqualError(t, err, tc.err)
344 } else {
345 require.NoError(t, err)
346
347 expected, err := json.MarshalIndent(tc.entries, "", " ")
348 require.NoError(t, err, "json(expected)")
349 got, err := json.MarshalIndent(entries, "", " ")
350 require.NoError(t, err, "json(got)")
351 require.Equal(t, string(expected), string(got))
352 }
353 })
354 }
355}
356