github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/tide/tide_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 tide 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 24 "github.com/shurcooL/githubql" 25 "github.com/sirupsen/logrus" 26 27 "k8s.io/test-infra/prow/config" 28 "k8s.io/test-infra/prow/git/localgit" 29 "k8s.io/test-infra/prow/github" 30 "k8s.io/test-infra/prow/kube" 31 ) 32 33 func testPullsMatchList(t *testing.T, test string, actual []pullRequest, expected []int) { 34 if len(actual) != len(expected) { 35 t.Errorf("Wrong size for case %s. Got PRs %+v, wanted numbers %v.", test, actual, expected) 36 return 37 } 38 for _, pr := range actual { 39 var found bool 40 n1 := int(pr.Number) 41 for _, n2 := range expected { 42 if n1 == n2 { 43 found = true 44 } 45 } 46 if !found { 47 t.Errorf("For case %s, found PR %d but shouldn't have.", test, n1) 48 } 49 } 50 } 51 52 func TestAccumulateBatch(t *testing.T) { 53 type pull struct { 54 number int 55 sha string 56 } 57 type prowjob struct { 58 prs []pull 59 job string 60 state kube.ProwJobState 61 } 62 tests := []struct { 63 name string 64 presubmits []string 65 pulls []pull 66 prowJobs []prowjob 67 68 merges []int 69 pending bool 70 }{ 71 { 72 name: "no batches running", 73 }, 74 { 75 name: "batch pending", 76 presubmits: []string{"foo", "bar", "baz"}, 77 pulls: []pull{{1, "a"}, {2, "b"}}, 78 prowJobs: []prowjob{{job: "foo", state: kube.PendingState, prs: []pull{{1, "a"}}}}, 79 pending: true, 80 }, 81 { 82 name: "batch pending, successful previous run", 83 presubmits: []string{"foo", "bar", "baz"}, 84 pulls: []pull{{1, "a"}, {2, "b"}}, 85 prowJobs: []prowjob{ 86 {job: "foo", state: kube.PendingState, prs: []pull{{1, "a"}}}, 87 {job: "foo", state: kube.SuccessState, prs: []pull{{2, "b"}}}, 88 {job: "bar", state: kube.SuccessState, prs: []pull{{2, "b"}}}, 89 {job: "baz", state: kube.SuccessState, prs: []pull{{2, "b"}}}, 90 }, 91 pending: true, 92 }, 93 { 94 name: "successful run", 95 presubmits: []string{"foo", "bar", "baz"}, 96 pulls: []pull{{1, "a"}, {2, "b"}}, 97 prowJobs: []prowjob{ 98 {job: "foo", state: kube.SuccessState, prs: []pull{{2, "b"}}}, 99 {job: "bar", state: kube.SuccessState, prs: []pull{{2, "b"}}}, 100 {job: "baz", state: kube.SuccessState, prs: []pull{{2, "b"}}}, 101 }, 102 merges: []int{2}, 103 }, 104 { 105 name: "successful run, multiple PRs", 106 presubmits: []string{"foo", "bar", "baz"}, 107 pulls: []pull{{1, "a"}, {2, "b"}}, 108 prowJobs: []prowjob{ 109 {job: "foo", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 110 {job: "bar", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 111 {job: "baz", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 112 }, 113 merges: []int{1, 2}, 114 }, 115 { 116 name: "successful run, failures in past", 117 presubmits: []string{"foo", "bar", "baz"}, 118 pulls: []pull{{1, "a"}, {2, "b"}}, 119 prowJobs: []prowjob{ 120 {job: "foo", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 121 {job: "bar", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 122 {job: "baz", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 123 {job: "foo", state: kube.FailureState, prs: []pull{{1, "a"}, {2, "b"}}}, 124 {job: "baz", state: kube.FailureState, prs: []pull{{1, "a"}, {2, "b"}}}, 125 {job: "foo", state: kube.FailureState, prs: []pull{{1, "c"}, {2, "b"}}}, 126 }, 127 merges: []int{1, 2}, 128 }, 129 { 130 name: "failures", 131 presubmits: []string{"foo", "bar", "baz"}, 132 pulls: []pull{{1, "a"}, {2, "b"}}, 133 prowJobs: []prowjob{ 134 {job: "foo", state: kube.FailureState, prs: []pull{{1, "a"}, {2, "b"}}}, 135 {job: "bar", state: kube.SuccessState, prs: []pull{{1, "a"}, {2, "b"}}}, 136 {job: "baz", state: kube.FailureState, prs: []pull{{1, "a"}, {2, "b"}}}, 137 {job: "foo", state: kube.FailureState, prs: []pull{{1, "c"}, {2, "b"}}}, 138 }, 139 }, 140 } 141 for _, test := range tests { 142 var pulls []pullRequest 143 for _, p := range test.pulls { 144 pr := pullRequest{Number: githubql.Int(p.number)} 145 pr.HeadRef.Target.OID = githubql.String(p.sha) 146 pulls = append(pulls, pr) 147 } 148 var pjs []kube.ProwJob 149 for _, pj := range test.prowJobs { 150 npj := kube.ProwJob{ 151 Spec: kube.ProwJobSpec{ 152 Job: pj.job, 153 Type: kube.BatchJob, 154 }, 155 Status: kube.ProwJobStatus{State: pj.state}, 156 } 157 for _, pr := range pj.prs { 158 npj.Spec.Refs.Pulls = append(npj.Spec.Refs.Pulls, kube.Pull{ 159 Number: pr.number, 160 SHA: pr.sha, 161 }) 162 } 163 pjs = append(pjs, npj) 164 } 165 merges, pending := accumulateBatch(test.presubmits, pulls, pjs) 166 if pending != test.pending { 167 t.Errorf("For case \"%s\", got wrong pending.", test.name) 168 } 169 testPullsMatchList(t, test.name, merges, test.merges) 170 } 171 } 172 173 func TestAccumulate(t *testing.T) { 174 type prowjob struct { 175 prNumber int 176 job string 177 state kube.ProwJobState 178 } 179 tests := []struct { 180 presubmits []string 181 pullRequests []int 182 prowJobs []prowjob 183 184 successes []int 185 pendings []int 186 none []int 187 }{ 188 { 189 presubmits: []string{"job1", "job2"}, 190 pullRequests: []int{1, 2, 3, 4, 5, 6, 7}, 191 prowJobs: []prowjob{ 192 {2, "job1", kube.PendingState}, 193 {3, "job1", kube.PendingState}, 194 {3, "job2", kube.TriggeredState}, 195 {4, "job1", kube.FailureState}, 196 {4, "job2", kube.PendingState}, 197 {5, "job1", kube.PendingState}, 198 {5, "job2", kube.FailureState}, 199 {5, "job2", kube.PendingState}, 200 {6, "job1", kube.SuccessState}, 201 {6, "job2", kube.PendingState}, 202 {7, "job1", kube.SuccessState}, 203 {7, "job2", kube.SuccessState}, 204 {7, "job1", kube.FailureState}, 205 }, 206 207 successes: []int{7}, 208 pendings: []int{3, 5, 6}, 209 none: []int{1, 2, 4}, 210 }, 211 { 212 presubmits: []string{"job1", "job2", "job3", "job4"}, 213 pullRequests: []int{7}, 214 prowJobs: []prowjob{ 215 {7, "job1", kube.SuccessState}, 216 {7, "job2", kube.FailureState}, 217 {7, "job3", kube.FailureState}, 218 {7, "job4", kube.FailureState}, 219 {7, "job3", kube.FailureState}, 220 {7, "job4", kube.FailureState}, 221 {7, "job2", kube.SuccessState}, 222 {7, "job3", kube.SuccessState}, 223 {7, "job4", kube.FailureState}, 224 }, 225 226 successes: []int{}, 227 pendings: []int{}, 228 none: []int{7}, 229 }, 230 { 231 presubmits: []string{"job1", "job2", "job3", "job4"}, 232 pullRequests: []int{7}, 233 prowJobs: []prowjob{ 234 {7, "job1", kube.FailureState}, 235 {7, "job2", kube.FailureState}, 236 {7, "job3", kube.FailureState}, 237 {7, "job4", kube.FailureState}, 238 {7, "job3", kube.FailureState}, 239 {7, "job4", kube.FailureState}, 240 {7, "job2", kube.FailureState}, 241 {7, "job3", kube.FailureState}, 242 {7, "job4", kube.FailureState}, 243 }, 244 245 successes: []int{}, 246 pendings: []int{}, 247 none: []int{7}, 248 }, 249 { 250 presubmits: []string{"job1", "job2", "job3", "job4"}, 251 pullRequests: []int{7}, 252 prowJobs: []prowjob{ 253 {7, "job1", kube.SuccessState}, 254 {7, "job2", kube.FailureState}, 255 {7, "job3", kube.FailureState}, 256 {7, "job4", kube.FailureState}, 257 {7, "job3", kube.FailureState}, 258 {7, "job4", kube.FailureState}, 259 {7, "job2", kube.SuccessState}, 260 {7, "job3", kube.SuccessState}, 261 {7, "job4", kube.SuccessState}, 262 {7, "job1", kube.FailureState}, 263 }, 264 265 successes: []int{7}, 266 pendings: []int{}, 267 none: []int{}, 268 }, 269 { 270 presubmits: []string{"job1", "job2", "job3", "job4"}, 271 pullRequests: []int{7}, 272 prowJobs: []prowjob{ 273 {7, "job1", kube.SuccessState}, 274 {7, "job2", kube.FailureState}, 275 {7, "job3", kube.FailureState}, 276 {7, "job4", kube.FailureState}, 277 {7, "job3", kube.FailureState}, 278 {7, "job4", kube.FailureState}, 279 {7, "job2", kube.SuccessState}, 280 {7, "job3", kube.SuccessState}, 281 {7, "job4", kube.PendingState}, 282 {7, "job1", kube.FailureState}, 283 }, 284 285 successes: []int{}, 286 pendings: []int{7}, 287 none: []int{}, 288 }, 289 } 290 291 for i, test := range tests { 292 var pulls []pullRequest 293 for _, p := range test.pullRequests { 294 pulls = append(pulls, pullRequest{Number: githubql.Int(p)}) 295 } 296 var pjs []kube.ProwJob 297 for _, pj := range test.prowJobs { 298 pjs = append(pjs, kube.ProwJob{ 299 Spec: kube.ProwJobSpec{ 300 Job: pj.job, 301 Type: kube.PresubmitJob, 302 Refs: kube.Refs{Pulls: []kube.Pull{{Number: pj.prNumber}}}, 303 }, 304 Status: kube.ProwJobStatus{State: pj.state}, 305 }) 306 } 307 308 successes, pendings, nones := accumulate(test.presubmits, pulls, pjs) 309 310 t.Logf("test run %d", i) 311 testPullsMatchList(t, "successes", successes, test.successes) 312 testPullsMatchList(t, "pendings", pendings, test.pendings) 313 testPullsMatchList(t, "nones", nones, test.none) 314 } 315 } 316 317 type fgc struct { 318 refs map[string]string 319 merged int 320 } 321 322 func (f *fgc) GetRef(o, r, ref string) (string, error) { 323 return f.refs[o+"/"+r+" "+ref], nil 324 } 325 326 func (f *fgc) Query(ctx context.Context, q interface{}, vars map[string]interface{}) error { 327 return nil 328 } 329 330 func (f *fgc) Merge(org, repo string, number int, details github.MergeDetails) error { 331 f.merged++ 332 return nil 333 } 334 335 // TestDividePool ensures that subpools returned by dividePool satisfy a few 336 // important invariants. 337 func TestDividePool(t *testing.T) { 338 testPulls := []struct { 339 org string 340 repo string 341 number int 342 branch string 343 }{ 344 { 345 org: "k", 346 repo: "t-i", 347 number: 5, 348 branch: "master", 349 }, 350 { 351 org: "k", 352 repo: "t-i", 353 number: 6, 354 branch: "master", 355 }, 356 { 357 org: "k", 358 repo: "k", 359 number: 123, 360 branch: "master", 361 }, 362 { 363 org: "k", 364 repo: "k", 365 number: 1000, 366 branch: "release-1.6", 367 }, 368 } 369 testPJs := []struct { 370 jobType kube.ProwJobType 371 org string 372 repo string 373 baseRef string 374 baseSHA string 375 }{ 376 { 377 jobType: kube.PresubmitJob, 378 org: "k", 379 repo: "t-i", 380 baseRef: "master", 381 baseSHA: "123", 382 }, 383 { 384 jobType: kube.BatchJob, 385 org: "k", 386 repo: "t-i", 387 baseRef: "master", 388 baseSHA: "123", 389 }, 390 { 391 jobType: kube.PeriodicJob, 392 }, 393 { 394 jobType: kube.PresubmitJob, 395 org: "k", 396 repo: "t-i", 397 baseRef: "patch", 398 baseSHA: "123", 399 }, 400 { 401 jobType: kube.PresubmitJob, 402 org: "k", 403 repo: "t-i", 404 baseRef: "master", 405 baseSHA: "abc", 406 }, 407 { 408 jobType: kube.PresubmitJob, 409 org: "o", 410 repo: "t-i", 411 baseRef: "master", 412 baseSHA: "123", 413 }, 414 { 415 jobType: kube.PresubmitJob, 416 org: "k", 417 repo: "other", 418 baseRef: "master", 419 baseSHA: "123", 420 }, 421 } 422 fc := &fgc{ 423 refs: map[string]string{"k/t-i heads/master": "123"}, 424 } 425 c := &Controller{ 426 ghc: fc, 427 } 428 var pulls []pullRequest 429 for _, p := range testPulls { 430 npr := pullRequest{Number: githubql.Int(p.number)} 431 npr.BaseRef.Name = githubql.String(p.branch) 432 npr.BaseRef.Prefix = "refs/heads/" 433 npr.Repository.Name = githubql.String(p.repo) 434 npr.Repository.Owner.Login = githubql.String(p.org) 435 pulls = append(pulls, npr) 436 } 437 var pjs []kube.ProwJob 438 for _, pj := range testPJs { 439 pjs = append(pjs, kube.ProwJob{ 440 Spec: kube.ProwJobSpec{ 441 Type: pj.jobType, 442 Refs: kube.Refs{ 443 Org: pj.org, 444 Repo: pj.repo, 445 BaseRef: pj.baseRef, 446 BaseSHA: pj.baseSHA, 447 }, 448 }, 449 }) 450 } 451 sps, err := c.dividePool(pulls, pjs) 452 if err != nil { 453 t.Fatalf("Error dividing pool: %v", err) 454 } 455 if len(sps) == 0 { 456 t.Error("No subpools.") 457 } 458 for _, sp := range sps { 459 name := fmt.Sprintf("%s/%s %s", sp.org, sp.repo, sp.branch) 460 sha := fc.refs[sp.org+"/"+sp.repo+" heads/"+sp.branch] 461 if sp.sha != sha { 462 t.Errorf("For subpool %s, got sha %s, expected %s.", name, sp.sha, sha) 463 } 464 if len(sp.prs) == 0 { 465 t.Errorf("Subpool %s has no PRs.", name) 466 } 467 for _, pr := range sp.prs { 468 if string(pr.Repository.Owner.Login) != sp.org || string(pr.Repository.Name) != sp.repo || string(pr.BaseRef.Name) != sp.branch { 469 t.Errorf("PR in wrong subpool. Got PR %+v in subpool %s.", pr, name) 470 } 471 } 472 for _, pj := range sp.pjs { 473 if pj.Spec.Type != kube.PresubmitJob && pj.Spec.Type != kube.BatchJob { 474 t.Errorf("PJ with bad type in subpool %s: %+v", name, pj) 475 } 476 if pj.Spec.Refs.Org != sp.org || pj.Spec.Refs.Repo != sp.repo || pj.Spec.Refs.BaseRef != sp.branch || pj.Spec.Refs.BaseSHA != sp.sha { 477 t.Errorf("PJ in wrong subpool. Got PJ %+v in subpool %s.", pj, name) 478 } 479 } 480 } 481 } 482 483 func TestPickBatch(t *testing.T) { 484 lg, gc, err := localgit.New() 485 if err != nil { 486 t.Fatalf("Error making local git: %v", err) 487 } 488 defer gc.Clean() 489 defer lg.Clean() 490 if err := lg.MakeFakeRepo("o", "r"); err != nil { 491 t.Fatalf("Error making fake repo: %v", err) 492 } 493 if err := lg.AddCommit("o", "r", map[string][]byte{"foo": []byte("foo")}); err != nil { 494 t.Fatalf("Adding initial commit: %v", err) 495 } 496 testprs := []struct { 497 files map[string][]byte 498 success bool 499 500 included bool 501 }{ 502 { 503 files: map[string][]byte{"bar": []byte("ok")}, 504 success: true, 505 included: true, 506 }, 507 { 508 files: map[string][]byte{"foo": []byte("ok")}, 509 success: true, 510 included: true, 511 }, 512 { 513 files: map[string][]byte{"bar": []byte("conflicts with 0")}, 514 success: true, 515 included: false, 516 }, 517 { 518 files: map[string][]byte{"qux": []byte("ok")}, 519 success: false, 520 included: false, 521 }, 522 { 523 files: map[string][]byte{"bazel": []byte("ok")}, 524 success: true, 525 included: true, 526 }, 527 } 528 sp := subpool{ 529 org: "o", 530 repo: "r", 531 branch: "master", 532 sha: "master", 533 } 534 for i, testpr := range testprs { 535 if err := lg.CheckoutNewBranch("o", "r", fmt.Sprintf("pr-%d", i)); err != nil { 536 t.Fatalf("Error checking out new branch: %v", err) 537 } 538 if err := lg.AddCommit("o", "r", testpr.files); err != nil { 539 t.Fatalf("Error adding commit: %v", err) 540 } 541 if err := lg.Checkout("o", "r", "master"); err != nil { 542 t.Fatalf("Error checking out master: %v", err) 543 } 544 var pr pullRequest 545 pr.Number = githubql.Int(i) 546 pr.Commits.Nodes = []struct { 547 Commit struct { 548 Status struct{ State githubql.String } 549 } 550 }{{}} 551 if testpr.success { 552 pr.Commits.Nodes[0].Commit.Status.State = githubql.String("SUCCESS") 553 } 554 pr.HeadRef.Target.OID = githubql.String(fmt.Sprintf("origin/pr-%d", i)) 555 sp.prs = append(sp.prs, pr) 556 } 557 c := &Controller{ 558 gc: gc, 559 } 560 prs, err := c.pickBatch(sp) 561 if err != nil { 562 t.Fatalf("Error from pickBatch: %v", err) 563 } 564 for i, testpr := range testprs { 565 var found bool 566 for _, pr := range prs { 567 if int(pr.Number) == i { 568 found = true 569 break 570 } 571 } 572 if found != testpr.included { 573 t.Errorf("PR %d should not be picked.", i) 574 } 575 } 576 } 577 578 type fkc struct { 579 createdJobs []kube.ProwJob 580 } 581 582 func (c *fkc) ListProwJobs(map[string]string) ([]kube.ProwJob, error) { 583 return nil, nil 584 } 585 586 func (c *fkc) CreateProwJob(pj kube.ProwJob) (kube.ProwJob, error) { 587 c.createdJobs = append(c.createdJobs, pj) 588 return pj, nil 589 } 590 591 func TestTakeAction(t *testing.T) { 592 // PRs 0-9 exist. All are mergable, and all are passing tests. 593 testcases := []struct { 594 name string 595 596 batchPending bool 597 successes []int 598 pendings []int 599 nones []int 600 batchMerges []int 601 602 merged int 603 triggered int 604 triggered_batches int 605 }{ 606 { 607 name: "no prs to test, should do nothing", 608 609 batchPending: true, 610 successes: []int{}, 611 pendings: []int{}, 612 nones: []int{}, 613 batchMerges: []int{}, 614 615 merged: 0, 616 triggered: 0, 617 }, 618 { 619 name: "pending batch, pending serial, nothing to do", 620 621 batchPending: true, 622 successes: []int{}, 623 pendings: []int{1}, 624 nones: []int{0, 2}, 625 batchMerges: []int{}, 626 627 merged: 0, 628 triggered: 0, 629 }, 630 { 631 name: "pending batch, successful serial, nothing to do", 632 633 batchPending: true, 634 successes: []int{1}, 635 pendings: []int{}, 636 nones: []int{0, 2}, 637 batchMerges: []int{}, 638 639 merged: 0, 640 triggered: 0, 641 }, 642 { 643 name: "pending batch, should trigger serial", 644 645 batchPending: true, 646 successes: []int{}, 647 pendings: []int{}, 648 nones: []int{0, 1, 2}, 649 batchMerges: []int{}, 650 651 merged: 0, 652 triggered: 1, 653 }, 654 { 655 name: "no pending batch, should trigger serial and batch", 656 657 batchPending: false, 658 successes: []int{}, 659 pendings: []int{}, 660 nones: []int{0, 1, 2, 3}, 661 batchMerges: []int{}, 662 663 merged: 0, 664 triggered: 2, 665 triggered_batches: 1, 666 }, 667 { 668 name: "one PR, should not trigger batch", 669 670 batchPending: false, 671 successes: []int{}, 672 pendings: []int{}, 673 nones: []int{0}, 674 batchMerges: []int{}, 675 676 merged: 0, 677 triggered: 1, 678 }, 679 { 680 name: "successful PR, should merge", 681 682 batchPending: false, 683 successes: []int{0}, 684 pendings: []int{}, 685 nones: []int{1, 2, 3}, 686 batchMerges: []int{}, 687 688 merged: 1, 689 triggered: 0, 690 }, 691 { 692 name: "successful batch, should merge", 693 694 batchPending: false, 695 successes: []int{0, 1}, 696 pendings: []int{2, 3}, 697 nones: []int{4, 5}, 698 batchMerges: []int{6, 7, 8}, 699 700 merged: 3, 701 triggered: 0, 702 }, 703 } 704 705 for _, tc := range testcases { 706 ca := &config.Agent{} 707 ca.Set(&config.Config{ 708 Presubmits: map[string][]config.Presubmit{ 709 "o/r": { 710 { 711 Name: "foo", 712 AlwaysRun: true, 713 }, 714 }, 715 }, 716 }) 717 lg, gc, err := localgit.New() 718 if err != nil { 719 t.Fatalf("Error making local git: %v", err) 720 } 721 defer gc.Clean() 722 defer lg.Clean() 723 if err := lg.MakeFakeRepo("o", "r"); err != nil { 724 t.Fatalf("Error making fake repo: %v", err) 725 } 726 if err := lg.AddCommit("o", "r", map[string][]byte{"foo": []byte("foo")}); err != nil { 727 t.Fatalf("Adding initial commit: %v", err) 728 } 729 730 sp := subpool{ 731 org: "o", 732 repo: "r", 733 branch: "master", 734 sha: "master", 735 } 736 genPulls := func(nums []int) []pullRequest { 737 var prs []pullRequest 738 for _, i := range nums { 739 if err := lg.CheckoutNewBranch("o", "r", fmt.Sprintf("pr-%d", i)); err != nil { 740 t.Fatalf("Error checking out new branch: %v", err) 741 } 742 if err := lg.AddCommit("o", "r", map[string][]byte{fmt.Sprintf("%d", i): []byte("WOW")}); err != nil { 743 t.Fatalf("Error adding commit: %v", err) 744 } 745 if err := lg.Checkout("o", "r", "master"); err != nil { 746 t.Fatalf("Error checking out master: %v", err) 747 } 748 var pr pullRequest 749 pr.Number = githubql.Int(i) 750 pr.Commits.Nodes = []struct { 751 Commit struct { 752 Status struct{ State githubql.String } 753 } 754 }{{}} 755 pr.Commits.Nodes[0].Commit.Status.State = githubql.String("SUCCESS") 756 pr.HeadRef.Target.OID = githubql.String(fmt.Sprintf("origin/pr-%d", i)) 757 sp.prs = append(sp.prs, pr) 758 prs = append(prs, pr) 759 } 760 return prs 761 } 762 var fkc fkc 763 var fgc fgc 764 c := &Controller{ 765 Logger: logrus.StandardLogger().WithField("controller", "tide"), 766 gc: gc, 767 ghc: &fgc, 768 ca: ca, 769 kc: &fkc, 770 } 771 t.Logf("Test case: %s", tc.name) 772 if err := c.takeAction(sp, tc.batchPending, genPulls(tc.successes), genPulls(tc.pendings), genPulls(tc.nones), genPulls(tc.batchMerges)); err != nil { 773 t.Errorf("Error in takeAction: %v", err) 774 continue 775 } 776 if tc.triggered != len(fkc.createdJobs) { 777 t.Errorf("Wrong number of jobs triggered. Got %d, expected %d.", len(fkc.createdJobs), tc.triggered) 778 } 779 if tc.merged != fgc.merged { 780 t.Errorf("Wrong number of merges. Got %d, expected %d.", fgc.merged, tc.merged) 781 } 782 // Ensure that the correct number of batch jobs were triggered 783 batches := 0 784 for _, job := range fkc.createdJobs { 785 if (len(job.Spec.Refs.Pulls) > 1) != (job.Spec.Type == kube.BatchJob) { 786 t.Error("Found a batch job that doesn't contain multiple pull refs!") 787 } 788 if len(job.Spec.Refs.Pulls) > 1 { 789 batches++ 790 } 791 } 792 if tc.triggered_batches != batches { 793 t.Errorf("Wrong number of batches triggered. Got %d, expected %d.", batches, tc.triggered_batches) 794 } 795 } 796 }