Skip to content

Commit 3ad8912

Browse files
authored
Merge pull request kubernetes#2753 from spiffxp/make-test-fixes
Get `make test` working again
2 parents f0df4e3 + d46a02d commit 3ad8912

File tree

25 files changed

+372
-364
lines changed

25 files changed

+372
-364
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ Session.vim
2424

2525
# Files generated by JetBrains IDEs, e.g. IntelliJ IDEA
2626
.idea/
27+
28+
# hack/test-go.sh writes files here if ARTIFACTS is unset
29+
tmp/

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ test-go-integration: ## Runs Golang integration tests
8686

8787
.PHONY: tools
8888

89-
KEP_TOOLS ?=
89+
WHAT ?= kepctl kepify
9090

91-
tools: ## Compiles a set of KEP tools, specified by $KEP_TOOLS
92-
./compile-tools $(KEP_TOOLS)
91+
tools: ## Installs all KEP tools, can select via e.g. WHAT=kepctl
92+
./compile-tools $(WHAT)
9393

9494
##@ Dependencies
9595

api/approval.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,6 @@ type PRRMilestone struct {
9494

9595
type PRRHandler Parser
9696

97-
func NewPRRHandler() (*PRRHandler, error) {
98-
handler := &PRRHandler{}
99-
100-
approvers, err := FetchPRRApprovers()
101-
if err != nil {
102-
return nil, errors.Wrap(err, "fetching PRR approvers")
103-
}
104-
105-
handler.PRRApprovers = approvers
106-
107-
return handler, nil
108-
}
109-
11097
// TODO(api): Make this a generic parser for all `Document` types
11198
func (p *PRRHandler) Parse(in io.Reader) (*PRRApproval, error) {
11299
scanner := bufio.NewScanner(in)

api/groups.go

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,65 @@ import (
2929
"sigs.k8s.io/yaml"
3030
)
3131

32-
const (
33-
// URLs
34-
sigListURL = "https://raw.githubusercontent.com/kubernetes/community/master/sigs.yaml"
35-
ownersAliasURL = "https://raw.githubusercontent.com/kubernetes/enhancements/master/OWNERS_ALIASES"
32+
// GroupFetcher is responsible for getting informationg about groups in the
33+
// Kubernetes Community
34+
type GroupFetcher interface {
35+
// FetchGroups returns the list of valid Kubernetes Community groups
36+
// e.g. (SIGs, WGs, UGs, Committees)
37+
FetchGroups() ([]string, error)
38+
// FetchPRRApprovers returns the list of valid PRR Approvers
39+
FetchPRRApprovers() ([]string, error)
40+
}
3641

37-
// Aliases
38-
prrApproversAlias = "prod-readiness-approvers"
39-
)
42+
// DefaultGroupFetcher returns the default GroupFetcher, which depends on GitHub
43+
func DefaultGroupFetcher() GroupFetcher {
44+
return &RemoteGroupFetcher{
45+
GroupsListURL: "https://raw.githubusercontent.com/kubernetes/community/master/sigs.yaml",
46+
OwnersAliasesURL: "https://raw.githubusercontent.com/kubernetes/enhancements/master/OWNERS_ALIASES",
47+
PRRApproversAlias: "prod-readiness-approvers",
48+
}
49+
}
50+
51+
// MockGroupFetcher returns the given Groups and PRR Approvers
52+
type MockGroupFetcher struct {
53+
Groups []string
54+
PRRApprovers []string
55+
}
56+
57+
var _ GroupFetcher = &MockGroupFetcher{}
58+
59+
func NewMockGroupFetcher(groups, prrApprovers []string) GroupFetcher {
60+
return &MockGroupFetcher{Groups: groups, PRRApprovers: prrApprovers}
61+
}
62+
63+
func (f *MockGroupFetcher) FetchGroups() ([]string, error) {
64+
result := make([]string, len(f.Groups))
65+
copy(result, f.Groups)
66+
return result, nil
67+
}
68+
69+
func (f *MockGroupFetcher) FetchPRRApprovers() ([]string, error) {
70+
result := make([]string, len(f.PRRApprovers))
71+
copy(result, f.PRRApprovers)
72+
return result, nil
73+
}
74+
75+
// RemoteGroupFetcher returns Groups and PRR Approvers from remote sources
76+
type RemoteGroupFetcher struct {
77+
// Basically kubernetes/community/sigs.yaml
78+
GroupsListURL string
79+
// Basically kubernetes/enhancements/OWNERS_ALIASES
80+
OwnersAliasesURL string
81+
// The alias name to look for in OWNERS_ALIASES
82+
PRRApproversAlias string
83+
}
84+
85+
var _ GroupFetcher = &RemoteGroupFetcher{}
4086

41-
// FetchGroups returns a list of Kubernetes governance groups
42-
// (SIGs, Working Groups, User Groups).
43-
func FetchGroups() ([]string, error) {
44-
resp, err := http.Get(sigListURL)
87+
// FetchGroups returns the list of valid Kubernetes Community groups as
88+
// fetched from a remote source
89+
func (f *RemoteGroupFetcher) FetchGroups() ([]string, error) {
90+
resp, err := http.Get(f.GroupsListURL)
4591
if err != nil {
4692
return nil, errors.Wrap(err, "fetching SIG list")
4793
}
@@ -78,8 +124,8 @@ func FetchGroups() ([]string, error) {
78124
}
79125

80126
// FetchPRRApprovers returns a list of PRR approvers.
81-
func FetchPRRApprovers() ([]string, error) {
82-
resp, err := http.Get(ownersAliasURL)
127+
func (f *RemoteGroupFetcher) FetchPRRApprovers() ([]string, error) {
128+
resp, err := http.Get(f.OwnersAliasesURL)
83129
if err != nil {
84130
return nil, errors.Wrap(err, "fetching owners aliases")
85131
}
@@ -108,7 +154,7 @@ func FetchPRRApprovers() ([]string, error) {
108154
}
109155

110156
var result []string
111-
result = append(result, config.Data[prrApproversAlias]...)
157+
result = append(result, config.Data[f.PRRApproversAlias]...)
112158

113159
if len(result) == 0 {
114160
return nil, errors.New("retrieved zero PRR approvers, which is unexpected")

api/proposal.go

Lines changed: 62 additions & 32 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
}
@@ -95,26 +86,6 @@ func (p *Proposal) IsMissingStage() bool {
9586

9687
type KEPHandler Parser
9788

98-
func NewKEPHandler() (*KEPHandler, error) {
99-
handler := &KEPHandler{}
100-
101-
groups, err := FetchGroups()
102-
if err != nil {
103-
return nil, errors.Wrap(err, "fetching groups")
104-
}
105-
106-
handler.Groups = groups
107-
108-
approvers, err := FetchPRRApprovers()
109-
if err != nil {
110-
return nil, errors.Wrap(err, "fetching PRR approvers")
111-
}
112-
113-
handler.PRRApprovers = approvers
114-
115-
return handler, nil
116-
}
117-
11889
// TODO(api): Make this a generic parser for all `Document` types
11990
func (k *KEPHandler) Parse(in io.Reader) (*Proposal, error) {
12091
scanner := bufio.NewScanner(in)
@@ -153,16 +124,75 @@ func (k *KEPHandler) Parse(in io.Reader) (*Proposal, error) {
153124
return kep, errors.Wrap(err, "unmarshalling YAML")
154125
}
155126

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")
127+
if err := k.validateStruct(kep); err != nil {
128+
k.Errors = append(k.Errors, err)
129+
return kep, fmt.Errorf("validating KEP: %w", err)
159130
}
160131

161132
kep.ID = hash(kep.OwningSIG + ":" + kep.Title)
162133

163134
return kep, nil
164135
}
165136

137+
// validateStruct returns an error if the given Proposal has invalid fields
138+
// as defined by struct tags, or nil if there are no invalid fields
139+
func (k *KEPHandler) validateStruct(p *Proposal) error {
140+
v := validator.New()
141+
return v.Struct(p)
142+
}
143+
144+
// validateGroups returns errors for each invalid group (e.g. SIG) in the given
145+
// Proposal, or nil if there are no invalid groups
146+
func (k *KEPHandler) validateGroups(p *Proposal) []error {
147+
var errs []error
148+
validGroups := make(map[string]bool)
149+
for _, g := range k.Groups {
150+
validGroups[g] = true
151+
}
152+
for _, g := range p.ParticipatingSIGs {
153+
if _, ok := validGroups[g]; !ok {
154+
errs = append(errs, fmt.Errorf("invalid participating-sig: %s", g))
155+
}
156+
}
157+
if _, ok := validGroups[p.OwningSIG]; !ok {
158+
errs = append(errs, fmt.Errorf("invalid owning-sig: %s", p.OwningSIG))
159+
}
160+
return errs
161+
}
162+
163+
// validatePRRApprovers returns errors for each invalid PRR Approver in the
164+
// given Proposal, or nil if there are no invalid PRR Approvers
165+
func (k *KEPHandler) validatePRRApprovers(p *Proposal) []error {
166+
var errs []error
167+
validPRRApprovers := make(map[string]bool)
168+
for _, a := range k.PRRApprovers {
169+
validPRRApprovers[a] = true
170+
}
171+
for _, a := range p.PRRApprovers {
172+
if _, ok := validPRRApprovers[a]; !ok {
173+
errs = append(errs, fmt.Errorf("invalid prr-approver: %s", a))
174+
}
175+
}
176+
return errs
177+
}
178+
179+
// Validate returns errors for each reason the given proposal is invalid,
180+
// or nil if it is valid
181+
func (k *KEPHandler) Validate(p *Proposal) []error {
182+
var allErrs []error
183+
184+
if err := k.validateStruct(p); err != nil {
185+
allErrs = append(allErrs, fmt.Errorf("struct-based validation: %w", err))
186+
}
187+
if errs := k.validateGroups(p); errs != nil {
188+
allErrs = append(allErrs, errs...)
189+
}
190+
if errs := k.validatePRRApprovers(p); errs != nil {
191+
allErrs = append(allErrs, errs...)
192+
}
193+
return allErrs
194+
}
195+
166196
type Milestone struct {
167197
Alpha string `json:"alpha" yaml:"alpha"`
168198
Beta string `json:"beta" yaml:"beta"`

cmd/kepify/main.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ import (
2525
"path/filepath"
2626
"strings"
2727

28-
"github.com/pkg/errors"
29-
3028
"k8s.io/enhancements/api"
3129
)
3230

@@ -72,8 +70,24 @@ func main() {
7270
os.Exit(1)
7371
}
7472

73+
fetcher := api.DefaultGroupFetcher()
74+
75+
groups, err := fetcher.FetchGroups()
76+
if err != nil {
77+
fmt.Fprintf(os.Stderr, "unable to fetch groups: %v", err)
78+
os.Exit(1)
79+
}
80+
81+
prrApprovers, err := fetcher.FetchPRRApprovers()
82+
if err != nil {
83+
fmt.Fprintf(os.Stderr, "unable to fetch PRR approvers: %v", err)
84+
os.Exit(1)
85+
}
86+
87+
kepHandler := &api.KEPHandler{Groups: groups, PRRApprovers: prrApprovers}
88+
7589
// Parse the files
76-
proposals, err := parseFiles(files)
90+
proposals, err := parseFiles(kepHandler, files)
7791
if err != nil {
7892
fmt.Fprintf(os.Stderr, "error parsing files: %q\n", err)
7993
os.Exit(1)
@@ -112,14 +126,9 @@ func findMarkdownFiles(dirPath *string) ([]string, error) {
112126
return files, err
113127
}
114128

115-
func parseFiles(files []string) (api.Proposals, error) {
129+
func parseFiles(parser *api.KEPHandler, files []string) (api.Proposals, error) {
116130
var proposals api.Proposals
117131
for _, filename := range files {
118-
parser, err := api.NewKEPHandler()
119-
if err != nil {
120-
return nil, errors.Wrap(err, "creating new KEP handler")
121-
}
122-
123132
file, err := os.Open(filename)
124133
if err != nil {
125134
return nil, fmt.Errorf("could not open file: %v", err)

compile-tools

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ setup_env() {
2929

3030
if [[ -z "${TOOL_BIN:-}" ]]; then
3131
if [ -n "${GOBIN:-}" ]; then
32-
export TOOL_BIN="${GOBIN}"
32+
TOOL_BIN="${GOBIN}"
3333
else
34-
export TOOL_BIN="${GOPATH}/bin"
34+
TOOL_BIN="$(go env GOPATH)/bin"
3535
fi
36+
export TOOL_BIN
3637
fi
3738

3839
export PATH="${PATH}:${TOOL_BIN}"
@@ -89,20 +90,22 @@ main() {
8990
setup_env
9091
check_deps
9192

92-
if [ $# -gt 0 ]; then
93-
for tool in "$@"; do
94-
if [[ ${tool} =~ github.com\/ ]]; then
95-
compile "${tool}"
96-
else
97-
compile_with_flags "${tool}"
98-
fi
99-
done
100-
else
101-
for tool in "${TOOLS[@]}"; do
102-
echo "Compiling default tools..."
103-
compile_with_flags "${tool}"
104-
done
93+
if [ $# = 0 ]; then
94+
# default to all tools
95+
set -- "${TOOLS[@]}"
10596
fi
97+
98+
for tool; do
99+
if ! (printf '%s\n' "${TOOLS[@]}" | grep -q "^${tool}$"); then
100+
echo "Skipping unrecognized tool name: ${tool}" >&2
101+
continue
102+
fi
103+
if [[ ${tool} =~ github.com\/ ]]; then
104+
compile "${tool}"
105+
else
106+
compile_with_flags "${tool}"
107+
fi
108+
done
106109
}
107110

108111
main "$@"

0 commit comments

Comments
 (0)