github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/deck/jobs/jobs_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 jobs 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "sort" 24 "testing" 25 "time" 26 27 "github.com/google/go-cmp/cmp" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 "k8s.io/apimachinery/pkg/labels" 30 "k8s.io/apimachinery/pkg/runtime" 31 "k8s.io/apimachinery/pkg/util/sets" 32 ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client" 33 fakectrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" 34 35 prowapi "sigs.k8s.io/prow/pkg/apis/prowjobs/v1" 36 "sigs.k8s.io/prow/pkg/config" 37 "sigs.k8s.io/prow/pkg/kube" 38 ) 39 40 func createTime(layout string, timeString string) metav1.Time { 41 t, _ := time.Parse(layout, timeString) 42 return metav1.NewTime(t) 43 } 44 45 type fkc []prowapi.ProwJob 46 47 func (f fkc) ListProwJobs(s string) ([]prowapi.ProwJob, error) { 48 return f, nil 49 } 50 51 type fpkc string 52 53 func (f fpkc) GetLogs(name, container string) ([]byte, error) { 54 if name == "wowowow" || name == "powowow" { 55 return []byte(fmt.Sprintf("%s.%s", f, container)), nil 56 } 57 return nil, fmt.Errorf("pod not found: %s", name) 58 } 59 60 func TestGetLog(t *testing.T) { 61 kc := fkc{ 62 prowapi.ProwJob{ 63 Spec: prowapi.ProwJobSpec{ 64 Agent: prowapi.KubernetesAgent, 65 Job: "job", 66 }, 67 Status: prowapi.ProwJobStatus{ 68 PodName: "wowowow", 69 BuildID: "123", 70 }, 71 }, 72 prowapi.ProwJob{ 73 Spec: prowapi.ProwJobSpec{ 74 Agent: prowapi.KubernetesAgent, 75 Job: "jib", 76 Cluster: "trusted", 77 }, 78 Status: prowapi.ProwJobStatus{ 79 PodName: "powowow", 80 BuildID: "123", 81 }, 82 }, 83 } 84 ja := &JobAgent{ 85 kc: kc, 86 pkcs: map[string]PodLogClient{kube.DefaultClusterAlias: fpkc("clusterA"), "trusted": fpkc("clusterB")}, 87 } 88 if err := ja.update(); err != nil { 89 t.Fatalf("Updating: %v", err) 90 } 91 if res, err := ja.GetJobLog("job", "123", kube.TestContainerName); err != nil { 92 t.Fatalf("Failed to get log: %v", err) 93 } else if got, expect := string(res), fmt.Sprintf("clusterA.%s", kube.TestContainerName); got != expect { 94 t.Errorf("Unexpected result getting logs for job 'job'. Expected %q, but got %q.", expect, got) 95 } 96 97 if res, err := ja.GetJobLog("jib", "123", kube.TestContainerName); err != nil { 98 t.Fatalf("Failed to get log: %v", err) 99 } else if got, expect := string(res), fmt.Sprintf("clusterB.%s", kube.TestContainerName); got != expect { 100 t.Errorf("Unexpected result getting logs for job 'job'. Expected %q, but got %q.", expect, got) 101 } 102 103 customContainerName := "custom-container-name" 104 if res, err := ja.GetJobLog("jib", "123", customContainerName); err != nil { 105 t.Fatalf("Failed to get log: %v", err) 106 } else if got, expect := string(res), fmt.Sprintf("clusterB.%s", customContainerName); got != expect { 107 t.Errorf("Unexpected result getting logs for job 'job'. Expected %q, but got %q.", expect, got) 108 } 109 } 110 111 func TestProwJobs(t *testing.T) { 112 kc := fkc{ 113 prowapi.ProwJob{ 114 Spec: prowapi.ProwJobSpec{ 115 Agent: prowapi.KubernetesAgent, 116 Job: "jobFirst", 117 Refs: &prowapi.Refs{ 118 Org: "kubernetes", 119 Repo: "test-infra", 120 }, 121 }, 122 Status: prowapi.ProwJobStatus{ 123 PodName: "newpod", 124 BuildID: "1236", 125 StartTime: createTime(time.RFC3339, "2008-01-02T15:04:05.999Z"), 126 }, 127 }, 128 prowapi.ProwJob{ 129 Spec: prowapi.ProwJobSpec{ 130 Agent: prowapi.KubernetesAgent, 131 Job: "jobThird", 132 Refs: &prowapi.Refs{ 133 Org: "kubernetes", 134 Repo: "test-infra", 135 }, 136 }, 137 Status: prowapi.ProwJobStatus{ 138 PodName: "wowowow", 139 BuildID: "1234", 140 StartTime: createTime(time.RFC3339, "2006-01-02T15:04:05.999Z"), 141 }, 142 }, 143 prowapi.ProwJob{ 144 Spec: prowapi.ProwJobSpec{ 145 Agent: prowapi.KubernetesAgent, 146 Job: "jobSecond", 147 Refs: &prowapi.Refs{ 148 Org: "kubernetes", 149 Repo: "test-infra", 150 }, 151 }, 152 Status: prowapi.ProwJobStatus{ 153 PodName: "wowowow", 154 BuildID: "1235", 155 StartTime: createTime(time.RFC3339, "2007-01-02T15:04:05.999Z"), 156 }, 157 }, 158 } 159 ja := &JobAgent{ 160 kc: kc, 161 pkcs: map[string]PodLogClient{kube.DefaultClusterAlias: fpkc("")}, 162 } 163 if err := ja.update(); err != nil { 164 t.Fatalf("Updating: %v", err) 165 } 166 167 pjs := ja.ProwJobs() 168 if expect, got := 3, len(pjs); expect != got { 169 t.Fatalf("Expected %d prowjobs, but got %d.", expect, got) 170 } 171 if expect, got := "kubernetes", pjs[0].Spec.Refs.Org; expect != got { 172 t.Errorf("Expected prowjob to have org %q, but got %q.", expect, got) 173 } 174 if expect, got := "jobFirst", pjs[0].Spec.Job; expect != got { 175 t.Errorf("Expected first prowjob to have job name %q, but got %q.", expect, got) 176 } 177 if expect, got := "jobSecond", pjs[1].Spec.Job; expect != got { 178 t.Errorf("Expected second prowjob to have job name %q, but got %q.", expect, got) 179 } 180 if expect, got := "jobThird", pjs[2].Spec.Job; expect != got { 181 t.Errorf("Expected third prowjob to have job name %q, but got %q.", expect, got) 182 } 183 } 184 185 func TestJobs(t *testing.T) { 186 kc := fkc{ 187 prowapi.ProwJob{ 188 Spec: prowapi.ProwJobSpec{ 189 Agent: prowapi.KubernetesAgent, 190 Job: "jobFirst", 191 Refs: &prowapi.Refs{ 192 Org: "kubernetes", 193 Repo: "test-infra", 194 }, 195 }, 196 Status: prowapi.ProwJobStatus{ 197 PodName: "newpod", 198 BuildID: "1236", 199 StartTime: createTime(time.RFC3339, "2008-01-02T15:04:05.999Z"), 200 }, 201 }, 202 prowapi.ProwJob{ 203 Spec: prowapi.ProwJobSpec{ 204 Agent: prowapi.KubernetesAgent, 205 Job: "jobThird", 206 Refs: &prowapi.Refs{ 207 Org: "kubernetes", 208 Repo: "test-infra", 209 }, 210 }, 211 Status: prowapi.ProwJobStatus{ 212 PodName: "wowowow", 213 BuildID: "1234", 214 StartTime: createTime(time.RFC3339, "2006-01-02T15:04:05.999Z"), 215 }, 216 }, 217 prowapi.ProwJob{ 218 Spec: prowapi.ProwJobSpec{ 219 Agent: prowapi.KubernetesAgent, 220 Job: "jobSecond", 221 Refs: &prowapi.Refs{ 222 Org: "kubernetes", 223 Repo: "test-infra", 224 }, 225 }, 226 Status: prowapi.ProwJobStatus{ 227 PodName: "wowowow", 228 BuildID: "1235", 229 StartTime: createTime(time.RFC3339, "2007-01-02T15:04:05.999Z"), 230 }, 231 }, 232 } 233 ja := &JobAgent{ 234 kc: kc, 235 pkcs: map[string]PodLogClient{kube.DefaultClusterAlias: fpkc("")}, 236 } 237 if err := ja.update(); err != nil { 238 t.Fatalf("Updating: %v", err) 239 } 240 241 jobs := ja.Jobs() 242 if expect, got := 3, len(jobs); expect != got { 243 t.Fatalf("Expected %d jobs, but got %d.", expect, got) 244 } 245 if expect, got := "kubernetes", jobs[0].Refs.Org; expect != got { 246 t.Errorf("Expected jobs to have org %q, but got %q.", expect, got) 247 } 248 if expect, got := "jobFirst", jobs[0].Job; expect != got { 249 t.Errorf("Expected first job to have job name %q, but got %q.", expect, got) 250 } 251 if expect, got := "jobSecond", jobs[1].Job; expect != got { 252 t.Errorf("Expected second job to have job name %q, but got %q.", expect, got) 253 } 254 if expect, got := "jobThird", jobs[2].Job; expect != got { 255 t.Errorf("Expected third job to have job name %q, but got %q.", expect, got) 256 } 257 } 258 259 func TestListProwJobs(t *testing.T) { 260 templateJob := &prowapi.ProwJob{ 261 ObjectMeta: metav1.ObjectMeta{ 262 Namespace: "prowjobs", 263 }, 264 } 265 266 var testCases = []struct { 267 name string 268 selector string 269 prowJobs []func(*prowapi.ProwJob) runtime.Object 270 listErr bool 271 hiddenRepos sets.Set[string] 272 hiddenOnly bool 273 showHidden bool 274 expected sets.Set[string] 275 expectedErr bool 276 tenantIDs []string 277 }{ 278 { 279 name: "list error results in filter error", 280 listErr: true, 281 expectedErr: true, 282 }, 283 { 284 name: "no hidden repos returns all prowjobs", 285 selector: labels.Everything().String(), 286 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 287 func(in *prowapi.ProwJob) runtime.Object { 288 in.Name = "first" 289 return in 290 }, 291 }, 292 expected: sets.New[string]("first"), 293 }, 294 { 295 name: "no hidden repos returns all prowjobs except those not matching label selector", 296 selector: "foo=bar", 297 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 298 func(in *prowapi.ProwJob) runtime.Object { 299 in.Name = "first" 300 return in 301 }, 302 func(in *prowapi.ProwJob) runtime.Object { 303 in.Name = "second" 304 in.Labels = map[string]string{"foo": "bar"} 305 return in 306 }, 307 }, 308 expected: sets.New[string]("second"), 309 }, 310 { 311 name: "hidden repos excludes prowjobs from those repos", 312 selector: labels.Everything().String(), 313 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 314 func(in *prowapi.ProwJob) runtime.Object { 315 in.Name = "first" 316 return in 317 }, 318 func(in *prowapi.ProwJob) runtime.Object { 319 in.Name = "second" 320 in.Spec.Refs = &prowapi.Refs{ 321 Org: "org", 322 Repo: "repo", 323 } 324 return in 325 }, 326 }, 327 hiddenRepos: sets.New[string]("org/repo"), 328 expected: sets.New[string]("first"), 329 }, 330 { 331 name: "hidden repos doesn't exclude prowjobs from other repos", 332 selector: labels.Everything().String(), 333 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 334 func(in *prowapi.ProwJob) runtime.Object { 335 in.Name = "first" 336 return in 337 }, 338 func(in *prowapi.ProwJob) runtime.Object { 339 in.Name = "second" 340 in.Spec.Refs = &prowapi.Refs{ 341 Org: "org", 342 Repo: "other", 343 } 344 return in 345 }, 346 }, 347 hiddenRepos: sets.New[string]("org/repo"), 348 expected: sets.New[string]("first", "second"), 349 }, 350 { 351 name: "hidden orgs excludes prowjobs from those orgs", 352 selector: labels.Everything().String(), 353 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 354 func(in *prowapi.ProwJob) runtime.Object { 355 in.Name = "first" 356 return in 357 }, 358 func(in *prowapi.ProwJob) runtime.Object { 359 in.Name = "second" 360 in.Spec.Refs = &prowapi.Refs{ 361 Org: "org", 362 Repo: "other", 363 } 364 return in 365 }, 366 }, 367 hiddenRepos: sets.New[string]("org"), 368 expected: sets.New[string]("first"), 369 }, 370 { 371 name: "hidden orgs doesn't exclude prowjobs from other orgs", 372 selector: labels.Everything().String(), 373 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 374 func(in *prowapi.ProwJob) runtime.Object { 375 in.Name = "first" 376 return in 377 }, 378 func(in *prowapi.ProwJob) runtime.Object { 379 in.Name = "second" 380 in.Spec.Refs = &prowapi.Refs{ 381 Org: "other", 382 Repo: "other", 383 } 384 return in 385 }, 386 }, 387 hiddenRepos: sets.New[string]("org"), 388 expected: sets.New[string]("first", "second"), 389 }, 390 { 391 name: "hidden repos excludes prowjobs from those repos even by extra_refs", 392 selector: labels.Everything().String(), 393 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 394 func(in *prowapi.ProwJob) runtime.Object { 395 in.Name = "first" 396 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "org", Repo: "repo"}} 397 return in 398 }, 399 }, 400 hiddenRepos: sets.New[string]("org/repo"), 401 expected: sets.New[string](), 402 }, 403 { 404 name: "hidden orgs excludes prowjobs from those orgs even by extra_refs", 405 selector: labels.Everything().String(), 406 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 407 func(in *prowapi.ProwJob) runtime.Object { 408 in.Name = "first" 409 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "org", Repo: "repo"}} 410 return in 411 }, 412 }, 413 hiddenRepos: sets.New[string]("org"), 414 expected: sets.New[string](), 415 }, 416 { 417 name: "prowjobs without refs are returned even with hidden repos filtering", 418 selector: labels.Everything().String(), 419 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 420 func(in *prowapi.ProwJob) runtime.Object { 421 in.Name = "first" 422 return in 423 }, 424 }, 425 hiddenRepos: sets.New[string]("org/repo"), 426 expected: sets.New[string]("first"), 427 }, 428 { 429 name: "all prowjobs are returned when showHidden is true", 430 selector: labels.Everything().String(), 431 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 432 func(in *prowapi.ProwJob) runtime.Object { 433 in.Name = "first" 434 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "org", Repo: "repo"}} 435 return in 436 }, 437 func(in *prowapi.ProwJob) runtime.Object { 438 in.Name = "second" 439 return in 440 }, 441 }, 442 hiddenRepos: sets.New[string]("org/repo"), 443 expected: sets.New[string]("first", "second"), 444 showHidden: true, 445 }, 446 { 447 name: "setting pj.Spec.Hidden hides it", 448 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 449 func(in *prowapi.ProwJob) runtime.Object { 450 in.Name = "hidden" 451 in.Spec.Hidden = true 452 return in 453 }, 454 func(in *prowapi.ProwJob) runtime.Object { 455 in.Name = "shown" 456 return in 457 }, 458 }, 459 expected: sets.New[string]("shown"), 460 }, 461 { 462 name: "hidden repo or org in extra_refs hides it", 463 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 464 func(in *prowapi.ProwJob) runtime.Object { 465 in.Name = "hidden-repo" 466 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hide", Repo: "me"}} 467 return in 468 }, 469 func(in *prowapi.ProwJob) runtime.Object { 470 in.Name = "hidden-org" 471 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hidden-org"}} 472 return in 473 }, 474 }, 475 hiddenRepos: sets.New[string]("hide/me", "hidden-org"), 476 }, 477 { 478 name: "tenantID on lister will not show jobs without id", 479 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 480 func(in *prowapi.ProwJob) runtime.Object { 481 in.Name = "no ID" 482 return in 483 }, 484 func(in *prowapi.ProwJob) runtime.Object { 485 in.Name = "no ID hidden" 486 in.Spec.Hidden = true 487 return in 488 }, 489 }, 490 expected: sets.New[string](), 491 tenantIDs: []string{"ID"}, 492 }, 493 { 494 name: "tenantID ID on lister will show jobs with id", 495 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 496 func(in *prowapi.ProwJob) runtime.Object { 497 in.Name = "no ID" 498 return in 499 }, 500 func(in *prowapi.ProwJob) runtime.Object { 501 in.Name = "ID" 502 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 503 return in 504 }, 505 }, 506 expected: sets.New[string]("ID"), 507 tenantIDs: []string{"ID"}, 508 }, 509 { 510 name: "tenantID on lister will not show jobs with different id", 511 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 512 func(in *prowapi.ProwJob) runtime.Object { 513 in.Name = "Wrong ID" 514 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Wrong ID"} 515 return in 516 }, 517 func(in *prowapi.ProwJob) runtime.Object { 518 in.Name = "ID" 519 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 520 return in 521 }, 522 }, 523 expected: sets.New[string]("ID"), 524 tenantIDs: []string{"ID"}, 525 }, 526 { 527 name: "tenantIDs on lister will show all matching jobs", 528 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 529 func(in *prowapi.ProwJob) runtime.Object { 530 in.Name = "Wrong ID" 531 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Wrong ID"} 532 return in 533 }, 534 func(in *prowapi.ProwJob) runtime.Object { 535 in.Name = "ID" 536 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 537 return in 538 }, 539 func(in *prowapi.ProwJob) runtime.Object { 540 in.Name = "Other ID" 541 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Other ID"} 542 return in 543 }, 544 }, 545 expected: sets.New[string]("ID", "Other ID"), 546 tenantIDs: []string{"ID", "Other ID"}, 547 }, 548 { 549 name: "tenantIDs on lister will show hidden jobs with correct ID", 550 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 551 func(in *prowapi.ProwJob) runtime.Object { 552 in.Name = "Wrong ID" 553 in.Spec.Hidden = true 554 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Wrong ID"} 555 return in 556 }, 557 func(in *prowapi.ProwJob) runtime.Object { 558 in.Name = "ID" 559 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 560 in.Spec.Hidden = true 561 return in 562 }, 563 func(in *prowapi.ProwJob) runtime.Object { 564 in.Name = "Other ID" 565 in.Spec.Hidden = true 566 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Other ID"} 567 return in 568 }, 569 }, 570 expected: sets.New[string]("ID", "Other ID"), 571 tenantIDs: []string{"ID", "Other ID"}, 572 }, 573 { 574 name: "hidden repo with correct ID still shows if matching tenantIDs", 575 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 576 func(in *prowapi.ProwJob) runtime.Object { 577 in.Name = "hidden-repo" 578 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hide", Repo: "me"}} 579 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 580 return in 581 }, 582 func(in *prowapi.ProwJob) runtime.Object { 583 in.Name = "hidden-org" 584 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hidden-org"}} 585 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 586 return in 587 }, 588 }, 589 expected: sets.New[string]("hidden-repo", "hidden-org"), 590 hiddenRepos: sets.New[string]("hide/me", "hidden-org"), 591 tenantIDs: []string{"ID"}, 592 }, 593 { 594 name: "hidden repo with tenantIDs will still show if show hidden", 595 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 596 func(in *prowapi.ProwJob) runtime.Object { 597 in.Name = "hidden-repo" 598 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hide", Repo: "me"}} 599 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 600 return in 601 }, 602 func(in *prowapi.ProwJob) runtime.Object { 603 in.Name = "hidden-org" 604 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hidden-org"}} 605 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 606 return in 607 }, 608 }, 609 expected: sets.New[string]("hidden-repo", "hidden-org"), 610 hiddenRepos: sets.New[string]("hide/me", "hidden-org"), 611 showHidden: true, 612 }, 613 { 614 name: "hidden repo with tenantIDs will still show if hidden only", 615 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 616 func(in *prowapi.ProwJob) runtime.Object { 617 in.Name = "hidden-repo" 618 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hide", Repo: "me"}} 619 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 620 return in 621 }, 622 func(in *prowapi.ProwJob) runtime.Object { 623 in.Name = "hidden-org" 624 in.Spec.ExtraRefs = []prowapi.Refs{{Org: "hidden-org"}} 625 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 626 return in 627 }, 628 }, 629 expected: sets.New[string]("hidden-repo", "hidden-org"), 630 hiddenRepos: sets.New[string]("hide/me", "hidden-org"), 631 hiddenOnly: true, 632 }, 633 { 634 name: "pjs with tenantIDs marked hidden will still show up if showHidden is true", 635 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 636 func(in *prowapi.ProwJob) runtime.Object { 637 in.Name = "ID" 638 in.Spec.Hidden = true 639 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 640 return in 641 }, 642 func(in *prowapi.ProwJob) runtime.Object { 643 in.Name = "Other ID" 644 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Other ID"} 645 return in 646 }, 647 }, 648 expected: sets.New[string]("ID"), 649 showHidden: true, 650 }, 651 { 652 name: "pjs with tenantIDs will show up on Deck with hiddenOnly", 653 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 654 func(in *prowapi.ProwJob) runtime.Object { 655 in.Name = "Hidden ID" 656 in.Spec.Hidden = true 657 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 658 return in 659 }, 660 func(in *prowapi.ProwJob) runtime.Object { 661 in.Name = "Other ID" 662 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Other ID"} 663 return in 664 }, 665 }, 666 expected: sets.New[string]("Hidden ID"), 667 hiddenOnly: true, 668 }, 669 { 670 name: "pjs with tenantIDs will not show up on Deck with no tenantID", 671 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 672 func(in *prowapi.ProwJob) runtime.Object { 673 in.Name = "tenantedID" 674 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "ID"} 675 return in 676 }, 677 func(in *prowapi.ProwJob) runtime.Object { 678 in.Name = "Other ID" 679 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Other ID"} 680 return in 681 }, 682 }, 683 expected: sets.New[string](), 684 }, 685 { 686 name: "pjs with Default ID will show up on Deck with no tenantID", 687 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 688 func(in *prowapi.ProwJob) runtime.Object { 689 in.Name = "tenantedID" 690 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: config.DefaultTenantID} 691 return in 692 }, 693 func(in *prowapi.ProwJob) runtime.Object { 694 in.Name = "Other ID" 695 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: "Other ID"} 696 return in 697 }, 698 }, 699 expected: sets.New[string]("tenantedID"), 700 }, 701 { 702 name: "empty tenantID counts as no tenantID", 703 prowJobs: []func(*prowapi.ProwJob) runtime.Object{ 704 func(in *prowapi.ProwJob) runtime.Object { 705 in.Name = "empty tenant id" 706 in.Spec.ProwJobDefault = &prowapi.ProwJobDefault{TenantID: ""} 707 return in 708 }, 709 func(in *prowapi.ProwJob) runtime.Object { 710 in.Name = "No ProwJobDefault" 711 return in 712 }, 713 }, 714 expected: sets.New[string]("empty tenant id", "No ProwJobDefault"), 715 }, 716 } 717 718 for _, testCase := range testCases { 719 builder := fakectrlruntimeclient.NewClientBuilder() 720 for _, generator := range testCase.prowJobs { 721 builder.WithRuntimeObjects(generator(templateJob.DeepCopy())) 722 } 723 fakeProwJobClient := &possiblyErroringFakeCtrlRuntimeClient{ 724 Client: builder.Build(), 725 shouldError: testCase.listErr, 726 } 727 lister := filteringProwJobLister{ 728 client: fakeProwJobClient, 729 hiddenRepos: func() sets.Set[string] { 730 return testCase.hiddenRepos 731 }, 732 hiddenOnly: testCase.hiddenOnly, 733 showHidden: testCase.showHidden, 734 tenantIDs: testCase.tenantIDs, 735 cfg: func() *config.Config { return &config.Config{} }, 736 } 737 738 filtered, err := lister.ListProwJobs(testCase.selector) 739 if err == nil && testCase.expectedErr { 740 t.Errorf("%s: expected an error but got none", testCase.name) 741 } 742 if err != nil && !testCase.expectedErr { 743 t.Errorf("%s: expected no error but got one: %v", testCase.name, err) 744 } 745 746 filteredNames := sets.New[string]() 747 for _, prowJob := range filtered { 748 filteredNames.Insert(prowJob.Name) 749 } 750 751 if missing := testCase.expected.Difference(filteredNames); missing.Len() > 0 { 752 t.Errorf("%s: did not get expected jobs in filtered list: %v", testCase.name, sets.List(missing)) 753 } 754 if extra := filteredNames.Difference(testCase.expected); extra.Len() > 0 { 755 t.Errorf("%s: got unexpected jobs in filtered list: %v", testCase.name, sets.List(extra)) 756 } 757 } 758 } 759 760 type possiblyErroringFakeCtrlRuntimeClient struct { 761 ctrlruntimeclient.Client 762 shouldError bool 763 } 764 765 func (p *possiblyErroringFakeCtrlRuntimeClient) List( 766 ctx context.Context, 767 pjl *prowapi.ProwJobList, 768 opts ...ctrlruntimeclient.ListOption) error { 769 if p.shouldError { 770 return errors.New("could not list ProwJobs") 771 } 772 return p.Client.List(ctx, pjl, opts...) 773 } 774 775 func TestByPJStartTime(t *testing.T) { 776 now := metav1.Now() 777 in := []prowapi.ProwJob{ 778 {Spec: prowapi.ProwJobSpec{Job: "foo"}}, 779 {Spec: prowapi.ProwJobSpec{Job: "bar"}, Status: prowapi.ProwJobStatus{StartTime: now}}, 780 {Spec: prowapi.ProwJobSpec{Job: "bar"}}, 781 } 782 expected := []prowapi.ProwJob{ 783 {Spec: prowapi.ProwJobSpec{Job: "bar"}, Status: prowapi.ProwJobStatus{StartTime: now}}, 784 {Spec: prowapi.ProwJobSpec{Job: "bar"}}, 785 {Spec: prowapi.ProwJobSpec{Job: "foo"}}, 786 } 787 788 sort.Sort(byPJStartTime(in)) 789 790 if diff := cmp.Diff(in, expected); diff != "" { 791 t.Errorf("actual differs from expected: %s", diff) 792 } 793 }