sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/apis/prowjobs/v1/types_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 v1 18 19 import ( 20 "reflect" 21 "strconv" 22 "testing" 23 "time" 24 25 "github.com/google/go-cmp/cmp" 26 "github.com/google/go-cmp/cmp/cmpopts" 27 fuzz "github.com/google/gofuzz" 28 pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" 29 ) 30 31 func pStr(str string) *string { 32 return &str 33 } 34 35 // TODO(mpherman): Add more tests when ProwJobDefaults have more than 1 field 36 func TestProwJobDefaulting(t *testing.T) { 37 var testCases = []struct { 38 name string 39 provided *ProwJobDefault 40 def *ProwJobDefault 41 expected *ProwJobDefault 42 }{ 43 { 44 name: "nothing provided", 45 provided: &ProwJobDefault{}, 46 def: &ProwJobDefault{}, 47 expected: &ProwJobDefault{}, 48 }, 49 { 50 name: "All provided, no default", 51 provided: &ProwJobDefault{ 52 ResultStoreConfig: &ResultStoreConfig{ 53 ProjectID: "project", 54 }, 55 TenantID: "tenant", 56 }, 57 def: &ProwJobDefault{}, 58 expected: &ProwJobDefault{ 59 ResultStoreConfig: &ResultStoreConfig{ 60 ProjectID: "project", 61 }, 62 TenantID: "tenant", 63 }, 64 }, 65 { 66 name: "All provided, no override", 67 provided: &ProwJobDefault{ 68 ResultStoreConfig: &ResultStoreConfig{ 69 ProjectID: "project", 70 }, 71 TenantID: "tenant", 72 }, 73 def: &ProwJobDefault{ 74 ResultStoreConfig: &ResultStoreConfig{ 75 ProjectID: "default-project", 76 }, 77 TenantID: "default-tenant", 78 }, 79 expected: &ProwJobDefault{ 80 ResultStoreConfig: &ResultStoreConfig{ 81 ProjectID: "project", 82 }, 83 TenantID: "tenant", 84 }, 85 }, 86 { 87 name: "Empty provided, no default", 88 provided: &ProwJobDefault{}, 89 def: &ProwJobDefault{}, 90 expected: &ProwJobDefault{}, 91 }, 92 { 93 name: "Empty provided, use default", 94 provided: &ProwJobDefault{}, 95 def: &ProwJobDefault{ 96 ResultStoreConfig: &ResultStoreConfig{ 97 ProjectID: "default-project", 98 }, 99 TenantID: "default-tenant", 100 }, 101 expected: &ProwJobDefault{ 102 ResultStoreConfig: &ResultStoreConfig{ 103 ProjectID: "default-project", 104 }, 105 TenantID: "default-tenant", 106 }, 107 }, 108 { 109 name: "Nil provided, empty default", 110 provided: nil, 111 def: &ProwJobDefault{}, 112 expected: &ProwJobDefault{}, 113 }, 114 { 115 name: "Nil provided, use default", 116 provided: nil, 117 def: &ProwJobDefault{ 118 ResultStoreConfig: &ResultStoreConfig{ 119 ProjectID: "default-project", 120 }, 121 TenantID: "default-tenant", 122 }, 123 expected: &ProwJobDefault{ 124 ResultStoreConfig: &ResultStoreConfig{ 125 ProjectID: "default-project", 126 }, 127 TenantID: "default-tenant", 128 }, 129 }, 130 { 131 name: "Nil provided, nil default", 132 provided: nil, 133 def: nil, 134 expected: nil, 135 }, 136 { 137 name: "This provided, that default", 138 provided: &ProwJobDefault{ 139 ResultStoreConfig: &ResultStoreConfig{ 140 ProjectID: "project", 141 }, 142 }, 143 def: &ProwJobDefault{ 144 TenantID: "default-tenant", 145 }, 146 expected: &ProwJobDefault{ 147 ResultStoreConfig: &ResultStoreConfig{ 148 ProjectID: "project", 149 }, 150 TenantID: "default-tenant", 151 }, 152 }, 153 } 154 for _, testCase := range testCases { 155 tc := testCase 156 t.Run(tc.name, func(t *testing.T) { 157 t.Parallel() 158 actual := tc.provided.ApplyDefault(tc.def) 159 if diff := cmp.Diff(actual, tc.expected, cmpopts.EquateEmpty()); diff != "" { 160 t.Errorf("expected defaulted config but got diff %v", diff) 161 } 162 }) 163 } 164 } 165 166 func TestDecorationDefaultingDoesntOverwrite(t *testing.T) { 167 truth := true 168 lies := false 169 170 var testCases = []struct { 171 name string 172 provided *DecorationConfig 173 // Note: def is a copy of the defaults and may be modified. 174 expected func(orig, def *DecorationConfig) *DecorationConfig 175 }{ 176 { 177 name: "nothing provided", 178 provided: &DecorationConfig{}, 179 expected: func(orig, def *DecorationConfig) *DecorationConfig { 180 return def 181 }, 182 }, 183 { 184 name: "timeout provided", 185 provided: &DecorationConfig{ 186 Timeout: &Duration{Duration: 10 * time.Minute}, 187 }, 188 expected: func(orig, def *DecorationConfig) *DecorationConfig { 189 def.Timeout = orig.Timeout 190 return def 191 }, 192 }, 193 { 194 name: "grace period provided", 195 provided: &DecorationConfig{ 196 GracePeriod: &Duration{Duration: 10 * time.Hour}, 197 }, 198 expected: func(orig, def *DecorationConfig) *DecorationConfig { 199 def.GracePeriod = orig.GracePeriod 200 return def 201 }, 202 }, 203 { 204 name: "utility images provided", 205 provided: &DecorationConfig{ 206 UtilityImages: &UtilityImages{ 207 CloneRefs: "clonerefs-special", 208 InitUpload: "initupload-special", 209 Entrypoint: "entrypoint-special", 210 Sidecar: "sidecar-special", 211 }, 212 }, 213 expected: func(orig, def *DecorationConfig) *DecorationConfig { 214 def.UtilityImages = orig.UtilityImages 215 return def 216 }, 217 }, 218 { 219 name: "gcs configuration provided", 220 provided: &DecorationConfig{ 221 GCSConfiguration: &GCSConfiguration{ 222 Bucket: "bucket-1", 223 PathPrefix: "prefix-2", 224 PathStrategy: PathStrategyExplicit, 225 DefaultOrg: "org2", 226 DefaultRepo: "repo2", 227 CompressFileTypes: []string{"txt", "json"}, 228 }, 229 }, 230 expected: func(orig, def *DecorationConfig) *DecorationConfig { 231 def.GCSConfiguration = orig.GCSConfiguration 232 return def 233 }, 234 }, 235 { 236 name: "gcs secret name provided", 237 provided: &DecorationConfig{ 238 GCSCredentialsSecret: pStr("somethingSecret"), 239 }, 240 expected: func(orig, def *DecorationConfig) *DecorationConfig { 241 def.GCSCredentialsSecret = orig.GCSCredentialsSecret 242 return def 243 }, 244 }, 245 { 246 name: "gcs secret name unset", 247 provided: &DecorationConfig{ 248 GCSCredentialsSecret: pStr(""), 249 }, 250 expected: func(orig, def *DecorationConfig) *DecorationConfig { 251 def.GCSCredentialsSecret = orig.GCSCredentialsSecret 252 return def 253 }, 254 }, 255 { 256 name: "s3 secret name provided", 257 provided: &DecorationConfig{ 258 S3CredentialsSecret: pStr("overwritten"), 259 }, 260 expected: func(orig, def *DecorationConfig) *DecorationConfig { 261 def.S3CredentialsSecret = orig.S3CredentialsSecret 262 return def 263 }, 264 }, 265 { 266 name: "s3 secret name unset", 267 provided: &DecorationConfig{ 268 S3CredentialsSecret: pStr(""), 269 }, 270 expected: func(orig, def *DecorationConfig) *DecorationConfig { 271 def.S3CredentialsSecret = orig.S3CredentialsSecret 272 return def 273 }, 274 }, 275 { 276 name: "default service account name provided", 277 provided: &DecorationConfig{ 278 DefaultServiceAccountName: pStr("gcs-upload-sa"), 279 }, 280 expected: func(orig, def *DecorationConfig) *DecorationConfig { 281 def.DefaultServiceAccountName = orig.DefaultServiceAccountName 282 return def 283 }, 284 }, 285 { 286 name: "ssh secrets provided", 287 provided: &DecorationConfig{ 288 SSHKeySecrets: []string{"my", "special"}, 289 }, 290 expected: func(orig, def *DecorationConfig) *DecorationConfig { 291 def.SSHKeySecrets = orig.SSHKeySecrets 292 return def 293 }, 294 }, 295 296 { 297 name: "utility images partially provided", 298 provided: &DecorationConfig{ 299 UtilityImages: &UtilityImages{ 300 CloneRefs: "clonerefs-special", 301 InitUpload: "initupload-special", 302 }, 303 }, 304 expected: func(orig, def *DecorationConfig) *DecorationConfig { 305 def.UtilityImages.CloneRefs = orig.UtilityImages.CloneRefs 306 def.UtilityImages.InitUpload = orig.UtilityImages.InitUpload 307 return def 308 }, 309 }, 310 { 311 name: "gcs configuration partially provided", 312 provided: &DecorationConfig{ 313 GCSConfiguration: &GCSConfiguration{ 314 Bucket: "bucket-1", 315 }, 316 }, 317 expected: func(orig, def *DecorationConfig) *DecorationConfig { 318 def.GCSConfiguration.Bucket = orig.GCSConfiguration.Bucket 319 return def 320 }, 321 }, 322 { 323 name: "skip_cloning provided", 324 provided: &DecorationConfig{ 325 SkipCloning: &lies, 326 }, 327 expected: func(orig, def *DecorationConfig) *DecorationConfig { 328 def.SkipCloning = orig.SkipCloning 329 return def 330 }, 331 }, 332 { 333 name: "ssh host fingerprints provided", 334 provided: &DecorationConfig{ 335 SSHHostFingerprints: []string{"unique", "print"}, 336 }, 337 expected: func(orig, def *DecorationConfig) *DecorationConfig { 338 def.SSHHostFingerprints = orig.SSHHostFingerprints 339 return def 340 }, 341 }, 342 { 343 name: "ingnore interrupts set", 344 provided: &DecorationConfig{ 345 UploadIgnoresInterrupts: &truth, 346 }, 347 expected: func(orig, def *DecorationConfig) *DecorationConfig { 348 def.UploadIgnoresInterrupts = orig.UploadIgnoresInterrupts 349 return def 350 }, 351 }, 352 { 353 name: "do not ingnore interrupts ", 354 provided: &DecorationConfig{ 355 UploadIgnoresInterrupts: &lies, 356 }, 357 expected: func(orig, def *DecorationConfig) *DecorationConfig { 358 def.UploadIgnoresInterrupts = orig.UploadIgnoresInterrupts 359 return def 360 }, 361 }, 362 } 363 364 for _, testCase := range testCases { 365 tc := testCase 366 t.Run(tc.name, func(t *testing.T) { 367 t.Parallel() 368 defaults := &DecorationConfig{ 369 Timeout: &Duration{Duration: 1 * time.Minute}, 370 GracePeriod: &Duration{Duration: 10 * time.Second}, 371 UtilityImages: &UtilityImages{ 372 CloneRefs: "clonerefs", 373 InitUpload: "initupload", 374 Entrypoint: "entrypoint", 375 Sidecar: "sidecar", 376 }, 377 GCSConfiguration: &GCSConfiguration{ 378 Bucket: "bucket", 379 PathPrefix: "prefix", 380 PathStrategy: PathStrategyLegacy, 381 DefaultOrg: "org", 382 DefaultRepo: "repo", 383 }, 384 GCSCredentialsSecret: pStr("secretName"), 385 S3CredentialsSecret: pStr("s3-secret"), 386 SSHKeySecrets: []string{"first", "second"}, 387 SSHHostFingerprints: []string{"primero", "segundo"}, 388 SkipCloning: &truth, 389 } 390 391 expected := tc.expected(tc.provided, defaults) 392 actual := tc.provided.ApplyDefault(defaults) 393 if diff := cmp.Diff(actual, expected, cmpopts.EquateEmpty()); diff != "" { 394 t.Errorf("expected defaulted config but got diff %v", diff) 395 } 396 }) 397 } 398 } 399 400 func TestApplyDefaultsAppliesDefaultsForAllFields(t *testing.T) { 401 t.Parallel() 402 seed := time.Now().UnixNano() 403 // Print the seed so failures can easily be reproduced 404 t.Logf("Seed: %d", seed) 405 fuzzer := fuzz.NewWithSeed(seed) 406 for i := 0; i < 100; i++ { 407 t.Run(strconv.Itoa(i), func(t *testing.T) { 408 def := &DecorationConfig{} 409 fuzzer.Fuzz(def) 410 411 // Each of those three has its own DeepCopy and in case it is nil, 412 // we just call that and return. In order to make this test verify 413 // that copying of their fields also works, we have to set them to 414 // something non-nil. 415 toDefault := &DecorationConfig{ 416 UtilityImages: &UtilityImages{}, 417 Resources: &Resources{}, 418 GCSConfiguration: &GCSConfiguration{}, 419 } 420 if def.UtilityImages == nil { 421 def.UtilityImages = &UtilityImages{} 422 } 423 if def.Resources == nil { 424 def.Resources = &Resources{} 425 } 426 if def.GCSConfiguration == nil { 427 def.GCSConfiguration = &GCSConfiguration{} 428 } 429 defaulted := toDefault.ApplyDefault(def) 430 431 if diff := cmp.Diff(def, defaulted); diff != "" { 432 t.Errorf("defaulted decoration config didn't get all fields defaulted: %s", diff) 433 } 434 }) 435 } 436 } 437 438 func TestSlackConfigApplyDefaultsAppliesDefaultsForAllFields(t *testing.T) { 439 t.Parallel() 440 seed := time.Now().UnixNano() 441 // Print the seed so failures can easily be reproduced 442 t.Logf("Seed: %d", seed) 443 fuzzer := fuzz.NewWithSeed(seed) 444 for i := 0; i < 100; i++ { 445 t.Run(strconv.Itoa(i), func(t *testing.T) { 446 def := &SlackReporterConfig{} 447 fuzzer.Fuzz(def) 448 449 // Each of those three has its own DeepCopy and in case it is nil, 450 // we just call that and return. In order to make this test verify 451 // that copying of their fields also works, we have to set them to 452 // something non-nil. 453 toDefault := &SlackReporterConfig{ 454 Host: "", 455 Channel: "", 456 JobStatesToReport: nil, 457 ReportTemplate: "", 458 } 459 defaulted := toDefault.ApplyDefault(def) 460 461 if diff := cmp.Diff(def, defaulted); diff != "" { 462 t.Errorf("defaulted decoration config didn't get all fields defaulted: %s", diff) 463 } 464 }) 465 } 466 } 467 468 func TestRefsToString(t *testing.T) { 469 var tests = []struct { 470 name string 471 ref Refs 472 expected string 473 }{ 474 { 475 name: "Refs with Pull", 476 ref: Refs{ 477 BaseRef: "master", 478 BaseSHA: "deadbeef", 479 Pulls: []Pull{ 480 { 481 Number: 123, 482 SHA: "abcd1234", 483 }, 484 }, 485 }, 486 expected: "master:deadbeef,123:abcd1234", 487 }, 488 { 489 name: "Refs with multiple Pulls", 490 ref: Refs{ 491 BaseRef: "master", 492 BaseSHA: "deadbeef", 493 Pulls: []Pull{ 494 { 495 Number: 123, 496 SHA: "abcd1234", 497 }, 498 { 499 Number: 456, 500 SHA: "dcba4321", 501 }, 502 }, 503 }, 504 expected: "master:deadbeef,123:abcd1234,456:dcba4321", 505 }, 506 { 507 name: "Refs with BaseRef only", 508 ref: Refs{ 509 BaseRef: "master", 510 }, 511 expected: "master", 512 }, 513 { 514 name: "Refs with BaseRef and BaseSHA", 515 ref: Refs{ 516 BaseRef: "master", 517 BaseSHA: "deadbeef", 518 }, 519 expected: "master:deadbeef", 520 }, 521 } 522 523 for _, test := range tests { 524 actual, expected := test.ref.String(), test.expected 525 if actual != expected { 526 t.Errorf("%s: got ref string: %s, but expected: %s", test.name, actual, expected) 527 } 528 } 529 } 530 531 func TestRerunAuthConfigValidate(t *testing.T) { 532 var testCases = []struct { 533 name string 534 config *RerunAuthConfig 535 errExpected bool 536 }{ 537 { 538 name: "disallow all", 539 config: &RerunAuthConfig{AllowAnyone: false}, 540 errExpected: false, 541 }, 542 { 543 name: "no restrictions", 544 config: &RerunAuthConfig{}, 545 errExpected: false, 546 }, 547 { 548 name: "allow any", 549 config: &RerunAuthConfig{AllowAnyone: true}, 550 errExpected: false, 551 }, 552 { 553 name: "restrict orgs", 554 config: &RerunAuthConfig{GitHubOrgs: []string{"istio"}}, 555 errExpected: false, 556 }, 557 { 558 name: "restrict orgs and users", 559 config: &RerunAuthConfig{GitHubOrgs: []string{"istio", "kubernetes"}, GitHubUsers: []string{"clarketm", "scoobydoo"}}, 560 errExpected: false, 561 }, 562 { 563 name: "allow any and has restriction", 564 config: &RerunAuthConfig{AllowAnyone: true, GitHubOrgs: []string{"istio"}}, 565 errExpected: true, 566 }, 567 } 568 569 for _, tc := range testCases { 570 t.Run(tc.name, func(t *testing.T) { 571 572 if err := tc.config.Validate(); (err != nil) != tc.errExpected { 573 t.Errorf("Expected error %v, got %v", tc.errExpected, err) 574 } 575 }) 576 } 577 } 578 579 func TestRerunAuthConfigIsAuthorized(t *testing.T) { 580 var testCases = []struct { 581 name string 582 user string 583 config *RerunAuthConfig 584 authorized bool 585 }{ 586 { 587 name: "authorized - AllowAnyone is true", 588 user: "gumby", 589 config: &RerunAuthConfig{AllowAnyone: true}, 590 authorized: true, 591 }, 592 { 593 name: "authorized - user in GitHubUsers", 594 user: "gumby", 595 config: &RerunAuthConfig{GitHubUsers: []string{"gumby"}}, 596 authorized: true, 597 }, 598 { 599 name: "unauthorized - RerunAuthConfig is nil", 600 user: "gumby", 601 config: nil, 602 authorized: false, 603 }, 604 { 605 name: "unauthorized - cli is nil", 606 user: "gumby", 607 config: &RerunAuthConfig{}, 608 authorized: false, 609 }, 610 } 611 612 for _, tc := range testCases { 613 t.Run(tc.name, func(t *testing.T) { 614 615 if actual, _ := tc.config.IsAuthorized("", tc.user, nil); actual != tc.authorized { 616 t.Errorf("Expected %v, got %v", tc.authorized, actual) 617 } 618 }) 619 } 620 } 621 622 func TestRerunAuthConfigIsAllowAnyone(t *testing.T) { 623 var testCases = []struct { 624 name string 625 config *RerunAuthConfig 626 expected bool 627 }{ 628 { 629 name: "AllowAnyone is true", 630 config: &RerunAuthConfig{AllowAnyone: true}, 631 expected: true, 632 }, 633 { 634 name: "AllowAnyone is false", 635 config: &RerunAuthConfig{AllowAnyone: false}, 636 expected: false, 637 }, 638 { 639 name: "AllowAnyone is unset", 640 config: &RerunAuthConfig{}, 641 expected: false, 642 }, 643 { 644 name: "RerunAuthConfig is nil", 645 config: nil, 646 expected: false, 647 }, 648 } 649 650 for _, tc := range testCases { 651 t.Run(tc.name, func(t *testing.T) { 652 653 if actual := tc.config.IsAllowAnyone(); actual != tc.expected { 654 t.Errorf("Expected %v, got %v", tc.expected, actual) 655 } 656 }) 657 } 658 } 659 660 func TestParsePath(t *testing.T) { 661 type args struct { 662 bucket string 663 } 664 tests := []struct { 665 name string 666 args args 667 wantStorageProvider string 668 wantBucket string 669 wantFullPath string 670 wantPath string 671 wantErr string 672 }{ 673 { 674 name: "valid gcs bucket", 675 args: args{ 676 bucket: "prow-artifacts", 677 }, 678 wantStorageProvider: "gs", 679 wantBucket: "prow-artifacts", 680 wantFullPath: "prow-artifacts", 681 wantPath: "", 682 }, 683 { 684 name: "valid gcs bucket with storage provider prefix", 685 args: args{ 686 bucket: "gs://prow-artifacts", 687 }, 688 wantStorageProvider: "gs", 689 wantBucket: "prow-artifacts", 690 wantFullPath: "prow-artifacts", 691 wantPath: "", 692 }, 693 { 694 name: "valid gcs bucket with multiple separator with storage provider prefix", 695 args: args{ 696 bucket: "gs://my-floppy-backup/a://doom2.wad.006", 697 }, 698 wantStorageProvider: "gs", 699 wantBucket: "my-floppy-backup", 700 wantFullPath: "my-floppy-backup/a://doom2.wad.006", 701 wantPath: "/a://doom2.wad.006", 702 }, 703 { 704 name: "valid s3 bucket with storage provider prefix", 705 args: args{ 706 bucket: "s3://prow-artifacts", 707 }, 708 wantStorageProvider: "s3", 709 wantBucket: "prow-artifacts", 710 wantFullPath: "prow-artifacts", 711 wantPath: "", 712 }, 713 } 714 for _, tt := range tests { 715 t.Run(tt.name, func(t *testing.T) { 716 prowPath, err := ParsePath(tt.args.bucket) 717 var gotErr string 718 if err != nil { 719 gotErr = err.Error() 720 } 721 if gotErr != tt.wantErr { 722 t.Errorf("ParsePath() error = %v, wantErr %v", err, tt.wantErr) 723 return 724 } 725 if prowPath.StorageProvider() != tt.wantStorageProvider { 726 t.Errorf("ParsePath() gotStorageProvider = %v, wantStorageProvider %v", prowPath.StorageProvider(), tt.wantStorageProvider) 727 } 728 if got, want := prowPath.Bucket(), tt.wantBucket; got != want { 729 t.Errorf("ParsePath() gotBucket = %v, wantBucket %v", got, want) 730 } 731 if got, want := prowPath.FullPath(), tt.wantFullPath; got != want { 732 t.Errorf("ParsePath() gotFullPath = %v, wantFullPath %v", got, want) 733 } 734 if got, want := prowPath.Path, tt.wantPath; got != want { 735 t.Errorf("ParsePath() gotPath = %v, wantPath %v", got, want) 736 } 737 }) 738 } 739 } 740 741 func TestProwJobSpec_HasPipelineRunSpec(t *testing.T) { 742 type fields struct { 743 PipelineRunSpec *pipelinev1beta1.PipelineRunSpec 744 TektonPipelineRunSpec *TektonPipelineRunSpec 745 } 746 tests := []struct { 747 name string 748 fields fields 749 want bool 750 }{{ 751 name: "none set", 752 want: false, 753 }, { 754 name: "PipelineRunSpec set", 755 fields: fields{ 756 PipelineRunSpec: &pipelinev1beta1.PipelineRunSpec{}, 757 }, 758 want: true, 759 }, { 760 name: "TektonPipelineRunSpec set", 761 fields: fields{ 762 TektonPipelineRunSpec: &TektonPipelineRunSpec{}, 763 }, 764 want: false, 765 }, { 766 name: "TektonPipelineRunSpec.V1VBeta1 set", 767 fields: fields{ 768 TektonPipelineRunSpec: &TektonPipelineRunSpec{ 769 V1Beta1: &pipelinev1beta1.PipelineRunSpec{}, 770 }, 771 }, 772 want: true, 773 }, { 774 name: "both set", 775 fields: fields{ 776 PipelineRunSpec: &pipelinev1beta1.PipelineRunSpec{}, 777 TektonPipelineRunSpec: &TektonPipelineRunSpec{ 778 V1Beta1: &pipelinev1beta1.PipelineRunSpec{}, 779 }, 780 }, 781 want: true, 782 }} 783 for _, tt := range tests { 784 t.Run(tt.name, func(t *testing.T) { 785 pjs := ProwJobSpec{ 786 PipelineRunSpec: tt.fields.PipelineRunSpec, 787 TektonPipelineRunSpec: tt.fields.TektonPipelineRunSpec, 788 } 789 if got := pjs.HasPipelineRunSpec(); got != tt.want { 790 t.Errorf("ProwJobSpec.HasPipelineRunSpec() = %v, want %v", got, tt.want) 791 } 792 }) 793 } 794 } 795 796 func TestProwJobSpec_GetPipelineRunSpec(t *testing.T) { 797 type fields struct { 798 PipelineRunSpec *pipelinev1beta1.PipelineRunSpec 799 TektonPipelineRunSpec *TektonPipelineRunSpec 800 } 801 tests := []struct { 802 name string 803 fields fields 804 want *pipelinev1beta1.PipelineRunSpec 805 wantErr bool 806 }{ 807 { 808 name: "none set", 809 fields: fields{ 810 PipelineRunSpec: nil, 811 TektonPipelineRunSpec: nil, 812 }, 813 wantErr: true, 814 }, 815 { 816 name: "only PipelineRunSpec set", 817 fields: fields{ 818 PipelineRunSpec: &pipelinev1beta1.PipelineRunSpec{ 819 ServiceAccountName: "robot", 820 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 821 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "abc"}}}, 822 }, 823 }, 824 TektonPipelineRunSpec: nil, 825 }, 826 want: &pipelinev1beta1.PipelineRunSpec{ 827 ServiceAccountName: "robot", 828 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 829 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "abc"}}}, 830 }, 831 }, 832 }, 833 { 834 name: "only TektonPipelineRunSpec set", 835 fields: fields{ 836 PipelineRunSpec: nil, 837 TektonPipelineRunSpec: &TektonPipelineRunSpec{ 838 V1Beta1: &pipelinev1beta1.PipelineRunSpec{ 839 ServiceAccountName: "robot", 840 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 841 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "abc"}}}, 842 }, 843 }, 844 }, 845 }, 846 want: &pipelinev1beta1.PipelineRunSpec{ 847 ServiceAccountName: "robot", 848 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 849 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "abc"}}}, 850 }, 851 }, 852 }, 853 { 854 name: "PipelineRunSpec and TektonPipelineRunSpec set", 855 fields: fields{ 856 PipelineRunSpec: &pipelinev1beta1.PipelineRunSpec{ 857 ServiceAccountName: "robot", 858 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 859 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "abc"}}}, 860 }, 861 }, 862 TektonPipelineRunSpec: &TektonPipelineRunSpec{ 863 V1Beta1: &pipelinev1beta1.PipelineRunSpec{ 864 ServiceAccountName: "robot", 865 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 866 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "def"}}}, 867 }, 868 }, 869 }, 870 }, 871 want: &pipelinev1beta1.PipelineRunSpec{ 872 ServiceAccountName: "robot", 873 PipelineSpec: &pipelinev1beta1.PipelineSpec{ 874 Tasks: []pipelinev1beta1.PipelineTask{{Name: "implicit git resource", TaskRef: &pipelinev1beta1.TaskRef{Name: "def"}}}, 875 }, 876 }, 877 }, 878 } 879 for _, tt := range tests { 880 t.Run(tt.name, func(t *testing.T) { 881 pjs := ProwJobSpec{ 882 PipelineRunSpec: tt.fields.PipelineRunSpec, 883 TektonPipelineRunSpec: tt.fields.TektonPipelineRunSpec, 884 } 885 got, err := pjs.GetPipelineRunSpec() 886 if (err != nil) != tt.wantErr { 887 t.Errorf("ProwJobSpec.GetPipelineRunSpec() error = %v, wantErr %v", err, tt.wantErr) 888 return 889 } 890 if !reflect.DeepEqual(got, tt.want) { 891 t.Errorf("ProwJobSpec.GetPipelineRunSpec() = %v, want %v", got, tt.want) 892 } 893 }) 894 } 895 }