cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.73.3

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/discovery/glob_test.go

357lines · modecode

1package discovery_test
2
3import (
4 "encoding/json"
5 "errors"
6 "os"
7 "path"
8 "regexp"
9 "strconv"
10 "strings"
11 "testing"
12
13 "github.com/prometheus/common/model"
14 "github.com/stretchr/testify/require"
15
16 "github.com/cloudflare/pint/internal/discovery"
17 "github.com/cloudflare/pint/internal/git"
18 "github.com/cloudflare/pint/internal/parser"
19)
20
21func TestGlobPathFinder(t *testing.T) {
22 type testCaseT struct {
23 files map[string]string
24 symlinks map[string]string
25 err string
26 entries []discovery.Entry
27 finder discovery.GlobFinder
28 }
29
30 p := parser.NewParser(false, parser.PrometheusSchema, model.UTF8Validation)
31 testRuleBody := "# pint file/owner bob\n\n- record: foo\n expr: sum(foo)\n"
32 testFile := p.Parse(strings.NewReader(testRuleBody))
33 require.NoError(t, testFile.Error.Err)
34
35 testCases := []testCaseT{
36 {
37 files: map[string]string{},
38 finder: discovery.NewGlobFinder([]string{"[]"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
39 err: "failed to expand file path pattern []: syntax error in pattern",
40 },
41 {
42 files: map[string]string{},
43 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
44 err: "no matching files",
45 },
46 {
47 files: map[string]string{},
48 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
49 err: "no matching files",
50 },
51 {
52 files: map[string]string{},
53 finder: discovery.NewGlobFinder([]string{"foo/*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
54 err: "no matching files",
55 },
56 {
57 files: map[string]string{"bar.yml": testRuleBody},
58 finder: discovery.NewGlobFinder([]string{"foo/*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
59 err: "no matching files",
60 },
61 {
62 files: map[string]string{"bar.yml": testRuleBody},
63 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")}), parser.PrometheusSchema, model.UTF8Validation, nil),
64 entries: []discovery.Entry{
65 {
66 State: discovery.Noop,
67 Path: discovery.Path{
68 Name: "bar.yml",
69 SymlinkTarget: "bar.yml",
70 },
71 Rule: testFile.Groups[0].Rules[0],
72 ModifiedLines: testFile.Groups[0].Rules[0].Lines.Expand(),
73 Owner: "bob",
74 },
75 },
76 },
77 {
78 files: map[string]string{"foo/bar.yml": testRuleBody + "\n\n# pint file/owner alice\n"},
79 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")}), parser.PrometheusSchema, model.UTF8Validation, nil),
80 entries: []discovery.Entry{
81 {
82 State: discovery.Noop,
83 Path: discovery.Path{
84 Name: "foo/bar.yml",
85 SymlinkTarget: "foo/bar.yml",
86 },
87 Rule: testFile.Groups[0].Rules[0],
88 ModifiedLines: testFile.Groups[0].Rules[0].Lines.Expand(),
89 Owner: "alice",
90 },
91 },
92 },
93 {
94 files: map[string]string{"bar.yml": testRuleBody},
95 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
96 entries: []discovery.Entry{
97 {
98 State: discovery.Noop,
99 Path: discovery.Path{
100 Name: "bar.yml",
101 SymlinkTarget: "bar.yml",
102 },
103 PathError: parser.ParseError{
104 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
105 Line: 3,
106 },
107 ModifiedLines: []int{1, 2, 3, 4},
108 Owner: "bob",
109 },
110 },
111 },
112 {
113 files: map[string]string{"bar.yml": "record:::{}\n expr: sum(foo)\n\n# pint file/owner bob\n"},
114 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")}), parser.PrometheusSchema, model.UTF8Validation, nil),
115 entries: []discovery.Entry{
116 {
117 State: discovery.Noop,
118 Path: discovery.Path{
119 Name: "bar.yml",
120 SymlinkTarget: "bar.yml",
121 },
122 PathError: parser.ParseError{
123 Err: errors.New("mapping values are not allowed in this context"),
124 Line: 2,
125 },
126 ModifiedLines: []int{1, 2, 3, 4},
127 Owner: "bob",
128 },
129 },
130 },
131 {
132 files: map[string]string{"bar.yml": testRuleBody},
133 symlinks: map[string]string{"link.yml": "bar.yml"},
134 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
135 entries: []discovery.Entry{
136 {
137 State: discovery.Noop,
138 Path: discovery.Path{
139 Name: "bar.yml",
140 SymlinkTarget: "bar.yml",
141 },
142 PathError: parser.ParseError{
143 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
144 Line: 3,
145 },
146 ModifiedLines: []int{1, 2, 3, 4},
147 Owner: "bob",
148 },
149 {
150 State: discovery.Noop,
151 Path: discovery.Path{
152 Name: "link.yml",
153 SymlinkTarget: "bar.yml",
154 },
155 PathError: parser.ParseError{
156 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
157 Line: 3,
158 },
159 ModifiedLines: []int{1, 2, 3, 4},
160 Owner: "bob",
161 },
162 },
163 },
164 {
165 files: map[string]string{"a/bar.yml": testRuleBody},
166 symlinks: map[string]string{
167 "b/link.yml": "../a/bar.yml",
168 "b/c/link.yml": "../../a/bar.yml",
169 },
170 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
171 entries: []discovery.Entry{
172 {
173 State: discovery.Noop,
174 Path: discovery.Path{
175 Name: "a/bar.yml",
176 SymlinkTarget: "a/bar.yml",
177 },
178 PathError: parser.ParseError{
179 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
180 Line: 3,
181 },
182 ModifiedLines: []int{1, 2, 3, 4},
183 Owner: "bob",
184 },
185 {
186 State: discovery.Noop,
187 Path: discovery.Path{
188 Name: "b/c/link.yml",
189 SymlinkTarget: "a/bar.yml",
190 },
191 PathError: parser.ParseError{
192 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
193 Line: 3,
194 },
195 ModifiedLines: []int{1, 2, 3, 4},
196 Owner: "bob",
197 },
198 {
199 State: discovery.Noop,
200 Path: discovery.Path{
201 Name: "b/link.yml",
202 SymlinkTarget: "a/bar.yml",
203 },
204 PathError: parser.ParseError{
205 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
206 Line: 3,
207 },
208 ModifiedLines: []int{1, 2, 3, 4},
209 Owner: "bob",
210 },
211 },
212 },
213 {
214 files: map[string]string{"a/bar.yml": testRuleBody},
215 symlinks: map[string]string{
216 "b/link.yml": "../a/bar.yml",
217 "b/c/link.yml": "../a/bar.yml",
218 },
219 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
220 err: "b/c/link.yml is a symlink but target file cannot be evaluated: lstat b/a: no such file or directory",
221 },
222 {
223 files: map[string]string{"a/bar.yml": "xxx:\n"},
224 symlinks: map[string]string{
225 "b/c/link.yml": "../../a/bar.yml",
226 },
227 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")}), parser.PrometheusSchema, model.UTF8Validation, nil),
228 },
229 {
230 files: map[string]string{"a/bar.yml": "xxx:\nyyy:\n"},
231 symlinks: map[string]string{
232 "b/c/link.yml": "../../a/bar.yml",
233 },
234 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
235 entries: []discovery.Entry{
236 {
237 State: discovery.Noop,
238 Path: discovery.Path{
239 Name: "a/bar.yml",
240 SymlinkTarget: "a/bar.yml",
241 },
242 PathError: parser.ParseError{
243 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
244 Line: 1,
245 },
246 ModifiedLines: []int{1, 2},
247 Owner: "",
248 },
249 {
250 State: discovery.Noop,
251 Path: discovery.Path{
252 Name: "b/c/link.yml",
253 SymlinkTarget: "a/bar.yml",
254 },
255 PathError: parser.ParseError{
256 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
257 Line: 1,
258 },
259 ModifiedLines: []int{1, 2},
260 Owner: "",
261 },
262 },
263 },
264 {
265 files: map[string]string{"a/bar.yml": "xxx:\nyyy:\n"},
266 symlinks: map[string]string{
267 "b/c/link.yml": "../../a/bar.yml",
268 },
269 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")}), parser.PrometheusSchema, model.UTF8Validation, nil),
270 },
271 {
272 files: map[string]string{"a/bar.yml": "xxx:\nyyy:\n"},
273 symlinks: map[string]string{
274 "b/c/d": "../../a",
275 },
276 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")}), parser.PrometheusSchema, model.UTF8Validation, nil),
277 },
278 {
279 files: map[string]string{"a/bar.yml": testRuleBody},
280 symlinks: map[string]string{
281 "b/c/link.yml": "../../a/bar.yml",
282 },
283 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
284 entries: []discovery.Entry{
285 {
286 State: discovery.Noop,
287 Path: discovery.Path{
288 Name: "a/bar.yml",
289 SymlinkTarget: "a/bar.yml",
290 },
291 PathError: parser.ParseError{
292 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
293 Line: 3,
294 },
295 ModifiedLines: []int{1, 2, 3, 4},
296 Owner: "bob",
297 },
298 {
299 State: discovery.Noop,
300 Path: discovery.Path{
301 Name: "b/c/link.yml",
302 SymlinkTarget: "a/bar.yml",
303 },
304 PathError: parser.ParseError{
305 Err: errors.New("YAML list is not allowed here, expected a YAML mapping"),
306 Line: 3,
307 },
308 ModifiedLines: []int{1, 2, 3, 4},
309 Owner: "bob",
310 },
311 },
312 },
313 {
314 symlinks: map[string]string{
315 "input.yml": "/xx/ccc/fdd",
316 },
317 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil), parser.PrometheusSchema, model.UTF8Validation, nil),
318 err: "input.yml is a symlink but target file cannot be evaluated: lstat /xx: no such file or directory",
319 },
320 }
321
322 for i, tc := range testCases {
323 t.Run(strconv.Itoa(i), func(t *testing.T) {
324 workdir := t.TempDir()
325 t.Chdir(workdir)
326
327 for p, content := range tc.files {
328 if strings.Contains(p, "/") {
329 err := os.MkdirAll(path.Dir(p), 0o755)
330 require.NoError(t, err)
331 }
332 err := os.WriteFile(p, []byte(content), 0o644)
333 require.NoError(t, err)
334 }
335 for symlink, target := range tc.symlinks {
336 if strings.Contains(symlink, "/") {
337 err := os.MkdirAll(path.Dir(symlink), 0o755)
338 require.NoError(t, err)
339 }
340 require.NoError(t, os.Symlink(target, symlink))
341 }
342
343 entries, err := tc.finder.Find()
344 if tc.err != "" {
345 require.EqualError(t, err, tc.err)
346 } else {
347 require.NoError(t, err)
348
349 expected, err := json.MarshalIndent(tc.entries, "", " ")
350 require.NoError(t, err, "json(expected)")
351 got, err := json.MarshalIndent(entries, "", " ")
352 require.NoError(t, err, "json(got)")
353 require.Equal(t, string(expected), string(got))
354 }
355 })
356 }
357}
358