github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/slackevents/slackevents_test.go (about) 1 /* 2 Copyright 2017 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 slackevents 18 19 import ( 20 "encoding/json" 21 "strings" 22 "testing" 23 24 "k8s.io/test-infra/prow/github" 25 "k8s.io/test-infra/prow/github/fakegithub" 26 "k8s.io/test-infra/prow/plugins" 27 "k8s.io/test-infra/prow/slack" 28 ) 29 30 type FakeClient struct { 31 SentMessages map[string][]string 32 } 33 34 func (fk *FakeClient) WriteMessage(text string, channel string) error { 35 fk.SentMessages[channel] = append(fk.SentMessages[channel], text) 36 return nil 37 } 38 39 func TestPush(t *testing.T) { 40 var pushStr = `{ 41 "ref": "refs/heads/master", 42 "before": "d73a75b4b1ddb63870954b9a60a63acaa4cb1ca5", 43 "after": "045a6dca07840efaf3311450b615e19b5c75f787", 44 "created": false, 45 "deleted": false, 46 "forced": false, 47 "compare": "https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...045a6dca0784", 48 "commits": [ 49 { 50 "id": "8427d5a27478c80167fd66affe1bd7cd01d3f9a8", 51 "message": "Decrease fluentd cpu request", 52 "url": "https://github.com/kubernetes/kubernetes/commit/8427d5a27478c80167fd66affe1bd7cd01d3f9a8" 53 }, 54 { 55 "id": "045a6dca07840efaf3311450b615e19b5c75f787", 56 "message": "Merge pull request #47906 from gmarek/fluentd\n\nDecrese fluentd cpu request\n\nFix #47905\r\n\r\ncc @piosz - this should fix your tests.\r\ncc @dchen1107", 57 "url": "https://github.com/kubernetes/kubernetes/commit/045a6dca07840efaf3311450b615e19b5c75f787" 58 } 59 ], 60 "repository": { 61 "id": 20580498, 62 "name": "kubernetes", 63 "owner": { 64 "name": "kubernetes", 65 "login": "kubernetes" 66 }, 67 "url": "https://github.com/kubernetes/kubernetes" 68 }, 69 "pusher": { 70 "name": "k8s-merge-robot", 71 "email": "k8s-merge-robot@users.noreply.github.com" 72 } 73 }` 74 75 var pushEv github.PushEvent 76 if err := json.Unmarshal([]byte(pushStr), &pushEv); err != nil { 77 t.Fatalf("Failed to parse Push Notification: %s", err) 78 } 79 80 // Non bot user merged the PR 81 pushEvManual := pushEv 82 pushEvManual.Pusher.Name = "Jester Tester" 83 pushEvManual.Pusher.Email = "tester@users.noreply.github.com" 84 pushEvManual.Sender.Login = "tester" 85 pushEvManual.Ref = "refs/head/master" 86 87 pushEvManualBranchWhiteListed := pushEv 88 pushEvManualBranchWhiteListed.Pusher.Name = "Warren Teened" 89 pushEvManualBranchWhiteListed.Pusher.Email = "wteened@users.noreply.github.com" 90 pushEvManualBranchWhiteListed.Sender.Login = "wteened" 91 pushEvManualBranchWhiteListed.Ref = "refs/head/warrens-branch" 92 93 pushEvManualNotBranchWhiteListed := pushEvManualBranchWhiteListed 94 pushEvManualNotBranchWhiteListed.Ref = "refs/head/master" 95 96 pushEvManualCreated := pushEvManual 97 pushEvManualCreated.Created = true 98 pushEvManualCreated.Ref = "refs/head/release-1.99" 99 pushEvManualCreated.Compare = "https://github.com/kubernetes/kubernetes/compare/045a6dca0784" 100 101 pushEvManualDeleted := pushEvManual 102 pushEvManualDeleted.Deleted = true 103 pushEvManualDeleted.Ref = "refs/head/release-1.99" 104 pushEvManualDeleted.Compare = "https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...000000000000" 105 106 pushEvManualForced := pushEvManual 107 pushEvManualForced.Forced = true 108 109 noMessages := map[string][]string{} 110 stdWarningMessages := map[string][]string{ 111 "sig-contribex": {"*Warning:* tester (<@tester>) manually merged 2 commit(s) into master: https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...045a6dca0784"}, 112 "kubernetes-dev": {"*Warning:* tester (<@tester>) manually merged 2 commit(s) into master: https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...045a6dca0784"}} 113 114 createdWarningMessages := map[string][]string{ 115 "sig-contribex": {"*Warning:* tester (<@tester>) pushed a new branch (release-1.99): https://github.com/kubernetes/kubernetes/compare/045a6dca0784"}, 116 "kubernetes-dev": {"*Warning:* tester (<@tester>) pushed a new branch (release-1.99): https://github.com/kubernetes/kubernetes/compare/045a6dca0784"}} 117 118 deletedWarningMessages := map[string][]string{ 119 "sig-contribex": {"*Warning:* tester (<@tester>) deleted a branch (release-1.99): https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...000000000000"}, 120 "kubernetes-dev": {"*Warning:* tester (<@tester>) deleted a branch (release-1.99): https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...000000000000"}} 121 122 forcedWarningMessages := map[string][]string{ 123 "sig-contribex": {"*Warning:* tester (<@tester>) *force* merged 2 commit(s) into master: https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...045a6dca0784"}, 124 "kubernetes-dev": {"*Warning:* tester (<@tester>) *force* merged 2 commit(s) into master: https://github.com/kubernetes/kubernetes/compare/d73a75b4b1dd...045a6dca0784"}} 125 126 type testCase struct { 127 name string 128 pushReq github.PushEvent 129 expectedMessages map[string][]string 130 } 131 132 testcases := []testCase{ 133 { 134 name: "If PR merged manually by a user, we send message to sig-contribex and kubernetes-dev.", 135 pushReq: pushEvManual, 136 expectedMessages: stdWarningMessages, 137 }, 138 { 139 name: "If PR force merged by a user, we send message to sig-contribex and kubernetes-dev with force merge message.", 140 pushReq: pushEvManualForced, 141 expectedMessages: forcedWarningMessages, 142 }, 143 { 144 name: "If PR merged by k8s merge bot we should NOT send message to sig-contribex and kubernetes-dev.", 145 pushReq: pushEv, 146 expectedMessages: noMessages, 147 }, 148 { 149 name: "If PR merged by a user not in the whitelist but in THIS branch whitelist, we should NOT send a message to sig-contrib-ax and kubernetes-dev.", 150 pushReq: pushEvManualBranchWhiteListed, 151 expectedMessages: noMessages, 152 }, 153 { 154 name: "If PR merged by a user not in the whitelist, in a branch whitelist, but not THIS branch whitelist, we should send a message to sig-contrib-ax and kubernetes-dev.", 155 pushReq: pushEvManualBranchWhiteListed, 156 expectedMessages: noMessages, 157 }, 158 { 159 name: "If a branch is created by a non-whitelisted user, we send message to sig-contribex and kubernetes-dev with branch created message.", 160 pushReq: pushEvManualCreated, 161 expectedMessages: createdWarningMessages, 162 }, 163 { 164 name: "If a branch is deleted by a non-whitelisted user, we send message to sig-contribex and kubernetes-dev with branch deleted message.", 165 pushReq: pushEvManualDeleted, 166 expectedMessages: deletedWarningMessages, 167 }, 168 } 169 170 pc := client{ 171 SlackConfig: plugins.Slack{ 172 MergeWarnings: []plugins.MergeWarning{ 173 { 174 Repos: []string{"kubernetes/kubernetes"}, 175 Channels: []string{"kubernetes-dev", "sig-contribex"}, 176 WhiteList: []string{"k8s-merge-robot"}, 177 BranchWhiteList: map[string][]string{ 178 "warrens-branch": {"wteened"}, 179 }, 180 }, 181 }, 182 }, 183 SlackClient: slack.NewFakeClient(), 184 } 185 186 //should not fail if slackClient is nil 187 for _, tc := range testcases { 188 if err := notifyOnSlackIfManualMerge(pc, tc.pushReq); err != nil { 189 t.Fatalf("Didn't expect error if slack client is nil: %s", err) 190 } 191 } 192 193 //repeat the tests with a fake slack client 194 for _, tc := range testcases { 195 slackClient := &FakeClient{ 196 SentMessages: make(map[string][]string), 197 } 198 pc.SlackClient = slackClient 199 200 if err := notifyOnSlackIfManualMerge(pc, tc.pushReq); err != nil { 201 t.Fatalf("Didn't expect error: %s", err) 202 } 203 if len(tc.expectedMessages) != len(slackClient.SentMessages) { 204 t.Fatalf("Test: %s The number of messages sent do not tally. Expecting %d messages but received %d messages.", 205 tc.name, len(tc.expectedMessages), len(slackClient.SentMessages)) 206 } 207 for k, v := range tc.expectedMessages { 208 if _, ok := slackClient.SentMessages[k]; !ok { 209 t.Fatalf("Test: %s Messages is not sent to channel %s", tc.name, k) 210 } 211 if strings.Compare(v[0], slackClient.SentMessages[k][0]) != 0 { 212 t.Fatalf("Expecting message: %s\nReceived message: %s", v, slackClient.SentMessages[k]) 213 } 214 if len(v) != len(slackClient.SentMessages[k]) { 215 t.Fatalf("Test: %s All messages are not delivered to the channel ", tc.name) 216 } 217 } 218 } 219 220 } 221 222 //Make sure we are sending message to proper sig mentions 223 func TestComment(t *testing.T) { 224 orgMember := "cjwagner" 225 bot := "k8s-ci-robot" 226 type testCase struct { 227 name string 228 action github.GenericCommentEventAction 229 body string 230 expectedMessages map[string][]string 231 issueLabels []string 232 repoLabels []string 233 commenter string 234 } 235 testcases := []testCase{ 236 { 237 name: "If sig mentioned then we send a message to the sig with the body of the comment", 238 action: github.GenericCommentActionCreated, 239 body: "@kubernetes/sig-node-misc This issue needs update.", 240 expectedMessages: map[string][]string{"sig-node": {"This issue needs update."}}, 241 commenter: orgMember, 242 }, 243 { 244 name: "Don't sent message if comment isn't new.", 245 action: github.GenericCommentActionEdited, 246 body: "@kubernetes/sig-node-misc This issue needs update.", 247 expectedMessages: map[string][]string{}, 248 commenter: orgMember, 249 }, 250 { 251 name: "Don't sent message if commenter is the bot.", 252 action: github.GenericCommentActionEdited, 253 body: "@kubernetes/sig-node-misc This issue needs update.", 254 expectedMessages: map[string][]string{}, 255 commenter: bot, 256 }, 257 { 258 name: "If multiple sigs mentioned, we send a message to each sig with the body of the comment", 259 action: github.GenericCommentActionCreated, 260 body: "@kubernetes/sig-node-misc, @kubernetes/sig-api-machinery-misc Message sent to multiple sigs.", 261 expectedMessages: map[string][]string{"sig-api-machinery": {"Message sent to multiple sigs."}, "sig-node": {"Message sent to multiple sigs."}}, 262 commenter: orgMember, 263 }, 264 { 265 name: "If multiple sigs mentioned, but only one channel is whitelisted, only send to one channel.", 266 action: github.GenericCommentActionCreated, 267 body: "@kubernetes/sig-node-misc, @kubernetes/sig-testing-misc Message sent to multiple sigs.", 268 expectedMessages: map[string][]string{"sig-node": {"Message sent to multiple sigs."}}, 269 issueLabels: []string{}, 270 commenter: orgMember, 271 }, 272 { 273 name: "Message should not be sent if the pattern for the channel does not match", 274 action: github.GenericCommentActionCreated, 275 body: "@kubernetes/node-misc No message sent", 276 expectedMessages: map[string][]string{}, 277 commenter: orgMember, 278 }, 279 { 280 name: "Message sent only if the pattern for the channel match", 281 action: github.GenericCommentActionCreated, 282 body: "@kubernetes/node-misc @kubernetes/sig-api-machinery-bugs Message sent to matching sigs.", 283 expectedMessages: map[string][]string{"sig-api-machinery": {"Message sent to matching sigs."}}, 284 commenter: orgMember, 285 }, 286 } 287 288 for _, tc := range testcases { 289 fakeSlackClient := &FakeClient{ 290 SentMessages: make(map[string][]string), 291 } 292 client := client{ 293 GithubClient: &fakegithub.FakeClient{}, 294 SlackClient: fakeSlackClient, 295 SlackConfig: plugins.Slack{MentionChannels: []string{"sig-node", "sig-api-machinery"}}, 296 } 297 e := github.GenericCommentEvent{ 298 Action: tc.action, 299 Body: tc.body, 300 User: github.User{Login: tc.commenter}, 301 } 302 303 if err := echoToSlack(client, e); err != nil { 304 t.Fatalf("For case %s, didn't expect error from label test: %v", tc.name, err) 305 } 306 if len(tc.expectedMessages) != len(fakeSlackClient.SentMessages) { 307 t.Fatalf("The number of messages sent do not tally. Expecting %d messages but received %d messages.", 308 len(tc.expectedMessages), len(fakeSlackClient.SentMessages)) 309 } 310 for k, v := range tc.expectedMessages { 311 if _, ok := fakeSlackClient.SentMessages[k]; !ok { 312 t.Fatalf("Messages is not sent to channel %s", k) 313 } 314 if len(v) != len(fakeSlackClient.SentMessages[k]) { 315 t.Fatalf("All messages are not delivered to the channel %s", k) 316 } 317 } 318 } 319 }