cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.57.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/discovery/glob_test.go

307lines · 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 ReportedPath: "bar.yml",
76 SourcePath: "bar.yml",
77 Rule: testRules[0],
78 ModifiedLines: testRules[0].Lines.Expand(),
79 Owner: "bob",
80 },
81 },
82 },
83 {
84 files: map[string]string{"foo/bar.yml": testRuleBody + "\n\n# pint file/owner alice\n"},
85 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")})),
86 entries: []discovery.Entry{
87 {
88 State: discovery.Noop,
89 ReportedPath: "foo/bar.yml",
90 SourcePath: "foo/bar.yml",
91 Rule: testRules[0],
92 ModifiedLines: testRules[0].Lines.Expand(),
93 Owner: "alice",
94 },
95 },
96 },
97 {
98 files: map[string]string{"bar.yml": testRuleBody},
99 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
100 entries: []discovery.Entry{
101 {
102 State: discovery.Noop,
103 ReportedPath: "bar.yml",
104 SourcePath: "bar.yml",
105 PathError: parseErr(testRuleBody),
106 ModifiedLines: []int{1, 2, 3, 4},
107 Owner: "bob",
108 },
109 },
110 },
111 {
112 files: map[string]string{"bar.yml": "record:::{}\n expr: sum(foo)\n\n# pint file/owner bob\n"},
113 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")})),
114 entries: []discovery.Entry{
115 {
116 State: discovery.Noop,
117 ReportedPath: "bar.yml",
118 SourcePath: "bar.yml",
119 PathError: errors.New("yaml: line 2: mapping values are not allowed in this context"),
120 ModifiedLines: []int{1, 2, 3, 4},
121 Owner: "bob",
122 },
123 },
124 },
125 {
126 files: map[string]string{"bar.yml": testRuleBody},
127 symlinks: map[string]string{"link.yml": "bar.yml"},
128 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
129 entries: []discovery.Entry{
130 {
131 State: discovery.Noop,
132 ReportedPath: "bar.yml",
133 SourcePath: "bar.yml",
134 PathError: parseErr(testRuleBody),
135 ModifiedLines: []int{1, 2, 3, 4},
136 Owner: "bob",
137 },
138 {
139 State: discovery.Noop,
140 ReportedPath: "bar.yml",
141 SourcePath: "link.yml",
142 PathError: parseErr(testRuleBody),
143 ModifiedLines: []int{1, 2, 3, 4},
144 Owner: "bob",
145 },
146 },
147 },
148 {
149 files: map[string]string{"a/bar.yml": testRuleBody},
150 symlinks: map[string]string{
151 "b/link.yml": "../a/bar.yml",
152 "b/c/link.yml": "../../a/bar.yml",
153 },
154 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
155 entries: []discovery.Entry{
156 {
157 State: discovery.Noop,
158 ReportedPath: "a/bar.yml",
159 SourcePath: "a/bar.yml",
160 PathError: parseErr(testRuleBody),
161 ModifiedLines: []int{1, 2, 3, 4},
162 Owner: "bob",
163 },
164 {
165 State: discovery.Noop,
166 ReportedPath: "a/bar.yml",
167 SourcePath: "b/c/link.yml",
168 PathError: parseErr(testRuleBody),
169 ModifiedLines: []int{1, 2, 3, 4},
170 Owner: "bob",
171 },
172 {
173 State: discovery.Noop,
174 ReportedPath: "a/bar.yml",
175 SourcePath: "b/link.yml",
176 PathError: parseErr(testRuleBody),
177 ModifiedLines: []int{1, 2, 3, 4},
178 Owner: "bob",
179 },
180 },
181 },
182 {
183 files: map[string]string{"a/bar.yml": testRuleBody},
184 symlinks: map[string]string{
185 "b/link.yml": "../a/bar.yml",
186 "b/c/link.yml": "../a/bar.yml",
187 },
188 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
189 err: "b/c/link.yml is a symlink but target file cannot be evaluated: lstat b/a: no such file or directory",
190 },
191 {
192 files: map[string]string{"a/bar.yml": "xxx:\n"},
193 symlinks: map[string]string{
194 "b/c/link.yml": "../../a/bar.yml",
195 },
196 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")})),
197 },
198 {
199 files: map[string]string{"a/bar.yml": "xxx:\nyyy:\n"},
200 symlinks: map[string]string{
201 "b/c/link.yml": "../../a/bar.yml",
202 },
203 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
204 entries: []discovery.Entry{
205 {
206 State: discovery.Noop,
207 ReportedPath: "a/bar.yml",
208 SourcePath: "a/bar.yml",
209 PathError: parseErr("xxx:\nyyy:\n"),
210 ModifiedLines: []int{1, 2},
211 Owner: "",
212 },
213 {
214 State: discovery.Noop,
215 ReportedPath: "a/bar.yml",
216 SourcePath: "b/c/link.yml",
217 PathError: parseErr("xxx:\nyyy:\n"),
218 ModifiedLines: []int{1, 2},
219 Owner: "",
220 },
221 },
222 },
223 {
224 files: map[string]string{"a/bar.yml": "xxx:\nyyy:\n"},
225 symlinks: map[string]string{
226 "b/c/link.yml": "../../a/bar.yml",
227 },
228 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")})),
229 },
230 {
231 files: map[string]string{"a/bar.yml": "xxx:\nyyy:\n"},
232 symlinks: map[string]string{
233 "b/c/d": "../../a",
234 },
235 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, []*regexp.Regexp{regexp.MustCompile(".*")})),
236 },
237 {
238 files: map[string]string{"a/bar.yml": testRuleBody},
239 symlinks: map[string]string{
240 "b/c/link.yml": "../../a/bar.yml",
241 },
242 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
243 entries: []discovery.Entry{
244 {
245 State: discovery.Noop,
246 ReportedPath: "a/bar.yml",
247 SourcePath: "a/bar.yml",
248 PathError: parseErr(testRuleBody),
249 ModifiedLines: []int{1, 2, 3, 4},
250 Owner: "bob",
251 },
252 {
253 State: discovery.Noop,
254 ReportedPath: "a/bar.yml",
255 SourcePath: "b/c/link.yml",
256 PathError: parseErr(testRuleBody),
257 ModifiedLines: []int{1, 2, 3, 4},
258 Owner: "bob",
259 },
260 },
261 },
262 {
263 symlinks: map[string]string{
264 "input.yml": "/xx/ccc/fdd",
265 },
266 finder: discovery.NewGlobFinder([]string{"*"}, git.NewPathFilter(nil, nil, nil)),
267 err: "input.yml is a symlink but target file cannot be evaluated: lstat /xx: no such file or directory",
268 },
269 }
270
271 for i, tc := range testCases {
272 t.Run(strconv.Itoa(i), func(t *testing.T) {
273 workdir := t.TempDir()
274 err := os.Chdir(workdir)
275 require.NoError(t, err)
276
277 for p, content := range tc.files {
278 if strings.Contains(p, "/") {
279 err = os.MkdirAll(path.Dir(p), 0o755)
280 require.NoError(t, err)
281 }
282 err = os.WriteFile(p, []byte(content), 0o644)
283 require.NoError(t, err)
284 }
285 for symlink, target := range tc.symlinks {
286 if strings.Contains(symlink, "/") {
287 err = os.MkdirAll(path.Dir(symlink), 0o755)
288 require.NoError(t, err)
289 }
290 require.NoError(t, os.Symlink(target, symlink))
291 }
292
293 entries, err := tc.finder.Find()
294 if tc.err != "" {
295 require.EqualError(t, err, tc.err)
296 } else {
297 require.NoError(t, err)
298
299 expected, err := json.MarshalIndent(tc.entries, "", " ")
300 require.NoError(t, err, "json(expected)")
301 got, err := json.MarshalIndent(entries, "", " ")
302 require.NoError(t, err, "json(got)")
303 require.Equal(t, string(expected), string(got))
304 }
305 })
306 }
307}
308