sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/plugins/merge-method-comment/merge-method-comment_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 mergemethodcomment 18 19 import ( 20 "fmt" 21 "strings" 22 "testing" 23 24 "sigs.k8s.io/prow/pkg/config" 25 "sigs.k8s.io/prow/pkg/git/types" 26 "sigs.k8s.io/prow/pkg/github" 27 ) 28 29 const fakeBotName = "k8s-bot" 30 31 type ghc struct { 32 *testing.T 33 comments map[string][]github.IssueComment 34 createCommentErr error 35 listCommentsErr error 36 } 37 38 func (c *ghc) CreateComment(org, repo string, num int, comment string) error { 39 c.T.Logf("CreateComment: %s/%s#%d: %s", org, repo, num, comment) 40 if c.createCommentErr != nil { 41 return c.createCommentErr 42 } 43 if len(c.comments) == 0 { 44 c.comments = make(map[string][]github.IssueComment) 45 } 46 orgRepoNum := fmt.Sprintf("%s/%s#%d", org, repo, num) 47 c.comments[orgRepoNum] = append(c.comments[orgRepoNum], 48 github.IssueComment{ 49 Body: comment, 50 User: github.User{Login: fakeBotName}, 51 }, 52 ) 53 return nil 54 } 55 56 func (c *ghc) ListIssueComments(org, repo string, num int) ([]github.IssueComment, error) { 57 c.T.Logf("ListIssueComments: %s/%s#%d", org, repo, num) 58 if c.listCommentsErr != nil { 59 return nil, c.listCommentsErr 60 } 61 return c.comments[fmt.Sprintf("%s/%s#%d", org, repo, num)], nil 62 } 63 64 func (c *ghc) BotUserChecker() (func(candidate string) bool, error) { 65 return func(candidate string) bool { return candidate == fakeBotName }, nil 66 } 67 68 func TestHandlePR(t *testing.T) { 69 singleCommitPR := github.PullRequest{ 70 Number: 101, 71 Base: github.PullRequestBranch{ 72 Repo: github.Repo{ 73 Owner: github.User{ 74 Login: "kubernetes", 75 }, 76 Name: "kubernetes", 77 }, 78 }, 79 Commits: 1, 80 } 81 multipleCommitsPR := github.PullRequest{ 82 Number: 101, 83 Base: github.PullRequestBranch{ 84 Repo: github.Repo{ 85 Owner: github.User{ 86 Login: "kubernetes", 87 }, 88 Name: "kubernetes", 89 }, 90 }, 91 Commits: 2, 92 } 93 94 cases := []struct { 95 name string 96 client *ghc 97 event github.PullRequestEvent 98 defaultMergeMethod types.PullRequestMergeType 99 squashLabel string 100 mergeLabel string 101 err error 102 comments []github.IssueComment 103 }{ 104 { 105 name: "single commit", 106 client: &ghc{}, 107 event: github.PullRequestEvent{ 108 Action: github.PullRequestActionOpened, 109 PullRequest: singleCommitPR, 110 }, 111 squashLabel: "squash-label", 112 defaultMergeMethod: types.MergeSquash, 113 }, 114 { 115 name: "multiple commits, merge by-default, squash label configured", 116 client: &ghc{}, 117 event: github.PullRequestEvent{ 118 Action: github.PullRequestActionOpened, 119 PullRequest: multipleCommitsPR, 120 }, 121 defaultMergeMethod: types.MergeMerge, 122 squashLabel: "squash-label", 123 comments: []github.IssueComment{ 124 { 125 Body: "You can request commits to be squashed using the label: squash-label", 126 }, 127 }, 128 }, 129 { 130 name: "multiple commits, merge by-default, squash label not configured", 131 client: &ghc{}, 132 event: github.PullRequestEvent{ 133 Action: github.PullRequestActionOpened, 134 PullRequest: multipleCommitsPR, 135 }, 136 defaultMergeMethod: types.MergeMerge, 137 comments: []github.IssueComment{ 138 { 139 Body: "Commits will be merged, as no squash labels are defined", 140 }, 141 }, 142 }, 143 { 144 name: "multiple commits, squash by-default, merge label configured", 145 client: &ghc{}, 146 event: github.PullRequestEvent{ 147 Action: github.PullRequestActionOpened, 148 PullRequest: multipleCommitsPR, 149 }, 150 defaultMergeMethod: types.MergeSquash, 151 mergeLabel: "merge-label", 152 comments: []github.IssueComment{ 153 { 154 Body: "You can request commits to be merged using the label: merge-label", 155 }, 156 }, 157 }, 158 { 159 name: "multiple commits, squash by-default, merge label not configured", 160 client: &ghc{}, 161 event: github.PullRequestEvent{ 162 Action: github.PullRequestActionOpened, 163 PullRequest: multipleCommitsPR, 164 }, 165 defaultMergeMethod: types.MergeSquash, 166 comments: []github.IssueComment{ 167 { 168 Body: "Commits will be squashed, as no merge labels are defined", 169 }, 170 }, 171 }, 172 { 173 name: "do not create comment if already commented", 174 client: &ghc{ 175 comments: map[string][]github.IssueComment{ 176 "kubernetes/kubernetes#101": { 177 { 178 User: github.User{Login: "k8s-bot"}, 179 Body: fmt.Sprintf("This PR has multiple commits, and the default merge method is: %s.\n%s", 180 types.MergeMerge, 181 "Commits will be merged, as no squash labels are defined"), 182 }, 183 }, 184 }, 185 }, 186 event: github.PullRequestEvent{ 187 Action: github.PullRequestActionOpened, 188 PullRequest: multipleCommitsPR, 189 }, 190 defaultMergeMethod: types.MergeMerge, 191 comments: []github.IssueComment{ 192 { 193 Body: "Commits will be merged, as no squash labels are defined", 194 }, 195 }, 196 }, 197 { 198 name: "error listing issue comments", 199 client: &ghc{ 200 listCommentsErr: fmt.Errorf("cannot list comments"), 201 }, 202 defaultMergeMethod: types.MergeMerge, 203 event: github.PullRequestEvent{ 204 Action: github.PullRequestActionOpened, 205 PullRequest: multipleCommitsPR, 206 }, 207 err: fmt.Errorf("error listing issue comments: %s", "cannot list comments"), 208 }, 209 { 210 name: "error creating comment", 211 client: &ghc{ 212 createCommentErr: fmt.Errorf("cannot create comment"), 213 }, 214 defaultMergeMethod: types.MergeMerge, 215 event: github.PullRequestEvent{ 216 Action: github.PullRequestActionSynchronize, 217 PullRequest: multipleCommitsPR, 218 }, 219 err: fmt.Errorf("cannot create comment"), 220 }, 221 { 222 name: "handle PR sync", 223 client: &ghc{}, 224 event: github.PullRequestEvent{ 225 Action: github.PullRequestActionSynchronize, 226 PullRequest: multipleCommitsPR, 227 }, 228 defaultMergeMethod: types.MergeMerge, 229 comments: []github.IssueComment{ 230 { 231 Body: "Commits will be merged, as no squash labels are defined", 232 }, 233 }, 234 }, 235 { 236 name: "handle PR reopen", 237 client: &ghc{}, 238 event: github.PullRequestEvent{ 239 Action: github.PullRequestActionReopened, 240 PullRequest: multipleCommitsPR, 241 }, 242 defaultMergeMethod: types.MergeMerge, 243 comments: []github.IssueComment{ 244 { 245 Body: "Commits will be merged, as no squash labels are defined", 246 }, 247 }, 248 }, 249 { 250 name: "handle PR edit", 251 client: &ghc{}, 252 event: github.PullRequestEvent{ 253 Action: github.PullRequestActionEdited, 254 PullRequest: multipleCommitsPR, 255 }, 256 defaultMergeMethod: types.MergeMerge, 257 comments: []github.IssueComment{ 258 { 259 Body: "Commits will be merged, as no squash labels are defined", 260 }, 261 }, 262 }, 263 { 264 name: "ignore irrelevant events", 265 client: &ghc{}, 266 event: github.PullRequestEvent{ 267 Action: github.PullRequestActionReviewRequested, 268 PullRequest: multipleCommitsPR, 269 }, 270 defaultMergeMethod: types.MergeMerge, 271 }, 272 } 273 274 for _, c := range cases { 275 t.Run(c.name, func(t *testing.T) { 276 if c.client == nil { 277 t.Fatalf("test case can not have nil github client") 278 } 279 280 // Set up test logging. 281 c.client.T = t 282 283 c.event.Number = 101 284 config := config.Tide{ 285 TideGitHubConfig: config.TideGitHubConfig{ 286 MergeType: map[string]config.TideOrgMergeType{ 287 "kubernetes/kubernetes": {MergeType: c.defaultMergeMethod}, 288 }, 289 SquashLabel: c.squashLabel, 290 MergeLabel: c.mergeLabel, 291 }, 292 } 293 err := handlePR(c.client, config, c.event) 294 295 if err != nil && c.err == nil { 296 t.Fatalf("handlePR error: %v", err) 297 } 298 299 if err == nil && c.err != nil { 300 t.Fatalf("handlePR wanted error %v, got nil", err) 301 } 302 303 if got, want := err, c.err; got != nil && got.Error() != want.Error() { 304 t.Fatalf("handlePR errors mismatch: got %v, want %v", got, want) 305 } 306 307 if c.err != nil { 308 return 309 } 310 311 if got, want := len(c.client.comments["kubernetes/kubernetes#101"]), len(c.comments); got != want { 312 t.Logf("github client comments: got %v; want %v", c.client.comments, c.comments) 313 t.Fatalf("issue comments count mismatch: got %d, want %d", got, want) 314 } 315 316 for i, comment := range c.comments { 317 if !strings.Contains(c.client.comments["kubernetes/kubernetes#101"][i].Body, comment.Body) { 318 t.Fatalf("github client comment: got %s, expected it to contain: %s", c.client.comments["kubernetes/kubernetes#101"][i].Body, comment.Body) 319 } 320 } 321 }) 322 } 323 }