sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/crier/reporters/github/reporter_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 github 18 19 import ( 20 "context" 21 "errors" 22 "sync" 23 "testing" 24 "time" 25 26 "github.com/google/go-cmp/cmp" 27 "github.com/google/go-cmp/cmp/cmpopts" 28 "github.com/sirupsen/logrus" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 31 v1 "sigs.k8s.io/prow/pkg/apis/prowjobs/v1" 32 "sigs.k8s.io/prow/pkg/config" 33 "sigs.k8s.io/prow/pkg/github/fakegithub" 34 "sigs.k8s.io/prow/pkg/kube" 35 36 fakectrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" 37 ) 38 39 func TestShouldReport(t *testing.T) { 40 var testcases = []struct { 41 name string 42 pj v1.ProwJob 43 report bool 44 reportAgent v1.ProwJobAgent 45 }{ 46 { 47 name: "should not report periodic job", 48 pj: v1.ProwJob{ 49 Spec: v1.ProwJobSpec{ 50 Type: v1.PeriodicJob, 51 Report: true, 52 }, 53 }, 54 report: false, 55 }, 56 { 57 name: "should report postsubmit job", 58 pj: v1.ProwJob{ 59 Spec: v1.ProwJobSpec{ 60 Type: v1.PostsubmitJob, 61 Report: true, 62 }, 63 }, 64 report: true, 65 }, 66 { 67 name: "should not report batch job", 68 pj: v1.ProwJob{ 69 Spec: v1.ProwJobSpec{ 70 Type: v1.BatchJob, 71 Report: true, 72 }, 73 }, 74 report: false, 75 }, 76 { 77 name: "should report presubmit job", 78 pj: v1.ProwJob{ 79 Spec: v1.ProwJobSpec{ 80 Type: v1.PresubmitJob, 81 Report: true, 82 }, 83 }, 84 report: true, 85 }, 86 { 87 name: "github should not report gerrit jobs", 88 pj: v1.ProwJob{ 89 ObjectMeta: metav1.ObjectMeta{ 90 Labels: map[string]string{ 91 kube.GerritReportLabel: "plus-one-this-gerrit-label-please", 92 }, 93 }, 94 Spec: v1.ProwJobSpec{ 95 Type: v1.PresubmitJob, 96 Report: true, 97 }, 98 }, 99 }, 100 } 101 102 for _, tc := range testcases { 103 t.Run(tc.name, func(t *testing.T) { 104 c := NewReporter(nil, nil, tc.reportAgent, nil) 105 if r := c.ShouldReport(context.Background(), logrus.NewEntry(logrus.StandardLogger()), &tc.pj); r == tc.report { 106 return 107 } 108 if tc.report { 109 t.Error("failed to report") 110 } else { 111 t.Error("unexpectedly reported") 112 } 113 }) 114 } 115 } 116 117 // TestPresumitReportingLocks verifies locking happens 118 // for Presubmit reporting. Must be run with -race, relies 119 // on sigs.k8s.io/prow/pkg/github/fakegithub not being 120 // threadsafe. 121 func TestPresumitReportingLocks(t *testing.T) { 122 reporter := NewReporter( 123 fakegithub.NewFakeClient(), 124 func() *config.Config { 125 return &config.Config{ 126 ProwConfig: config.ProwConfig{ 127 GitHubReporter: config.GitHubReporter{ 128 JobTypesToReport: []v1.ProwJobType{v1.PresubmitJob}, 129 }, 130 }, 131 } 132 }, 133 v1.ProwJobAgent(""), 134 nil, 135 ) 136 137 pj := &v1.ProwJob{ 138 Spec: v1.ProwJobSpec{ 139 Refs: &v1.Refs{ 140 Org: "org", 141 Repo: "repo", 142 Pulls: []v1.Pull{{Number: 1}}, 143 }, 144 Type: v1.PresubmitJob, 145 Report: true, 146 }, 147 Status: v1.ProwJobStatus{ 148 State: v1.ErrorState, 149 CompletionTime: &metav1.Time{}, 150 }, 151 } 152 153 wg := &sync.WaitGroup{} 154 wg.Add(2) 155 go func() { 156 if _, _, err := reporter.Report(context.Background(), logrus.NewEntry(logrus.StandardLogger()), pj); err != nil { 157 t.Errorf("error reporting: %v", err) 158 } 159 wg.Done() 160 }() 161 go func() { 162 if _, _, err := reporter.Report(context.Background(), logrus.NewEntry(logrus.StandardLogger()), pj); err != nil { 163 t.Errorf("error reporting: %v", err) 164 } 165 wg.Done() 166 }() 167 168 wg.Wait() 169 } 170 171 func TestReport(t *testing.T) { 172 t.Parallel() 173 testCases := []struct { 174 name string 175 createStatusContextError error 176 listIssueCommentsWithContextError error 177 expectedError string 178 }{ 179 { 180 name: "Success", 181 }, 182 { 183 name: "Maximum sha error gets swallowed", 184 createStatusContextError: errors.New(`This SHA and context has reached the maximum number of statuses`), 185 }, 186 { 187 name: "Error from user side gets swallowed", 188 createStatusContextError: errors.New(`error setting status: status code 404 not one of [201], body: {"message":"Not Found","documentation_url":"https://docs.github.com/rest/reference/repos#create-a-commit-status"}`), 189 }, 190 { 191 name: "Error from user side gets swallowed2", 192 createStatusContextError: errors.New(`failed to report job: error setting status: status code 422 not one of [201], body: {"message":"No commit found for SHA: 9d04799d1a22e9e604c50f6bbbec067aaccc1b32","documentation_url":"https://docs.github.com/rest/reference/repos#create-a-commit-status"}`), 193 }, 194 { 195 name: "Other error get returned", 196 createStatusContextError: errors.New("something went wrong :("), 197 expectedError: "error setting status: something went wrong :(", 198 }, 199 { 200 name: "Comment error_Maximum sha error gets swallowed", 201 listIssueCommentsWithContextError: errors.New(`This SHA and context has reached the maximum number of statuses`), 202 expectedError: "error listing comments: This SHA and context has reached the maximum number of statuses", 203 }, 204 { 205 name: "Comment error_Error from user side gets swallowed", 206 listIssueCommentsWithContextError: errors.New(`error setting status: status code 404 not one of [201], body: {"message":"Not Found","documentation_url":"https://docs.github.com/rest/reference/repos#create-a-commit-status"}`), 207 expectedError: "error listing comments: error setting status: status code 404 not one of [201], body: {\"message\":\"Not Found\",\"documentation_url\":\"https://docs.github.com/rest/reference/repos#create-a-commit-status\"}", 208 }, 209 { 210 name: "Comment error_Error from user side gets swallowed2", 211 listIssueCommentsWithContextError: errors.New(`failed to report job: error setting status: status code 422 not one of [201], body: {"message":"No commit found for SHA: 9d04799d1a22e9e604c50f6bbbec067aaccc1b32","documentation_url":"https://docs.github.com/rest/reference/repos#create-a-commit-status"}`), 212 expectedError: "error listing comments: failed to report job: error setting status: status code 422 not one of [201], body: {\"message\":\"No commit found for SHA: 9d04799d1a22e9e604c50f6bbbec067aaccc1b32\",\"documentation_url\":\"https://docs.github.com/rest/reference/repos#create-a-commit-status\"}", 213 }, 214 { 215 name: "Comment error_Other error get returned", 216 listIssueCommentsWithContextError: errors.New("something went wrong :("), 217 expectedError: "error listing comments: something went wrong :(", 218 }, 219 } 220 221 for _, tc := range testCases { 222 t.Run(tc.name, func(t *testing.T) { 223 fghc := fakegithub.NewFakeClient() 224 fghc.Error = tc.createStatusContextError 225 fghc.ListIssueCommentsWithContextError = tc.listIssueCommentsWithContextError 226 c := Client{ 227 gc: fghc, 228 config: func() *config.Config { 229 return &config.Config{ 230 ProwConfig: config.ProwConfig{ 231 GitHubReporter: config.GitHubReporter{ 232 JobTypesToReport: []v1.ProwJobType{v1.PostsubmitJob}, 233 }, 234 }, 235 } 236 }, 237 } 238 pj := &v1.ProwJob{ 239 Spec: v1.ProwJobSpec{ 240 Type: v1.PostsubmitJob, 241 Report: true, 242 Refs: &v1.Refs{ 243 Pulls: []v1.Pull{ 244 {}, 245 }, 246 }, 247 }, 248 Status: v1.ProwJobStatus{ 249 State: v1.SuccessState, 250 CompletionTime: &metav1.Time{}, 251 }, 252 } 253 254 errMsg := "" 255 _, _, err := c.Report(context.Background(), logrus.NewEntry(logrus.StandardLogger()), pj) 256 if err != nil { 257 errMsg = err.Error() 258 } 259 if errMsg != tc.expectedError { 260 t.Errorf("expected error %q got error %q", tc.expectedError, errMsg) 261 } 262 }) 263 } 264 } 265 266 func TestPjsToReport(t *testing.T) { 267 timeNow := time.Now().Truncate(time.Second) // Truncate so that comparison works. 268 var testcases = []struct { 269 name string 270 pj *v1.ProwJob 271 existingPJs []*v1.ProwJob 272 wantPjs []v1.ProwJob 273 wantErr bool 274 }{ 275 { 276 name: "two-jobs-finished", 277 pj: &v1.ProwJob{ 278 ObjectMeta: metav1.ObjectMeta{ 279 Name: "0", 280 Labels: map[string]string{ 281 kube.ProwJobTypeLabel: "presubmit", 282 kube.OrgLabel: "org", 283 kube.RepoLabel: "repo", 284 kube.PullLabel: "123", 285 }, 286 CreationTimestamp: metav1.Time{ 287 Time: timeNow.Add(-time.Hour), 288 }, 289 }, 290 Status: v1.ProwJobStatus{ 291 State: v1.SuccessState, 292 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 293 }, 294 Spec: v1.ProwJobSpec{ 295 Type: v1.PresubmitJob, 296 Refs: &v1.Refs{ 297 Repo: "foo", 298 Pulls: []v1.Pull{ 299 { 300 Number: 123, 301 }, 302 }, 303 }, 304 Job: "ci-foo", 305 Report: true, 306 }, 307 }, 308 existingPJs: []*v1.ProwJob{ 309 { 310 ObjectMeta: metav1.ObjectMeta{ 311 Name: "1", 312 Labels: map[string]string{ 313 kube.ProwJobTypeLabel: "presubmit", 314 kube.OrgLabel: "org", 315 kube.RepoLabel: "repo", 316 kube.PullLabel: "123", 317 }, 318 CreationTimestamp: metav1.Time{ 319 Time: timeNow.Add(-time.Hour), 320 }, 321 }, 322 Status: v1.ProwJobStatus{ 323 State: v1.FailureState, 324 PrevReportStates: map[string]v1.ProwJobState{ 325 "github-reporter": v1.FailureState, 326 }, 327 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 328 }, 329 Spec: v1.ProwJobSpec{ 330 Refs: &v1.Refs{ 331 Repo: "bar", 332 Pulls: []v1.Pull{ 333 { 334 Number: 123, 335 }, 336 }, 337 }, 338 Job: "ci-bar", 339 Type: v1.PresubmitJob, 340 Report: true, 341 }, 342 }, 343 }, 344 wantPjs: []v1.ProwJob{ 345 { 346 ObjectMeta: metav1.ObjectMeta{ 347 Name: "0", 348 Labels: map[string]string{ 349 kube.ProwJobTypeLabel: "presubmit", 350 kube.OrgLabel: "org", 351 kube.RepoLabel: "repo", 352 kube.PullLabel: "123", 353 }, 354 CreationTimestamp: metav1.Time{ 355 Time: timeNow.Add(-time.Hour), 356 }, 357 ResourceVersion: "999", 358 }, 359 Status: v1.ProwJobStatus{ 360 State: v1.SuccessState, 361 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 362 }, 363 Spec: v1.ProwJobSpec{ 364 Type: v1.PresubmitJob, 365 Refs: &v1.Refs{ 366 Repo: "foo", 367 Pulls: []v1.Pull{ 368 { 369 Number: 123, 370 }, 371 }, 372 }, 373 Job: "ci-foo", 374 Report: true, 375 }, 376 }, 377 { 378 ObjectMeta: metav1.ObjectMeta{ 379 Name: "1", 380 Labels: map[string]string{ 381 kube.ProwJobTypeLabel: "presubmit", 382 kube.OrgLabel: "org", 383 kube.RepoLabel: "repo", 384 kube.PullLabel: "123", 385 }, 386 CreationTimestamp: metav1.Time{ 387 Time: timeNow.Add(-time.Hour), 388 }, 389 ResourceVersion: "999", 390 }, 391 Status: v1.ProwJobStatus{ 392 State: v1.FailureState, 393 PrevReportStates: map[string]v1.ProwJobState{ 394 "github-reporter": v1.FailureState, 395 }, 396 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 397 }, 398 Spec: v1.ProwJobSpec{ 399 Refs: &v1.Refs{ 400 Repo: "bar", 401 Pulls: []v1.Pull{ 402 { 403 Number: 123, 404 }, 405 }, 406 }, 407 Job: "ci-bar", 408 Type: v1.PresubmitJob, 409 Report: true, 410 }, 411 }, 412 }, 413 }, 414 { 415 name: "one-job-still-running", 416 pj: &v1.ProwJob{ 417 ObjectMeta: metav1.ObjectMeta{ 418 Name: "0", 419 Labels: map[string]string{ 420 kube.ProwJobTypeLabel: "presubmit", 421 kube.OrgLabel: "org", 422 kube.RepoLabel: "repo", 423 kube.PullLabel: "123", 424 }, 425 CreationTimestamp: metav1.Time{ 426 Time: timeNow.Add(-time.Hour), 427 }, 428 }, 429 Status: v1.ProwJobStatus{ 430 State: v1.SuccessState, 431 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 432 }, 433 Spec: v1.ProwJobSpec{ 434 Type: v1.PresubmitJob, 435 Refs: &v1.Refs{ 436 Repo: "foo", 437 Pulls: []v1.Pull{ 438 { 439 Number: 123, 440 }, 441 }, 442 }, 443 Job: "ci-foo", 444 Report: true, 445 }, 446 }, 447 existingPJs: []*v1.ProwJob{ 448 { 449 ObjectMeta: metav1.ObjectMeta{ 450 Name: "1", 451 Labels: map[string]string{ 452 kube.ProwJobTypeLabel: "presubmit", 453 kube.OrgLabel: "org", 454 kube.RepoLabel: "repo", 455 kube.PullLabel: "123", 456 }, 457 CreationTimestamp: metav1.Time{ 458 Time: timeNow.Add(-time.Hour), 459 }, 460 }, 461 Status: v1.ProwJobStatus{ 462 State: v1.FailureState, 463 PrevReportStates: map[string]v1.ProwJobState{ 464 "github-reporter": v1.FailureState, 465 }, 466 }, 467 Spec: v1.ProwJobSpec{ 468 Refs: &v1.Refs{ 469 Repo: "bar", 470 Pulls: []v1.Pull{ 471 { 472 Number: 123, 473 }, 474 }, 475 }, 476 Job: "ci-bar", 477 Type: v1.PresubmitJob, 478 Report: true, 479 }, 480 }, 481 }, 482 }, 483 { 484 name: "mix-of-finished-and-running", 485 pj: &v1.ProwJob{ 486 ObjectMeta: metav1.ObjectMeta{ 487 Name: "0", 488 Labels: map[string]string{ 489 kube.ProwJobTypeLabel: "presubmit", 490 kube.OrgLabel: "org", 491 kube.RepoLabel: "repo", 492 kube.PullLabel: "123", 493 }, 494 CreationTimestamp: metav1.Time{ 495 Time: timeNow.Add(-time.Hour), 496 }, 497 }, 498 Status: v1.ProwJobStatus{ 499 State: v1.SuccessState, 500 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 501 }, 502 Spec: v1.ProwJobSpec{ 503 Type: v1.PresubmitJob, 504 Refs: &v1.Refs{ 505 Repo: "foo", 506 Pulls: []v1.Pull{ 507 { 508 Number: 123, 509 }, 510 }, 511 }, 512 Job: "ci-foo", 513 Report: true, 514 }, 515 }, 516 existingPJs: []*v1.ProwJob{ 517 { 518 ObjectMeta: metav1.ObjectMeta{ 519 Name: "1", 520 Labels: map[string]string{ 521 kube.ProwJobTypeLabel: "presubmit", 522 kube.OrgLabel: "org", 523 kube.RepoLabel: "repo", 524 kube.PullLabel: "123", 525 }, 526 CreationTimestamp: metav1.Time{ 527 Time: timeNow.Add(-time.Hour), 528 }, 529 }, 530 Status: v1.ProwJobStatus{ 531 State: v1.FailureState, 532 PrevReportStates: map[string]v1.ProwJobState{ 533 "github-reporter": v1.FailureState, 534 }, 535 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 536 }, 537 Spec: v1.ProwJobSpec{ 538 Refs: &v1.Refs{ 539 Repo: "bar", 540 Pulls: []v1.Pull{ 541 { 542 Number: 123, 543 }, 544 }, 545 }, 546 Job: "ci-bar", 547 Type: v1.PresubmitJob, 548 Report: true, 549 }, 550 }, 551 { 552 ObjectMeta: metav1.ObjectMeta{ 553 Name: "2", 554 Labels: map[string]string{ 555 kube.ProwJobTypeLabel: "presubmit", 556 kube.OrgLabel: "org", 557 kube.RepoLabel: "repo", 558 kube.PullLabel: "123", 559 }, 560 CreationTimestamp: metav1.Time{ 561 Time: timeNow.Add(-time.Hour), 562 }, 563 }, 564 Status: v1.ProwJobStatus{ 565 State: v1.PendingState, 566 }, 567 Spec: v1.ProwJobSpec{ 568 Refs: &v1.Refs{ 569 Repo: "bar", 570 Pulls: []v1.Pull{ 571 { 572 Number: 123, 573 }, 574 }, 575 }, 576 Job: "ci-baz", 577 Type: v1.PresubmitJob, 578 Report: true, 579 }, 580 }, 581 }, 582 }, 583 { 584 name: "current-job-only", 585 pj: &v1.ProwJob{ 586 ObjectMeta: metav1.ObjectMeta{ 587 Name: "0", 588 Labels: map[string]string{ 589 kube.ProwJobTypeLabel: "presubmit", 590 kube.OrgLabel: "org", 591 kube.RepoLabel: "repo", 592 kube.PullLabel: "123", 593 }, 594 CreationTimestamp: metav1.Time{ 595 Time: timeNow.Add(-time.Hour), 596 }, 597 }, 598 Status: v1.ProwJobStatus{ 599 State: v1.SuccessState, 600 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 601 }, 602 Spec: v1.ProwJobSpec{ 603 Type: v1.PresubmitJob, 604 Refs: &v1.Refs{ 605 Repo: "foo", 606 Pulls: []v1.Pull{ 607 { 608 Number: 123, 609 }, 610 }, 611 }, 612 Job: "ci-foo", 613 Report: true, 614 }, 615 }, 616 wantPjs: []v1.ProwJob{ 617 { 618 ObjectMeta: metav1.ObjectMeta{ 619 Name: "0", 620 Labels: map[string]string{ 621 kube.ProwJobTypeLabel: "presubmit", 622 kube.OrgLabel: "org", 623 kube.RepoLabel: "repo", 624 kube.PullLabel: "123", 625 }, 626 CreationTimestamp: metav1.Time{ 627 Time: timeNow.Add(-time.Hour), 628 }, 629 ResourceVersion: "999", 630 }, 631 Status: v1.ProwJobStatus{ 632 State: v1.SuccessState, 633 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 634 }, 635 Spec: v1.ProwJobSpec{ 636 Type: v1.PresubmitJob, 637 Refs: &v1.Refs{ 638 Repo: "foo", 639 Pulls: []v1.Pull{ 640 { 641 Number: 123, 642 }, 643 }, 644 }, 645 Job: "ci-foo", 646 Report: true, 647 }, 648 }, 649 }, 650 }, 651 { 652 name: "current-job-not-finished", 653 pj: &v1.ProwJob{ 654 ObjectMeta: metav1.ObjectMeta{ 655 Name: "0", 656 Labels: map[string]string{ 657 kube.ProwJobTypeLabel: "presubmit", 658 kube.OrgLabel: "org", 659 kube.RepoLabel: "repo", 660 kube.PullLabel: "123", 661 }, 662 CreationTimestamp: metav1.Time{ 663 Time: timeNow.Add(-time.Hour), 664 }, 665 }, 666 Status: v1.ProwJobStatus{ 667 State: v1.SuccessState, 668 }, 669 Spec: v1.ProwJobSpec{ 670 Type: v1.PresubmitJob, 671 Refs: &v1.Refs{ 672 Repo: "foo", 673 Pulls: []v1.Pull{ 674 { 675 Number: 123, 676 }, 677 }, 678 }, 679 Job: "ci-foo", 680 Report: true, 681 }, 682 }, 683 }, 684 { 685 name: "job-not-same-pr", 686 pj: &v1.ProwJob{ 687 ObjectMeta: metav1.ObjectMeta{ 688 Name: "0", 689 Labels: map[string]string{ 690 kube.ProwJobTypeLabel: "presubmit", 691 kube.OrgLabel: "org", 692 kube.RepoLabel: "repo", 693 kube.PullLabel: "456", 694 }, 695 CreationTimestamp: metav1.Time{ 696 Time: timeNow.Add(-time.Hour), 697 }, 698 }, 699 Status: v1.ProwJobStatus{ 700 State: v1.SuccessState, 701 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 702 }, 703 Spec: v1.ProwJobSpec{ 704 Type: v1.PresubmitJob, 705 Refs: &v1.Refs{ 706 Repo: "foo", 707 Pulls: []v1.Pull{ 708 { 709 Number: 123, 710 }, 711 }, 712 }, 713 Job: "ci-foo", 714 Report: true, 715 }, 716 }, 717 existingPJs: []*v1.ProwJob{ 718 { 719 ObjectMeta: metav1.ObjectMeta{ 720 Name: "1", 721 Labels: map[string]string{ 722 kube.ProwJobTypeLabel: "presubmit", 723 kube.OrgLabel: "org", 724 kube.RepoLabel: "repo", 725 kube.PullLabel: "123", 726 }, 727 CreationTimestamp: metav1.Time{ 728 Time: timeNow.Add(-time.Hour), 729 }, 730 }, 731 Status: v1.ProwJobStatus{ 732 State: v1.FailureState, 733 PrevReportStates: map[string]v1.ProwJobState{ 734 "github-reporter": v1.FailureState, 735 }, 736 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 737 }, 738 Spec: v1.ProwJobSpec{ 739 Refs: &v1.Refs{ 740 Repo: "bar", 741 Pulls: []v1.Pull{ 742 { 743 Number: 123, 744 }, 745 }, 746 }, 747 Job: "ci-bar", 748 Type: v1.PresubmitJob, 749 Report: true, 750 }, 751 }, 752 }, 753 wantPjs: []v1.ProwJob{ 754 { 755 ObjectMeta: metav1.ObjectMeta{ 756 Name: "0", 757 Labels: map[string]string{ 758 kube.ProwJobTypeLabel: "presubmit", 759 kube.OrgLabel: "org", 760 kube.RepoLabel: "repo", 761 kube.PullLabel: "456", 762 }, 763 CreationTimestamp: metav1.Time{ 764 Time: timeNow.Add(-time.Hour), 765 }, 766 ResourceVersion: "999", 767 }, 768 Status: v1.ProwJobStatus{ 769 State: v1.SuccessState, 770 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 771 }, 772 Spec: v1.ProwJobSpec{ 773 Type: v1.PresubmitJob, 774 Refs: &v1.Refs{ 775 Repo: "foo", 776 Pulls: []v1.Pull{ 777 { 778 Number: 123, 779 }, 780 }, 781 }, 782 Job: "ci-foo", 783 Report: true, 784 }, 785 }, 786 }, 787 }, 788 { 789 name: "job-not-same-org", 790 pj: &v1.ProwJob{ 791 ObjectMeta: metav1.ObjectMeta{ 792 Name: "0", 793 Labels: map[string]string{ 794 kube.ProwJobTypeLabel: "presubmit", 795 kube.OrgLabel: "org-different", 796 kube.RepoLabel: "repo", 797 kube.PullLabel: "123", 798 }, 799 CreationTimestamp: metav1.Time{ 800 Time: timeNow.Add(-time.Hour), 801 }, 802 }, 803 Status: v1.ProwJobStatus{ 804 State: v1.SuccessState, 805 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 806 }, 807 Spec: v1.ProwJobSpec{ 808 Type: v1.PresubmitJob, 809 Refs: &v1.Refs{ 810 Repo: "foo", 811 Pulls: []v1.Pull{ 812 { 813 Number: 123, 814 }, 815 }, 816 }, 817 Job: "ci-foo", 818 Report: true, 819 }, 820 }, 821 existingPJs: []*v1.ProwJob{ 822 { 823 ObjectMeta: metav1.ObjectMeta{ 824 Name: "1", 825 Labels: map[string]string{ 826 kube.ProwJobTypeLabel: "presubmit", 827 kube.OrgLabel: "org", 828 kube.RepoLabel: "repo", 829 kube.PullLabel: "123", 830 }, 831 CreationTimestamp: metav1.Time{ 832 Time: timeNow.Add(-time.Hour), 833 }, 834 }, 835 Status: v1.ProwJobStatus{ 836 State: v1.FailureState, 837 PrevReportStates: map[string]v1.ProwJobState{ 838 "github-reporter": v1.FailureState, 839 }, 840 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 841 }, 842 Spec: v1.ProwJobSpec{ 843 Refs: &v1.Refs{ 844 Repo: "bar", 845 Pulls: []v1.Pull{ 846 { 847 Number: 123, 848 }, 849 }, 850 }, 851 Job: "ci-bar", 852 Type: v1.PresubmitJob, 853 Report: true, 854 }, 855 }, 856 }, 857 wantPjs: []v1.ProwJob{ 858 { 859 ObjectMeta: metav1.ObjectMeta{ 860 Name: "0", 861 Labels: map[string]string{ 862 kube.ProwJobTypeLabel: "presubmit", 863 kube.OrgLabel: "org-different", 864 kube.RepoLabel: "repo", 865 kube.PullLabel: "123", 866 }, 867 CreationTimestamp: metav1.Time{ 868 Time: timeNow.Add(-time.Hour), 869 }, 870 ResourceVersion: "999", 871 }, 872 Status: v1.ProwJobStatus{ 873 State: v1.SuccessState, 874 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 875 }, 876 Spec: v1.ProwJobSpec{ 877 Type: v1.PresubmitJob, 878 Refs: &v1.Refs{ 879 Repo: "foo", 880 Pulls: []v1.Pull{ 881 { 882 Number: 123, 883 }, 884 }, 885 }, 886 Job: "ci-foo", 887 Report: true, 888 }, 889 }, 890 }, 891 }, 892 { 893 name: "job-not-same-pr", 894 pj: &v1.ProwJob{ 895 ObjectMeta: metav1.ObjectMeta{ 896 Name: "0", 897 Labels: map[string]string{ 898 kube.ProwJobTypeLabel: "presubmit", 899 kube.OrgLabel: "org", 900 kube.RepoLabel: "repo-different", 901 kube.PullLabel: "123", 902 }, 903 CreationTimestamp: metav1.Time{ 904 Time: timeNow.Add(-time.Hour), 905 }, 906 }, 907 Status: v1.ProwJobStatus{ 908 State: v1.SuccessState, 909 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 910 }, 911 Spec: v1.ProwJobSpec{ 912 Type: v1.PresubmitJob, 913 Refs: &v1.Refs{ 914 Repo: "foo", 915 Pulls: []v1.Pull{ 916 { 917 Number: 123, 918 }, 919 }, 920 }, 921 Job: "ci-foo", 922 Report: true, 923 }, 924 }, 925 existingPJs: []*v1.ProwJob{ 926 { 927 ObjectMeta: metav1.ObjectMeta{ 928 Name: "1", 929 Labels: map[string]string{ 930 kube.ProwJobTypeLabel: "presubmit", 931 kube.OrgLabel: "org", 932 kube.RepoLabel: "repo", 933 kube.PullLabel: "123", 934 }, 935 CreationTimestamp: metav1.Time{ 936 Time: timeNow.Add(-time.Hour), 937 }, 938 }, 939 Status: v1.ProwJobStatus{ 940 State: v1.FailureState, 941 PrevReportStates: map[string]v1.ProwJobState{ 942 "github-reporter": v1.FailureState, 943 }, 944 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 945 }, 946 Spec: v1.ProwJobSpec{ 947 Refs: &v1.Refs{ 948 Repo: "bar", 949 Pulls: []v1.Pull{ 950 { 951 Number: 123, 952 }, 953 }, 954 }, 955 Job: "ci-bar", 956 Type: v1.PresubmitJob, 957 Report: true, 958 }, 959 }, 960 }, 961 wantPjs: []v1.ProwJob{ 962 { 963 ObjectMeta: metav1.ObjectMeta{ 964 Name: "0", 965 Labels: map[string]string{ 966 kube.ProwJobTypeLabel: "presubmit", 967 kube.OrgLabel: "org", 968 kube.RepoLabel: "repo-different", 969 kube.PullLabel: "123", 970 }, 971 CreationTimestamp: metav1.Time{ 972 Time: timeNow.Add(-time.Hour), 973 }, 974 ResourceVersion: "999", 975 }, 976 Status: v1.ProwJobStatus{ 977 State: v1.SuccessState, 978 CompletionTime: &metav1.Time{Time: timeNow.Add(-time.Minute)}, 979 }, 980 Spec: v1.ProwJobSpec{ 981 Type: v1.PresubmitJob, 982 Refs: &v1.Refs{ 983 Repo: "foo", 984 Pulls: []v1.Pull{ 985 { 986 Number: 123, 987 }, 988 }, 989 }, 990 Job: "ci-foo", 991 Report: true, 992 }, 993 }, 994 }, 995 }, 996 } 997 998 for _, tc := range testcases { 999 t.Run(tc.name, func(t *testing.T) { 1000 builder := fakectrlruntimeclient.NewClientBuilder().WithObjects(tc.pj) 1001 for _, pj := range tc.existingPJs { 1002 builder.WithObjects(pj) 1003 } 1004 1005 lister := builder.Build() 1006 1007 gotPjs, gotErr := pjsToReport(context.Background(), &logrus.Entry{}, lister, tc.pj) 1008 if (gotErr != nil && !tc.wantErr) || (gotErr == nil && tc.wantErr) { 1009 t.Fatalf("error mismatch. got: %v, want: %v", gotErr, tc.wantErr) 1010 } 1011 if diff := cmp.Diff(tc.wantPjs, gotPjs, cmpopts.SortSlices(func(a, b v1.ProwJob) bool { 1012 return a.Name > b.Name 1013 })); diff != "" { 1014 t.Fatalf("pjs mismatch. got(+), want(-):\n%s", diff) 1015 } 1016 }) 1017 } 1018 }