Skip to content

Commit 1ea8997

Browse files
committed
make test: fix TestProposalValidate invalid sig
Move validation logic from Proposal to KEPHandler, since Proposals don't know which Groups and PRRApprovers are valid
1 parent 544afe2 commit 1ea8997

File tree

3 files changed

+81
-28
lines changed

3 files changed

+81
-28
lines changed

api/proposal.go

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,6 @@ type Proposal struct {
7676
Contents string `json:"markdown" yaml:"-"`
7777
}
7878

79-
func (p *Proposal) Validate() error {
80-
v := validator.New()
81-
if err := v.Struct(p); err != nil {
82-
return errors.Wrap(err, "running validation")
83-
}
84-
85-
return nil
86-
}
87-
8879
func (p *Proposal) IsMissingMilestone() bool {
8980
return p.LatestMilestone == ""
9081
}
@@ -153,16 +144,75 @@ func (k *KEPHandler) Parse(in io.Reader) (*Proposal, error) {
153144
return kep, errors.Wrap(err, "unmarshalling YAML")
154145
}
155146

156-
if valErr := kep.Validate(); valErr != nil {
157-
k.Errors = append(k.Errors, errors.Wrap(valErr, "validating KEP"))
158-
return kep, errors.Wrap(valErr, "validating KEP")
147+
if err := k.validateStruct(kep); err != nil {
148+
k.Errors = append(k.Errors, err)
149+
return kep, fmt.Errorf("validating KEP: %w", err)
159150
}
160151

161152
kep.ID = hash(kep.OwningSIG + ":" + kep.Title)
162153

163154
return kep, nil
164155
}
165156

157+
// validateStruct returns an error if the given Proposal has invalid fields
158+
// as defined by struct tags, or nil if there are no invalid fields
159+
func (k *KEPHandler) validateStruct(p *Proposal) error {
160+
v := validator.New()
161+
return v.Struct(p)
162+
}
163+
164+
// validateGroups returns errors for each invalid group (e.g. SIG) in the given
165+
// Proposal, or nil if there are no invalid groups
166+
func (k *KEPHandler) validateGroups(p *Proposal) []error {
167+
var errs []error
168+
validGroups := make(map[string]bool)
169+
for _, g := range k.Groups {
170+
validGroups[g] = true
171+
}
172+
for _, g := range p.ParticipatingSIGs {
173+
if _, ok := validGroups[g]; !ok {
174+
errs = append(errs, fmt.Errorf("invalid participating-sig: %s", g))
175+
}
176+
}
177+
if _, ok := validGroups[p.OwningSIG]; !ok {
178+
errs = append(errs, fmt.Errorf("invalid owning-sig: %s", p.OwningSIG))
179+
}
180+
return errs
181+
}
182+
183+
// validatePRRApprovers returns errors for each invalid PRR Approver in the
184+
// given Proposal, or nil if there are no invalid PRR Approvers
185+
func (k *KEPHandler) validatePRRApprovers(p *Proposal) []error {
186+
var errs []error
187+
validPRRApprovers := make(map[string]bool)
188+
for _, a := range k.PRRApprovers {
189+
validPRRApprovers[a] = true
190+
}
191+
for _, a := range p.PRRApprovers {
192+
if _, ok := validPRRApprovers[a]; !ok {
193+
errs = append(errs, fmt.Errorf("invalid prr-approver: %s", a))
194+
}
195+
}
196+
return errs
197+
}
198+
199+
// Validate returns errors for each reason the given proposal is invalid,
200+
// or nil if it is valid
201+
func (k *KEPHandler) Validate(p *Proposal) []error {
202+
var allErrs []error
203+
204+
if err := k.validateStruct(p); err != nil {
205+
allErrs = append(allErrs, fmt.Errorf("struct-based validation: %w", err))
206+
}
207+
if errs := k.validateGroups(p); errs != nil {
208+
allErrs = append(allErrs, errs...)
209+
}
210+
if errs := k.validatePRRApprovers(p); errs != nil {
211+
allErrs = append(allErrs, errs...)
212+
}
213+
return allErrs
214+
}
215+
166216
type Milestone struct {
167217
Alpha string `json:"alpha" yaml:"alpha"`
168218
Beta string `json:"beta" yaml:"beta"`

pkg/proposal/create.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ func Create(opts *CreateOpts) error {
8080

8181
populateProposal(kep, opts)
8282

83-
err := kep.Validate()
84-
if err != nil {
85-
return err
83+
errs := r.KEPHandler.Validate(kep)
84+
if errs != nil {
85+
return fmt.Errorf("invalid kep: %v", errs)
8686
}
8787

88-
err = createKEP(kep, opts)
88+
err := createKEP(kep, opts)
8989
if err != nil {
9090
return err
9191
}

pkg/repo/repo_test.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,25 @@ import (
2929

3030
func TestProposalValidate(t *testing.T) {
3131
testcases := []struct {
32-
name string
33-
file string
34-
expectError bool
32+
name string
33+
file string
34+
expectErrors bool
3535
}{
3636
{
37-
name: "valid KEP passes validate",
38-
file: "testdata/valid-kep.yaml",
39-
expectError: false,
37+
name: "valid KEP passes validate",
38+
file: "testdata/valid-kep.yaml",
39+
expectErrors: false,
4040
},
4141
{
42-
name: "invalid KEP fails validate for owning-sig",
43-
file: "testdata/invalid-kep.yaml",
44-
expectError: true,
42+
name: "invalid KEP fails validate for owning-sig",
43+
file: "testdata/invalid-kep.yaml",
44+
expectErrors: true,
4545
},
4646
}
4747

48+
parser := api.KEPHandler{}
49+
parser.Groups = []string{"sig-api-machinery"}
50+
4851
for _, tc := range testcases {
4952
t.Run(tc.name, func(t *testing.T) {
5053
b, err := ioutil.ReadFile(tc.file)
@@ -54,9 +57,9 @@ func TestProposalValidate(t *testing.T) {
5457
err = yaml.Unmarshal(b, &p)
5558
require.NoError(t, err)
5659

57-
err = p.Validate()
58-
if tc.expectError {
59-
require.Error(t, err)
60+
errs := parser.Validate(&p)
61+
if tc.expectErrors {
62+
require.NotEmpty(t, errs)
6063
}
6164

6265
require.NoError(t, err)

0 commit comments

Comments
 (0)