Skip to content

Commit b003f6b

Browse files
committed
kepctl query: add test coverage
Add some basic coverage for each "query" field in QueryOpts, aka ignore IncludePRs and Output Add some TODO-titled test cases that are skipped for things that seem like opportunities to improve validation
1 parent 1046342 commit b003f6b

File tree

8 files changed

+355
-5
lines changed

8 files changed

+355
-5
lines changed

pkg/repo/query.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (r *Repo) PrepareQueryOpts(opts *QueryOpts) error {
6363
}
6464

6565
if len(sigs) == 0 {
66-
return fmt.Errorf("no SIG matches any of the passed regular expressions")
66+
return fmt.Errorf("no SIGs match any of: %v", opts.Groups)
6767
}
6868

6969
opts.Groups = sigs
@@ -81,7 +81,7 @@ func (r *Repo) Query(opts *QueryOpts) ([]*api.Proposal, error) {
8181

8282
err := r.PrepareQueryOpts(opts)
8383
if err != nil {
84-
return nil, fmt.Errorf("unable to prepare query opts: %w", err)
84+
return nil, fmt.Errorf("invalid query options: %w", err)
8585
}
8686

8787
if r.TokenPath != "" {

pkg/repo/query_test.go

Lines changed: 262 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestValidateQueryOpt(t *testing.T) {
4646
IncludePRs: true,
4747
Output: "json",
4848
},
49-
err: fmt.Errorf("No SIG matches any of the passed regular expressions"),
49+
err: fmt.Errorf("no SIGs match any of: [sig-does-not-exist]"),
5050
},
5151
{
5252
name: "output: unsupported format",
@@ -74,3 +74,264 @@ func TestValidateQueryOpt(t *testing.T) {
7474
})
7575
}
7676
}
77+
78+
func TestQuery(t *testing.T) {
79+
testcases := map[string][]struct {
80+
name string
81+
queryOpts repo.QueryOpts
82+
err error
83+
kepNames []string
84+
skip bool
85+
}{
86+
"all": {
87+
{
88+
name: "defaults",
89+
queryOpts: repo.QueryOpts{},
90+
kepNames: []string{
91+
"1-the-bare-minimum",
92+
"123-newstyle",
93+
"13-keps-as-crds",
94+
"404-question-not-found",
95+
"42-the-answer",
96+
},
97+
},
98+
{
99+
name: "everything",
100+
queryOpts: repo.QueryOpts{
101+
Groups: []string{"sig-architecture"},
102+
Status: []string{"provisional"},
103+
Stage: []string{"alpha"},
104+
// TODO: PRRApprover: []string{""},
105+
Author: []string{"@rjbez17"},
106+
Approver: []string{"@liggitt"},
107+
},
108+
kepNames: []string{
109+
"123-newstyle",
110+
},
111+
},
112+
},
113+
"groups": {
114+
{
115+
name: "results",
116+
queryOpts: repo.QueryOpts{
117+
Groups: []string{"sig-owns-participates"},
118+
},
119+
kepNames: []string{"1-the-bare-minimum", "13-keps-as-crds"},
120+
},
121+
{
122+
name: "no results",
123+
queryOpts: repo.QueryOpts{
124+
Groups: []string{"sig-participates-only"},
125+
},
126+
},
127+
{
128+
name: "invalid",
129+
queryOpts: repo.QueryOpts{
130+
Groups: []string{"sig-does-not-exist"},
131+
},
132+
err: fmt.Errorf("invalid query options: no SIGs match any of: [sig-does-not-exist]"),
133+
},
134+
},
135+
"status": {
136+
{
137+
name: "results",
138+
queryOpts: repo.QueryOpts{
139+
Status: []string{"provisional"},
140+
},
141+
kepNames: []string{
142+
"123-newstyle",
143+
"13-keps-as-crds",
144+
},
145+
},
146+
{
147+
name: "TODO: invalid should error, but instead returns nothing",
148+
queryOpts: repo.QueryOpts{
149+
Status: []string{"status-does-not-exist"},
150+
},
151+
err: fmt.Errorf("something about invalid status"),
152+
skip: true,
153+
},
154+
},
155+
"stage": {
156+
{
157+
name: "empty-string",
158+
queryOpts: repo.QueryOpts{
159+
Stage: []string{""},
160+
},
161+
kepNames: []string{
162+
"1-the-bare-minimum",
163+
},
164+
},
165+
{
166+
name: "alpha",
167+
queryOpts: repo.QueryOpts{
168+
Stage: []string{"alpha"},
169+
},
170+
kepNames: []string{
171+
"123-newstyle",
172+
"42-the-answer",
173+
},
174+
},
175+
{
176+
name: "beta",
177+
queryOpts: repo.QueryOpts{
178+
Stage: []string{"beta"},
179+
},
180+
kepNames: []string{
181+
"404-question-not-found",
182+
},
183+
},
184+
{
185+
name: "stable",
186+
queryOpts: repo.QueryOpts{
187+
Stage: []string{"stable"},
188+
},
189+
kepNames: []string{
190+
"13-keps-as-crds",
191+
},
192+
},
193+
{
194+
name: "TODO: invalid should error, but instead returns nothing",
195+
queryOpts: repo.QueryOpts{
196+
Stage: []string{"stage-does-not-exist"},
197+
},
198+
err: fmt.Errorf("something about invalid stage"),
199+
skip: true,
200+
},
201+
},
202+
"prr-approver": {
203+
{
204+
name: "results",
205+
queryOpts: repo.QueryOpts{
206+
PRRApprover: []string{"@dorothy"},
207+
},
208+
kepNames: []string{
209+
"404-question-not-found",
210+
"42-the-answer",
211+
"13-keps-as-crds",
212+
},
213+
},
214+
{
215+
name: "no results",
216+
queryOpts: repo.QueryOpts{
217+
PRRApprover: []string{"prr-approves-nothing"},
218+
},
219+
},
220+
{
221+
name: "TODO: invalid should error but instead returns nothing",
222+
queryOpts: repo.QueryOpts{
223+
PRRApprover: []string{"prr-approver-does-not-exist"},
224+
},
225+
err: fmt.Errorf("something about invalid prr-approver"),
226+
skip: true,
227+
},
228+
},
229+
"author": {
230+
{
231+
name: "results",
232+
queryOpts: repo.QueryOpts{
233+
Author: []string{"@alice"},
234+
},
235+
kepNames: []string{
236+
"404-question-not-found",
237+
"42-the-answer",
238+
"13-keps-as-crds",
239+
},
240+
},
241+
{
242+
name: "no results",
243+
queryOpts: repo.QueryOpts{
244+
Author: []string{"authors-nothing"},
245+
},
246+
},
247+
{
248+
name: "TODO: empty-string should error but instead returns nothing",
249+
queryOpts: repo.QueryOpts{
250+
Author: []string{""},
251+
},
252+
err: fmt.Errorf("something about invalid author"),
253+
skip: true,
254+
},
255+
},
256+
"approver": {
257+
{
258+
name: "results",
259+
queryOpts: repo.QueryOpts{
260+
Approver: []string{"@carolyn"},
261+
},
262+
kepNames: []string{
263+
"404-question-not-found",
264+
"42-the-answer",
265+
"13-keps-as-crds",
266+
},
267+
},
268+
{
269+
name: "no results",
270+
queryOpts: repo.QueryOpts{
271+
Approver: []string{"approves-nothing"},
272+
},
273+
},
274+
{
275+
name: "TODO: empty-string should error but instead returns nothing",
276+
queryOpts: repo.QueryOpts{
277+
Author: []string{""},
278+
},
279+
err: fmt.Errorf("something about invalid approver"),
280+
skip: true,
281+
},
282+
},
283+
}
284+
285+
r := fixture.validRepo
286+
287+
for group, groupTestcases := range testcases {
288+
for _, tc := range groupTestcases {
289+
t.Run(fmt.Sprintf("%s/%s", group, tc.name), func(t *testing.T) {
290+
if tc.skip {
291+
t.Skip("TODO")
292+
}
293+
// TODO(spiffxp): uh, Query shouldn't care about Output
294+
queryOpts := tc.queryOpts
295+
queryOpts.Output = "json"
296+
297+
results, err := r.Query(&queryOpts)
298+
299+
if tc.err == nil {
300+
require.Nil(t, err)
301+
} else {
302+
// TODO(spiffxp): does this verify not nil, or the actual error?
303+
require.Error(t, err, tc.err.Error())
304+
}
305+
306+
if len(tc.kepNames) != len(results) {
307+
t.Errorf("expected %v results, found: %v", len(tc.kepNames), len(results))
308+
}
309+
310+
expectedKEPs := make(map[string]bool)
311+
for _, name := range tc.kepNames {
312+
expectedKEPs[name] = false
313+
}
314+
315+
errs := []error{}
316+
317+
for _, kep := range results {
318+
if _, expected := expectedKEPs[kep.Name]; expected {
319+
expectedKEPs[kep.Name] = true
320+
} else {
321+
errs = append(errs, fmt.Errorf("query returned unexpected kep: %+v", kep))
322+
}
323+
}
324+
325+
for _, name := range tc.kepNames {
326+
if found := expectedKEPs[name]; !found {
327+
errs = append(errs, fmt.Errorf("query did not return expected kep: %v", name))
328+
}
329+
}
330+
331+
for _, err := range errs {
332+
t.Error(err)
333+
}
334+
})
335+
}
336+
}
337+
}

pkg/repo/repo_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ var fixture = struct {
3737
}{}
3838

3939
func TestMain(m *testing.M) {
40-
err := log.SetupGlobalLogger("debug")
40+
err := log.SetupGlobalLogger("info")
4141
if err != nil {
4242
fmt.Fprintf(os.Stderr, "Unable to setup global logger: %v: ", err)
4343
}
@@ -48,6 +48,10 @@ func TestMain(m *testing.M) {
4848
fetcher := &api.MockGroupFetcher{
4949
Groups: []string{
5050
"sig-architecture",
51+
"sig-does-nothing",
52+
"sig-owns-only",
53+
"sig-owns-participates",
54+
"sig-participates-only",
5155
},
5256
}
5357
r, err := repo.NewRepo(fixture.validRepoPath, fetcher)

pkg/repo/testdata/repos/valid/keps/sig-architecture/123-newstyle/kep.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ kep-number: 1687
33
authors:
44
- "@rjbez17"
55
- "@adrianludwin"
6-
owning-sig: sig-auth
6+
owning-sig: sig-architecture
77
participating-sigs:
88
- sig-auth
99
reviewers:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
title: Using Deep Thought
2+
kep-number: 13
3+
authors:
4+
- "@alice"
5+
owning-sig: sig-owns-only
6+
participating-sigs:
7+
- sig-owns-participates
8+
- sig-participates-only
9+
status: implemented
10+
# creation-date: yyyy-mm-dd
11+
reviewers:
12+
- "@beth"
13+
approvers:
14+
- "@carolyn"
15+
prr-approvers:
16+
- "@dorothy"
17+
stage: beta
18+
latest-milestone: v1.4
19+
milestone:
20+
alpha: v1.1
21+
beta: v1.2
22+
stable: v1.3
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
title: Life, The Universe, And Everything
2+
kep-number: 42
3+
authors:
4+
- "@alice"
5+
owning-sig: sig-owns-only
6+
participating-sigs:
7+
- sig-owns-participates
8+
- sig-participates-only
9+
status: implemented
10+
# creation-date: yyyy-mm-dd
11+
reviewers:
12+
- "@beth"
13+
approvers:
14+
- "@carolyn"
15+
prr-approvers:
16+
- "@dorothy"
17+
stage: alpha
18+
latest-milestone: v1.4
19+
milestone:
20+
alpha: v1.1
21+
beta: v1.2
22+
stable: v1.3
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
title: The Bare Minimum
2+
kep-number: a non-empty string
3+
# authors:
4+
# - "@alice"
5+
# TODO: this should fail to load/validate unless owning-sig is sig-owns-participates
6+
owning-sig: a non-empty string
7+
# TODO: this should fail to load/validate unless status is one of...
8+
status: a non-empty string
9+
# creation-date: yyyy-mm-dd
10+
# reviewers:
11+
# - "@beth"
12+
# approvers:
13+
# - "@carolyn"
14+
# prr-approvers:
15+
# - "@dorothy"
16+
# stage: stable
17+
# latest-milestone: v1.4
18+
# milestone:
19+
# alpha: v1.1
20+
# beta: v1.2
21+
# stable: v1.3

0 commit comments

Comments
 (0)