cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.60.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/discovery/glob_test.go

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