github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/tide/blockers/blockers_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 blockers 18 19 import ( 20 "reflect" 21 "strconv" 22 "strings" 23 "testing" 24 25 githubql "github.com/shurcooL/githubv4" 26 27 "k8s.io/apimachinery/pkg/util/sets" 28 ) 29 30 func TestParseBranches(t *testing.T) { 31 tcs := []struct { 32 text string 33 expected []string 34 }{ 35 { 36 text: "", 37 expected: nil, 38 }, 39 { 40 text: "BAD THINGS (all branches blocked)", 41 expected: nil, 42 }, 43 { 44 text: "branch:foo", 45 expected: []string{"foo"}, 46 }, 47 { 48 text: "branch: foo-bar", 49 expected: []string{"foo-bar"}, 50 }, 51 { 52 text: "BAD THINGS (BLOCKING BRANCH:foo branch:bar) AHHH", 53 expected: []string{"foo", "bar"}, 54 }, 55 { 56 text: "branch:\"FOO-bar\"", 57 expected: []string{"FOO-bar"}, 58 }, 59 { 60 text: "branch: \"foo\" branch: \"bar\"", 61 expected: []string{"foo", "bar"}, 62 }, 63 } 64 65 for _, tc := range tcs { 66 if got := parseBranches(tc.text); !reflect.DeepEqual(got, tc.expected) { 67 t.Errorf("Expected parseBranches(%q)==%q, but got %q.", tc.text, tc.expected, got) 68 } 69 } 70 } 71 72 func TestBlockerQuery(t *testing.T) { 73 tcs := []struct { 74 orgRepoQuery string 75 expected sets.String 76 }{ 77 { 78 orgRepoQuery: "org:\"k8s\"", 79 expected: sets.NewString( 80 "is:issue", 81 "state:open", 82 "label:\"blocker\"", 83 "org:\"k8s\"", 84 ), 85 }, 86 { 87 orgRepoQuery: "repo:\"k8s/t-i\"", 88 expected: sets.NewString( 89 "is:issue", 90 "state:open", 91 "label:\"blocker\"", 92 "repo:\"k8s/t-i\"", 93 ), 94 }, 95 { 96 orgRepoQuery: "org:\"k8s\" org:\"kuber\"", 97 expected: sets.NewString( 98 "is:issue", 99 "state:open", 100 "label:\"blocker\"", 101 "org:\"k8s\"", 102 "org:\"kuber\"", 103 ), 104 }, 105 { 106 orgRepoQuery: "repo:\"k8s/t-i\" repo:\"k8s/k8s\"", 107 expected: sets.NewString( 108 "is:issue", 109 "state:open", 110 "label:\"blocker\"", 111 "repo:\"k8s/t-i\"", 112 "repo:\"k8s/k8s\"", 113 ), 114 }, 115 { 116 orgRepoQuery: "org:\"k8s\" org:\"kuber\" repo:\"k8s/t-i\" repo:\"k8s/k8s\"", 117 expected: sets.NewString( 118 "is:issue", 119 "state:open", 120 "label:\"blocker\"", 121 "repo:\"k8s/t-i\"", 122 "repo:\"k8s/k8s\"", 123 "org:\"k8s\"", 124 "org:\"kuber\"", 125 ), 126 }, 127 } 128 129 for _, tc := range tcs { 130 got := sets.NewString(strings.Split(blockerQuery("blocker", tc.orgRepoQuery), " ")...) 131 if !reflect.DeepEqual(got, tc.expected) { 132 t.Errorf("Expected blockerQuery(\"blocker\", %q)==%q, but got %q.", tc.orgRepoQuery, tc.expected, got) 133 } 134 } 135 } 136 137 func testIssue(number int, title, org, repo string) Issue { 138 return Issue{ 139 Number: githubql.Int(number), 140 Title: githubql.String(title), 141 URL: githubql.String(strconv.Itoa(number)), 142 Repository: struct { 143 Name githubql.String 144 Owner struct { 145 Login githubql.String 146 } 147 }{ 148 Name: githubql.String(repo), 149 Owner: struct { 150 Login githubql.String 151 }{ 152 Login: githubql.String(org), 153 }, 154 }, 155 } 156 } 157 158 func TestBlockers(t *testing.T) { 159 type check struct { 160 org, repo, branch string 161 blockers sets.Int 162 } 163 164 tcs := []struct { 165 name string 166 issues []Issue 167 checks []check 168 }{ 169 { 170 name: "No blocker issues", 171 issues: []Issue{}, 172 checks: []check{ 173 { 174 org: "org", 175 repo: "repo", 176 branch: "branch", 177 blockers: sets.NewInt(), 178 }, 179 }, 180 }, 181 { 182 name: "1 repo blocker", 183 issues: []Issue{ 184 testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"), 185 }, 186 checks: []check{ 187 { 188 org: "k", 189 repo: "t-i", 190 branch: "feature", 191 blockers: sets.NewInt(5), 192 }, 193 { 194 org: "k", 195 repo: "t-i", 196 branch: "master", 197 blockers: sets.NewInt(5), 198 }, 199 { 200 org: "k", 201 repo: "k", 202 branch: "master", 203 blockers: sets.NewInt(), 204 }, 205 }, 206 }, 207 { 208 name: "2 repo blockers for same repo", 209 issues: []Issue{ 210 testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"), 211 testIssue(6, "BLOCK THE WHOLE REPO AGAIN!", "k", "t-i"), 212 }, 213 checks: []check{ 214 { 215 org: "k", 216 repo: "t-i", 217 branch: "feature", 218 blockers: sets.NewInt(5, 6), 219 }, 220 { 221 org: "k", 222 repo: "t-i", 223 branch: "master", 224 blockers: sets.NewInt(5, 6), 225 }, 226 { 227 org: "k", 228 repo: "k", 229 branch: "master", 230 blockers: sets.NewInt(), 231 }, 232 }, 233 }, 234 { 235 name: "2 repo blockers for different repos", 236 issues: []Issue{ 237 testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"), 238 testIssue(6, "BLOCK THE WHOLE (different) REPO!", "k", "community"), 239 }, 240 checks: []check{ 241 { 242 org: "k", 243 repo: "t-i", 244 branch: "feature", 245 blockers: sets.NewInt(5), 246 }, 247 { 248 org: "k", 249 repo: "t-i", 250 branch: "master", 251 blockers: sets.NewInt(5), 252 }, 253 { 254 org: "k", 255 repo: "community", 256 branch: "feature", 257 blockers: sets.NewInt(6), 258 }, 259 { 260 org: "k", 261 repo: "community", 262 branch: "master", 263 blockers: sets.NewInt(6), 264 }, 265 { 266 org: "k", 267 repo: "k", 268 branch: "master", 269 blockers: sets.NewInt(), 270 }, 271 }, 272 }, 273 { 274 name: "1 repo blocker, 1 branch blocker for different repos", 275 issues: []Issue{ 276 testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"), 277 testIssue(6, "BLOCK THE feature BRANCH! branch:feature", "k", "community"), 278 }, 279 checks: []check{ 280 { 281 org: "k", 282 repo: "t-i", 283 branch: "feature", 284 blockers: sets.NewInt(5), 285 }, 286 { 287 org: "k", 288 repo: "t-i", 289 branch: "master", 290 blockers: sets.NewInt(5), 291 }, 292 { 293 org: "k", 294 repo: "community", 295 branch: "feature", 296 blockers: sets.NewInt(6), 297 }, 298 { 299 org: "k", 300 repo: "community", 301 branch: "master", 302 blockers: sets.NewInt(), 303 }, 304 { 305 org: "k", 306 repo: "k", 307 branch: "master", 308 blockers: sets.NewInt(), 309 }, 310 }, 311 }, 312 { 313 name: "1 repo blocker, 1 branch blocker for same repo", 314 issues: []Issue{ 315 testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"), 316 testIssue(6, "BLOCK THE feature BRANCH! branch:feature", "k", "t-i"), 317 }, 318 checks: []check{ 319 { 320 org: "k", 321 repo: "t-i", 322 branch: "feature", 323 blockers: sets.NewInt(5, 6), 324 }, 325 { 326 org: "k", 327 repo: "t-i", 328 branch: "master", 329 blockers: sets.NewInt(5), 330 }, 331 { 332 org: "k", 333 repo: "k", 334 branch: "master", 335 blockers: sets.NewInt(), 336 }, 337 }, 338 }, 339 { 340 name: "2 repo blockers, 3 branch blockers (with overlap) for same repo", 341 issues: []Issue{ 342 testIssue(5, "BLOCK THE WHOLE REPO!", "k", "t-i"), 343 testIssue(6, "BLOCK THE WHOLE REPO AGAIN!", "k", "t-i"), 344 testIssue(7, "BLOCK THE feature BRANCH! branch:feature", "k", "t-i"), 345 testIssue(8, "BLOCK THE feature BRANCH! branch:master", "k", "t-i"), 346 testIssue(9, "BLOCK THE feature BRANCH! branch:feature branch: master branch:foo", "k", "t-i"), 347 }, 348 checks: []check{ 349 { 350 org: "k", 351 repo: "t-i", 352 branch: "feature", 353 blockers: sets.NewInt(5, 6, 7, 9), 354 }, 355 { 356 org: "k", 357 repo: "t-i", 358 branch: "master", 359 blockers: sets.NewInt(5, 6, 8, 9), 360 }, 361 { 362 org: "k", 363 repo: "t-i", 364 branch: "foo", 365 blockers: sets.NewInt(5, 6, 9), 366 }, 367 { 368 org: "k", 369 repo: "t-i", 370 branch: "bar", 371 blockers: sets.NewInt(5, 6), 372 }, 373 { 374 org: "k", 375 repo: "k", 376 branch: "master", 377 blockers: sets.NewInt(), 378 }, 379 }, 380 }, 381 } 382 383 for _, tc := range tcs { 384 t.Logf("Running test case %q.", tc.name) 385 b := fromIssues(tc.issues) 386 for _, c := range tc.checks { 387 actuals := b.GetApplicable(c.org, c.repo, c.branch) 388 nums := sets.NewInt() 389 for _, actual := range actuals { 390 // Check blocker URLs: 391 if actual.URL != strconv.Itoa(actual.Number) { 392 t.Errorf("blocker %d has URL %q, expected %q", actual.Number, actual.URL, strconv.Itoa(actual.Number)) 393 } 394 nums.Insert(actual.Number) 395 } 396 // Check that correct blockers were selected: 397 if !reflect.DeepEqual(nums, c.blockers) { 398 t.Errorf("expected blockers %v, but got %v", c.blockers, nums) 399 } 400 } 401 } 402 }