sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/plugins/reward-owners/reward-owners_test.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package rewardowners 18 19 import ( 20 "testing" 21 22 "sigs.k8s.io/prow/pkg/github/fakegithub" 23 24 "k8s.io/apimachinery/pkg/util/sets" 25 "sigs.k8s.io/prow/pkg/layeredsets" 26 27 "sigs.k8s.io/prow/pkg/plugins/ownersconfig" 28 "sigs.k8s.io/prow/pkg/repoowners" 29 30 "github.com/sirupsen/logrus" 31 "sigs.k8s.io/prow/pkg/git/localgit" 32 "sigs.k8s.io/prow/pkg/github" 33 ) 34 35 type fakeOwnersClient struct{} 36 37 func (f *fakeOwnersClient) LoadRepoOwnersSha(org, repo, base, sha string, updateCache bool) (repoowners.RepoOwner, error) { 38 return &fakeRepoOwners{sha: sha}, nil 39 } 40 41 type fakeRepoOwners struct { 42 sha string 43 } 44 45 func (f *fakeRepoOwners) Filenames() ownersconfig.Filenames { return ownersconfig.Filenames{} } 46 func (f *fakeRepoOwners) FindApproverOwnersForFile(path string) string { return "" } 47 func (f *fakeRepoOwners) FindReviewersOwnersForFile(path string) string { return "" } 48 func (f *fakeRepoOwners) FindLabelsForFile(path string) sets.Set[string] { return nil } 49 func (f *fakeRepoOwners) IsNoParentOwners(path string) bool { return false } 50 func (f *fakeRepoOwners) IsAutoApproveUnownedSubfolders(path string) bool { return false } 51 func (f *fakeRepoOwners) LeafApprovers(path string) sets.Set[string] { return nil } 52 func (f *fakeRepoOwners) Approvers(path string) layeredsets.String { return layeredsets.String{} } 53 func (f *fakeRepoOwners) LeafReviewers(path string) sets.Set[string] { return nil } 54 func (f *fakeRepoOwners) ParseSimpleConfig(path string) (repoowners.SimpleConfig, error) { 55 return repoowners.SimpleConfig{}, nil 56 } 57 func (f *fakeRepoOwners) ParseFullConfig(path string) (repoowners.FullConfig, error) { 58 return repoowners.FullConfig{}, nil 59 } 60 func (f *fakeRepoOwners) Reviewers(path string) layeredsets.String { return layeredsets.String{} } 61 func (f *fakeRepoOwners) RequiredReviewers(path string) sets.Set[string] { return nil } 62 func (f *fakeRepoOwners) TopLevelApprovers() sets.Set[string] { return nil } 63 64 func (f *fakeRepoOwners) AllApprovers() sets.Set[string] { 65 return ownersBySha[f.sha] 66 } 67 68 func (f *fakeRepoOwners) AllOwners() sets.Set[string] { 69 return ownersBySha[f.sha] 70 } 71 72 func (f *fakeRepoOwners) AllReviewers() sets.Set[string] { 73 return ownersBySha[f.sha] 74 } 75 76 var ownersBySha = map[string]sets.Set[string]{ 77 "base": sets.New[string]("alice", "bob"), 78 "add cole": sets.New[string]("alice", "bob", "cole"), 79 "remove alice": sets.New[string]("bob"), 80 } 81 82 func makeChanges(files []string) map[string]string { 83 changes := make(map[string]string, len(files)) 84 for _, f := range files { 85 changes[f] = "foo" 86 } 87 return changes 88 } 89 90 func newFakeGitHubClient(changed map[string]string, pr int) *fakegithub.FakeClient { 91 var changes []github.PullRequestChange 92 for file, patch := range changed { 93 changes = append(changes, github.PullRequestChange{Filename: file, Patch: patch}) 94 } 95 return &fakegithub.FakeClient{ 96 PullRequestChanges: map[int][]github.PullRequestChange{pr: changes}, 97 Reviews: map[int][]github.Review{}, 98 Collaborators: []string{"alice", "bob", "jdoe"}, 99 IssueComments: map[int][]github.IssueComment{}, 100 } 101 } 102 103 func TestHandleV2(t *testing.T) { 104 testHandle(localgit.NewV2, t) 105 } 106 107 func testHandle(clients localgit.Clients, t *testing.T) { 108 var tests = []struct { 109 name string 110 filesChanged []string 111 sha string 112 expectComment bool 113 }{ 114 { 115 name: "no OWNERS file", 116 filesChanged: []string{"a.go", "b.go"}, 117 expectComment: false, 118 }, 119 { 120 name: "add user to OWNERS", 121 filesChanged: []string{"OWNERS", "b.go"}, 122 sha: "add cole", 123 expectComment: true, 124 }, 125 { 126 name: "add user to OWNERS_ALIASES", 127 filesChanged: []string{"OWNERS_ALIASES", "b.go"}, 128 sha: "add cole", 129 expectComment: true, 130 }, 131 { 132 name: "remove user from OWNERS", 133 filesChanged: []string{"OWNERS", "b.go"}, 134 sha: "remove alice", 135 expectComment: false, 136 }, 137 { 138 name: "remove user from OWNERS_ALIASES", 139 filesChanged: []string{"OWNERS_ALIASES", "b.go"}, 140 sha: "remove alice", 141 expectComment: false, 142 }, 143 { 144 name: "move user from OWNERS_ALIASES to OWNERS", 145 filesChanged: []string{"OWNERS", "OWNERS_ALIASES"}, 146 sha: "head", 147 expectComment: false, 148 }, 149 } 150 lg, c, err := clients() 151 if err != nil { 152 t.Fatalf("Making localgit: %v", err) 153 } 154 defer func() { 155 if err := lg.Clean(); err != nil { 156 t.Errorf("Cleaning up localgit: %v", err) 157 } 158 if err := c.Clean(); err != nil { 159 t.Errorf("Cleaning up client: %v", err) 160 } 161 }() 162 if err := lg.MakeFakeRepo("org", "repo"); err != nil { 163 t.Fatalf("Making fake repo: %v", err) 164 } 165 for i, test := range tests { 166 t.Run(test.name, func(t *testing.T) { 167 pr := i + 1 168 169 changes := makeChanges(test.filesChanged) 170 fghc := newFakeGitHubClient(changes, pr) 171 oc := &fakeOwnersClient{} 172 173 prInfo := info{ 174 base: github.PullRequestBranch{ 175 Ref: "master", 176 SHA: "base", 177 }, 178 head: github.PullRequestBranch{ 179 Ref: "master", 180 SHA: test.sha, 181 }, 182 number: pr, 183 org: "org", 184 repo: "repo", 185 repoFullName: "org/repo", 186 } 187 188 if err := handle(fghc, oc, logrus.WithField("plugin", PluginName), prInfo, ownersconfig.FakeResolver); err != nil { 189 t.Fatalf("Handle PR: %v", err) 190 } 191 numComments := len(fghc.IssueCommentsAdded) 192 if numComments > 1 { 193 t.Fatalf("did not expect multiple comments for any test case and got %d comments", numComments) 194 } 195 if numComments == 0 && test.expectComment { 196 t.Fatalf("expected a comment for case '%s' and got none", test.name) 197 } else if numComments > 0 && !test.expectComment { 198 t.Fatalf("did not expect comments for case '%s' and got %d comments", test.name, numComments) 199 } 200 }) 201 } 202 }