github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/config/config_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 config 18 19 import ( 20 "bytes" 21 "errors" 22 "fmt" 23 "io/ioutil" 24 "reflect" 25 "regexp" 26 "strings" 27 "testing" 28 29 "github.com/ghodss/yaml" 30 "k8s.io/test-infra/prow/kube" 31 ) 32 33 func TestConfigLoads(t *testing.T) { 34 _, err := Load("../config.yaml") 35 if err != nil { 36 t.Fatalf("Could not load config: %v", err) 37 } 38 } 39 40 func Replace(j *Presubmit, ks *Presubmit) error { 41 name := strings.Replace(j.Name, "pull-kubernetes", "pull-security-kubernetes", -1) 42 if name != ks.Name { 43 return fmt.Errorf("%s should match %s", name, ks.Name) 44 } 45 j.Name = name 46 j.RerunCommand = strings.Replace(j.RerunCommand, "pull-kubernetes", "pull-security-kubernetes", -1) 47 j.Trigger = strings.Replace(j.Trigger, "pull-kubernetes", "pull-security-kubernetes", -1) 48 j.Context = strings.Replace(j.Context, "pull-kubernetes", "pull-security-kubernetes", -1) 49 j.re = ks.re 50 if len(j.RunAfterSuccess) != len(ks.RunAfterSuccess) { 51 return fmt.Errorf("length of RunAfterSuccess should match. - %s", name) 52 } 53 54 for i := range j.RunAfterSuccess { 55 if err := Replace(&j.RunAfterSuccess[i], &ks.RunAfterSuccess[i]); err != nil { 56 return err 57 } 58 } 59 60 return nil 61 } 62 63 func CheckContext(t *testing.T, repo string, p Presubmit) { 64 if p.Name != p.Context { 65 t.Errorf("Context does not match job name: %s in %s", p.Name, repo) 66 } 67 for _, c := range p.RunAfterSuccess { 68 CheckContext(t, repo, c) 69 } 70 } 71 72 func TestContextMatches(t *testing.T) { 73 c, err := Load("../config.yaml") 74 if err != nil { 75 t.Fatalf("Could not load config: %v", err) 76 } 77 78 for repo, presubmits := range c.Presubmits { 79 for _, p := range presubmits { 80 CheckContext(t, repo, p) 81 } 82 } 83 } 84 85 func CheckRetest(t *testing.T, repo string, presubmits []Presubmit) { 86 for _, p := range presubmits { 87 expected := fmt.Sprintf("/test %s", p.Name) 88 if p.RerunCommand != expected { 89 t.Errorf("%s in %s rerun_command: %s != expected: %s", repo, p.Name, p.RerunCommand, expected) 90 } 91 CheckRetest(t, repo, p.RunAfterSuccess) 92 } 93 } 94 95 func TestRetestMatchJobsName(t *testing.T) { 96 c, err := Load("../config.yaml") 97 if err != nil { 98 t.Fatalf("Could not load config: %v", err) 99 } 100 for repo, presubmits := range c.Presubmits { 101 CheckRetest(t, repo, presubmits) 102 } 103 } 104 105 type SubmitQueueConfig struct { 106 Data map[string]string `json:"data"` 107 } 108 109 func FindRequired(t *testing.T, presubmits []Presubmit) []string { 110 var required []string 111 for _, p := range presubmits { 112 if !p.AlwaysRun { 113 continue 114 } 115 for _, r := range FindRequired(t, p.RunAfterSuccess) { 116 required = append(required, r) 117 } 118 if p.SkipReport { 119 continue 120 } 121 required = append(required, p.Context) 122 } 123 return required 124 } 125 126 func TestRequiredRetestContextsMatch(t *testing.T) { 127 c, err := Load("../config.yaml") 128 if err != nil { 129 t.Fatalf("Could not load config: %v", err) 130 } 131 b, err := ioutil.ReadFile("../../mungegithub/submit-queue/deployment/kubernetes/configmap.yaml") 132 if err != nil { 133 t.Fatalf("Could not load submit queue configmap: %v", err) 134 } 135 sqc := &SubmitQueueConfig{} 136 if err = yaml.Unmarshal(b, sqc); err != nil { 137 t.Fatalf("Could not parse submit queue configmap: %v", err) 138 } 139 re := regexp.MustCompile(`"([^"]+)"`) 140 var required []string 141 for _, g := range re.FindAllStringSubmatch(sqc.Data["test-options.required-retest-contexts"], -1) { 142 required = append(required, g[1]) 143 } 144 145 running := FindRequired(t, c.Presubmits["kubernetes/kubernetes"]) 146 147 for _, r := range required { 148 found := false 149 for _, s := range running { 150 if s == r { 151 found = true 152 break 153 } 154 } 155 if !found { 156 t.Errorf("Required context: %s does not always run: %s", r, running) 157 } 158 } 159 } 160 161 func TestConfigSecurityJobsMatch(t *testing.T) { 162 c, err := Load("../config.yaml") 163 if err != nil { 164 t.Fatalf("Could not load config: %v", err) 165 } 166 kp := c.Presubmits["kubernetes/kubernetes"] 167 sp := c.Presubmits["kubernetes-security/kubernetes"] 168 if len(kp) != len(sp) { 169 t.Fatalf("length of kubernetes/kubernetes presubmits %d does not equal length of kubernetes-security/kubernetes presubmits %d", len(kp), len(sp)) 170 } 171 for i, j := range kp { 172 if err := Replace(&j, &sp[i]); err != nil { 173 t.Fatalf("[Replace] : %v", err) 174 } 175 176 if !reflect.DeepEqual(j, sp[i]) { 177 t.Fatalf("kubernetes/kubernetes prow config jobs do not match kubernetes-security/kubernetes jobs:\n%#v\nshould match: %#v", j, sp[i]) 178 } 179 } 180 } 181 182 func CheckBazelPortContainer(c kube.Container, cache bool) error { 183 if !cache { 184 if len(c.Ports) != 0 { 185 return errors.New("job does not use --cache-ssd and so should not set ports in spec") 186 } 187 return nil 188 } 189 190 if len(c.Ports) != 1 { 191 return errors.New("job uses --cache-ssd and so needs to set ports in spec") 192 } else if c.Ports[0].ContainerPort != 9999 { 193 return errors.New("job uses --cache-ssd and so needs to have ContainerPort 9999") 194 } else if c.Ports[0].HostPort != 9999 { 195 return errors.New("job uses --cache-ssd and so needs to have HostPort 9999") 196 } 197 return nil 198 } 199 200 func CheckBazelPortPresubmit(presubmits []Presubmit) error { 201 for _, presubmit := range presubmits { 202 if presubmit.Spec == nil { 203 continue 204 } 205 hasCache := false 206 for _, volume := range presubmit.Spec.Volumes { 207 if volume.Name == "cache-ssd" { 208 hasCache = true 209 } 210 } 211 212 for _, container := range presubmit.Spec.Containers { 213 if err := CheckBazelPortContainer(container, hasCache); err != nil { 214 return fmt.Errorf("%s: %v", presubmit.Name, err) 215 } 216 } 217 218 if err := CheckBazelPortPresubmit(presubmit.RunAfterSuccess); err != nil { 219 return fmt.Errorf("%s: %v", presubmit.Name, err) 220 } 221 } 222 223 return nil 224 } 225 226 func CheckBazelPortPostsubmit(postsubmits []Postsubmit) error { 227 for _, postsubmit := range postsubmits { 228 hasCache := false 229 for _, volume := range postsubmit.Spec.Volumes { 230 if volume.Name == "cache-ssd" { 231 hasCache = true 232 } 233 } 234 235 for _, container := range postsubmit.Spec.Containers { 236 if err := CheckBazelPortContainer(container, hasCache); err != nil { 237 return fmt.Errorf("%s: %v", postsubmit.Name, err) 238 } 239 } 240 241 if err := CheckBazelPortPostsubmit(postsubmit.RunAfterSuccess); err != nil { 242 return fmt.Errorf("%s: %v", postsubmit.Name, err) 243 } 244 } 245 246 return nil 247 } 248 249 func CheckBazelPortPeriodic(periodics []Periodic) error { 250 for _, periodic := range periodics { 251 hasCache := false 252 for _, volume := range periodic.Spec.Volumes { 253 if volume.Name == "cache-ssd" { 254 hasCache = true 255 } 256 } 257 258 for _, container := range periodic.Spec.Containers { 259 if err := CheckBazelPortContainer(container, hasCache); err != nil { 260 return fmt.Errorf("%s: %v", periodic.Name, err) 261 } 262 } 263 264 if err := CheckBazelPortPeriodic(periodic.RunAfterSuccess); err != nil { 265 return fmt.Errorf("%s: %v", periodic.Name, err) 266 } 267 } 268 269 return nil 270 } 271 272 // Set the HostPort to 9999 for all bazel pods so that they are forced 273 // onto different nodes. Once pod affinity is GA, use that instead. 274 // Until https://github.com/kubernetes/community/blob/master/contributors/design-proposals/local-storage-overview.md 275 func TestBazelJobHasContainerPort(t *testing.T) { 276 c, err := Load("../config.yaml") 277 if err != nil { 278 t.Fatalf("Could not load config: %v", err) 279 } 280 281 for _, pres := range c.Presubmits { 282 if err := CheckBazelPortPresubmit(pres); err != nil { 283 t.Errorf("Error in presubmit: %v", err) 284 } 285 } 286 287 for _, posts := range c.Postsubmits { 288 if err := CheckBazelPortPostsubmit(posts); err != nil { 289 t.Errorf("Error in postsubmit: %v", err) 290 } 291 } 292 293 if err := CheckBazelPortPeriodic(c.Periodics); err != nil { 294 t.Errorf("Error in periodic: %v", err) 295 } 296 } 297 298 // Load the config and extract all jobs, including any child jobs inside 299 // RunAfterSuccess fields. 300 func allJobs() ([]Presubmit, []Postsubmit, []Periodic, error) { 301 c, err := Load("../config.yaml") 302 if err != nil { 303 return nil, nil, nil, err 304 } 305 306 pres := []Presubmit{} 307 posts := []Postsubmit{} 308 peris := []Periodic{} 309 310 { // Find all presubmit jobs, including child jobs. 311 q := []Presubmit{} 312 313 for _, p := range c.Presubmits { 314 for _, p2 := range p { 315 q = append(q, p2) 316 } 317 } 318 319 for len(q) > 0 { 320 pres = append(pres, q[0]) 321 for _, p := range q[0].RunAfterSuccess { 322 q = append(q, p) 323 } 324 q = q[1:] 325 } 326 } 327 328 { // Find all postsubmit jobs, including child jobs. 329 q := []Postsubmit{} 330 331 for _, p := range c.Postsubmits { 332 for _, p2 := range p { 333 q = append(q, p2) 334 } 335 } 336 337 for len(q) > 0 { 338 posts = append(posts, q[0]) 339 for _, p := range q[0].RunAfterSuccess { 340 q = append(q, p) 341 } 342 q = q[1:] 343 } 344 } 345 346 { // Find all periodic jobs, including child jobs. 347 q := []Periodic{} 348 for _, p := range c.Periodics { 349 q = append(q, p) 350 } 351 352 for len(q) > 0 { 353 peris = append(peris, q[0]) 354 for _, p := range q[0].RunAfterSuccess { 355 q = append(q, p) 356 } 357 q = q[1:] 358 } 359 } 360 361 return pres, posts, peris, nil 362 } 363 364 // Validate any containers using a bazelbuild image, returning which bazelbuild tags are used. 365 // In particular ensure that: 366 // * Presubmit, postsubmit jobs specify at least one --repo flag, the first of which uses PULL_REFS and REPO_NAME vars 367 // * Prow injected vars like REPO_NAME, PULL_REFS, etc are only used on non-periodic jobs 368 // * Deprecated --branch, --pull flags are not used 369 // * Required --service-account, --upload, --git-cache, --job, --clean flags are present 370 func CheckBazelbuildSpec(t *testing.T, name string, spec *kube.PodSpec, periodic bool) map[string]int { 371 img := "gcr.io/k8s-testimages/bazelbuild" 372 tags := map[string]int{} 373 if spec == nil { 374 return tags 375 } 376 // Tags look something like vDATE-SHA or vDATE-SHA-BAZELVERSION. 377 // We want to match only on the date + sha 378 tagRE := regexp.MustCompile(`^([^-]+-[^-]+)(-[^-]+)?$`) 379 for _, c := range spec.Containers { 380 parts := strings.SplitN(c.Image, ":", 2) 381 var i, tag string // image:tag 382 i = parts[0] 383 if i != img { 384 continue 385 } 386 if len(parts) == 1 { 387 tag = "latest" 388 } else { 389 submatches := tagRE.FindStringSubmatch(parts[1]) 390 if submatches != nil { 391 tag = submatches[1] 392 } else { 393 t.Errorf("bazelbuild tag '%s' doesn't match expected format", parts[1]) 394 } 395 } 396 tags[tag]++ 397 398 found := map[string][]string{} 399 for _, a := range c.Args { 400 parts := strings.SplitN(a, "=", 2) 401 k := parts[0] 402 v := "true" 403 if len(parts) == 2 { 404 v = parts[1] 405 } 406 found[k] = append(found[k], v) 407 408 // Require --flag=FOO for easier processing 409 if k == "--repo" && len(parts) == 1 { 410 t.Errorf("%s: use --repo=FOO not --repo foo", name) 411 } 412 } 413 414 if _, ok := found["--pull"]; ok { 415 t.Errorf("%s: uses deprecated --pull arg, use --repo=org/repo=$(PULL_REFS) instead", name) 416 } 417 if _, ok := found["--branch"]; ok { 418 t.Errorf("%s: uses deprecated --branch arg, use --repo=org/repo=$(PULL_REFS) instead", name) 419 } 420 421 for _, f := range []string{ 422 "--service-account", 423 "--upload", 424 "--git-cache", 425 "--job", 426 "--clean", 427 } { 428 if _, ok := found[f]; !ok { 429 t.Errorf("%s: missing %s flag", name, f) 430 } 431 } 432 433 if v, ok := found["--repo"]; !ok { 434 t.Errorf("%s: missing %s flag", name, "--repo") 435 } else { 436 firstRepo := true 437 hasRefs := false 438 hasName := false 439 for _, r := range v { 440 hasRefs = hasRefs || strings.Contains(r, "$(PULL_REFS)") 441 hasName = hasName || strings.Contains(r, "$(REPO_NAME)") 442 if !firstRepo { 443 t.Errorf("%s: has too many --repo. REMOVE THIS CHECK BEFORE MERGE", name) 444 } 445 for _, d := range []string{ 446 "$(REPO_NAME)", 447 "$(REPO_OWNER)", 448 "$(PULL_BASE_REF)", 449 "$(PULL_BASE_SHA)", 450 "$(PULL_REFS)", 451 "$(PULL_NUMBER)", 452 "$(PULL_PULL_SHA)", 453 } { 454 has := strings.Contains(r, d) 455 if periodic && has { 456 t.Errorf("%s: %s are not available to periodic jobs, please use a static --repo=org/repo=branch", name, d) 457 } else if !firstRepo && has { 458 t.Errorf("%s: %s are only relevant to the first --repo flag, remove from --repo=%s", name, d, r) 459 } 460 } 461 firstRepo = false 462 } 463 if !periodic && !hasRefs { 464 t.Errorf("%s: non-periodic jobs need a --repo=org/branch=$(PULL_REFS) somewhere", name) 465 } 466 if !periodic && !hasName { 467 t.Errorf("%s: non-periodic jobs need a --repo=org/$(REPO_NAME) somewhere", name) 468 } 469 } 470 } 471 return tags 472 } 473 474 // Unit test jobs that use a bazelbuild image do so correctly. 475 func TestBazelbuildArgs(t *testing.T) { 476 pres, posts, peris, err := allJobs() 477 if err != nil { 478 t.Fatalf("Could not load config: %v", err) 479 } 480 481 tags := map[string][]string{} // tag -> jobs map 482 for _, p := range pres { 483 for t := range CheckBazelbuildSpec(t, p.Name, p.Spec, false) { 484 tags[t] = append(tags[t], p.Name) 485 } 486 } 487 for _, p := range posts { 488 for t := range CheckBazelbuildSpec(t, p.Name, p.Spec, false) { 489 tags[t] = append(tags[t], p.Name) 490 } 491 } 492 for _, p := range peris { 493 for t := range CheckBazelbuildSpec(t, p.Name, p.Spec, true) { 494 tags[t] = append(tags[t], p.Name) 495 } 496 } 497 pinnedJobs := map[string]string{ 498 //job: reason for pinning 499 "ci-kubernetes-bazel-build-1-6": "https://github.com/kubernetes/kubernetes/issues/51571", 500 "ci-kubernetes-bazel-test-1-6": "https://github.com/kubernetes/kubernetes/issues/51571", 501 "periodic-kubernetes-bazel-build-1-6": "https://github.com/kubernetes/kubernetes/issues/51571", 502 "periodic-kubernetes-bazel-test-1-6": "https://github.com/kubernetes/kubernetes/issues/51571", 503 "pull-test-infra-bazel": "canary testing the latest bazel on test-infra", 504 "ci-test-infra-bazel": "canary testing the latest bazel on test-infra", 505 "pull-kubernetes-bazel-build": "need different versions of bazel for release branches", 506 "pull-kubernetes-bazel-test": "need different versions of bazel for release branches", 507 "pull-security-kubernetes-bazel-build": "need different versions of bazel for release branches", 508 "pull-security-kubernetes-bazel-test": "need different versions of bazel for release branches", 509 } 510 maxTag := "" 511 maxN := 0 512 for t, js := range tags { 513 n := len(js) 514 if n > maxN { 515 maxTag = t 516 maxN = n 517 } 518 } 519 for tag, js := range tags { 520 current := tag == maxTag 521 for _, j := range js { 522 if v, pinned := pinnedJobs[j]; !pinned && !current { 523 t.Errorf("%s: please add to the pinnedJobs list or else update tag to %s", j, maxTag) 524 } else if current && pinned { 525 t.Errorf("%s: please remove from the pinnedJobs list", j) 526 } else if !current && v == "" { 527 t.Errorf("%s: pinning to a non-default version requires a non-empty reason for doing so", j) 528 } 529 } 530 } 531 } 532 533 func TestURLTemplate(t *testing.T) { 534 c, err := Load("../config.yaml") 535 if err != nil { 536 t.Fatalf("Could not load config: %v", err) 537 } 538 testcases := []struct { 539 name string 540 jobType kube.ProwJobType 541 org string 542 repo string 543 job string 544 build string 545 expect string 546 }{ 547 { 548 name: "k8s presubmit", 549 jobType: kube.PresubmitJob, 550 org: "kubernetes", 551 repo: "kubernetes", 552 job: "k8s-pre-1", 553 build: "1", 554 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/pr-logs/pull/0/k8s-pre-1/1/", 555 }, 556 { 557 name: "k8s/test-infra presubmit", 558 jobType: kube.PresubmitJob, 559 org: "kubernetes", 560 repo: "test-infra", 561 job: "ti-pre-1", 562 build: "1", 563 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/pr-logs/pull/test-infra/0/ti-pre-1/1/", 564 }, 565 { 566 name: "foo/k8s presubmit", 567 jobType: kube.PresubmitJob, 568 org: "foo", 569 repo: "kubernetes", 570 job: "k8s-pre-1", 571 build: "1", 572 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/pr-logs/pull/foo_kubernetes/0/k8s-pre-1/1/", 573 }, 574 { 575 name: "foo-bar presubmit", 576 jobType: kube.PresubmitJob, 577 org: "foo", 578 repo: "bar", 579 job: "foo-pre-1", 580 build: "1", 581 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/pr-logs/pull/foo_bar/0/foo-pre-1/1/", 582 }, 583 { 584 name: "k8s postsubmit", 585 jobType: kube.PostsubmitJob, 586 org: "kubernetes", 587 repo: "kubernetes", 588 job: "k8s-post-1", 589 build: "1", 590 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/logs/k8s-post-1/1/", 591 }, 592 { 593 name: "k8s periodic", 594 jobType: kube.PeriodicJob, 595 org: "kubernetes", 596 repo: "kubernetes", 597 job: "k8s-peri-1", 598 build: "1", 599 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/logs/k8s-peri-1/1/", 600 }, 601 { 602 name: "empty periodic", 603 jobType: kube.PeriodicJob, 604 org: "", 605 repo: "", 606 job: "nan-peri-1", 607 build: "1", 608 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/logs/nan-peri-1/1/", 609 }, 610 { 611 name: "k8s batch", 612 jobType: kube.BatchJob, 613 org: "kubernetes", 614 repo: "kubernetes", 615 job: "k8s-batch-1", 616 build: "1", 617 expect: "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/pr-logs/pull/batch/k8s-batch-1/1/", 618 }, 619 } 620 621 for _, tc := range testcases { 622 var pj = kube.ProwJob{ 623 Metadata: kube.ObjectMeta{Name: tc.name}, 624 Spec: kube.ProwJobSpec{ 625 Type: tc.jobType, 626 Job: tc.job, 627 Refs: kube.Refs{ 628 Pulls: []kube.Pull{{}}, 629 Org: tc.org, 630 Repo: tc.repo, 631 }, 632 }, 633 Status: kube.ProwJobStatus{ 634 BuildID: tc.build, 635 }, 636 } 637 638 var b bytes.Buffer 639 if err := c.Plank.JobURLTemplate.Execute(&b, &pj); err != nil { 640 t.Fatalf("Error executing template: %v", err) 641 } 642 res := b.String() 643 if res != tc.expect { 644 t.Errorf("tc: %s, Expect URL: %s, got %s", tc.name, tc.expect, res) 645 } 646 } 647 } 648 649 func TestReportTemplate(t *testing.T) { 650 c, err := Load("../config.yaml") 651 if err != nil { 652 t.Fatalf("Could not load config: %v", err) 653 } 654 var testcases = []struct { 655 org string 656 repo string 657 number int 658 suffix string 659 }{ 660 { 661 org: "o", 662 repo: "r", 663 number: 4, 664 suffix: "o_r/4", 665 }, 666 { 667 org: "kubernetes", 668 repo: "test-infra", 669 number: 123, 670 suffix: "test-infra/123", 671 }, 672 { 673 org: "kubernetes", 674 repo: "kubernetes", 675 number: 123, 676 suffix: "123", 677 }, 678 { 679 org: "o", 680 repo: "kubernetes", 681 number: 456, 682 suffix: "o_kubernetes/456", 683 }, 684 } 685 for _, tc := range testcases { 686 var b bytes.Buffer 687 if err := c.Plank.ReportTemplate.Execute(&b, &kube.ProwJob{ 688 Spec: kube.ProwJobSpec{ 689 Refs: kube.Refs{ 690 Org: tc.org, 691 Repo: tc.repo, 692 Pulls: []kube.Pull{ 693 { 694 Number: tc.number, 695 }, 696 }, 697 }, 698 }, 699 }); err != nil { 700 t.Errorf("Error executing template: %v", err) 701 continue 702 } 703 expectedPath := "https://k8s-gubernator.appspot.com/pr/" + tc.suffix 704 if !strings.Contains(b.String(), expectedPath) { 705 t.Errorf("Expected template to contain %s, but it didn't: %s", expectedPath, b.String()) 706 } 707 } 708 } 709 710 func TestPullKubernetesCross(t *testing.T) { 711 crossBuildJob := "pull-kubernetes-cross" 712 c, err := Load("../config.yaml") 713 if err != nil { 714 t.Fatalf("Could not load config: %v", err) 715 } 716 tests := []struct { 717 changedFile string 718 expected bool 719 }{ 720 { 721 changedFile: "pkg/kubelet/cadvisor/cadvisor_unsupported.go", 722 expected: true, 723 }, 724 { 725 changedFile: "pkg/kubelet/cadvisor/util.go", 726 expected: false, 727 }, 728 { 729 changedFile: "Makefile", 730 expected: true, 731 }, 732 { 733 changedFile: "hack/lib/etcd.sh", 734 expected: true, 735 }, 736 { 737 changedFile: "build/debs/kubelet.service", 738 expected: true, 739 }, 740 { 741 changedFile: "federation/README.md", 742 expected: false, 743 }, 744 } 745 kkPresumits := c.Presubmits["kubernetes/kubernetes"] 746 var cross *Presubmit 747 for i := range kkPresumits { 748 ps := kkPresumits[i] 749 if ps.Name == crossBuildJob { 750 cross = &ps 751 break 752 } 753 } 754 if cross == nil { 755 t.Fatalf("expected %q in the presubmit section of the prow config", crossBuildJob) 756 } 757 758 for i, test := range tests { 759 t.Logf("test run #%d", i) 760 got := cross.RunsAgainstChanges([]string{test.changedFile}) 761 if got != test.expected { 762 t.Errorf("expected changes (%s) to run cross job: %t, got: %t", 763 test.changedFile, test.expected, got) 764 } 765 } 766 }