github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/cmd/deck/rerun_test.go (about) 1 /* 2 Copyright 2022 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 main 18 19 import ( 20 "context" 21 "io" 22 "net/http" 23 "net/http/httptest" 24 "testing" 25 "time" 26 27 "github.com/google/go-cmp/cmp" 28 "github.com/gorilla/sessions" 29 "github.com/sirupsen/logrus" 30 "golang.org/x/oauth2" 31 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 32 prowapi "sigs.k8s.io/prow/pkg/apis/prowjobs/v1" 33 "sigs.k8s.io/prow/pkg/client/clientset/versioned/fake" 34 "sigs.k8s.io/prow/pkg/config" 35 "sigs.k8s.io/prow/pkg/github/fakegithub" 36 "sigs.k8s.io/prow/pkg/githuboauth" 37 "sigs.k8s.io/prow/pkg/kube" 38 "sigs.k8s.io/prow/pkg/plugins" 39 "sigs.k8s.io/yaml" 40 ) 41 42 func getPresubmitConfig() *config.Config { 43 presubmitJobs := []config.Presubmit{ 44 { 45 JobBase: config.JobBase{ 46 Name: "whoa", 47 Labels: map[string]string{ 48 "foo": "foo", 49 }, 50 Annotations: map[string]string{ 51 "foo": "foo", 52 }, 53 RerunAuthConfig: &prowapi.RerunAuthConfig{ 54 AllowAnyone: false, 55 GitHubUsers: []string{"authorized", "alsoauthorized"}, 56 GitHubTeamIDs: []int{42}, 57 }, 58 }, 59 Brancher: config.Brancher{ 60 Branches: []string{"master"}, 61 }, 62 }, 63 } 64 config.SetPresubmitRegexes(presubmitJobs) 65 return &config.Config{ 66 JobConfig: config.JobConfig{ 67 PresubmitsStatic: map[string][]config.Presubmit{"org/repo": presubmitJobs}, 68 }, 69 } 70 } 71 72 func getPeriodicConfig() *config.Config { 73 return &config.Config{ 74 JobConfig: config.JobConfig{ 75 Periodics: []config.Periodic{{ 76 JobBase: config.JobBase{ 77 Name: "whoa", 78 Labels: map[string]string{ 79 "foo": "foo", 80 }, 81 Annotations: map[string]string{ 82 "foo": "foo", 83 }, 84 RerunAuthConfig: &prowapi.RerunAuthConfig{ 85 AllowAnyone: false, 86 GitHubUsers: []string{"authorized", "alsoauthorized"}, 87 GitHubTeamIDs: []int{42}, 88 }, 89 }, 90 }}, 91 }, 92 } 93 } 94 95 // TestRerun just checks that the result can be unmarshaled properly, has an 96 // updated status, and has equal spec. 97 func TestRerun(t *testing.T) { 98 testCases := []struct { 99 name string 100 login string 101 authorized []string 102 allowAnyone bool 103 rerunCreatesJob bool 104 shouldCreateProwJob bool 105 httpCode int 106 httpMethod string 107 enableScheduling bool 108 wantProwJobState prowapi.ProwJobState 109 }{ 110 { 111 name: "Handler returns ProwJob", 112 login: "authorized", 113 authorized: []string{"authorized", "alsoauthorized"}, 114 allowAnyone: false, 115 rerunCreatesJob: true, 116 shouldCreateProwJob: true, 117 httpCode: http.StatusOK, 118 httpMethod: http.MethodPost, 119 wantProwJobState: prowapi.TriggeredState, 120 }, 121 { 122 name: "User not authorized to create prow job", 123 login: "random-dude", 124 authorized: []string{"authorized", "alsoauthorized"}, 125 allowAnyone: false, 126 rerunCreatesJob: true, 127 shouldCreateProwJob: false, 128 httpCode: http.StatusOK, 129 httpMethod: http.MethodPost, 130 }, 131 { 132 name: "RerunCreatesJob set to false, should not create prow job", 133 login: "authorized", 134 authorized: []string{"authorized", "alsoauthorized"}, 135 allowAnyone: true, 136 rerunCreatesJob: false, 137 shouldCreateProwJob: false, 138 httpCode: http.StatusOK, 139 httpMethod: http.MethodGet, 140 }, 141 { 142 name: "Allow anyone set to true, creates job", 143 login: "ugh", 144 authorized: []string{"authorized", "alsoauthorized"}, 145 allowAnyone: true, 146 rerunCreatesJob: true, 147 shouldCreateProwJob: true, 148 httpCode: http.StatusOK, 149 httpMethod: http.MethodPost, 150 wantProwJobState: prowapi.TriggeredState, 151 }, 152 { 153 name: "Direct rerun disabled, post request", 154 login: "authorized", 155 authorized: []string{"authorized", "alsoauthorized"}, 156 allowAnyone: true, 157 rerunCreatesJob: false, 158 shouldCreateProwJob: false, 159 httpCode: http.StatusMethodNotAllowed, 160 httpMethod: http.MethodPost, 161 }, 162 { 163 name: "User permitted on specific job", 164 login: "authorized", 165 authorized: []string{}, 166 allowAnyone: false, 167 rerunCreatesJob: true, 168 shouldCreateProwJob: true, 169 httpCode: http.StatusOK, 170 httpMethod: http.MethodPost, 171 wantProwJobState: prowapi.TriggeredState, 172 }, 173 { 174 name: "User on permitted team", 175 login: "sig-lead", 176 authorized: []string{}, 177 allowAnyone: false, 178 rerunCreatesJob: true, 179 shouldCreateProwJob: true, 180 httpCode: http.StatusOK, 181 httpMethod: http.MethodPost, 182 wantProwJobState: prowapi.TriggeredState, 183 }, 184 { 185 name: "Org member permitted for presubmits", 186 login: "org-member", 187 authorized: []string{}, 188 allowAnyone: false, 189 rerunCreatesJob: true, 190 shouldCreateProwJob: true, 191 httpCode: http.StatusOK, 192 httpMethod: http.MethodPost, 193 wantProwJobState: prowapi.TriggeredState, 194 }, 195 { 196 name: "Rerun ProwJob in scheduling state", 197 login: "authorized", 198 authorized: []string{"authorized", "alsoauthorized"}, 199 allowAnyone: false, 200 rerunCreatesJob: true, 201 shouldCreateProwJob: true, 202 httpCode: http.StatusOK, 203 httpMethod: http.MethodPost, 204 enableScheduling: true, 205 wantProwJobState: prowapi.SchedulingState, 206 }, 207 } 208 209 for _, tc := range testCases { 210 t.Run(tc.name, func(t *testing.T) { 211 fakeProwJobClient := fake.NewSimpleClientset(&prowapi.ProwJob{ 212 ObjectMeta: metav1.ObjectMeta{ 213 Name: "wowsuch", 214 Namespace: "prowjobs", 215 }, 216 Spec: prowapi.ProwJobSpec{ 217 Job: "whoa", 218 Type: prowapi.PresubmitJob, 219 Refs: &prowapi.Refs{ 220 Org: "org", 221 Repo: "repo", 222 Pulls: []prowapi.Pull{ 223 { 224 Number: 1, 225 Author: tc.login, 226 }, 227 }, 228 }, 229 RerunAuthConfig: &prowapi.RerunAuthConfig{ 230 AllowAnyone: false, 231 GitHubUsers: []string{"authorized", "alsoauthorized"}, 232 GitHubTeamIDs: []int{42}, 233 }, 234 }, 235 Status: prowapi.ProwJobStatus{ 236 State: prowapi.PendingState, 237 }, 238 }) 239 authCfgGetter := func(refs *prowapi.ProwJobSpec) *prowapi.RerunAuthConfig { 240 return &prowapi.RerunAuthConfig{ 241 AllowAnyone: tc.allowAnyone, 242 GitHubUsers: tc.authorized, 243 } 244 } 245 246 req, err := http.NewRequest(tc.httpMethod, "/rerun?prowjob=wowsuch", nil) 247 if err != nil { 248 t.Fatalf("Error making request: %v", err) 249 } 250 req.AddCookie(&http.Cookie{ 251 Name: "github_login", 252 Value: tc.login, 253 Path: "/", 254 Expires: time.Now().Add(time.Hour * 24 * 30), 255 Secure: true, 256 }) 257 mockCookieStore := sessions.NewCookieStore([]byte("secret-key")) 258 session, err := sessions.GetRegistry(req).Get(mockCookieStore, "access-token-session") 259 if err != nil { 260 t.Fatalf("Error making access token session: %v", err) 261 } 262 session.Values["access-token"] = &oauth2.Token{AccessToken: "validtoken"} 263 264 rr := httptest.NewRecorder() 265 mockConfig := &githuboauth.Config{ 266 CookieStore: mockCookieStore, 267 } 268 goa := githuboauth.NewAgent(mockConfig, &logrus.Entry{}) 269 ghc := &fakeAuthenticatedUserIdentifier{login: tc.login} 270 rc := fakegithub.NewFakeClient() 271 rc.OrgMembers = map[string][]string{"org": {"org-member"}} 272 pca := plugins.NewFakeConfigAgent() 273 cfg := func() *config.Config { 274 return &config.Config{ProwConfig: config.ProwConfig{Scheduler: config.Scheduler{Enabled: tc.enableScheduling}}} 275 } 276 handler := handleRerun(cfg, fakeProwJobClient.ProwV1().ProwJobs("prowjobs"), tc.rerunCreatesJob, authCfgGetter, goa, ghc, rc, &pca, logrus.WithField("handler", "/rerun")) 277 handler.ServeHTTP(rr, req) 278 if rr.Code != tc.httpCode { 279 t.Fatalf("Bad error code: %d", rr.Code) 280 } 281 282 if tc.shouldCreateProwJob { 283 pjs, err := fakeProwJobClient.ProwV1().ProwJobs("prowjobs").List(context.Background(), metav1.ListOptions{}) 284 if err != nil { 285 t.Fatalf("failed to list prowjobs: %v", err) 286 } 287 if numPJs := len(pjs.Items); numPJs != 2 { 288 t.Errorf("expected to get two prowjobs, got %d", numPJs) 289 } 290 for i := range pjs.Items { 291 pj := &pjs.Items[i] 292 if pj.Name != "wowsuch" && pj.Status.State != tc.wantProwJobState { 293 t.Errorf("expected state %s but got %s in pj %s", tc.wantProwJobState, pj.Status.State, pj.Spec.Job) 294 } 295 } 296 } else if !tc.rerunCreatesJob && tc.httpCode == http.StatusOK { 297 resp := rr.Result() 298 defer resp.Body.Close() 299 body, err := io.ReadAll(resp.Body) 300 if err != nil { 301 t.Fatalf("Error reading response body: %v", err) 302 } 303 var res prowapi.ProwJob 304 if err := yaml.Unmarshal(body, &res); err != nil { 305 t.Fatalf("Error unmarshaling: %v", err) 306 } 307 if res.Spec.Job != "whoa" { 308 t.Errorf("Wrong job, expected \"whoa\", got \"%s\"", res.Spec.Job) 309 } 310 if res.Status.State != prowapi.TriggeredState { 311 t.Errorf("Wrong state, expected \"%v\", got \"%v\"", prowapi.TriggeredState, res.Status.State) 312 } 313 } 314 }) 315 } 316 } 317 318 // TestLatestRerun just checks that the result can be unmarshaled properly, has an 319 // updated status, and has equal spec. 320 func TestLatestRerun(t *testing.T) { 321 testCases := []struct { 322 name string 323 pjType prowapi.ProwJobType 324 config *config.Config 325 login string 326 authorized []string 327 allowAnyone bool 328 rerunCreatesJob bool 329 shouldCreateProwJob bool 330 reported bool 331 httpCode int 332 httpMethod string 333 enableScheduling bool 334 wantProwJobState prowapi.ProwJobState 335 }{ 336 { 337 name: "Handler returns Presubmit ProwJob", 338 pjType: prowapi.PresubmitJob, 339 config: getPresubmitConfig(), 340 login: "authorized", 341 authorized: []string{"authorized", "alsoauthorized"}, 342 allowAnyone: false, 343 rerunCreatesJob: true, 344 shouldCreateProwJob: true, 345 reported: false, 346 httpCode: http.StatusOK, 347 httpMethod: http.MethodPost, 348 wantProwJobState: prowapi.TriggeredState, 349 }, 350 { 351 name: "Handler returns Periodic ProwJob", 352 pjType: prowapi.PeriodicJob, 353 config: getPeriodicConfig(), 354 login: "authorized", 355 authorized: []string{"authorized", "alsoauthorized"}, 356 allowAnyone: false, 357 rerunCreatesJob: true, 358 shouldCreateProwJob: true, 359 reported: false, 360 httpCode: http.StatusOK, 361 httpMethod: http.MethodPost, 362 wantProwJobState: prowapi.TriggeredState, 363 }, 364 { 365 name: "User not authorized to create prow job", 366 pjType: prowapi.PresubmitJob, 367 config: getPresubmitConfig(), 368 login: "random-dude", 369 authorized: []string{"authorized", "alsoauthorized"}, 370 allowAnyone: false, 371 rerunCreatesJob: true, 372 shouldCreateProwJob: false, 373 reported: false, 374 httpCode: http.StatusOK, 375 httpMethod: http.MethodPost, 376 }, 377 { 378 name: "RerunCreatesJob set to false, should not create prow job", 379 pjType: prowapi.PresubmitJob, 380 config: getPresubmitConfig(), 381 login: "authorized", 382 authorized: []string{"authorized", "alsoauthorized"}, 383 allowAnyone: true, 384 rerunCreatesJob: false, 385 shouldCreateProwJob: false, 386 reported: true, 387 httpCode: http.StatusOK, 388 httpMethod: http.MethodGet, 389 }, 390 { 391 name: "Allow anyone set to true, creates job", 392 pjType: prowapi.PresubmitJob, 393 config: getPresubmitConfig(), 394 login: "ugh", 395 authorized: []string{"authorized", "alsoauthorized"}, 396 allowAnyone: true, 397 rerunCreatesJob: true, 398 shouldCreateProwJob: true, 399 reported: false, 400 httpCode: http.StatusOK, 401 httpMethod: http.MethodPost, 402 wantProwJobState: prowapi.TriggeredState, 403 }, 404 { 405 name: "Direct rerun disabled, post request", 406 pjType: prowapi.PresubmitJob, 407 config: getPresubmitConfig(), 408 login: "authorized", 409 authorized: []string{"authorized", "alsoauthorized"}, 410 allowAnyone: true, 411 rerunCreatesJob: false, 412 shouldCreateProwJob: false, 413 httpCode: http.StatusMethodNotAllowed, 414 httpMethod: http.MethodPost, 415 }, 416 { 417 name: "User permitted on specific job", 418 pjType: prowapi.PresubmitJob, 419 config: getPresubmitConfig(), 420 login: "authorized", 421 authorized: []string{}, 422 allowAnyone: false, 423 rerunCreatesJob: true, 424 shouldCreateProwJob: true, 425 reported: false, 426 httpCode: http.StatusOK, 427 httpMethod: http.MethodPost, 428 wantProwJobState: prowapi.TriggeredState, 429 }, 430 { 431 name: "User on permitted team", 432 pjType: prowapi.PresubmitJob, 433 config: getPresubmitConfig(), 434 login: "sig-lead", 435 authorized: []string{}, 436 allowAnyone: false, 437 rerunCreatesJob: true, 438 shouldCreateProwJob: true, 439 reported: false, 440 httpCode: http.StatusOK, 441 httpMethod: http.MethodPost, 442 wantProwJobState: prowapi.TriggeredState, 443 }, 444 { 445 name: "Org member permitted for presubmits", 446 pjType: prowapi.PresubmitJob, 447 config: getPresubmitConfig(), 448 login: "org-member", 449 authorized: []string{}, 450 allowAnyone: false, 451 rerunCreatesJob: true, 452 shouldCreateProwJob: true, 453 reported: false, 454 httpCode: http.StatusOK, 455 httpMethod: http.MethodPost, 456 wantProwJobState: prowapi.TriggeredState, 457 }, 458 { 459 name: "Org member not permitted for periodic", 460 pjType: prowapi.PeriodicJob, 461 config: getPeriodicConfig(), 462 login: "org-member", 463 authorized: []string{}, 464 allowAnyone: false, 465 rerunCreatesJob: true, 466 shouldCreateProwJob: false, 467 reported: false, 468 httpCode: http.StatusOK, 469 httpMethod: http.MethodPost, 470 }, 471 { 472 name: "Rerun ProwJob in scheduling state", 473 pjType: prowapi.PresubmitJob, 474 config: getPresubmitConfig(), 475 login: "authorized", 476 authorized: []string{"authorized", "alsoauthorized"}, 477 allowAnyone: false, 478 rerunCreatesJob: true, 479 shouldCreateProwJob: true, 480 reported: false, 481 httpCode: http.StatusOK, 482 httpMethod: http.MethodPost, 483 enableScheduling: true, 484 wantProwJobState: prowapi.SchedulingState, 485 }, 486 } 487 488 for _, tc := range testCases { 489 t.Run(tc.name, func(t *testing.T) { 490 fakeProwJobClient := fake.NewSimpleClientset(&prowapi.ProwJob{ 491 ObjectMeta: metav1.ObjectMeta{ 492 Name: "wowsuch", 493 Namespace: "prowjobs", 494 Labels: map[string]string{ 495 kube.GerritReportLabel: "foo", 496 "random": "foo", 497 }, 498 Annotations: map[string]string{ 499 kube.GerritID: "foo", 500 "random": "foo", 501 }, 502 }, 503 Spec: prowapi.ProwJobSpec{ 504 Job: "whoa", 505 Type: tc.pjType, 506 Refs: &prowapi.Refs{ 507 Org: "org", 508 Repo: "repo", 509 Pulls: []prowapi.Pull{ 510 { 511 Number: 1, 512 Author: tc.login, 513 }, 514 }, 515 BaseSHA: "foo", 516 BaseRef: "master", 517 }, 518 RerunAuthConfig: &prowapi.RerunAuthConfig{ 519 AllowAnyone: false, 520 GitHubUsers: []string{"random", "random"}, 521 }, 522 }, 523 Status: prowapi.ProwJobStatus{ 524 State: prowapi.PendingState, 525 }, 526 }) 527 authCfgGetter := func(refs *prowapi.ProwJobSpec) *prowapi.RerunAuthConfig { 528 return &prowapi.RerunAuthConfig{ 529 AllowAnyone: tc.allowAnyone, 530 GitHubUsers: tc.authorized, 531 } 532 } 533 534 req, err := http.NewRequest(tc.httpMethod, "/rerun?mode=latest&prowjob=wowsuch", nil) 535 if err != nil { 536 t.Fatalf("Error making request: %v", err) 537 } 538 req.AddCookie(&http.Cookie{ 539 Name: "github_login", 540 Value: tc.login, 541 Path: "/", 542 Expires: time.Now().Add(time.Hour * 24 * 30), 543 Secure: true, 544 }) 545 mockCookieStore := sessions.NewCookieStore([]byte("secret-key")) 546 session, err := sessions.GetRegistry(req).Get(mockCookieStore, "access-token-session") 547 if err != nil { 548 t.Fatalf("Error making access token session: %v", err) 549 } 550 session.Values["access-token"] = &oauth2.Token{AccessToken: "validtoken"} 551 552 rr := httptest.NewRecorder() 553 mockConfig := &githuboauth.Config{ 554 CookieStore: mockCookieStore, 555 } 556 goa := githuboauth.NewAgent(mockConfig, &logrus.Entry{}) 557 ghc := &fakeAuthenticatedUserIdentifier{login: tc.login} 558 rc := fakegithub.NewFakeClient() 559 rc.OrgMembers = map[string][]string{"org": {"org-member"}} 560 pca := plugins.NewFakeConfigAgent() 561 cfg := func() *config.Config { 562 cfg := tc.config 563 cfg.Scheduler.Enabled = tc.enableScheduling 564 return cfg 565 } 566 handler := handleRerun(cfg, fakeProwJobClient.ProwV1().ProwJobs("prowjobs"), tc.rerunCreatesJob, authCfgGetter, goa, ghc, rc, &pca, logrus.WithField("handler", "/rerun")) 567 handler.ServeHTTP(rr, req) 568 if rr.Code != tc.httpCode { 569 t.Fatalf("Bad error code: %d", rr.Code) 570 } 571 572 if tc.shouldCreateProwJob { 573 pjs, err := fakeProwJobClient.ProwV1().ProwJobs("prowjobs").List(context.Background(), metav1.ListOptions{}) 574 if err != nil { 575 t.Fatalf("failed to list prowjobs: %v", err) 576 } 577 if numPJs := len(pjs.Items); numPJs != 2 { 578 t.Errorf("expected to get two prowjobs, got %d", numPJs) 579 } 580 for i := range pjs.Items { 581 pj := &pjs.Items[i] 582 if pj.Name != "wowsuch" && pj.Status.State != tc.wantProwJobState { 583 t.Errorf("expected state %s but got %s in pj %s", tc.wantProwJobState, pj.Status.State, pj.Spec.Job) 584 } 585 } 586 } else if !tc.rerunCreatesJob && tc.httpCode == http.StatusOK { 587 expectedProwJob := prowapi.ProwJob{ 588 TypeMeta: metav1.TypeMeta{ 589 Kind: "ProwJob", 590 APIVersion: "prow.k8s.io/v1", 591 }, 592 ObjectMeta: metav1.ObjectMeta{ 593 Labels: map[string]string{ 594 "created-by-prow": "true", 595 "foo": "foo", 596 "prow.k8s.io/context": "", 597 "prow.k8s.io/gerrit-report-label": "foo", 598 "prow.k8s.io/job": "whoa", 599 "prow.k8s.io/refs.base_ref": "master", 600 "prow.k8s.io/refs.org": "org", 601 "prow.k8s.io/refs.pull": "1", 602 "prow.k8s.io/refs.repo": "repo", 603 "prow.k8s.io/type": string(tc.pjType), 604 }, 605 Annotations: map[string]string{ 606 "foo": "foo", 607 "prow.k8s.io/context": "", 608 "prow.k8s.io/gerrit-id": "foo", 609 "prow.k8s.io/job": "whoa", 610 }, 611 }, 612 Spec: prowapi.ProwJobSpec{ 613 Job: "whoa", 614 Type: tc.pjType, 615 Refs: &prowapi.Refs{ 616 Org: "org", 617 Repo: "repo", 618 Pulls: []prowapi.Pull{ 619 { 620 Number: 1, 621 Author: tc.login, 622 }, 623 }, 624 BaseSHA: "foo", 625 BaseRef: "master", 626 }, 627 Report: tc.reported, 628 RerunAuthConfig: &prowapi.RerunAuthConfig{ 629 AllowAnyone: false, 630 GitHubUsers: tc.authorized, 631 GitHubTeamIDs: []int{42}, 632 }, 633 }, 634 Status: prowapi.ProwJobStatus{ 635 State: prowapi.TriggeredState, 636 }, 637 } 638 639 resp := rr.Result() 640 defer resp.Body.Close() 641 body, err := io.ReadAll(resp.Body) 642 if err != nil { 643 t.Fatalf("Error reading response body: %v", err) 644 } 645 var res prowapi.ProwJob 646 if err := yaml.Unmarshal(body, &res); err != nil { 647 t.Fatalf("Error unmarshaling: %v", err) 648 } 649 // These two fields are undeterministic so there are being set to the default 650 res.Status.StartTime = metav1.Time{} 651 res.ObjectMeta.Name = "" 652 if diff := cmp.Diff(expectedProwJob, res); diff != "" { 653 t.Fatalf("Job mismatch. Want: (-), got: (+). \n%s", diff) 654 } 655 } 656 }) 657 } 658 } 659 660 func TestCanTriggerJob(t *testing.T) { 661 t.Parallel() 662 org := "org" 663 trustedUser := "trusted" 664 untrustedUser := "untrusted" 665 666 pcfg := &plugins.Configuration{ 667 Triggers: []plugins.Trigger{{Repos: []string{org}}}, 668 } 669 pcfgGetter := func() *plugins.Configuration { return pcfg } 670 671 ghc := fakegithub.NewFakeClient() 672 ghc.OrgMembers = map[string][]string{org: {trustedUser}} 673 674 pj := prowapi.ProwJob{ 675 Spec: prowapi.ProwJobSpec{ 676 Refs: &prowapi.Refs{ 677 Org: org, 678 Repo: "repo", 679 Pulls: []prowapi.Pull{{Author: trustedUser}}, 680 }, 681 Type: prowapi.PresubmitJob, 682 }, 683 } 684 testCases := []struct { 685 name string 686 user string 687 expectAllowed bool 688 }{ 689 { 690 name: "Unauthorized user can not rerun", 691 user: untrustedUser, 692 expectAllowed: false, 693 }, 694 { 695 name: "Authorized user can re-run", 696 user: trustedUser, 697 expectAllowed: true, 698 }, 699 } 700 701 log := logrus.NewEntry(logrus.StandardLogger()) 702 for _, tc := range testCases { 703 result, err := canTriggerJob(tc.user, pj, nil, ghc, pcfgGetter, log) 704 if err != nil { 705 t.Fatalf("error: %v", err) 706 } 707 if result != tc.expectAllowed { 708 t.Errorf("got result %t, expected %t", result, tc.expectAllowed) 709 } 710 } 711 }