github.com/abayer/test-infra@v0.0.5/prow/plugins/approve/approvers/owners_test.go (about) 1 /* 2 Copyright 2016 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 approvers 18 19 import ( 20 "testing" 21 22 "github.com/sirupsen/logrus" 23 24 "k8s.io/apimachinery/pkg/util/sets" 25 26 "path/filepath" 27 "reflect" 28 "strings" 29 ) 30 31 const ( 32 TEST_SEED = int64(0) 33 ) 34 35 type FakeRepo struct { 36 approversMap map[string]sets.String 37 leafApproversMap map[string]sets.String 38 noParentOwnersMap map[string]bool 39 } 40 41 func (f FakeRepo) Approvers(path string) sets.String { 42 return f.approversMap[path] 43 } 44 45 func (f FakeRepo) LeafApprovers(path string) sets.String { 46 return f.leafApproversMap[path] 47 } 48 49 func (f FakeRepo) FindApproverOwnersForFile(path string) string { 50 for dir := path; dir != "."; dir = filepath.Dir(dir) { 51 if _, ok := f.leafApproversMap[dir]; ok { 52 return dir 53 } 54 } 55 return "" 56 } 57 58 func (f FakeRepo) IsNoParentOwners(path string) bool { 59 return f.noParentOwnersMap[path] 60 } 61 62 type dir struct { 63 fullPath string 64 approvers sets.String 65 } 66 67 func canonicalize(path string) string { 68 if path == "." { 69 return "" 70 } 71 return strings.TrimSuffix(path, "/") 72 } 73 74 func createFakeRepo(la map[string]sets.String) FakeRepo { 75 // github doesn't use / at the root 76 a := map[string]sets.String{} 77 for dir, approvers := range la { 78 la[dir] = setToLower(approvers) 79 a[dir] = setToLower(approvers) 80 starting_path := dir 81 for { 82 dir = canonicalize(filepath.Dir(dir)) 83 if parent_approvers, ok := la[dir]; ok { 84 a[starting_path] = a[starting_path].Union(setToLower(parent_approvers)) 85 } 86 if dir == "" { 87 break 88 } 89 } 90 } 91 92 return FakeRepo{approversMap: a, leafApproversMap: la} 93 } 94 95 func setToLower(s sets.String) sets.String { 96 lowered := sets.NewString() 97 for _, elem := range s.List() { 98 lowered.Insert(strings.ToLower(elem)) 99 } 100 return lowered 101 } 102 103 func TestCreateFakeRepo(t *testing.T) { 104 rootApprovers := sets.NewString("Alice", "Bob") 105 aApprovers := sets.NewString("Art", "Anne") 106 bApprovers := sets.NewString("Bill", "Ben", "Barbara") 107 cApprovers := sets.NewString("Chris", "Carol") 108 eApprovers := sets.NewString("Eve", "Erin") 109 edcApprovers := eApprovers.Union(cApprovers) 110 FakeRepoMap := map[string]sets.String{ 111 "": rootApprovers, 112 "a": aApprovers, 113 "b": bApprovers, 114 "c": cApprovers, 115 "a/combo": edcApprovers, 116 } 117 fake_repo := createFakeRepo(FakeRepoMap) 118 119 tests := []struct { 120 testName string 121 ownersFile string 122 expectedLeafApprovers sets.String 123 expectedApprovers sets.String 124 }{ 125 { 126 testName: "Root Owners", 127 ownersFile: "", 128 expectedApprovers: rootApprovers, 129 expectedLeafApprovers: rootApprovers, 130 }, 131 { 132 testName: "A Owners", 133 ownersFile: "a", 134 expectedLeafApprovers: aApprovers, 135 expectedApprovers: aApprovers.Union(rootApprovers), 136 }, 137 { 138 testName: "B Owners", 139 ownersFile: "b", 140 expectedLeafApprovers: bApprovers, 141 expectedApprovers: bApprovers.Union(rootApprovers), 142 }, 143 { 144 testName: "C Owners", 145 ownersFile: "c", 146 expectedLeafApprovers: cApprovers, 147 expectedApprovers: cApprovers.Union(rootApprovers), 148 }, 149 { 150 testName: "Combo Owners", 151 ownersFile: "a/combo", 152 expectedLeafApprovers: edcApprovers, 153 expectedApprovers: edcApprovers.Union(aApprovers).Union(rootApprovers), 154 }, 155 } 156 157 for _, test := range tests { 158 calculated_leaf_approvers := fake_repo.LeafApprovers(test.ownersFile) 159 calculated_approvers := fake_repo.Approvers(test.ownersFile) 160 161 test.expectedLeafApprovers = setToLower(test.expectedLeafApprovers) 162 if !calculated_leaf_approvers.Equal(test.expectedLeafApprovers) { 163 t.Errorf("Failed for test %v. Expected Leaf Approvers: %v. Actual Leaf Approvers %v", test.testName, test.expectedLeafApprovers, calculated_leaf_approvers) 164 } 165 166 test.expectedApprovers = setToLower(test.expectedApprovers) 167 if !calculated_approvers.Equal(test.expectedApprovers) { 168 t.Errorf("Failed for test %v. Expected Approvers: %v. Actual Approvers %v", test.testName, test.expectedApprovers, calculated_approvers) 169 } 170 } 171 } 172 173 func TestGetLeafApprovers(t *testing.T) { 174 rootApprovers := sets.NewString("Alice", "Bob") 175 aApprovers := sets.NewString("Art", "Anne") 176 bApprovers := sets.NewString("Bill", "Ben", "Barbara") 177 dApprovers := sets.NewString("David", "Dan", "Debbie") 178 FakeRepoMap := map[string]sets.String{ 179 "": rootApprovers, 180 "a": aApprovers, 181 "b": bApprovers, 182 "a/d": dApprovers, 183 } 184 185 tests := []struct { 186 testName string 187 filenames []string 188 expectedMap map[string]sets.String 189 }{ 190 { 191 testName: "Empty PR", 192 filenames: []string{}, 193 expectedMap: map[string]sets.String{}, 194 }, 195 { 196 testName: "Single Root File PR", 197 filenames: []string{"kubernetes.go"}, 198 expectedMap: map[string]sets.String{"": setToLower(rootApprovers)}, 199 }, 200 { 201 testName: "Internal Node File PR", 202 filenames: []string{"a/test.go"}, 203 expectedMap: map[string]sets.String{"a": setToLower(aApprovers)}, 204 }, 205 { 206 testName: "Two Leaf File PR", 207 filenames: []string{"a/d/test.go", "b/test.go"}, 208 expectedMap: map[string]sets.String{ 209 "a/d": setToLower(dApprovers), 210 "b": setToLower(bApprovers)}, 211 }, 212 { 213 testName: "Leaf and Parent 2 File PR", 214 filenames: []string{"a/test.go", "a/d/test.go"}, 215 expectedMap: map[string]sets.String{ 216 "a": setToLower(aApprovers), 217 }, 218 }, 219 } 220 221 for _, test := range tests { 222 testOwners := Owners{ 223 filenames: test.filenames, 224 repo: createFakeRepo(FakeRepoMap), 225 seed: TEST_SEED, 226 log: logrus.WithField("plugin", "some_plugin"), 227 } 228 oMap := testOwners.GetLeafApprovers() 229 if !reflect.DeepEqual(test.expectedMap, oMap) { 230 t.Errorf("Failed for test %v. Expected Owners: %v. Actual Owners %v", test.testName, test.expectedMap, oMap) 231 } 232 } 233 } 234 func TestGetOwnersSet(t *testing.T) { 235 rootApprovers := sets.NewString("Alice", "Bob") 236 aApprovers := sets.NewString("Art", "Anne") 237 bApprovers := sets.NewString("Bill", "Ben", "Barbara") 238 dApprovers := sets.NewString("David", "Dan", "Debbie") 239 FakeRepoMap := map[string]sets.String{ 240 "": rootApprovers, 241 "a": aApprovers, 242 "b": bApprovers, 243 "a/d": dApprovers, 244 } 245 246 tests := []struct { 247 testName string 248 filenames []string 249 expectedOwnersFiles sets.String 250 }{ 251 { 252 testName: "Empty PR", 253 filenames: []string{}, 254 expectedOwnersFiles: sets.NewString(), 255 }, 256 { 257 testName: "Single Root File PR", 258 filenames: []string{"kubernetes.go"}, 259 expectedOwnersFiles: sets.NewString(""), 260 }, 261 { 262 testName: "Multiple Root File PR", 263 filenames: []string{"test.go", "kubernetes.go"}, 264 expectedOwnersFiles: sets.NewString(""), 265 }, 266 { 267 testName: "Internal Node File PR", 268 filenames: []string{"a/test.go"}, 269 expectedOwnersFiles: sets.NewString("a"), 270 }, 271 { 272 testName: "Two Leaf File PR", 273 filenames: []string{"a/test.go", "b/test.go"}, 274 expectedOwnersFiles: sets.NewString("a", "b"), 275 }, 276 { 277 testName: "Leaf and Parent 2 File PR", 278 filenames: []string{"a/test.go", "a/c/test.go"}, 279 expectedOwnersFiles: sets.NewString("a"), 280 }, 281 } 282 283 for _, test := range tests { 284 testOwners := Owners{ 285 filenames: test.filenames, 286 repo: createFakeRepo(FakeRepoMap), 287 seed: TEST_SEED, 288 log: logrus.WithField("plugin", "some_plugin"), 289 } 290 oSet := testOwners.GetOwnersSet() 291 if !oSet.Equal(test.expectedOwnersFiles) { 292 t.Errorf("Failed for test %v. Expected Owners: %v. Actual Owners %v", test.testName, test.expectedOwnersFiles, oSet) 293 } 294 } 295 } 296 297 func TestGetSuggestedApprovers(t *testing.T) { 298 var rootApprovers = sets.NewString("Alice", "Bob") 299 var aApprovers = sets.NewString("Art", "Anne") 300 var bApprovers = sets.NewString("Bill", "Ben", "Barbara") 301 var dApprovers = sets.NewString("David", "Dan", "Debbie") 302 var eApprovers = sets.NewString("Eve", "Erin") 303 var edcApprovers = eApprovers.Union(dApprovers) 304 var FakeRepoMap = map[string]sets.String{ 305 "": rootApprovers, 306 "a": aApprovers, 307 "b": bApprovers, 308 "a/d": dApprovers, 309 "a/combo": edcApprovers, 310 } 311 tests := []struct { 312 testName string 313 filenames []string 314 // need at least one person from each set 315 expectedOwners []sets.String 316 }{ 317 { 318 testName: "Empty PR", 319 filenames: []string{}, 320 expectedOwners: []sets.String{}, 321 }, 322 { 323 testName: "Single Root File PR", 324 filenames: []string{"kubernetes.go"}, 325 expectedOwners: []sets.String{setToLower(rootApprovers)}, 326 }, 327 { 328 testName: "Internal Node File PR", 329 filenames: []string{"a/test.go"}, 330 expectedOwners: []sets.String{setToLower(aApprovers)}, 331 }, 332 { 333 testName: "Multiple Files Internal Node File PR", 334 filenames: []string{"a/test.go", "a/test1.go"}, 335 expectedOwners: []sets.String{setToLower(aApprovers)}, 336 }, 337 { 338 testName: "Two Leaf File PR", 339 filenames: []string{"a/test.go", "b/test.go"}, 340 expectedOwners: []sets.String{setToLower(aApprovers), setToLower(bApprovers)}, 341 }, 342 { 343 testName: "Leaf and Parent 2 File PR", 344 filenames: []string{"a/test.go", "a/d/test.go"}, 345 expectedOwners: []sets.String{setToLower(aApprovers)}, 346 }, 347 { 348 testName: "Combo and B", 349 filenames: []string{"a/combo/test.go", "b/test.go"}, 350 expectedOwners: []sets.String{setToLower(edcApprovers), setToLower(bApprovers)}, 351 }, 352 { 353 testName: "Lowest Leaf", 354 filenames: []string{"a/combo/test.go"}, 355 expectedOwners: []sets.String{setToLower(edcApprovers)}, 356 }, 357 } 358 359 for _, test := range tests { 360 testOwners := Owners{ 361 filenames: test.filenames, 362 repo: createFakeRepo(FakeRepoMap), 363 seed: TEST_SEED, 364 log: logrus.WithField("plugin", "some_plugin"), 365 } 366 suggested := testOwners.GetSuggestedApprovers(testOwners.GetReverseMap(testOwners.GetLeafApprovers()), testOwners.GetShuffledApprovers()) 367 for _, ownersSet := range test.expectedOwners { 368 if ownersSet.Intersection(suggested).Len() == 0 { 369 t.Errorf("Failed for test %v. Didn't find an approver from: %v. Actual Owners %v", test.testName, ownersSet, suggested) 370 t.Errorf("%v", test.filenames) 371 } 372 } 373 } 374 } 375 376 func TestGetAllPotentialApprovers(t *testing.T) { 377 rootApprovers := sets.NewString("Alice", "Bob") 378 aApprovers := sets.NewString("Art", "Anne") 379 bApprovers := sets.NewString("Bill", "Ben", "Barbara") 380 cApprovers := sets.NewString("Chris", "Carol") 381 dApprovers := sets.NewString("David", "Dan", "Debbie") 382 eApprovers := sets.NewString("Eve", "Erin") 383 edcApprovers := eApprovers.Union(dApprovers).Union(cApprovers) 384 FakeRepoMap := map[string]sets.String{ 385 "": rootApprovers, 386 "a": aApprovers, 387 "b": bApprovers, 388 "c": cApprovers, 389 "a/d": dApprovers, 390 "a/combo": edcApprovers, 391 } 392 tests := []struct { 393 testName string 394 filenames []string 395 // use an array because we expected output of this function to be sorted 396 expectedApprovers []string 397 }{ 398 { 399 testName: "Empty PR", 400 filenames: []string{}, 401 expectedApprovers: []string{}, 402 }, 403 { 404 testName: "Single Root File PR", 405 filenames: []string{"kubernetes.go"}, 406 expectedApprovers: setToLower(rootApprovers).List(), 407 }, 408 { 409 testName: "Internal Node File PR", 410 filenames: []string{"a/test.go"}, 411 expectedApprovers: setToLower(aApprovers).List(), 412 }, 413 { 414 testName: "One Leaf One Internal Node File PR", 415 filenames: []string{"a/test.go", "b/test.go"}, 416 expectedApprovers: setToLower(aApprovers.Union(bApprovers)).List(), 417 }, 418 { 419 testName: "Two Leaf Files PR", 420 filenames: []string{"a/d/test.go", "c/test.go"}, 421 expectedApprovers: setToLower(dApprovers.Union(cApprovers)).List(), 422 }, 423 { 424 testName: "Leaf and Parent 2 File PR", 425 filenames: []string{"a/test.go", "a/combo/test.go"}, 426 expectedApprovers: setToLower(aApprovers).List(), 427 }, 428 { 429 testName: "Two Leafs", 430 filenames: []string{"a/d/test.go", "b/test.go"}, 431 expectedApprovers: setToLower(dApprovers.Union(bApprovers)).List(), 432 }, 433 { 434 testName: "Lowest Leaf", 435 filenames: []string{"a/combo/test.go"}, 436 expectedApprovers: setToLower(edcApprovers).List(), 437 }, 438 { 439 testName: "Root And Everything Else PR", 440 filenames: []string{"a/combo/test.go", "b/test.go", "c/test.go", "d/test.go"}, 441 expectedApprovers: setToLower(rootApprovers).List(), 442 }, 443 } 444 445 for _, test := range tests { 446 testOwners := Owners{ 447 filenames: test.filenames, 448 repo: createFakeRepo(FakeRepoMap), 449 seed: TEST_SEED, 450 log: logrus.WithField("plugin", "some_plugin"), 451 } 452 all := testOwners.GetAllPotentialApprovers() 453 if !reflect.DeepEqual(all, test.expectedApprovers) { 454 t.Errorf("Failed for test %v. Didn't correct approvers list. Expected: %v. Found %v", test.testName, test.expectedApprovers, all) 455 } 456 } 457 } 458 459 func TestFindMostCoveringApprover(t *testing.T) { 460 rootApprovers := sets.NewString("Alice", "Bob") 461 aApprovers := sets.NewString("Art", "Anne") 462 bApprovers := sets.NewString("Bill", "Ben", "Barbara") 463 cApprovers := sets.NewString("Chris", "Carol") 464 dApprovers := sets.NewString("David", "Dan", "Debbie") 465 eApprovers := sets.NewString("Eve", "Erin") 466 edcApprovers := eApprovers.Union(dApprovers).Union(cApprovers) 467 FakeRepoMap := map[string]sets.String{ 468 "": rootApprovers, 469 "a": aApprovers, 470 "b": bApprovers, 471 "c": cApprovers, 472 "a/d": dApprovers, 473 "a/combo": edcApprovers, 474 } 475 tests := []struct { 476 testName string 477 filenames []string 478 unapproved sets.String 479 // because most covering could be two or more people 480 expectedMostCovering sets.String 481 }{ 482 { 483 testName: "Empty PR", 484 filenames: []string{}, 485 unapproved: sets.String{}, 486 expectedMostCovering: sets.NewString(""), 487 }, 488 { 489 testName: "Single Root File PR", 490 filenames: []string{"kubernetes.go"}, 491 unapproved: sets.NewString(""), 492 expectedMostCovering: setToLower(rootApprovers), 493 }, 494 { 495 testName: "Internal Node File PR", 496 filenames: []string{"a/test.go"}, 497 unapproved: sets.NewString("a"), 498 expectedMostCovering: setToLower(aApprovers), 499 }, 500 { 501 testName: "Combo and Intersecting Leaf PR", 502 filenames: []string{"a/combo/test.go", "a/d/test.go"}, 503 unapproved: sets.NewString("a/combo", "a/d"), 504 expectedMostCovering: setToLower(edcApprovers.Intersection(dApprovers)), 505 }, 506 { 507 testName: "Three Leaf PR Only B Approved", 508 filenames: []string{"a/combo/test.go", "c/test.go", "b/test.go"}, 509 unapproved: sets.NewString("a/combo", "c/"), 510 expectedMostCovering: setToLower(edcApprovers.Intersection(cApprovers)), 511 }, 512 { 513 testName: "Three Leaf PR Only B Left Unapproved", 514 filenames: []string{"a/combo/test.go", "a/d/test.go", "b/test.go"}, 515 unapproved: sets.NewString("b"), 516 expectedMostCovering: setToLower(bApprovers), 517 }, 518 { 519 testName: "Leaf and Parent 2 File PR", 520 filenames: []string{"a/test.go", "a/d/test.go"}, 521 unapproved: sets.NewString("a", "a/d"), 522 expectedMostCovering: setToLower(aApprovers.Union(dApprovers)), 523 }, 524 } 525 526 for _, test := range tests { 527 testOwners := Owners{ 528 filenames: test.filenames, 529 repo: createFakeRepo(FakeRepoMap), 530 seed: TEST_SEED, 531 log: logrus.WithField("plugin", "some_plugin"), 532 } 533 bestPerson := findMostCoveringApprover(testOwners.GetAllPotentialApprovers(), testOwners.GetReverseMap(testOwners.GetLeafApprovers()), test.unapproved) 534 if test.expectedMostCovering.Intersection(sets.NewString(bestPerson)).Len() != 1 { 535 t.Errorf("Failed for test %v. Didn't correct approvers list. Expected: %v. Found %v", test.testName, test.expectedMostCovering, bestPerson) 536 } 537 } 538 } 539 540 func TestGetReverseMap(t *testing.T) { 541 rootApprovers := sets.NewString("Alice", "Bob") 542 aApprovers := sets.NewString("Art", "Anne") 543 cApprovers := sets.NewString("Chris", "Carol") 544 dApprovers := sets.NewString("David", "Dan", "Debbie") 545 eApprovers := sets.NewString("Eve", "Erin") 546 edcApprovers := eApprovers.Union(dApprovers).Union(cApprovers) 547 FakeRepoMap := map[string]sets.String{ 548 "": rootApprovers, 549 "a": aApprovers, 550 "c": cApprovers, 551 "a/d": dApprovers, 552 "a/combo": edcApprovers, 553 } 554 tests := []struct { 555 testName string 556 filenames []string 557 expectedRevMap map[string]sets.String // people -> files they can approve 558 }{ 559 { 560 testName: "Empty PR", 561 filenames: []string{}, 562 expectedRevMap: map[string]sets.String{}, 563 }, 564 { 565 testName: "Single Root File PR", 566 filenames: []string{"kubernetes.go"}, 567 expectedRevMap: map[string]sets.String{ 568 "alice": sets.NewString(""), 569 "bob": sets.NewString(""), 570 }, 571 }, 572 { 573 testName: "Two Leaf PRs", 574 filenames: []string{"a/combo/test.go", "a/d/test.go"}, 575 expectedRevMap: map[string]sets.String{ 576 "david": sets.NewString("a/d", "a/combo"), 577 "dan": sets.NewString("a/d", "a/combo"), 578 "debbie": sets.NewString("a/d", "a/combo"), 579 "eve": sets.NewString("a/combo"), 580 "erin": sets.NewString("a/combo"), 581 "chris": sets.NewString("a/combo"), 582 "carol": sets.NewString("a/combo"), 583 }, 584 }, 585 } 586 587 for _, test := range tests { 588 testOwners := Owners{ 589 filenames: test.filenames, 590 repo: createFakeRepo(FakeRepoMap), 591 seed: TEST_SEED, 592 log: logrus.WithField("plugin", "some_plugin"), 593 } 594 calculatedRevMap := testOwners.GetReverseMap(testOwners.GetLeafApprovers()) 595 if !reflect.DeepEqual(calculatedRevMap, test.expectedRevMap) { 596 t.Errorf("Failed for test %v. Didn't find correct reverse map.", test.testName) 597 t.Errorf("Person \t\t Expected \t\tFound ") 598 // printing the calculated vs expected in a nicer way for debugging 599 for k, v := range test.expectedRevMap { 600 if calcVal, ok := calculatedRevMap[k]; ok { 601 t.Errorf("%v\t\t%v\t\t%v ", k, v, calcVal) 602 } else { 603 t.Errorf("%v\t\t%v", k, v) 604 } 605 } 606 } 607 } 608 } 609 610 func TestGetShuffledApprovers(t *testing.T) { 611 rootApprovers := sets.NewString("Alice", "Bob") 612 aApprovers := sets.NewString("Art", "Anne") 613 bApprovers := sets.NewString("Bill", "Ben", "Barbara") 614 cApprovers := sets.NewString("Chris", "Carol") 615 dApprovers := sets.NewString("David", "Dan", "Debbie") 616 eApprovers := sets.NewString("Eve", "Erin") 617 edcApprovers := eApprovers.Union(dApprovers).Union(cApprovers) 618 FakeRepoMap := map[string]sets.String{ 619 "": rootApprovers, 620 "a": aApprovers, 621 "b": bApprovers, 622 "c": cApprovers, 623 "a/d": dApprovers, 624 "a/combo": edcApprovers, 625 } 626 tests := []struct { 627 testName string 628 filenames []string 629 seed int64 630 expectedOrder []string 631 }{ 632 { 633 testName: "Empty PR", 634 filenames: []string{}, 635 seed: 0, 636 expectedOrder: []string{}, 637 }, 638 { 639 testName: "Single Root File PR Approved", 640 filenames: []string{"kubernetes.go"}, 641 seed: 0, 642 expectedOrder: []string{"bob", "alice"}, 643 }, 644 { 645 testName: "Combo And B PR", 646 filenames: []string{"a/combo/test.go", "b/test.go"}, 647 seed: 0, 648 expectedOrder: []string{"erin", "bill", "carol", "barbara", "dan", "debbie", "ben", "david", "eve", "chris"}, 649 }, 650 { 651 testName: "Combo and D, Seed 0", 652 filenames: []string{"a/combo/test.go", "a/d/test.go"}, 653 seed: 0, 654 expectedOrder: []string{"erin", "dan", "dan", "carol", "david", "debbie", "chris", "debbie", "eve", "david"}, 655 }, 656 { 657 testName: "Combo and D, Seed 2", 658 filenames: []string{"a/combo/test.go", "a/d/test.go"}, 659 seed: 2, 660 expectedOrder: []string{"dan", "carol", "debbie", "dan", "erin", "chris", "eve", "david", "debbie", "david"}, 661 }, 662 } 663 664 for _, test := range tests { 665 testOwners := Owners{ 666 filenames: test.filenames, 667 repo: createFakeRepo(FakeRepoMap), 668 seed: test.seed, 669 log: logrus.WithField("plugin", "some_plugin"), 670 } 671 calculated := testOwners.GetShuffledApprovers() 672 if !reflect.DeepEqual(test.expectedOrder, calculated) { 673 t.Errorf("Failed for test %v. Expected unapproved files: %v. Found %v", test.testName, test.expectedOrder, calculated) 674 } 675 } 676 } 677 678 func TestRemoveSubdirs(t *testing.T) { 679 tests := []struct { 680 testName string 681 directories sets.String 682 noParentOwners map[string]bool 683 684 expected sets.String 685 }{ 686 { 687 testName: "Empty PR", 688 directories: sets.NewString(), 689 expected: sets.NewString(), 690 }, 691 { 692 testName: "Root and One Level Below PR", 693 directories: sets.NewString("", "a/"), 694 expected: sets.NewString(""), 695 }, 696 { 697 testName: "Two Separate Branches", 698 directories: sets.NewString("a/", "c/"), 699 expected: sets.NewString("a/", "c/"), 700 }, 701 { 702 testName: "Lots of Branches and Leaves", 703 directories: sets.NewString("a", "a/combo", "a/d", "b", "c"), 704 expected: sets.NewString("a", "b", "c"), 705 }, 706 { 707 testName: "NoParentOwners", 708 directories: sets.NewString("a", "a/combo"), 709 noParentOwners: map[string]bool{"a/combo": true}, 710 expected: sets.NewString("a", "a/combo"), 711 }, 712 { 713 testName: "NoParentOwners in relative path", 714 directories: sets.NewString("a", "a/b/combo"), 715 noParentOwners: map[string]bool{"a/b": true}, 716 expected: sets.NewString("a", "a/b/combo"), 717 }, 718 { 719 testName: "NoParentOwners with child", 720 directories: sets.NewString("a", "a/b", "a/b/combo"), 721 noParentOwners: map[string]bool{"a/b": true}, 722 expected: sets.NewString("a", "a/b"), 723 }, 724 } 725 726 for _, test := range tests { 727 if test.noParentOwners == nil { 728 test.noParentOwners = map[string]bool{} 729 } 730 o := &Owners{repo: FakeRepo{noParentOwnersMap: test.noParentOwners}} 731 o.removeSubdirs(test.directories) 732 if !reflect.DeepEqual(test.expected, test.directories) { 733 t.Errorf("Failed to remove subdirectories for test %v. Expected files: %q. Found %q", test.testName, test.expected.List(), test.directories.List()) 734 735 } 736 } 737 }