sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/plugins/owners-label/owners-label_test.go (about) 1 /* 2 Copyright 2018 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 ownerslabel 18 19 import ( 20 "fmt" 21 "reflect" 22 "sort" 23 "testing" 24 25 "github.com/sirupsen/logrus" 26 27 "k8s.io/apimachinery/pkg/util/sets" 28 "sigs.k8s.io/prow/pkg/github" 29 "sigs.k8s.io/prow/pkg/github/fakegithub" 30 "sigs.k8s.io/prow/pkg/labels" 31 ) 32 33 func formatLabels(labels ...string) []string { 34 r := []string{} 35 for _, l := range labels { 36 r = append(r, fmt.Sprintf("%s/%s#%d:%s", "org", "repo", 1, l)) 37 } 38 if len(r) == 0 { 39 return nil 40 } 41 return r 42 } 43 44 type fakeOwnersClient struct { 45 labels map[string]sets.Set[string] 46 } 47 48 func (foc *fakeOwnersClient) FindLabelsForFile(path string) sets.Set[string] { 49 return foc.labels[path] 50 } 51 52 // TestHandle tests that the handle function requests reviews from the correct number of unique users. 53 func TestHandle(t *testing.T) { 54 foc := &fakeOwnersClient{ 55 labels: map[string]sets.Set[string]{ 56 "a.go": sets.New[string](labels.LGTM, labels.Approved, "kind/docs"), 57 "b.go": sets.New[string](labels.LGTM), 58 "c.go": sets.New[string](labels.LGTM, "dnm/frozen-docs"), 59 "d.sh": sets.New[string]("dnm/bash"), 60 "e.sh": sets.New[string]("dnm/bash"), 61 }, 62 } 63 64 type testCase struct { 65 name string 66 filesChanged []string 67 expectedNewLabels []string 68 repoLabels []string 69 issueLabels []string 70 } 71 testcases := []testCase{ 72 { 73 name: "no labels", 74 filesChanged: []string{"other.go", "something.go"}, 75 expectedNewLabels: []string{}, 76 repoLabels: []string{}, 77 issueLabels: []string{}, 78 }, 79 { 80 name: "1 file 1 label", 81 filesChanged: []string{"b.go"}, 82 expectedNewLabels: formatLabels(labels.LGTM), 83 repoLabels: []string{labels.LGTM}, 84 issueLabels: []string{}, 85 }, 86 { 87 name: "1 file 3 labels", 88 filesChanged: []string{"a.go"}, 89 expectedNewLabels: formatLabels(labels.LGTM, labels.Approved, "kind/docs"), 90 repoLabels: []string{labels.LGTM, labels.Approved, "kind/docs"}, 91 issueLabels: []string{}, 92 }, 93 { 94 name: "2 files no overlap", 95 filesChanged: []string{"c.go", "d.sh"}, 96 expectedNewLabels: formatLabels(labels.LGTM, "dnm/frozen-docs", "dnm/bash"), 97 repoLabels: []string{labels.LGTM, "dnm/frozen-docs", "dnm/bash"}, 98 issueLabels: []string{}, 99 }, 100 { 101 name: "2 files partial overlap", 102 filesChanged: []string{"a.go", "b.go"}, 103 expectedNewLabels: formatLabels(labels.LGTM, labels.Approved, "kind/docs"), 104 repoLabels: []string{labels.LGTM, labels.Approved, "kind/docs"}, 105 issueLabels: []string{}, 106 }, 107 { 108 name: "2 files complete overlap", 109 filesChanged: []string{"d.sh", "e.sh"}, 110 expectedNewLabels: formatLabels("dnm/bash"), 111 repoLabels: []string{"dnm/bash"}, 112 issueLabels: []string{}, 113 }, 114 { 115 name: "3 files partial overlap", 116 filesChanged: []string{"a.go", "b.go", "c.go"}, 117 expectedNewLabels: formatLabels(labels.LGTM, labels.Approved, "kind/docs", "dnm/frozen-docs"), 118 repoLabels: []string{labels.LGTM, labels.Approved, "kind/docs", "dnm/frozen-docs"}, 119 issueLabels: []string{}, 120 }, 121 { 122 name: "no labels to add, initial unrelated label", 123 filesChanged: []string{"other.go", "something.go"}, 124 expectedNewLabels: []string{}, 125 repoLabels: []string{labels.LGTM}, 126 issueLabels: []string{labels.LGTM}, 127 }, 128 { 129 name: "1 file 1 label, already present", 130 filesChanged: []string{"b.go"}, 131 expectedNewLabels: []string{}, 132 repoLabels: []string{labels.LGTM}, 133 issueLabels: []string{labels.LGTM}, 134 }, 135 { 136 name: "1 file 1 label, doesn't exist on the repo", 137 filesChanged: []string{"b.go"}, 138 expectedNewLabels: []string{}, 139 repoLabels: []string{labels.Approved}, 140 issueLabels: []string{}, 141 }, 142 { 143 name: "2 files no overlap, 1 label already present", 144 filesChanged: []string{"c.go", "d.sh"}, 145 expectedNewLabels: formatLabels(labels.LGTM, "dnm/frozen-docs"), 146 repoLabels: []string{"dnm/bash", labels.Approved, labels.LGTM, "dnm/frozen-docs"}, 147 issueLabels: []string{"dnm/bash", labels.Approved}, 148 }, 149 { 150 name: "2 files complete overlap, label already present", 151 filesChanged: []string{"d.sh", "e.sh"}, 152 expectedNewLabels: []string{}, 153 repoLabels: []string{"dnm/bash"}, 154 issueLabels: []string{"dnm/bash"}, 155 }, 156 } 157 158 for _, tc := range testcases { 159 basicPR := github.PullRequest{ 160 Number: 1, 161 Base: github.PullRequestBranch{ 162 Repo: github.Repo{ 163 Owner: github.User{ 164 Login: "org", 165 }, 166 Name: "repo", 167 }, 168 }, 169 User: github.User{ 170 Login: "user", 171 }, 172 } 173 174 t.Logf("Running scenario %q", tc.name) 175 sort.Strings(tc.expectedNewLabels) 176 changes := make([]github.PullRequestChange, 0, len(tc.filesChanged)) 177 for _, name := range tc.filesChanged { 178 changes = append(changes, github.PullRequestChange{Filename: name}) 179 } 180 fghc := fakegithub.NewFakeClient() 181 fghc.PullRequests = map[int]*github.PullRequest{ 182 basicPR.Number: &basicPR, 183 } 184 fghc.PullRequestChanges = map[int][]github.PullRequestChange{ 185 basicPR.Number: changes, 186 } 187 fghc.RepoLabelsExisting = tc.repoLabels 188 fghc.IssueLabelsAdded = []string{} 189 // Add initial labels 190 for _, label := range tc.issueLabels { 191 fghc.AddLabel(basicPR.Base.Repo.Owner.Login, basicPR.Base.Repo.Name, basicPR.Number, label) 192 } 193 pre := &github.PullRequestEvent{ 194 Action: github.PullRequestActionOpened, 195 Number: basicPR.Number, 196 PullRequest: basicPR, 197 Repo: basicPR.Base.Repo, 198 } 199 200 err := handle(fghc, foc, logrus.WithField("plugin", PluginName), pre) 201 if err != nil { 202 t.Errorf("[%s] unexpected error from handle: %v", tc.name, err) 203 continue 204 } 205 206 // Check that all the correct labels (and only the correct labels) were added. 207 expectLabels := append(formatLabels(tc.issueLabels...), tc.expectedNewLabels...) 208 if expectLabels == nil { 209 expectLabels = []string{} 210 } 211 sort.Strings(expectLabels) 212 sort.Strings(fghc.IssueLabelsAdded) 213 if !reflect.DeepEqual(expectLabels, fghc.IssueLabelsAdded) { 214 t.Errorf("expected the labels %q to be added, but %q were added.", expectLabels, fghc.IssueLabelsAdded) 215 } 216 217 } 218 }