github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/gerrit/adapter/adapter_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 adapter
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"regexp"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/andygrunwald/go-gerrit"
    28  	"github.com/google/go-cmp/cmp"
    29  	"github.com/google/go-cmp/cmp/cmpopts"
    30  	"github.com/sirupsen/logrus"
    31  	v1 "k8s.io/api/core/v1"
    32  	"k8s.io/apimachinery/pkg/api/equality"
    33  	"k8s.io/apimachinery/pkg/util/diff"
    34  	"k8s.io/apimachinery/pkg/util/sets"
    35  	clienttesting "k8s.io/client-go/testing"
    36  
    37  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    38  
    39  	prowapi "sigs.k8s.io/prow/pkg/apis/prowjobs/v1"
    40  	prowfake "sigs.k8s.io/prow/pkg/client/clientset/versioned/fake"
    41  	"sigs.k8s.io/prow/pkg/config"
    42  	reporter "sigs.k8s.io/prow/pkg/crier/reporters/gerrit"
    43  	"sigs.k8s.io/prow/pkg/gerrit/client"
    44  	"sigs.k8s.io/prow/pkg/git/localgit"
    45  	"sigs.k8s.io/prow/pkg/git/v2"
    46  	"sigs.k8s.io/prow/pkg/kube"
    47  )
    48  
    49  func makeStamp(t time.Time) gerrit.Timestamp {
    50  	return gerrit.Timestamp{Time: t}
    51  }
    52  
    53  var (
    54  	timeNow   = time.Date(1234, time.May, 15, 1, 2, 3, 4, time.UTC)
    55  	stampNow  = makeStamp(timeNow)
    56  	trueBool  = true
    57  	namespace = "default"
    58  )
    59  
    60  type fca struct {
    61  	sync.Mutex
    62  	c *config.Config
    63  }
    64  
    65  func (f *fca) Config() *config.Config {
    66  	f.Lock()
    67  	defer f.Unlock()
    68  	return f.c
    69  }
    70  
    71  type fgc struct {
    72  	reviews     int
    73  	instanceMap map[string]*gerrit.AccountInfo
    74  }
    75  
    76  func (f *fgc) HasRelatedChanges(instance, id, revision string) (bool, error) {
    77  	return false, nil
    78  }
    79  
    80  func (f *fgc) ApplyGlobalConfig(orgRepoConfigGetter func() *config.GerritOrgRepoConfigs, lastSyncTracker *client.SyncTime, cookiefilePath, tokenPathOverride string, additionalFunc func()) {
    81  
    82  }
    83  
    84  func (f *fgc) Authenticate(cookiefilePath, tokenPath string) {
    85  
    86  }
    87  
    88  func (f *fgc) QueryChanges(lastUpdate client.LastSyncState, rateLimit int) map[string][]client.ChangeInfo {
    89  	return nil
    90  }
    91  
    92  func (f *fgc) QueryChangesForProject(instance, project string, lastUpdate time.Time, rateLimit int, additionalFilters ...string) ([]gerrit.ChangeInfo, error) {
    93  	return nil, nil
    94  }
    95  
    96  func (f *fgc) SetReview(instance, id, revision, message string, labels map[string]string) error {
    97  	f.reviews++
    98  	return nil
    99  }
   100  
   101  func (f *fgc) GetBranchRevision(instance, project, branch string) (string, error) {
   102  	return "abc", nil
   103  }
   104  
   105  func (f *fgc) Account(instance string) (*gerrit.AccountInfo, error) {
   106  	res, ok := f.instanceMap[instance]
   107  	if !ok {
   108  		return nil, errors.New("not exit")
   109  	}
   110  	return res, nil
   111  }
   112  
   113  func fakeProwYAMLGetter(
   114  	c *config.Config,
   115  	gc git.ClientFactory,
   116  	identifier string,
   117  	baseBranch string,
   118  	baseSHA string,
   119  	headSHAs ...string) (*config.ProwYAML, error) {
   120  
   121  	presubmits := []config.Presubmit{
   122  		{
   123  			JobBase: config.JobBase{
   124  				Name:      "always-runs-inRepoConfig",
   125  				Spec:      &v1.PodSpec{Containers: []v1.Container{{Name: "always-runs-inRepoConfig", Env: []v1.EnvVar{}}}},
   126  				Namespace: &namespace,
   127  			},
   128  			Brancher: config.Brancher{
   129  				Branches: []string{"inRepoConfig"},
   130  			},
   131  			AlwaysRun: true,
   132  			Reporter: config.Reporter{
   133  				Context:    "always-runs-inRepoConfig",
   134  				SkipReport: true,
   135  			},
   136  		},
   137  	}
   138  	postsubmits := []config.Postsubmit{
   139  		{
   140  			JobBase: config.JobBase{
   141  				Name:      "always-runs-inRepoConfig-Post",
   142  				Spec:      &v1.PodSpec{Containers: []v1.Container{{Name: "always-runs-inRepoConfig-Post", Env: []v1.EnvVar{}}}},
   143  				Namespace: &namespace,
   144  			},
   145  			Brancher: config.Brancher{
   146  				Branches: []string{"inRepoConfig"},
   147  			},
   148  			AlwaysRun: &trueBool,
   149  			Reporter: config.Reporter{
   150  				Context:    "always-runs-inRepoConfig-Post",
   151  				SkipReport: true,
   152  			},
   153  		},
   154  	}
   155  	if err := config.SetPostsubmitRegexes(postsubmits); err != nil {
   156  		return nil, err
   157  	}
   158  	if err := config.SetPresubmitRegexes(presubmits); err != nil {
   159  		return nil, err
   160  	}
   161  	res := config.ProwYAML{
   162  		Presubmits:  presubmits,
   163  		Postsubmits: postsubmits,
   164  	}
   165  	return &res, nil
   166  }
   167  
   168  func TestShouldTriggerJobs(t *testing.T) {
   169  	now := time.Now()
   170  	instance := "gke-host"
   171  	project := "private-cloud"
   172  	var lastUpdateTime = now.Add(-time.Hour)
   173  	c := &Controller{
   174  		configAgent: &config.Agent{},
   175  	}
   176  	presubmitTriggerRawString := "(?mi)/test\\s.*"
   177  	c.configAgent.Set(&config.Config{ProwConfig: config.ProwConfig{Gerrit: config.Gerrit{AllowedPresubmitTriggerReRawString: presubmitTriggerRawString}}})
   178  	presubmitTriggerRegex, err := regexp.Compile(presubmitTriggerRawString)
   179  	if err != nil {
   180  		t.Fatalf("failed to compile regex for allowed presubmit triggers: %s", err.Error())
   181  	}
   182  	c.configAgent.Config().Gerrit.AllowedPresubmitTriggerRe = &config.CopyableRegexp{Regexp: presubmitTriggerRegex}
   183  	cases := []struct {
   184  		name     string
   185  		instance string
   186  		change   gerrit.ChangeInfo
   187  		latest   time.Time
   188  		result   bool
   189  	}{
   190  		{
   191  			name:     "trigger jobs when revision is new",
   192  			instance: instance,
   193  			change: gerrit.ChangeInfo{ID: "1", CurrentRevision: "10", Project: project,
   194  				Revisions: map[string]gerrit.RevisionInfo{
   195  					"10": {Created: makeStamp(now)},
   196  				}},
   197  			latest: lastUpdateTime,
   198  			result: true,
   199  		},
   200  		{
   201  			name:     "trigger jobs when comment contains test related commands",
   202  			instance: instance,
   203  			change: gerrit.ChangeInfo{ID: "1", CurrentRevision: "10", Project: project,
   204  				Revisions: map[string]gerrit.RevisionInfo{
   205  					"10": {Number: 10, Created: makeStamp(now.Add(-2 * time.Hour))},
   206  				}, Messages: []gerrit.ChangeMessageInfo{
   207  					{
   208  						Date:           makeStamp(now),
   209  						Message:        "/test all",
   210  						RevisionNumber: 10,
   211  					},
   212  				}},
   213  			latest: lastUpdateTime,
   214  			result: true,
   215  		},
   216  		{
   217  			name:     "trigger jobs when comment contains /test with custom test name",
   218  			instance: instance,
   219  			change: gerrit.ChangeInfo{ID: "1", CurrentRevision: "10", Project: project,
   220  				Revisions: map[string]gerrit.RevisionInfo{
   221  					"10": {Number: 10, Created: makeStamp(now.Add(-2 * time.Hour))},
   222  				}, Messages: []gerrit.ChangeMessageInfo{
   223  					{
   224  						Date:           makeStamp(now),
   225  						Message:        "/test integration",
   226  						RevisionNumber: 10,
   227  					},
   228  				}},
   229  			latest: lastUpdateTime,
   230  			result: true,
   231  		},
   232  		{
   233  			name:     "do not trigger when command does not conform to requirements",
   234  			instance: instance,
   235  			change: gerrit.ChangeInfo{ID: "1", CurrentRevision: "10", Project: project,
   236  				Revisions: map[string]gerrit.RevisionInfo{
   237  					"10": {Number: 10, Created: makeStamp(now.Add(-2 * time.Hour))},
   238  				}, Messages: []gerrit.ChangeMessageInfo{
   239  					{
   240  						Date:           makeStamp(now),
   241  						Message:        "LGTM",
   242  						RevisionNumber: 10,
   243  					},
   244  				}},
   245  			latest: lastUpdateTime,
   246  			result: false,
   247  		},
   248  		{
   249  			name:     "trigger jobs for merge events (in order to trigger postsubmit jobs)",
   250  			instance: instance,
   251  			change:   gerrit.ChangeInfo{Status: client.Merged},
   252  			latest:   lastUpdateTime,
   253  			result:   true,
   254  		},
   255  		{
   256  			name:     "trigger jobs for previously-seen change coming out of WIP status (via ReadyForReviewMessageFixed)",
   257  			instance: instance,
   258  			change: gerrit.ChangeInfo{ID: "1", CurrentRevision: "10", Project: project,
   259  				Revisions: map[string]gerrit.RevisionInfo{
   260  					"10": {
   261  						Number: 10,
   262  						// The associated revision is old (predates
   263  						// lastUpdateTime)...
   264  						Created: makeStamp(now.Add(-2 * time.Hour))},
   265  				}, Messages: []gerrit.ChangeMessageInfo{
   266  					{
   267  						Date: makeStamp(now),
   268  						// ...but we shouldn't skip triggering jobs for it
   269  						// because the message says this is no longer WIP.
   270  						Message:        client.ReadyForReviewMessageFixed,
   271  						RevisionNumber: 10,
   272  					},
   273  				}},
   274  			latest: lastUpdateTime,
   275  			result: true,
   276  		},
   277  		{
   278  			name:     "trigger jobs for previously-seen change coming out of WIP status (via ReadyForReviewMessageCustomizable)",
   279  			instance: instance,
   280  			change: gerrit.ChangeInfo{ID: "1", CurrentRevision: "10", Project: project,
   281  				Revisions: map[string]gerrit.RevisionInfo{
   282  					"10": {
   283  						Number: 10,
   284  						// The associated revision is old (predates
   285  						// lastUpdateTime)...
   286  						Created: makeStamp(now.Add(-2 * time.Hour))},
   287  				}, Messages: []gerrit.ChangeMessageInfo{
   288  					{
   289  						Date: makeStamp(now),
   290  						// ...but we shouldn't skip triggering jobs for it
   291  						// because the message says this is no longer WIP.
   292  						Message:        client.ReadyForReviewMessageCustomizable,
   293  						RevisionNumber: 10,
   294  					},
   295  				}},
   296  			latest: lastUpdateTime,
   297  			result: true,
   298  		},
   299  	}
   300  
   301  	for _, tc := range cases {
   302  		t.Run(tc.name, func(t *testing.T) {
   303  			if got := c.shouldTriggerJobs(tc.change, tc.latest); got != tc.result {
   304  				t.Errorf("want %t, got %t", tc.result, got)
   305  			}
   306  		})
   307  	}
   308  }
   309  
   310  func TestHandleInRepoConfigError(t *testing.T) {
   311  	change := gerrit.ChangeInfo{ID: "1", CurrentRevision: "1"}
   312  	instanceName := "instance"
   313  	changeHash := fmt.Sprintf("%s%s%s", instanceName, change.ID, change.CurrentRevision)
   314  	cases := []struct {
   315  		name                      string
   316  		err                       error
   317  		allowedPresubmitTriggerRe string
   318  		startingFailures          map[string]bool
   319  		expectedFailures          map[string]bool
   320  		expectedReview            bool
   321  	}{
   322  		{
   323  			name:             "No error. Do not send message",
   324  			expectedReview:   false,
   325  			startingFailures: map[string]bool{},
   326  			expectedFailures: map[string]bool{},
   327  			err:              nil,
   328  		},
   329  		{
   330  			name:             "First time (or previously resolved) error send review",
   331  			err:              errors.New("InRepoConfigError"),
   332  			expectedReview:   true,
   333  			startingFailures: map[string]bool{},
   334  			expectedFailures: map[string]bool{changeHash: true},
   335  		},
   336  		{
   337  			name:             "second time error do not send review",
   338  			err:              errors.New("InRepoConfigError"),
   339  			expectedReview:   false,
   340  			startingFailures: map[string]bool{changeHash: true},
   341  			expectedFailures: map[string]bool{changeHash: true},
   342  		},
   343  		{
   344  			name:             "Resolved error changes Failures map",
   345  			err:              nil,
   346  			expectedReview:   false,
   347  			startingFailures: map[string]bool{changeHash: true},
   348  			expectedFailures: map[string]bool{},
   349  		},
   350  		{
   351  			name:                      "second time error DO send review if irrelevant changes are being skipped",
   352  			err:                       errors.New("InRepoConfigError"),
   353  			allowedPresubmitTriggerRe: "^/test.*",
   354  			expectedReview:            true,
   355  			startingFailures:          map[string]bool{changeHash: true},
   356  			expectedFailures:          map[string]bool{changeHash: true},
   357  		},
   358  	}
   359  	for _, tc := range cases {
   360  		t.Run(tc.name, func(t *testing.T) {
   361  			gc := &fgc{reviews: 0}
   362  			gerritConfig := config.Gerrit{AllowedPresubmitTriggerReRawString: tc.allowedPresubmitTriggerRe}
   363  			if err := gerritConfig.DefaultAndValidate(); err != nil {
   364  				t.Fatalf("Failed to default and validate the gerrit config: %v", err)
   365  			}
   366  			controller := &Controller{
   367  				inRepoConfigFailuresTracker: tc.startingFailures,
   368  				gc:                          gc,
   369  				config:                      func() *config.Config { return &config.Config{ProwConfig: config.ProwConfig{Gerrit: gerritConfig}} },
   370  			}
   371  
   372  			ret := controller.handleInRepoConfigError(tc.err, instanceName, change)
   373  			if ret != nil {
   374  				t.Errorf("handleInRepoConfigError returned with non nil error")
   375  			}
   376  			if tc.expectedReview && gc.reviews == 0 {
   377  				t.Errorf("expected a review and did not get one")
   378  			}
   379  			if !tc.expectedReview && gc.reviews != 0 {
   380  				t.Error("expected no reviews and got one")
   381  			}
   382  			if diff := cmp.Diff(tc.expectedFailures, controller.inRepoConfigFailuresTracker, cmpopts.SortSlices(func(a, b string) bool {
   383  				return a < b
   384  			})); diff != "" {
   385  				t.Fatalf("expected failures mismatch. got(+), want(-):\n%s", diff)
   386  			}
   387  		})
   388  	}
   389  }
   390  
   391  type fakeSync struct {
   392  	val  client.LastSyncState
   393  	lock sync.Mutex
   394  }
   395  
   396  func (s *fakeSync) Current() client.LastSyncState {
   397  	s.lock.Lock()
   398  	defer s.lock.Unlock()
   399  	return s.val
   400  }
   401  
   402  func (s *fakeSync) Update(t client.LastSyncState) error {
   403  	s.lock.Lock()
   404  	defer s.lock.Unlock()
   405  	s.val = t
   406  	return nil
   407  }
   408  
   409  func TestCreateRefs(t *testing.T) {
   410  	reviewHost := "https://cat-review.example.com"
   411  	change := client.ChangeInfo{
   412  		Number:          42,
   413  		Project:         "meow/purr",
   414  		CurrentRevision: "123456",
   415  		Branch:          "master",
   416  		Revisions: map[string]client.RevisionInfo{
   417  			"123456": {
   418  				Ref: "refs/changes/00/1/1",
   419  				Commit: gerrit.CommitInfo{
   420  					Author: gerrit.GitPersonInfo{
   421  						Name:  "Some Cat",
   422  						Email: "nyan@example.com",
   423  					},
   424  				},
   425  			},
   426  		},
   427  	}
   428  	expected := prowapi.Refs{
   429  		Org:      "https://cat-review.example.com",
   430  		Repo:     "meow/purr",
   431  		BaseRef:  "master",
   432  		BaseSHA:  "abcdef",
   433  		CloneURI: "https://cat-review.example.com/meow/purr",
   434  		RepoLink: "https://cat.example.com/meow/purr",
   435  		BaseLink: "https://cat.example.com/meow/purr/+/abcdef",
   436  		Pulls: []prowapi.Pull{
   437  			{
   438  				Number:     42,
   439  				Author:     "Some Cat",
   440  				SHA:        "123456",
   441  				Ref:        "refs/changes/00/1/1",
   442  				Link:       "https://cat-review.example.com/c/meow/purr/+/42",
   443  				CommitLink: "https://cat.example.com/meow/purr/+/123456",
   444  				AuthorLink: "https://cat-review.example.com/q/nyan@example.com",
   445  			},
   446  		},
   447  	}
   448  	actual, err := CreateRefs(reviewHost, change.Project, change.Branch, "abcdef", change)
   449  	if err != nil {
   450  		t.Errorf("unexpected error creating refs: %v", err)
   451  	}
   452  	if !equality.Semantic.DeepEqual(expected, actual) {
   453  		t.Errorf("diff between expected and actual refs:%s", diff.ObjectReflectDiff(expected, actual))
   454  	}
   455  }
   456  
   457  func TestFailedJobs(t *testing.T) {
   458  	const (
   459  		me      = 314159
   460  		stan    = 666
   461  		current = 555
   462  		old     = 4
   463  	)
   464  	now := time.Now()
   465  	message := func(msg string, patch func(*gerrit.ChangeMessageInfo)) gerrit.ChangeMessageInfo {
   466  		var out gerrit.ChangeMessageInfo
   467  		out.Author.AccountID = me
   468  		out.Message = msg
   469  		out.RevisionNumber = current
   470  		out.Date.Time = now
   471  		now = now.Add(time.Minute)
   472  		if patch != nil {
   473  			patch(&out)
   474  		}
   475  		return out
   476  	}
   477  
   478  	report := func(jobs map[string]prowapi.ProwJobState) string {
   479  		var pjs []*prowapi.ProwJob
   480  		for name, state := range jobs {
   481  			var pj prowapi.ProwJob
   482  			pj.Spec.Job = name
   483  			pj.Status.State = state
   484  			pj.Status.URL = "whatever"
   485  			pjs = append(pjs, &pj)
   486  		}
   487  		return reporter.GenerateReport(pjs, 0).String()
   488  	}
   489  
   490  	cases := []struct {
   491  		name     string
   492  		messages []gerrit.ChangeMessageInfo
   493  		expected sets.Set[string]
   494  	}{
   495  		{
   496  			name: "basically works",
   497  		},
   498  		{
   499  			name: "report parses",
   500  			messages: []gerrit.ChangeMessageInfo{
   501  				message("ignore this", nil),
   502  				message(report(map[string]prowapi.ProwJobState{
   503  					"foo":          prowapi.SuccessState,
   504  					"should-fail":  prowapi.FailureState,
   505  					"should-abort": prowapi.AbortedState,
   506  				}), nil),
   507  				message("also ignore this", nil),
   508  			},
   509  			expected: sets.New[string]("should-fail", "should-abort"),
   510  		},
   511  		{
   512  			name: "ignore report from someone else",
   513  			messages: []gerrit.ChangeMessageInfo{
   514  				message(report(map[string]prowapi.ProwJobState{
   515  					"foo":                  prowapi.SuccessState,
   516  					"ignore-their-failure": prowapi.FailureState,
   517  				}), func(msg *gerrit.ChangeMessageInfo) {
   518  					msg.Author.AccountID = stan
   519  				}),
   520  				message(report(map[string]prowapi.ProwJobState{
   521  					"whatever":    prowapi.SuccessState,
   522  					"should-fail": prowapi.FailureState,
   523  				}), nil),
   524  			},
   525  			expected: sets.New[string]("should-fail"),
   526  		},
   527  		{
   528  			name: "ignore failures on other revisions",
   529  			messages: []gerrit.ChangeMessageInfo{
   530  				message(report(map[string]prowapi.ProwJobState{
   531  					"current-pass": prowapi.SuccessState,
   532  					"current-fail": prowapi.FailureState,
   533  				}), nil),
   534  				message(report(map[string]prowapi.ProwJobState{
   535  					"old-pass": prowapi.SuccessState,
   536  					"old-fail": prowapi.FailureState,
   537  				}), func(msg *gerrit.ChangeMessageInfo) {
   538  					msg.RevisionNumber = old
   539  				}),
   540  			},
   541  			expected: sets.New[string]("current-fail"),
   542  		},
   543  		{
   544  			name: "ignore jobs in my earlier report",
   545  			messages: []gerrit.ChangeMessageInfo{
   546  				message(report(map[string]prowapi.ProwJobState{
   547  					"failed-then-pass": prowapi.FailureState,
   548  					"old-broken":       prowapi.FailureState,
   549  					"old-pass":         prowapi.SuccessState,
   550  					"pass-then-failed": prowapi.SuccessState,
   551  					"still-fail":       prowapi.FailureState,
   552  					"still-pass":       prowapi.SuccessState,
   553  				}), nil),
   554  				message(report(map[string]prowapi.ProwJobState{
   555  					"failed-then-pass": prowapi.SuccessState,
   556  					"new-broken":       prowapi.FailureState,
   557  					"new-pass":         prowapi.SuccessState,
   558  					"pass-then-failed": prowapi.FailureState,
   559  					"still-fail":       prowapi.FailureState,
   560  					"still-pass":       prowapi.SuccessState,
   561  				}), nil),
   562  			},
   563  			expected: sets.New[string]("old-broken", "new-broken", "still-fail", "pass-then-failed"),
   564  		},
   565  		{
   566  			// https://en.wikipedia.org/wiki/Gravitational_redshift
   567  			name: "handle gravitationally redshifted results",
   568  			messages: []gerrit.ChangeMessageInfo{
   569  				message(report(map[string]prowapi.ProwJobState{
   570  					"earth-broken":              prowapi.FailureState,
   571  					"earth-pass":                prowapi.SuccessState,
   572  					"fail-earth-pass-blackhole": prowapi.FailureState,
   573  					"pass-earth-fail-blackhole": prowapi.SuccessState,
   574  				}), nil),
   575  				message(report(map[string]prowapi.ProwJobState{
   576  					"blackhole-broken":          prowapi.FailureState,
   577  					"blackhole-pass":            prowapi.SuccessState,
   578  					"fail-earth-pass-blackhole": prowapi.SuccessState,
   579  					"pass-earth-fail-blackhole": prowapi.FailureState,
   580  				}), func(change *gerrit.ChangeMessageInfo) {
   581  					change.Date.Time = change.Date.Time.Add(-time.Hour)
   582  				}),
   583  			},
   584  			expected: sets.New[string]("earth-broken", "blackhole-broken", "fail-earth-pass-blackhole"),
   585  		},
   586  	}
   587  
   588  	for _, tc := range cases {
   589  		t.Run(tc.name, func(t *testing.T) {
   590  			if actual, expected := failedJobs(me, current, tc.messages...), tc.expected; !equality.Semantic.DeepEqual(expected, actual) {
   591  				t.Errorf(diff.ObjectReflectDiff(expected, actual))
   592  			}
   593  		})
   594  	}
   595  }
   596  
   597  func createTestRepoCache(t *testing.T, ca *fca) (*config.InRepoConfigCache, error) {
   598  	// triggerJobs takes a ClientFactory. If provided a nil clientFactory it will skip inRepoConfig
   599  	// otherwise it will get the prow yaml using the client provided. We are mocking ProwYamlGetter
   600  	// so we are creating a localClientFactory but leaving it unpopulated.
   601  	var cf git.ClientFactory
   602  	var lg *localgit.LocalGit
   603  	lg, cf, err := localgit.NewV2()
   604  	if err != nil {
   605  		return nil, fmt.Errorf("error making local git repo: %v", err)
   606  	}
   607  	defer func() {
   608  		if err := lg.Clean(); err != nil {
   609  			t.Errorf("Error cleaning LocalGit: %v", err)
   610  		}
   611  		if err := cf.Clean(); err != nil {
   612  			t.Errorf("Error cleaning Client: %v", err)
   613  		}
   614  	}()
   615  
   616  	// Initialize cache for fetching Presubmit and Postsubmit information. If
   617  	// the cache cannot be initialized, exit with an error.
   618  	cache, err := config.NewInRepoConfigCache(10, ca, cf)
   619  	if err != nil {
   620  		t.Errorf("error creating cache: %v", err)
   621  	}
   622  	return cache, nil
   623  }
   624  
   625  func TestTriggerJobs(t *testing.T) {
   626  	testInstance := "https://gerrit"
   627  	var testcases = []struct {
   628  		name           string
   629  		change         client.ChangeInfo
   630  		instancesMap   map[string]*gerrit.AccountInfo
   631  		instance       string
   632  		wantError      bool
   633  		wantSkipReport bool
   634  		wantPjs        []*prowapi.ProwJob
   635  	}{
   636  		{
   637  			name: "no presubmit Prow jobs automatically triggered from WorkInProgess change",
   638  			change: client.ChangeInfo{
   639  				CurrentRevision: "1",
   640  				Project:         "test-infra",
   641  				Status:          "NEW",
   642  				WorkInProgress:  true,
   643  				Revisions: map[string]gerrit.RevisionInfo{
   644  					"1": {
   645  						Number: 1001,
   646  					},
   647  				},
   648  			},
   649  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   650  			instance:     testInstance,
   651  		},
   652  		{
   653  			name: "no revisions errors out",
   654  			change: client.ChangeInfo{
   655  				CurrentRevision: "1",
   656  				Project:         "test-infra",
   657  				Status:          "NEW",
   658  			},
   659  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   660  			instance:     testInstance,
   661  			wantError:    true,
   662  		},
   663  		{
   664  			name: "wrong project triggers no jobs",
   665  			change: client.ChangeInfo{
   666  				CurrentRevision: "1",
   667  				Project:         "woof",
   668  				Status:          "NEW",
   669  				Revisions: map[string]client.RevisionInfo{
   670  					"1": {
   671  						Created: stampNow,
   672  					},
   673  				},
   674  			},
   675  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   676  			instance:     testInstance,
   677  		},
   678  		{
   679  			name: "normal changes should trigger matching branch jobs",
   680  			change: client.ChangeInfo{
   681  				CurrentRevision: "1",
   682  				Project:         "test-infra",
   683  				Status:          "NEW",
   684  				Revisions: map[string]client.RevisionInfo{
   685  					"1": {
   686  						Ref:     "refs/changes/00/1/1",
   687  						Created: stampNow,
   688  					},
   689  				},
   690  			},
   691  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   692  			instance:     testInstance,
   693  			wantPjs: []*prowapi.ProwJob{
   694  				{
   695  					ObjectMeta: metav1.ObjectMeta{
   696  						Labels: map[string]string{
   697  							"prow.k8s.io/refs.repo":           "test-infra",
   698  							"prow.k8s.io/gerrit-patchset":     "0",
   699  							"prow.k8s.io/job":                 "always-runs-all-branches",
   700  							"prow.k8s.io/context":             "always-runs-all-branches",
   701  							"prow.k8s.io/gerrit-report-label": "Code-Review",
   702  							"prow.k8s.io/gerrit-revision":     "1",
   703  							"created-by-prow":                 "true",
   704  							"prow.k8s.io/type":                "presubmit",
   705  							"prow.k8s.io/refs.base_ref":       "",
   706  							"prow.k8s.io/refs.pull":           "0",
   707  							"prow.k8s.io/refs.org":            "gerrit",
   708  						},
   709  						Annotations: map[string]string{
   710  							"prow.k8s.io/job":             "always-runs-all-branches",
   711  							"prow.k8s.io/context":         "always-runs-all-branches",
   712  							"foo":                         "bar",
   713  							"prow.k8s.io/gerrit-instance": "https://gerrit",
   714  							"prow.k8s.io/gerrit-id":       "",
   715  						},
   716  					},
   717  					Spec: prowapi.ProwJobSpec{
   718  						Refs: &prowapi.Refs{
   719  							Org:      "https://gerrit",
   720  							Repo:     "test-infra",
   721  							RepoLink: "https://gerrit/test-infra",
   722  							BaseSHA:  "abc",
   723  							BaseLink: "https://gerrit/test-infra/+/abc",
   724  							CloneURI: "https://gerrit/test-infra",
   725  							Pulls: []prowapi.Pull{
   726  								{
   727  									Ref:        "refs/changes/00/1/1",
   728  									SHA:        "1",
   729  									Link:       "https://gerrit/c/test-infra/+/0",
   730  									CommitLink: "https://gerrit/test-infra/+/1",
   731  									AuthorLink: "https://gerrit/q/",
   732  								},
   733  							},
   734  						},
   735  					},
   736  				},
   737  				{
   738  					ObjectMeta: metav1.ObjectMeta{
   739  						Labels: map[string]string{
   740  							"prow.k8s.io/gerrit-patchset":     "0",
   741  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
   742  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
   743  							"prow.k8s.io/refs.base_ref":       "",
   744  							"prow.k8s.io/refs.pull":           "0",
   745  							"prow.k8s.io/gerrit-revision":     "1",
   746  							"prow.k8s.io/refs.repo":           "test-infra",
   747  							"prow.k8s.io/gerrit-report-label": "Code-Review",
   748  							"created-by-prow":                 "true",
   749  							"prow.k8s.io/type":                "presubmit",
   750  							"prow.k8s.io/refs.org":            "gerrit",
   751  						},
   752  						Annotations: map[string]string{
   753  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
   754  							"prow.k8s.io/gerrit-id":       "",
   755  							"prow.k8s.io/gerrit-instance": "https://gerrit",
   756  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
   757  						},
   758  					},
   759  					Spec: prowapi.ProwJobSpec{
   760  						Refs: &prowapi.Refs{
   761  							Org:      "https://gerrit",
   762  							Repo:     "test-infra",
   763  							RepoLink: "https://gerrit/test-infra",
   764  							BaseSHA:  "abc",
   765  							BaseLink: "https://gerrit/test-infra/+/abc",
   766  							CloneURI: "https://gerrit/test-infra",
   767  							Pulls: []prowapi.Pull{
   768  								{
   769  									Ref:        "refs/changes/00/1/1",
   770  									SHA:        "1",
   771  									Link:       "https://gerrit/c/test-infra/+/0",
   772  									CommitLink: "https://gerrit/test-infra/+/1",
   773  									AuthorLink: "https://gerrit/q/",
   774  								},
   775  							},
   776  						},
   777  					},
   778  				},
   779  			},
   780  		},
   781  		{
   782  			name: "instance not registered",
   783  			change: client.ChangeInfo{
   784  				CurrentRevision: "1",
   785  				Project:         "test-infra",
   786  				Status:          "NEW",
   787  				Revisions: map[string]client.RevisionInfo{
   788  					"1": {
   789  						Ref:     "refs/changes/00/1/1",
   790  						Created: stampNow,
   791  					},
   792  				},
   793  			},
   794  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   795  			instance:     testInstance + "_notexist",
   796  			wantError:    true,
   797  		},
   798  		{
   799  			name: "jobs should trigger with correct labels",
   800  			change: client.ChangeInfo{
   801  				CurrentRevision: "rev42",
   802  				Project:         "test-infra",
   803  				Status:          "NEW",
   804  				Revisions: map[string]client.RevisionInfo{
   805  					"rev42": {
   806  						Ref:     "refs/changes/00/1/1",
   807  						Created: stampNow,
   808  						Number:  42,
   809  					},
   810  				},
   811  			},
   812  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   813  			instance:     testInstance,
   814  			wantPjs: []*prowapi.ProwJob{
   815  				{
   816  					ObjectMeta: metav1.ObjectMeta{
   817  						Labels: map[string]string{
   818  							"prow.k8s.io/gerrit-report-label": "Code-Review",
   819  							"prow.k8s.io/context":             "always-runs-all-branches",
   820  							"prow.k8s.io/refs.repo":           "test-infra",
   821  							"prow.k8s.io/refs.base_ref":       "",
   822  							"prow.k8s.io/refs.pull":           "0",
   823  							"prow.k8s.io/refs.org":            "gerrit",
   824  							"prow.k8s.io/gerrit-patchset":     "42",
   825  							"prow.k8s.io/gerrit-revision":     "rev42",
   826  							"created-by-prow":                 "true",
   827  							"prow.k8s.io/type":                "presubmit",
   828  							"prow.k8s.io/job":                 "always-runs-all-branches",
   829  						},
   830  						Annotations: map[string]string{
   831  							"prow.k8s.io/gerrit-instance": "https://gerrit",
   832  							"prow.k8s.io/gerrit-id":       "",
   833  							"prow.k8s.io/job":             "always-runs-all-branches",
   834  							"prow.k8s.io/context":         "always-runs-all-branches",
   835  							"foo":                         "bar",
   836  						},
   837  					},
   838  					Spec: prowapi.ProwJobSpec{
   839  						Refs: &prowapi.Refs{
   840  							Org:      "https://gerrit",
   841  							Repo:     "test-infra",
   842  							RepoLink: "https://gerrit/test-infra",
   843  							BaseSHA:  "abc",
   844  							BaseLink: "https://gerrit/test-infra/+/abc",
   845  							CloneURI: "https://gerrit/test-infra",
   846  							Pulls: []prowapi.Pull{
   847  								{
   848  									Ref:        "refs/changes/00/1/1",
   849  									SHA:        "rev42",
   850  									Link:       "https://gerrit/c/test-infra/+/0",
   851  									CommitLink: "https://gerrit/test-infra/+/rev42",
   852  									AuthorLink: "https://gerrit/q/",
   853  								},
   854  							},
   855  						},
   856  					},
   857  				},
   858  				{
   859  					ObjectMeta: metav1.ObjectMeta{
   860  						Labels: map[string]string{
   861  							"prow.k8s.io/refs.base_ref":       "",
   862  							"prow.k8s.io/refs.pull":           "0",
   863  							"created-by-prow":                 "true",
   864  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
   865  							"prow.k8s.io/refs.repo":           "test-infra",
   866  							"prow.k8s.io/gerrit-report-label": "Code-Review",
   867  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
   868  							"prow.k8s.io/refs.org":            "gerrit",
   869  							"prow.k8s.io/gerrit-revision":     "rev42",
   870  							"prow.k8s.io/gerrit-patchset":     "42",
   871  							"prow.k8s.io/type":                "presubmit",
   872  						},
   873  						Annotations: map[string]string{
   874  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
   875  							"prow.k8s.io/gerrit-instance": "https://gerrit",
   876  							"prow.k8s.io/gerrit-id":       "",
   877  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
   878  						},
   879  					},
   880  					Spec: prowapi.ProwJobSpec{
   881  						Refs: &prowapi.Refs{
   882  							Org:      "https://gerrit",
   883  							Repo:     "test-infra",
   884  							RepoLink: "https://gerrit/test-infra",
   885  							BaseSHA:  "abc",
   886  							BaseLink: "https://gerrit/test-infra/+/abc",
   887  							CloneURI: "https://gerrit/test-infra",
   888  							Pulls: []prowapi.Pull{
   889  								{
   890  									Ref:        "refs/changes/00/1/1",
   891  									SHA:        "rev42",
   892  									Link:       "https://gerrit/c/test-infra/+/0",
   893  									CommitLink: "https://gerrit/test-infra/+/rev42",
   894  									AuthorLink: "https://gerrit/q/",
   895  								},
   896  							},
   897  						},
   898  					},
   899  				},
   900  			},
   901  		},
   902  		{
   903  			name: "multiple revisions",
   904  			change: client.ChangeInfo{
   905  				CurrentRevision: "2",
   906  				Project:         "test-infra",
   907  				Status:          "NEW",
   908  				Revisions: map[string]client.RevisionInfo{
   909  					"1": {
   910  						Ref:     "refs/changes/00/2/1",
   911  						Created: stampNow,
   912  					},
   913  					"2": {
   914  						Ref:     "refs/changes/00/2/2",
   915  						Created: stampNow,
   916  					},
   917  				},
   918  			},
   919  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
   920  			instance:     testInstance,
   921  			wantPjs: []*prowapi.ProwJob{
   922  				{
   923  					ObjectMeta: metav1.ObjectMeta{
   924  						Labels: map[string]string{
   925  							"prow.k8s.io/job":                 "always-runs-all-branches",
   926  							"prow.k8s.io/gerrit-patchset":     "0",
   927  							"prow.k8s.io/context":             "always-runs-all-branches",
   928  							"prow.k8s.io/refs.pull":           "0",
   929  							"prow.k8s.io/gerrit-report-label": "Code-Review",
   930  							"prow.k8s.io/refs.repo":           "test-infra",
   931  							"prow.k8s.io/gerrit-revision":     "2",
   932  							"created-by-prow":                 "true",
   933  							"prow.k8s.io/type":                "presubmit",
   934  							"prow.k8s.io/refs.org":            "gerrit",
   935  							"prow.k8s.io/refs.base_ref":       "",
   936  						},
   937  						Annotations: map[string]string{
   938  							"prow.k8s.io/job":             "always-runs-all-branches",
   939  							"prow.k8s.io/context":         "always-runs-all-branches",
   940  							"prow.k8s.io/gerrit-id":       "",
   941  							"foo":                         "bar",
   942  							"prow.k8s.io/gerrit-instance": "https://gerrit",
   943  						},
   944  					},
   945  					Spec: prowapi.ProwJobSpec{
   946  						Refs: &prowapi.Refs{
   947  							Org:      "https://gerrit",
   948  							Repo:     "test-infra",
   949  							RepoLink: "https://gerrit/test-infra",
   950  							BaseSHA:  "abc",
   951  							BaseLink: "https://gerrit/test-infra/+/abc",
   952  							CloneURI: "https://gerrit/test-infra",
   953  							Pulls: []prowapi.Pull{
   954  								{
   955  									Ref:        "refs/changes/00/2/2",
   956  									SHA:        "2",
   957  									Link:       "https://gerrit/c/test-infra/+/0",
   958  									CommitLink: "https://gerrit/test-infra/+/2",
   959  									AuthorLink: "https://gerrit/q/",
   960  								},
   961  							},
   962  						},
   963  					},
   964  				},
   965  				{
   966  					ObjectMeta: metav1.ObjectMeta{
   967  						Labels: map[string]string{
   968  							"prow.k8s.io/refs.pull":           "0",
   969  							"created-by-prow":                 "true",
   970  							"prow.k8s.io/type":                "presubmit",
   971  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
   972  							"prow.k8s.io/refs.repo":           "test-infra",
   973  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
   974  							"prow.k8s.io/gerrit-patchset":     "0",
   975  							"prow.k8s.io/gerrit-report-label": "Code-Review",
   976  							"prow.k8s.io/refs.org":            "gerrit",
   977  							"prow.k8s.io/gerrit-revision":     "2",
   978  							"prow.k8s.io/refs.base_ref":       "",
   979  						},
   980  						Annotations: map[string]string{
   981  							"prow.k8s.io/gerrit-instance": "https://gerrit",
   982  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
   983  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
   984  							"prow.k8s.io/gerrit-id":       "",
   985  						},
   986  					},
   987  					Spec: prowapi.ProwJobSpec{
   988  						Refs: &prowapi.Refs{
   989  							Org:      "https://gerrit",
   990  							Repo:     "test-infra",
   991  							RepoLink: "https://gerrit/test-infra",
   992  							BaseSHA:  "abc",
   993  							BaseLink: "https://gerrit/test-infra/+/abc",
   994  							CloneURI: "https://gerrit/test-infra",
   995  							Pulls: []prowapi.Pull{
   996  								{
   997  									Ref:        "refs/changes/00/2/2",
   998  									SHA:        "2",
   999  									Link:       "https://gerrit/c/test-infra/+/0",
  1000  									CommitLink: "https://gerrit/test-infra/+/2",
  1001  									AuthorLink: "https://gerrit/q/",
  1002  								},
  1003  							},
  1004  						},
  1005  					},
  1006  				},
  1007  			},
  1008  		},
  1009  		{
  1010  			name: "other-test-with-https",
  1011  			change: client.ChangeInfo{
  1012  				CurrentRevision: "1",
  1013  				Project:         "other-repo",
  1014  				Status:          "NEW",
  1015  				Revisions: map[string]client.RevisionInfo{
  1016  					"1": {
  1017  						Ref:     "refs/changes/00/1/1",
  1018  						Created: stampNow,
  1019  					},
  1020  				},
  1021  			},
  1022  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1023  			instance:     testInstance,
  1024  			wantPjs: []*prowapi.ProwJob{
  1025  				{
  1026  					ObjectMeta: metav1.ObjectMeta{
  1027  						Labels: map[string]string{
  1028  							"prow.k8s.io/context":             "other-test",
  1029  							"prow.k8s.io/refs.pull":           "0",
  1030  							"created-by-prow":                 "true",
  1031  							"prow.k8s.io/gerrit-revision":     "1",
  1032  							"prow.k8s.io/type":                "presubmit",
  1033  							"prow.k8s.io/refs.base_ref":       "",
  1034  							"prow.k8s.io/gerrit-patchset":     "0",
  1035  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1036  							"prow.k8s.io/refs.repo":           "other-repo",
  1037  							"prow.k8s.io/job":                 "other-test",
  1038  							"prow.k8s.io/refs.org":            "gerrit",
  1039  						},
  1040  						Annotations: map[string]string{
  1041  							"prow.k8s.io/job":             "other-test",
  1042  							"prow.k8s.io/context":         "other-test",
  1043  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1044  							"prow.k8s.io/gerrit-id":       "",
  1045  						},
  1046  					},
  1047  					Spec: prowapi.ProwJobSpec{
  1048  						Refs: &prowapi.Refs{
  1049  							Org:      "https://gerrit",
  1050  							Repo:     "other-repo",
  1051  							RepoLink: "https://gerrit/other-repo",
  1052  							BaseSHA:  "abc",
  1053  							BaseLink: "https://gerrit/other-repo/+/abc",
  1054  							CloneURI: "https://gerrit/other-repo",
  1055  							Pulls: []prowapi.Pull{
  1056  								{
  1057  									Ref:        "refs/changes/00/1/1",
  1058  									SHA:        "1",
  1059  									Link:       "https://gerrit/c/other-repo/+/0",
  1060  									CommitLink: "https://gerrit/other-repo/+/1",
  1061  									AuthorLink: "https://gerrit/q/",
  1062  								},
  1063  							},
  1064  						},
  1065  					},
  1066  				},
  1067  			},
  1068  		},
  1069  		{
  1070  			name: "merged change should trigger postsubmit",
  1071  			change: client.ChangeInfo{
  1072  				CurrentRevision: "1",
  1073  				Project:         "postsubmits-project",
  1074  				Status:          "MERGED",
  1075  				Revisions: map[string]client.RevisionInfo{
  1076  					"1": {
  1077  						Ref:     "refs/changes/00/1/1",
  1078  						Created: stampNow,
  1079  					},
  1080  				},
  1081  			},
  1082  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1083  			instance:     testInstance,
  1084  			wantPjs: []*prowapi.ProwJob{
  1085  				{
  1086  					ObjectMeta: metav1.ObjectMeta{
  1087  						Labels: map[string]string{
  1088  							"created-by-prow":                 "true",
  1089  							"prow.k8s.io/context":             "test-bar",
  1090  							"prow.k8s.io/gerrit-patchset":     "0",
  1091  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1092  							"prow.k8s.io/gerrit-revision":     "1",
  1093  							"prow.k8s.io/job":                 "test-bar",
  1094  							"prow.k8s.io/refs.base_ref":       "",
  1095  							"prow.k8s.io/refs.org":            "gerrit",
  1096  							"prow.k8s.io/refs.pull":           "0",
  1097  							"prow.k8s.io/refs.repo":           "postsubmits-project",
  1098  							"prow.k8s.io/type":                "postsubmit",
  1099  						},
  1100  						Annotations: map[string]string{
  1101  							"prow.k8s.io/context":         "test-bar",
  1102  							"prow.k8s.io/gerrit-id":       "",
  1103  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1104  							"prow.k8s.io/job":             "test-bar",
  1105  						},
  1106  					},
  1107  					Spec: prowapi.ProwJobSpec{
  1108  						Refs: &prowapi.Refs{
  1109  							Org:      "https://gerrit",
  1110  							Repo:     "postsubmits-project",
  1111  							RepoLink: "https://gerrit/postsubmits-project",
  1112  							BaseSHA:  "abc",
  1113  							BaseLink: "https://gerrit/postsubmits-project/+/abc",
  1114  							CloneURI: "https://gerrit/postsubmits-project",
  1115  							Pulls: []prowapi.Pull{
  1116  								{
  1117  									Ref:        "refs/changes/00/1/1",
  1118  									SHA:        "1",
  1119  									Link:       "https://gerrit/c/postsubmits-project/+/0",
  1120  									CommitLink: "https://gerrit/postsubmits-project/+/1",
  1121  									AuthorLink: "https://gerrit/q/",
  1122  								},
  1123  							},
  1124  						},
  1125  					},
  1126  				},
  1127  			},
  1128  		},
  1129  		{
  1130  			name: "merged change on project without postsubmits",
  1131  			change: client.ChangeInfo{
  1132  				CurrentRevision: "1",
  1133  				Project:         "test-infra",
  1134  				Status:          "MERGED",
  1135  				Revisions: map[string]client.RevisionInfo{
  1136  					"1": {
  1137  						Ref:     "refs/changes/00/1/1",
  1138  						Created: stampNow,
  1139  					},
  1140  				},
  1141  			},
  1142  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1143  			instance:     testInstance,
  1144  		},
  1145  		{
  1146  			name: "presubmit runs when a file matches run_if_changed",
  1147  			change: client.ChangeInfo{
  1148  				CurrentRevision: "1",
  1149  				Project:         "test-infra",
  1150  				Status:          "NEW",
  1151  				Revisions: map[string]client.RevisionInfo{
  1152  					"1": {
  1153  						Files: map[string]client.FileInfo{
  1154  							"bee-movie-script.txt": {},
  1155  							"africa-lyrics.txt":    {},
  1156  							"important-code.go":    {},
  1157  						},
  1158  						Created: stampNow,
  1159  					},
  1160  				},
  1161  			},
  1162  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1163  			instance:     testInstance,
  1164  			wantPjs: []*prowapi.ProwJob{
  1165  				{
  1166  					ObjectMeta: metav1.ObjectMeta{
  1167  						Labels: map[string]string{
  1168  							"prow.k8s.io/refs.org":            "gerrit",
  1169  							"prow.k8s.io/gerrit-revision":     "1",
  1170  							"prow.k8s.io/refs.pull":           "0",
  1171  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1172  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1173  							"prow.k8s.io/gerrit-patchset":     "0",
  1174  							"prow.k8s.io/refs.base_ref":       "",
  1175  							"created-by-prow":                 "true",
  1176  							"prow.k8s.io/context":             "always-runs-all-branches",
  1177  							"prow.k8s.io/refs.repo":           "test-infra",
  1178  							"prow.k8s.io/type":                "presubmit",
  1179  						},
  1180  						Annotations: map[string]string{
  1181  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1182  							"prow.k8s.io/gerrit-id":       "",
  1183  							"foo":                         "bar",
  1184  							"prow.k8s.io/context":         "always-runs-all-branches",
  1185  							"prow.k8s.io/job":             "always-runs-all-branches",
  1186  						},
  1187  					},
  1188  					Spec: prowapi.ProwJobSpec{
  1189  						Refs: &prowapi.Refs{
  1190  							Org:      "https://gerrit",
  1191  							Repo:     "test-infra",
  1192  							RepoLink: "https://gerrit/test-infra",
  1193  							BaseSHA:  "abc",
  1194  							BaseLink: "https://gerrit/test-infra/+/abc",
  1195  							CloneURI: "https://gerrit/test-infra",
  1196  							Pulls: []prowapi.Pull{
  1197  								{
  1198  									SHA:        "1",
  1199  									Link:       "https://gerrit/c/test-infra/+/0",
  1200  									CommitLink: "https://gerrit/test-infra/+/1",
  1201  									AuthorLink: "https://gerrit/q/",
  1202  								},
  1203  							},
  1204  						},
  1205  					},
  1206  				},
  1207  				{
  1208  					ObjectMeta: metav1.ObjectMeta{
  1209  						Labels: map[string]string{
  1210  							"prow.k8s.io/job":                 "run-if-changed-all-branches",
  1211  							"prow.k8s.io/refs.org":            "gerrit",
  1212  							"prow.k8s.io/gerrit-revision":     "1",
  1213  							"prow.k8s.io/gerrit-patchset":     "0",
  1214  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1215  							"prow.k8s.io/type":                "presubmit",
  1216  							"created-by-prow":                 "true",
  1217  							"prow.k8s.io/refs.pull":           "0",
  1218  							"prow.k8s.io/context":             "run-if-changed-all-branches",
  1219  							"prow.k8s.io/refs.repo":           "test-infra",
  1220  							"prow.k8s.io/refs.base_ref":       "",
  1221  						},
  1222  						Annotations: map[string]string{
  1223  							"prow.k8s.io/job":             "run-if-changed-all-branches",
  1224  							"prow.k8s.io/gerrit-id":       "",
  1225  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1226  							"prow.k8s.io/context":         "run-if-changed-all-branches",
  1227  						},
  1228  					},
  1229  					Spec: prowapi.ProwJobSpec{
  1230  						Refs: &prowapi.Refs{
  1231  							Org:      "https://gerrit",
  1232  							Repo:     "test-infra",
  1233  							RepoLink: "https://gerrit/test-infra",
  1234  							BaseSHA:  "abc",
  1235  							BaseLink: "https://gerrit/test-infra/+/abc",
  1236  							CloneURI: "https://gerrit/test-infra",
  1237  							Pulls: []prowapi.Pull{
  1238  								{
  1239  									SHA:        "1",
  1240  									Link:       "https://gerrit/c/test-infra/+/0",
  1241  									CommitLink: "https://gerrit/test-infra/+/1",
  1242  									AuthorLink: "https://gerrit/q/",
  1243  								},
  1244  							},
  1245  						},
  1246  					},
  1247  				},
  1248  				{
  1249  					ObjectMeta: metav1.ObjectMeta{
  1250  						Labels: map[string]string{
  1251  							"prow.k8s.io/refs.base_ref":       "",
  1252  							"prow.k8s.io/gerrit-patchset":     "0",
  1253  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1254  							"prow.k8s.io/refs.org":            "gerrit",
  1255  							"prow.k8s.io/refs.pull":           "0",
  1256  							"prow.k8s.io/type":                "presubmit",
  1257  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  1258  							"created-by-prow":                 "true",
  1259  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  1260  							"prow.k8s.io/refs.repo":           "test-infra",
  1261  							"prow.k8s.io/gerrit-revision":     "1",
  1262  						},
  1263  						Annotations: map[string]string{
  1264  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  1265  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  1266  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1267  							"prow.k8s.io/gerrit-id":       "",
  1268  						},
  1269  					},
  1270  					Spec: prowapi.ProwJobSpec{
  1271  						Refs: &prowapi.Refs{
  1272  							Org:      "https://gerrit",
  1273  							Repo:     "test-infra",
  1274  							RepoLink: "https://gerrit/test-infra",
  1275  							BaseSHA:  "abc",
  1276  							BaseLink: "https://gerrit/test-infra/+/abc",
  1277  							CloneURI: "https://gerrit/test-infra",
  1278  							Pulls: []prowapi.Pull{
  1279  								{
  1280  									SHA:        "1",
  1281  									Link:       "https://gerrit/c/test-infra/+/0",
  1282  									CommitLink: "https://gerrit/test-infra/+/1",
  1283  									AuthorLink: "https://gerrit/q/",
  1284  								},
  1285  							},
  1286  						},
  1287  					},
  1288  				},
  1289  			},
  1290  		},
  1291  		{
  1292  			name: "presubmit runs when a file matching run_if_changed is renamed",
  1293  			change: client.ChangeInfo{
  1294  				CurrentRevision: "1",
  1295  				Project:         "test-infra",
  1296  				Status:          "NEW",
  1297  				Revisions: map[string]client.RevisionInfo{
  1298  					"1": {
  1299  						Files: map[string]client.FileInfo{
  1300  							"bee-movie-script.txt": {},
  1301  							"just-a-copy.bar":      {Status: "C", OldPath: "important.go"},  // Copied file doesn't affect original
  1302  							"important.bar":        {Status: "R", OldPath: "important.foo"}, // Renamed file affects original
  1303  						},
  1304  						Created: stampNow,
  1305  					},
  1306  				},
  1307  			},
  1308  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1309  			instance:     testInstance,
  1310  			wantPjs: []*prowapi.ProwJob{
  1311  				{
  1312  					ObjectMeta: metav1.ObjectMeta{
  1313  						Labels: map[string]string{
  1314  							"prow.k8s.io/refs.org":            "gerrit",
  1315  							"prow.k8s.io/gerrit-revision":     "1",
  1316  							"prow.k8s.io/refs.pull":           "0",
  1317  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1318  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1319  							"prow.k8s.io/gerrit-patchset":     "0",
  1320  							"prow.k8s.io/refs.base_ref":       "",
  1321  							"created-by-prow":                 "true",
  1322  							"prow.k8s.io/context":             "always-runs-all-branches",
  1323  							"prow.k8s.io/refs.repo":           "test-infra",
  1324  							"prow.k8s.io/type":                "presubmit",
  1325  						},
  1326  						Annotations: map[string]string{
  1327  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1328  							"prow.k8s.io/gerrit-id":       "",
  1329  							"foo":                         "bar",
  1330  							"prow.k8s.io/context":         "always-runs-all-branches",
  1331  							"prow.k8s.io/job":             "always-runs-all-branches",
  1332  						},
  1333  					},
  1334  					Spec: prowapi.ProwJobSpec{
  1335  						Refs: &prowapi.Refs{
  1336  							Org:      "https://gerrit",
  1337  							Repo:     "test-infra",
  1338  							RepoLink: "https://gerrit/test-infra",
  1339  							BaseSHA:  "abc",
  1340  							BaseLink: "https://gerrit/test-infra/+/abc",
  1341  							CloneURI: "https://gerrit/test-infra",
  1342  							Pulls: []prowapi.Pull{
  1343  								{
  1344  									SHA:        "1",
  1345  									Link:       "https://gerrit/c/test-infra/+/0",
  1346  									CommitLink: "https://gerrit/test-infra/+/1",
  1347  									AuthorLink: "https://gerrit/q/",
  1348  								},
  1349  							},
  1350  						},
  1351  					},
  1352  				},
  1353  				{
  1354  					ObjectMeta: metav1.ObjectMeta{
  1355  						Labels: map[string]string{
  1356  							"prow.k8s.io/job":                 "reported-job-runs-on-foo-file-change",
  1357  							"prow.k8s.io/refs.org":            "gerrit",
  1358  							"prow.k8s.io/gerrit-revision":     "1",
  1359  							"prow.k8s.io/gerrit-patchset":     "0",
  1360  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1361  							"prow.k8s.io/type":                "presubmit",
  1362  							"created-by-prow":                 "true",
  1363  							"prow.k8s.io/refs.pull":           "0",
  1364  							"prow.k8s.io/context":             "foo-job-reported",
  1365  							"prow.k8s.io/refs.repo":           "test-infra",
  1366  							"prow.k8s.io/refs.base_ref":       "",
  1367  						},
  1368  						Annotations: map[string]string{
  1369  							"prow.k8s.io/job":             "reported-job-runs-on-foo-file-change",
  1370  							"prow.k8s.io/gerrit-id":       "",
  1371  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1372  							"prow.k8s.io/context":         "foo-job-reported",
  1373  						},
  1374  					},
  1375  					Spec: prowapi.ProwJobSpec{
  1376  						Refs: &prowapi.Refs{
  1377  							Org:      "https://gerrit",
  1378  							Repo:     "test-infra",
  1379  							RepoLink: "https://gerrit/test-infra",
  1380  							BaseSHA:  "abc",
  1381  							BaseLink: "https://gerrit/test-infra/+/abc",
  1382  							CloneURI: "https://gerrit/test-infra",
  1383  							Pulls: []prowapi.Pull{
  1384  								{
  1385  									SHA:        "1",
  1386  									Link:       "https://gerrit/c/test-infra/+/0",
  1387  									CommitLink: "https://gerrit/test-infra/+/1",
  1388  									AuthorLink: "https://gerrit/q/",
  1389  								},
  1390  							},
  1391  						},
  1392  					},
  1393  				},
  1394  				{
  1395  					ObjectMeta: metav1.ObjectMeta{
  1396  						Labels: map[string]string{
  1397  							"prow.k8s.io/refs.base_ref":       "",
  1398  							"prow.k8s.io/gerrit-patchset":     "0",
  1399  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1400  							"prow.k8s.io/refs.org":            "gerrit",
  1401  							"prow.k8s.io/refs.pull":           "0",
  1402  							"prow.k8s.io/type":                "presubmit",
  1403  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  1404  							"created-by-prow":                 "true",
  1405  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  1406  							"prow.k8s.io/refs.repo":           "test-infra",
  1407  							"prow.k8s.io/gerrit-revision":     "1",
  1408  						},
  1409  						Annotations: map[string]string{
  1410  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  1411  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  1412  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1413  							"prow.k8s.io/gerrit-id":       "",
  1414  						},
  1415  					},
  1416  					Spec: prowapi.ProwJobSpec{
  1417  						Refs: &prowapi.Refs{
  1418  							Org:      "https://gerrit",
  1419  							Repo:     "test-infra",
  1420  							RepoLink: "https://gerrit/test-infra",
  1421  							BaseSHA:  "abc",
  1422  							BaseLink: "https://gerrit/test-infra/+/abc",
  1423  							CloneURI: "https://gerrit/test-infra",
  1424  							Pulls: []prowapi.Pull{
  1425  								{
  1426  									SHA:        "1",
  1427  									Link:       "https://gerrit/c/test-infra/+/0",
  1428  									CommitLink: "https://gerrit/test-infra/+/1",
  1429  									AuthorLink: "https://gerrit/q/",
  1430  								},
  1431  							},
  1432  						},
  1433  					},
  1434  				},
  1435  			},
  1436  		},
  1437  		{
  1438  			name: "presubmit does not run when a file matches run_if_changed but the change is WorkInProgress",
  1439  			change: client.ChangeInfo{
  1440  				CurrentRevision: "1",
  1441  				Project:         "test-infra",
  1442  				Status:          "NEW",
  1443  				WorkInProgress:  true,
  1444  				Revisions: map[string]client.RevisionInfo{
  1445  					"1": {
  1446  						Files: map[string]client.FileInfo{
  1447  							"bee-movie-script.txt": {},
  1448  							"africa-lyrics.txt":    {},
  1449  							"important-code.go":    {},
  1450  						},
  1451  						Created: stampNow,
  1452  					},
  1453  				},
  1454  			},
  1455  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1456  			instance:     testInstance,
  1457  		},
  1458  		{
  1459  			name: "presubmit doesn't run when no files match run_if_changed",
  1460  			change: client.ChangeInfo{
  1461  				CurrentRevision: "1",
  1462  				Project:         "test-infra",
  1463  				Status:          "NEW",
  1464  				Revisions: map[string]client.RevisionInfo{
  1465  					"1": {
  1466  						Files: map[string]client.FileInfo{
  1467  							"hacky-hack.sh": {},
  1468  							"README.md":     {},
  1469  							"let-it-go.txt": {},
  1470  						},
  1471  						Created: stampNow,
  1472  					},
  1473  				},
  1474  			},
  1475  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1476  			instance:     testInstance,
  1477  			wantPjs: []*prowapi.ProwJob{
  1478  				{
  1479  					ObjectMeta: metav1.ObjectMeta{
  1480  						Labels: map[string]string{
  1481  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1482  							"prow.k8s.io/refs.base_ref":       "",
  1483  							"prow.k8s.io/gerrit-revision":     "1",
  1484  							"prow.k8s.io/context":             "always-runs-all-branches",
  1485  							"prow.k8s.io/refs.pull":           "0",
  1486  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1487  							"created-by-prow":                 "true",
  1488  							"prow.k8s.io/type":                "presubmit",
  1489  							"prow.k8s.io/gerrit-patchset":     "0",
  1490  							"prow.k8s.io/refs.org":            "gerrit",
  1491  							"prow.k8s.io/refs.repo":           "test-infra",
  1492  						},
  1493  						Annotations: map[string]string{
  1494  							"prow.k8s.io/context":         "always-runs-all-branches",
  1495  							"prow.k8s.io/job":             "always-runs-all-branches",
  1496  							"foo":                         "bar",
  1497  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1498  							"prow.k8s.io/gerrit-id":       "",
  1499  						},
  1500  					},
  1501  					Spec: prowapi.ProwJobSpec{
  1502  						Refs: &prowapi.Refs{
  1503  							Org:      "https://gerrit",
  1504  							Repo:     "test-infra",
  1505  							RepoLink: "https://gerrit/test-infra",
  1506  							BaseSHA:  "abc",
  1507  							BaseLink: "https://gerrit/test-infra/+/abc",
  1508  							CloneURI: "https://gerrit/test-infra",
  1509  							Pulls: []prowapi.Pull{
  1510  								{
  1511  									SHA:        "1",
  1512  									Link:       "https://gerrit/c/test-infra/+/0",
  1513  									CommitLink: "https://gerrit/test-infra/+/1",
  1514  									AuthorLink: "https://gerrit/q/",
  1515  								},
  1516  							},
  1517  						},
  1518  					},
  1519  				},
  1520  				{
  1521  					ObjectMeta: metav1.ObjectMeta{
  1522  						Labels: map[string]string{
  1523  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  1524  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  1525  							"prow.k8s.io/gerrit-patchset":     "0",
  1526  							"prow.k8s.io/type":                "presubmit",
  1527  							"prow.k8s.io/refs.base_ref":       "",
  1528  							"prow.k8s.io/refs.pull":           "0",
  1529  							"prow.k8s.io/gerrit-revision":     "1",
  1530  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1531  							"created-by-prow":                 "true",
  1532  							"prow.k8s.io/refs.org":            "gerrit",
  1533  							"prow.k8s.io/refs.repo":           "test-infra",
  1534  						},
  1535  						Annotations: map[string]string{
  1536  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  1537  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  1538  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1539  							"prow.k8s.io/gerrit-id":       "",
  1540  						},
  1541  					},
  1542  					Spec: prowapi.ProwJobSpec{
  1543  						Refs: &prowapi.Refs{
  1544  							Org:      "https://gerrit",
  1545  							Repo:     "test-infra",
  1546  							RepoLink: "https://gerrit/test-infra",
  1547  							BaseSHA:  "abc",
  1548  							BaseLink: "https://gerrit/test-infra/+/abc",
  1549  							CloneURI: "https://gerrit/test-infra",
  1550  							Pulls: []prowapi.Pull{
  1551  								{
  1552  									SHA:        "1",
  1553  									Link:       "https://gerrit/c/test-infra/+/0",
  1554  									CommitLink: "https://gerrit/test-infra/+/1",
  1555  									AuthorLink: "https://gerrit/q/",
  1556  								},
  1557  							},
  1558  						},
  1559  					},
  1560  				},
  1561  			},
  1562  		},
  1563  		{
  1564  			name: "presubmit run when change against matched branch",
  1565  			change: client.ChangeInfo{
  1566  				CurrentRevision: "1",
  1567  				Project:         "test-infra",
  1568  				Branch:          "pony",
  1569  				Status:          "NEW",
  1570  				Revisions: map[string]client.RevisionInfo{
  1571  					"1": {
  1572  						Created: stampNow,
  1573  					},
  1574  				},
  1575  			},
  1576  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1577  			instance:     testInstance,
  1578  			wantPjs: []*prowapi.ProwJob{
  1579  				{
  1580  					ObjectMeta: metav1.ObjectMeta{
  1581  						Labels: map[string]string{
  1582  							"prow.k8s.io/gerrit-revision":     "1",
  1583  							"prow.k8s.io/gerrit-patchset":     "0",
  1584  							"created-by-prow":                 "true",
  1585  							"prow.k8s.io/context":             "always-runs-all-branches",
  1586  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1587  							"prow.k8s.io/refs.org":            "gerrit",
  1588  							"prow.k8s.io/type":                "presubmit",
  1589  							"prow.k8s.io/refs.base_ref":       "pony",
  1590  							"prow.k8s.io/refs.repo":           "test-infra",
  1591  							"prow.k8s.io/refs.pull":           "0",
  1592  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1593  						},
  1594  						Annotations: map[string]string{
  1595  							"prow.k8s.io/context":         "always-runs-all-branches",
  1596  							"prow.k8s.io/job":             "always-runs-all-branches",
  1597  							"foo":                         "bar",
  1598  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1599  							"prow.k8s.io/gerrit-id":       "",
  1600  						},
  1601  					},
  1602  					Spec: prowapi.ProwJobSpec{
  1603  						Refs: &prowapi.Refs{
  1604  							Org:      "https://gerrit",
  1605  							Repo:     "test-infra",
  1606  							RepoLink: "https://gerrit/test-infra",
  1607  							BaseSHA:  "abc",
  1608  							BaseRef:  "pony",
  1609  							BaseLink: "https://gerrit/test-infra/+/abc",
  1610  							CloneURI: "https://gerrit/test-infra",
  1611  							Pulls: []prowapi.Pull{
  1612  								{
  1613  									SHA:        "1",
  1614  									Link:       "https://gerrit/c/test-infra/+/0",
  1615  									CommitLink: "https://gerrit/test-infra/+/1",
  1616  									AuthorLink: "https://gerrit/q/",
  1617  								},
  1618  							},
  1619  						},
  1620  					},
  1621  				},
  1622  				{
  1623  					ObjectMeta: metav1.ObjectMeta{
  1624  						Labels: map[string]string{
  1625  							"created-by-prow":                 "true",
  1626  							"prow.k8s.io/job":                 "runs-on-pony-branch",
  1627  							"prow.k8s.io/type":                "presubmit",
  1628  							"prow.k8s.io/refs.org":            "gerrit",
  1629  							"prow.k8s.io/refs.repo":           "test-infra",
  1630  							"prow.k8s.io/context":             "runs-on-pony-branch",
  1631  							"prow.k8s.io/refs.pull":           "0",
  1632  							"prow.k8s.io/gerrit-revision":     "1",
  1633  							"prow.k8s.io/gerrit-patchset":     "0",
  1634  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1635  							"prow.k8s.io/refs.base_ref":       "pony",
  1636  						},
  1637  						Annotations: map[string]string{
  1638  							"prow.k8s.io/job":             "runs-on-pony-branch",
  1639  							"prow.k8s.io/context":         "runs-on-pony-branch",
  1640  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1641  							"prow.k8s.io/gerrit-id":       "",
  1642  						},
  1643  					},
  1644  					Spec: prowapi.ProwJobSpec{
  1645  						Refs: &prowapi.Refs{
  1646  							Org:      "https://gerrit",
  1647  							Repo:     "test-infra",
  1648  							RepoLink: "https://gerrit/test-infra",
  1649  							BaseSHA:  "abc",
  1650  							BaseRef:  "pony",
  1651  							BaseLink: "https://gerrit/test-infra/+/abc",
  1652  							CloneURI: "https://gerrit/test-infra",
  1653  							Pulls: []prowapi.Pull{
  1654  								{
  1655  									SHA:        "1",
  1656  									Link:       "https://gerrit/c/test-infra/+/0",
  1657  									CommitLink: "https://gerrit/test-infra/+/1",
  1658  									AuthorLink: "https://gerrit/q/",
  1659  								},
  1660  							},
  1661  						},
  1662  					},
  1663  				},
  1664  				{
  1665  					ObjectMeta: metav1.ObjectMeta{
  1666  						Labels: map[string]string{
  1667  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1668  							"created-by-prow":                 "true",
  1669  							"prow.k8s.io/refs.org":            "gerrit",
  1670  							"prow.k8s.io/refs.repo":           "test-infra",
  1671  							"prow.k8s.io/gerrit-patchset":     "0",
  1672  							"prow.k8s.io/type":                "presubmit",
  1673  							"prow.k8s.io/gerrit-revision":     "1",
  1674  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  1675  							"prow.k8s.io/refs.pull":           "0",
  1676  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  1677  							"prow.k8s.io/refs.base_ref":       "pony",
  1678  						},
  1679  						Annotations: map[string]string{
  1680  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  1681  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  1682  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1683  							"prow.k8s.io/gerrit-id":       "",
  1684  						},
  1685  					},
  1686  					Spec: prowapi.ProwJobSpec{
  1687  						Refs: &prowapi.Refs{
  1688  							Org:      "https://gerrit",
  1689  							Repo:     "test-infra",
  1690  							RepoLink: "https://gerrit/test-infra",
  1691  							BaseSHA:  "abc",
  1692  							BaseRef:  "pony",
  1693  							BaseLink: "https://gerrit/test-infra/+/abc",
  1694  							CloneURI: "https://gerrit/test-infra",
  1695  							Pulls: []prowapi.Pull{
  1696  								{
  1697  									SHA:        "1",
  1698  									Link:       "https://gerrit/c/test-infra/+/0",
  1699  									CommitLink: "https://gerrit/test-infra/+/1",
  1700  									AuthorLink: "https://gerrit/q/",
  1701  								},
  1702  							},
  1703  						},
  1704  					},
  1705  				},
  1706  			},
  1707  		},
  1708  		{
  1709  			name: "presubmit doesn't run when not against target branch",
  1710  			change: client.ChangeInfo{
  1711  				CurrentRevision: "1",
  1712  				Project:         "test-infra",
  1713  				Branch:          "baz",
  1714  				Status:          "NEW",
  1715  				Revisions: map[string]client.RevisionInfo{
  1716  					"1": {
  1717  						Created: stampNow,
  1718  					},
  1719  				},
  1720  			},
  1721  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1722  			instance:     testInstance,
  1723  			wantPjs: []*prowapi.ProwJob{
  1724  				{
  1725  					ObjectMeta: metav1.ObjectMeta{
  1726  						Labels: map[string]string{
  1727  							"prow.k8s.io/refs.pull":           "0",
  1728  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1729  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1730  							"prow.k8s.io/refs.org":            "gerrit",
  1731  							"prow.k8s.io/gerrit-patchset":     "0",
  1732  							"created-by-prow":                 "true",
  1733  							"prow.k8s.io/context":             "always-runs-all-branches",
  1734  							"prow.k8s.io/refs.repo":           "test-infra",
  1735  							"prow.k8s.io/refs.base_ref":       "baz",
  1736  							"prow.k8s.io/type":                "presubmit",
  1737  							"prow.k8s.io/gerrit-revision":     "1",
  1738  						},
  1739  						Annotations: map[string]string{
  1740  							"foo":                         "bar",
  1741  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1742  							"prow.k8s.io/gerrit-id":       "",
  1743  							"prow.k8s.io/context":         "always-runs-all-branches",
  1744  							"prow.k8s.io/job":             "always-runs-all-branches",
  1745  						},
  1746  					},
  1747  					Spec: prowapi.ProwJobSpec{
  1748  						Refs: &prowapi.Refs{
  1749  							Org:      "https://gerrit",
  1750  							Repo:     "test-infra",
  1751  							RepoLink: "https://gerrit/test-infra",
  1752  							BaseSHA:  "abc",
  1753  							BaseRef:  "baz",
  1754  							BaseLink: "https://gerrit/test-infra/+/abc",
  1755  							CloneURI: "https://gerrit/test-infra",
  1756  							Pulls: []prowapi.Pull{
  1757  								{
  1758  									SHA:        "1",
  1759  									Link:       "https://gerrit/c/test-infra/+/0",
  1760  									CommitLink: "https://gerrit/test-infra/+/1",
  1761  									AuthorLink: "https://gerrit/q/",
  1762  								},
  1763  							},
  1764  						},
  1765  					},
  1766  				},
  1767  			},
  1768  		},
  1769  		{
  1770  			name: "old presubmits don't run on old revision but trigger job does because new message",
  1771  			change: client.ChangeInfo{
  1772  				CurrentRevision: "1",
  1773  				Project:         "test-infra",
  1774  				Branch:          "baz",
  1775  				Status:          "NEW",
  1776  				Revisions: map[string]client.RevisionInfo{
  1777  					"1": {
  1778  						Number:  1,
  1779  						Created: makeStamp(timeNow.Add(-time.Hour)),
  1780  					},
  1781  				},
  1782  				Messages: []gerrit.ChangeMessageInfo{
  1783  					{
  1784  						Message:        "/test troll",
  1785  						RevisionNumber: 1,
  1786  						Date:           makeStamp(timeNow.Add(time.Hour)),
  1787  					},
  1788  				},
  1789  			},
  1790  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1791  			instance:     testInstance,
  1792  			wantPjs: []*prowapi.ProwJob{
  1793  				{
  1794  					ObjectMeta: metav1.ObjectMeta{
  1795  						Labels: map[string]string{
  1796  							"prow.k8s.io/refs.pull":           "0",
  1797  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1798  							"prow.k8s.io/job":                 "trigger-regex-all-branches",
  1799  							"prow.k8s.io/refs.base_ref":       "baz",
  1800  							"prow.k8s.io/gerrit-revision":     "1",
  1801  							"created-by-prow":                 "true",
  1802  							"prow.k8s.io/type":                "presubmit",
  1803  							"prow.k8s.io/refs.org":            "gerrit",
  1804  							"prow.k8s.io/gerrit-patchset":     "1",
  1805  							"prow.k8s.io/context":             "trigger-regex-all-branches",
  1806  							"prow.k8s.io/refs.repo":           "test-infra",
  1807  						},
  1808  						Annotations: map[string]string{
  1809  							"prow.k8s.io/job":             "trigger-regex-all-branches",
  1810  							"prow.k8s.io/context":         "trigger-regex-all-branches",
  1811  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1812  							"prow.k8s.io/gerrit-id":       "",
  1813  						},
  1814  					},
  1815  					Spec: prowapi.ProwJobSpec{
  1816  						Refs: &prowapi.Refs{
  1817  							Org:      "https://gerrit",
  1818  							Repo:     "test-infra",
  1819  							RepoLink: "https://gerrit/test-infra",
  1820  							BaseSHA:  "abc",
  1821  							BaseRef:  "baz",
  1822  							BaseLink: "https://gerrit/test-infra/+/abc",
  1823  							CloneURI: "https://gerrit/test-infra",
  1824  							Pulls: []prowapi.Pull{
  1825  								{
  1826  									SHA:        "1",
  1827  									Link:       "https://gerrit/c/test-infra/+/0",
  1828  									CommitLink: "https://gerrit/test-infra/+/1",
  1829  									AuthorLink: "https://gerrit/q/",
  1830  								},
  1831  							},
  1832  						},
  1833  					},
  1834  				},
  1835  			},
  1836  		},
  1837  		{
  1838  			name: "unrelated comment shouldn't trigger anything",
  1839  			change: client.ChangeInfo{
  1840  				CurrentRevision: "1",
  1841  				Project:         "test-infra",
  1842  				Branch:          "baz",
  1843  				Status:          "NEW",
  1844  				Revisions: map[string]client.RevisionInfo{
  1845  					"1": {
  1846  						Number:  1,
  1847  						Created: makeStamp(timeNow.Add(-time.Hour)),
  1848  					},
  1849  				},
  1850  				Messages: []gerrit.ChangeMessageInfo{
  1851  					{
  1852  						Message:        "/test diasghdgasudhkashdk",
  1853  						RevisionNumber: 1,
  1854  						Date:           makeStamp(timeNow.Add(time.Hour)),
  1855  					},
  1856  				},
  1857  			},
  1858  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1859  			instance:     testInstance,
  1860  		},
  1861  		{
  1862  			name: "trigger always run job on test all even if revision is old",
  1863  			change: client.ChangeInfo{
  1864  				CurrentRevision: "1",
  1865  				Project:         "test-infra",
  1866  				Branch:          "baz",
  1867  				Status:          "NEW",
  1868  				Revisions: map[string]client.RevisionInfo{
  1869  					"1": {
  1870  						Number:  1,
  1871  						Created: makeStamp(timeNow.Add(-time.Hour)),
  1872  					},
  1873  				},
  1874  				Messages: []gerrit.ChangeMessageInfo{
  1875  					{
  1876  						Message:        "/test all",
  1877  						RevisionNumber: 1,
  1878  						Date:           makeStamp(timeNow.Add(time.Hour)),
  1879  					},
  1880  				},
  1881  			},
  1882  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1883  			instance:     testInstance,
  1884  			wantPjs: []*prowapi.ProwJob{
  1885  				{
  1886  					ObjectMeta: metav1.ObjectMeta{
  1887  						Labels: map[string]string{
  1888  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1889  							"created-by-prow":                 "true",
  1890  							"prow.k8s.io/type":                "presubmit",
  1891  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1892  							"prow.k8s.io/refs.pull":           "0",
  1893  							"prow.k8s.io/refs.repo":           "test-infra",
  1894  							"prow.k8s.io/refs.org":            "gerrit",
  1895  							"prow.k8s.io/refs.base_ref":       "baz",
  1896  							"prow.k8s.io/gerrit-revision":     "1",
  1897  							"prow.k8s.io/gerrit-patchset":     "1",
  1898  							"prow.k8s.io/context":             "always-runs-all-branches",
  1899  						},
  1900  						Annotations: map[string]string{
  1901  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1902  							"prow.k8s.io/gerrit-id":       "",
  1903  							"prow.k8s.io/job":             "always-runs-all-branches",
  1904  							"prow.k8s.io/context":         "always-runs-all-branches",
  1905  							"foo":                         "bar",
  1906  						},
  1907  					},
  1908  					Spec: prowapi.ProwJobSpec{
  1909  						Refs: &prowapi.Refs{
  1910  							Org:      "https://gerrit",
  1911  							Repo:     "test-infra",
  1912  							RepoLink: "https://gerrit/test-infra",
  1913  							BaseSHA:  "abc",
  1914  							BaseRef:  "baz",
  1915  							BaseLink: "https://gerrit/test-infra/+/abc",
  1916  							CloneURI: "https://gerrit/test-infra",
  1917  							Pulls: []prowapi.Pull{
  1918  								{
  1919  									SHA:        "1",
  1920  									Link:       "https://gerrit/c/test-infra/+/0",
  1921  									CommitLink: "https://gerrit/test-infra/+/1",
  1922  									AuthorLink: "https://gerrit/q/",
  1923  								},
  1924  							},
  1925  						},
  1926  					},
  1927  				},
  1928  			},
  1929  		},
  1930  		{
  1931  			name: "trigger always run job on test all even if the change is WorkInProgress",
  1932  			change: client.ChangeInfo{
  1933  				CurrentRevision: "1",
  1934  				Project:         "test-infra",
  1935  				Branch:          "baz",
  1936  				Status:          "NEW",
  1937  				WorkInProgress:  true,
  1938  				Revisions: map[string]client.RevisionInfo{
  1939  					"1": {
  1940  						Number: 1,
  1941  					},
  1942  				},
  1943  				Messages: []gerrit.ChangeMessageInfo{
  1944  					{
  1945  						Message:        "/test all",
  1946  						RevisionNumber: 1,
  1947  						Date:           makeStamp(timeNow.Add(time.Hour)),
  1948  					},
  1949  				},
  1950  			},
  1951  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  1952  			instance:     testInstance,
  1953  			wantPjs: []*prowapi.ProwJob{
  1954  				{
  1955  					ObjectMeta: metav1.ObjectMeta{
  1956  						Labels: map[string]string{
  1957  							"prow.k8s.io/type":                "presubmit",
  1958  							"prow.k8s.io/context":             "always-runs-all-branches",
  1959  							"created-by-prow":                 "true",
  1960  							"prow.k8s.io/refs.base_ref":       "baz",
  1961  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  1962  							"prow.k8s.io/gerrit-revision":     "1",
  1963  							"prow.k8s.io/job":                 "always-runs-all-branches",
  1964  							"prow.k8s.io/refs.pull":           "0",
  1965  							"prow.k8s.io/refs.org":            "gerrit",
  1966  							"prow.k8s.io/refs.repo":           "test-infra",
  1967  							"prow.k8s.io/gerrit-patchset":     "1",
  1968  						},
  1969  						Annotations: map[string]string{
  1970  							"prow.k8s.io/job":             "always-runs-all-branches",
  1971  							"prow.k8s.io/context":         "always-runs-all-branches",
  1972  							"foo":                         "bar",
  1973  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  1974  							"prow.k8s.io/gerrit-id":       "",
  1975  						},
  1976  					},
  1977  					Spec: prowapi.ProwJobSpec{
  1978  						Refs: &prowapi.Refs{
  1979  							Org:      "https://gerrit",
  1980  							Repo:     "test-infra",
  1981  							RepoLink: "https://gerrit/test-infra",
  1982  							BaseSHA:  "abc",
  1983  							BaseRef:  "baz",
  1984  							BaseLink: "https://gerrit/test-infra/+/abc",
  1985  							CloneURI: "https://gerrit/test-infra",
  1986  							Pulls: []prowapi.Pull{
  1987  								{
  1988  									SHA:        "1",
  1989  									Link:       "https://gerrit/c/test-infra/+/0",
  1990  									CommitLink: "https://gerrit/test-infra/+/1",
  1991  									AuthorLink: "https://gerrit/q/",
  1992  								},
  1993  							},
  1994  						},
  1995  					},
  1996  				},
  1997  			},
  1998  		},
  1999  		{
  2000  			name: "retest correctly triggers failed jobs",
  2001  			change: client.ChangeInfo{
  2002  				CurrentRevision: "1",
  2003  				Project:         "test-infra",
  2004  				Branch:          "retest-branch",
  2005  				Status:          "NEW",
  2006  				Revisions: map[string]client.RevisionInfo{
  2007  					"1": {
  2008  						Number:  1,
  2009  						Created: makeStamp(timeNow.Add(-time.Hour)),
  2010  					},
  2011  				},
  2012  				Messages: []gerrit.ChangeMessageInfo{
  2013  					{
  2014  						Message:        "/retest",
  2015  						RevisionNumber: 1,
  2016  						Date:           makeStamp(timeNow.Add(time.Hour)),
  2017  					},
  2018  					{
  2019  						Message:        "Prow Status: 1 out of 2 passed\n✔️ foo-job SUCCESS - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2020  						Author:         gerrit.AccountInfo{AccountID: 42},
  2021  						RevisionNumber: 1,
  2022  						Date:           makeStamp(timeNow.Add(-time.Hour)),
  2023  					},
  2024  				},
  2025  			},
  2026  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2027  			instance:     testInstance,
  2028  			wantPjs: []*prowapi.ProwJob{
  2029  				{
  2030  					ObjectMeta: metav1.ObjectMeta{
  2031  						Labels: map[string]string{
  2032  							"prow.k8s.io/refs.org":            "gerrit",
  2033  							"prow.k8s.io/refs.pull":           "0",
  2034  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2035  							"prow.k8s.io/job":                 "bar-job",
  2036  							"prow.k8s.io/refs.repo":           "test-infra",
  2037  							"prow.k8s.io/type":                "presubmit",
  2038  							"prow.k8s.io/context":             "bar-job",
  2039  							"prow.k8s.io/gerrit-patchset":     "1",
  2040  							"created-by-prow":                 "true",
  2041  							"prow.k8s.io/refs.base_ref":       "retest-branch",
  2042  							"prow.k8s.io/gerrit-revision":     "1",
  2043  						},
  2044  						Annotations: map[string]string{
  2045  							"prow.k8s.io/job":             "bar-job",
  2046  							"prow.k8s.io/context":         "bar-job",
  2047  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2048  							"prow.k8s.io/gerrit-id":       "",
  2049  						},
  2050  					},
  2051  					Spec: prowapi.ProwJobSpec{
  2052  						Refs: &prowapi.Refs{
  2053  							Org:      "https://gerrit",
  2054  							Repo:     "test-infra",
  2055  							RepoLink: "https://gerrit/test-infra",
  2056  							BaseSHA:  "abc",
  2057  							BaseRef:  "retest-branch",
  2058  							BaseLink: "https://gerrit/test-infra/+/abc",
  2059  							CloneURI: "https://gerrit/test-infra",
  2060  							Pulls: []prowapi.Pull{
  2061  								{
  2062  									SHA:        "1",
  2063  									Link:       "https://gerrit/c/test-infra/+/0",
  2064  									CommitLink: "https://gerrit/test-infra/+/1",
  2065  									AuthorLink: "https://gerrit/q/",
  2066  								},
  2067  							},
  2068  						},
  2069  					},
  2070  				},
  2071  			},
  2072  		},
  2073  		{
  2074  			name: "retest uses latest status and ignores earlier status",
  2075  			change: client.ChangeInfo{
  2076  				CurrentRevision: "1",
  2077  				Project:         "test-infra",
  2078  				Branch:          "retest-branch",
  2079  				Status:          "NEW",
  2080  				Revisions: map[string]client.RevisionInfo{
  2081  					"1": {
  2082  						Number:  1,
  2083  						Created: makeStamp(timeNow.Add(-3 * time.Hour)),
  2084  					},
  2085  				},
  2086  				Messages: []gerrit.ChangeMessageInfo{
  2087  					{
  2088  						Message:        "/retest",
  2089  						RevisionNumber: 1,
  2090  						Date:           makeStamp(timeNow.Add(time.Hour)),
  2091  					},
  2092  					{
  2093  						Message:        "Prow Status: 1 out of 2 passed\n✔️ foo-job SUCCESS - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2094  						RevisionNumber: 1,
  2095  						Author:         gerrit.AccountInfo{AccountID: 42},
  2096  						Date:           makeStamp(timeNow.Add(-time.Hour)),
  2097  					},
  2098  					{
  2099  						Message:        "Prow Status: 0 out of 2 passed\n❌️ foo-job FAILURE - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2100  						RevisionNumber: 1,
  2101  						Author:         gerrit.AccountInfo{AccountID: 42},
  2102  						Date:           makeStamp(timeNow.Add(-2 * time.Hour)),
  2103  					},
  2104  				},
  2105  			},
  2106  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2107  			instance:     testInstance,
  2108  			wantPjs: []*prowapi.ProwJob{
  2109  				{
  2110  					ObjectMeta: metav1.ObjectMeta{
  2111  						Labels: map[string]string{
  2112  							"prow.k8s.io/gerrit-patchset":     "1",
  2113  							"prow.k8s.io/refs.org":            "gerrit",
  2114  							"prow.k8s.io/refs.repo":           "test-infra",
  2115  							"prow.k8s.io/refs.base_ref":       "retest-branch",
  2116  							"prow.k8s.io/refs.pull":           "0",
  2117  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2118  							"prow.k8s.io/job":                 "bar-job",
  2119  							"prow.k8s.io/gerrit-revision":     "1",
  2120  							"prow.k8s.io/type":                "presubmit",
  2121  							"prow.k8s.io/context":             "bar-job",
  2122  							"created-by-prow":                 "true",
  2123  						},
  2124  						Annotations: map[string]string{
  2125  							"prow.k8s.io/context":         "bar-job",
  2126  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2127  							"prow.k8s.io/gerrit-id":       "",
  2128  							"prow.k8s.io/job":             "bar-job",
  2129  						},
  2130  					},
  2131  					Spec: prowapi.ProwJobSpec{
  2132  						Refs: &prowapi.Refs{
  2133  							Org:      "https://gerrit",
  2134  							Repo:     "test-infra",
  2135  							RepoLink: "https://gerrit/test-infra",
  2136  							BaseSHA:  "abc",
  2137  							BaseRef:  "retest-branch",
  2138  							BaseLink: "https://gerrit/test-infra/+/abc",
  2139  							CloneURI: "https://gerrit/test-infra",
  2140  							Pulls: []prowapi.Pull{
  2141  								{
  2142  									SHA:        "1",
  2143  									Link:       "https://gerrit/c/test-infra/+/0",
  2144  									CommitLink: "https://gerrit/test-infra/+/1",
  2145  									AuthorLink: "https://gerrit/q/",
  2146  								},
  2147  							},
  2148  						},
  2149  					},
  2150  				},
  2151  			},
  2152  		},
  2153  		{
  2154  			name: "retest ignores statuses not reported by the prow account",
  2155  			change: client.ChangeInfo{
  2156  				CurrentRevision: "1",
  2157  				Project:         "test-infra",
  2158  				Branch:          "retest-branch",
  2159  				Status:          "NEW",
  2160  				Revisions: map[string]client.RevisionInfo{
  2161  					"1": {
  2162  						Number:  1,
  2163  						Created: makeStamp(timeNow.Add(-3 * time.Hour)),
  2164  					},
  2165  				},
  2166  				Messages: []gerrit.ChangeMessageInfo{
  2167  					{
  2168  						Message:        "/retest",
  2169  						RevisionNumber: 1,
  2170  						Date:           makeStamp(timeNow.Add(time.Hour)),
  2171  					},
  2172  					{
  2173  						Message:        "Prow Status: 1 out of 2 passed\n✔️ foo-job SUCCESS - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2174  						RevisionNumber: 1,
  2175  						Author:         gerrit.AccountInfo{AccountID: 123},
  2176  						Date:           makeStamp(timeNow.Add(-time.Hour)),
  2177  					},
  2178  					{
  2179  						Message:        "Prow Status: 0 out of 2 passed\n❌️ foo-job FAILURE - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2180  						RevisionNumber: 1,
  2181  						Author:         gerrit.AccountInfo{AccountID: 42},
  2182  						Date:           makeStamp(timeNow.Add(-2 * time.Hour)),
  2183  					},
  2184  				},
  2185  			},
  2186  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2187  			instance:     testInstance,
  2188  			wantPjs: []*prowapi.ProwJob{
  2189  				{
  2190  					ObjectMeta: metav1.ObjectMeta{
  2191  						Labels: map[string]string{
  2192  							"prow.k8s.io/job":                 "foo-job",
  2193  							"prow.k8s.io/refs.org":            "gerrit",
  2194  							"prow.k8s.io/refs.repo":           "test-infra",
  2195  							"prow.k8s.io/refs.pull":           "0",
  2196  							"created-by-prow":                 "true",
  2197  							"prow.k8s.io/gerrit-patchset":     "1",
  2198  							"prow.k8s.io/context":             "foo-job",
  2199  							"prow.k8s.io/refs.base_ref":       "retest-branch",
  2200  							"prow.k8s.io/gerrit-revision":     "1",
  2201  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2202  							"prow.k8s.io/type":                "presubmit",
  2203  						},
  2204  						Annotations: map[string]string{
  2205  							"prow.k8s.io/job":             "foo-job",
  2206  							"prow.k8s.io/context":         "foo-job",
  2207  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2208  							"prow.k8s.io/gerrit-id":       "",
  2209  						},
  2210  					},
  2211  					Spec: prowapi.ProwJobSpec{
  2212  						Refs: &prowapi.Refs{
  2213  							Org:      "https://gerrit",
  2214  							Repo:     "test-infra",
  2215  							RepoLink: "https://gerrit/test-infra",
  2216  							BaseSHA:  "abc",
  2217  							BaseRef:  "retest-branch",
  2218  							BaseLink: "https://gerrit/test-infra/+/abc",
  2219  							CloneURI: "https://gerrit/test-infra",
  2220  							Pulls: []prowapi.Pull{
  2221  								{
  2222  									SHA:        "1",
  2223  									Link:       "https://gerrit/c/test-infra/+/0",
  2224  									CommitLink: "https://gerrit/test-infra/+/1",
  2225  									AuthorLink: "https://gerrit/q/",
  2226  								},
  2227  							},
  2228  						},
  2229  					},
  2230  				},
  2231  				{
  2232  					ObjectMeta: metav1.ObjectMeta{
  2233  						Labels: map[string]string{
  2234  							"prow.k8s.io/type":                "presubmit",
  2235  							"prow.k8s.io/refs.pull":           "0",
  2236  							"prow.k8s.io/gerrit-patchset":     "1",
  2237  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2238  							"prow.k8s.io/refs.org":            "gerrit",
  2239  							"prow.k8s.io/context":             "bar-job",
  2240  							"prow.k8s.io/refs.base_ref":       "retest-branch",
  2241  							"prow.k8s.io/gerrit-revision":     "1",
  2242  							"created-by-prow":                 "true",
  2243  							"prow.k8s.io/job":                 "bar-job",
  2244  							"prow.k8s.io/refs.repo":           "test-infra",
  2245  						},
  2246  						Annotations: map[string]string{
  2247  							"prow.k8s.io/context":         "bar-job",
  2248  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2249  							"prow.k8s.io/gerrit-id":       "",
  2250  							"prow.k8s.io/job":             "bar-job",
  2251  						},
  2252  					},
  2253  					Spec: prowapi.ProwJobSpec{
  2254  						Refs: &prowapi.Refs{
  2255  							Org:      "https://gerrit",
  2256  							Repo:     "test-infra",
  2257  							RepoLink: "https://gerrit/test-infra",
  2258  							BaseSHA:  "abc",
  2259  							BaseRef:  "retest-branch",
  2260  							BaseLink: "https://gerrit/test-infra/+/abc",
  2261  							CloneURI: "https://gerrit/test-infra",
  2262  							Pulls: []prowapi.Pull{
  2263  								{
  2264  									SHA:        "1",
  2265  									Link:       "https://gerrit/c/test-infra/+/0",
  2266  									CommitLink: "https://gerrit/test-infra/+/1",
  2267  									AuthorLink: "https://gerrit/q/",
  2268  								},
  2269  							},
  2270  						},
  2271  					},
  2272  				},
  2273  			},
  2274  		},
  2275  		{
  2276  			name: "retest does nothing if there are no latest reports",
  2277  			change: client.ChangeInfo{
  2278  				CurrentRevision: "1",
  2279  				Project:         "test-infra",
  2280  				Branch:          "retest-branch",
  2281  				Status:          "NEW",
  2282  				Revisions: map[string]client.RevisionInfo{
  2283  					"1": {
  2284  						Number:  1,
  2285  						Created: makeStamp(timeNow.Add(-time.Hour)),
  2286  					},
  2287  				},
  2288  				Messages: []gerrit.ChangeMessageInfo{
  2289  					{
  2290  						Message:        "/retest",
  2291  						RevisionNumber: 1,
  2292  						Date:           makeStamp(timeNow),
  2293  					},
  2294  				},
  2295  			},
  2296  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2297  			instance:     testInstance,
  2298  		},
  2299  		{
  2300  			name: "retest uses the latest report",
  2301  			change: client.ChangeInfo{
  2302  				CurrentRevision: "1",
  2303  				Project:         "test-infra",
  2304  				Branch:          "retest-branch",
  2305  				Status:          "NEW",
  2306  				Revisions: map[string]client.RevisionInfo{
  2307  					"1": {
  2308  						Number:  1,
  2309  						Created: makeStamp(timeNow.Add(-3 * time.Hour)),
  2310  					},
  2311  				},
  2312  				Messages: []gerrit.ChangeMessageInfo{
  2313  					{
  2314  						Message:        "/retest",
  2315  						RevisionNumber: 1,
  2316  						Date:           makeStamp(timeNow.Add(time.Hour)),
  2317  					},
  2318  					{
  2319  						Message:        "Prow Status: 1 out of 2 passed\n✔️ foo-job SUCCESS - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2320  						RevisionNumber: 1,
  2321  						Author:         gerrit.AccountInfo{AccountID: 42},
  2322  						Date:           makeStamp(timeNow.Add(-2 * time.Hour)),
  2323  					},
  2324  					{
  2325  						Message:        "Prow Status: 0 out of 2 passed\n❌️ foo-job FAILURE - http://foo-status\n❌ bar-job FAILURE - http://bar-status",
  2326  						RevisionNumber: 1,
  2327  						Author:         gerrit.AccountInfo{AccountID: 42},
  2328  						Date:           makeStamp(timeNow.Add(-time.Hour)),
  2329  					},
  2330  				},
  2331  			},
  2332  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2333  			instance:     testInstance,
  2334  			wantPjs: []*prowapi.ProwJob{
  2335  				{
  2336  					ObjectMeta: metav1.ObjectMeta{
  2337  						Labels: map[string]string{
  2338  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2339  							"created-by-prow":                 "true",
  2340  							"prow.k8s.io/job":                 "foo-job",
  2341  							"prow.k8s.io/gerrit-revision":     "1",
  2342  							"prow.k8s.io/type":                "presubmit",
  2343  							"prow.k8s.io/context":             "foo-job",
  2344  							"prow.k8s.io/refs.org":            "gerrit",
  2345  							"prow.k8s.io/refs.base_ref":       "retest-branch",
  2346  							"prow.k8s.io/refs.pull":           "0",
  2347  							"prow.k8s.io/refs.repo":           "test-infra",
  2348  							"prow.k8s.io/gerrit-patchset":     "1",
  2349  						},
  2350  						Annotations: map[string]string{
  2351  							"prow.k8s.io/gerrit-id":       "",
  2352  							"prow.k8s.io/job":             "foo-job",
  2353  							"prow.k8s.io/context":         "foo-job",
  2354  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2355  						},
  2356  					},
  2357  					Spec: prowapi.ProwJobSpec{
  2358  						Refs: &prowapi.Refs{
  2359  							Org:      "https://gerrit",
  2360  							Repo:     "test-infra",
  2361  							RepoLink: "https://gerrit/test-infra",
  2362  							BaseSHA:  "abc",
  2363  							BaseRef:  "retest-branch",
  2364  							BaseLink: "https://gerrit/test-infra/+/abc",
  2365  							CloneURI: "https://gerrit/test-infra",
  2366  							Pulls: []prowapi.Pull{
  2367  								{
  2368  									SHA:        "1",
  2369  									Link:       "https://gerrit/c/test-infra/+/0",
  2370  									CommitLink: "https://gerrit/test-infra/+/1",
  2371  									AuthorLink: "https://gerrit/q/",
  2372  								},
  2373  							},
  2374  						},
  2375  					},
  2376  				},
  2377  				{
  2378  					ObjectMeta: metav1.ObjectMeta{
  2379  						Labels: map[string]string{
  2380  							"prow.k8s.io/gerrit-revision":     "1",
  2381  							"prow.k8s.io/gerrit-patchset":     "1",
  2382  							"created-by-prow":                 "true",
  2383  							"prow.k8s.io/context":             "bar-job",
  2384  							"prow.k8s.io/refs.repo":           "test-infra",
  2385  							"prow.k8s.io/refs.org":            "gerrit",
  2386  							"prow.k8s.io/refs.base_ref":       "retest-branch",
  2387  							"prow.k8s.io/refs.pull":           "0",
  2388  							"prow.k8s.io/type":                "presubmit",
  2389  							"prow.k8s.io/job":                 "bar-job",
  2390  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2391  						},
  2392  						Annotations: map[string]string{
  2393  							"prow.k8s.io/gerrit-id":       "",
  2394  							"prow.k8s.io/job":             "bar-job",
  2395  							"prow.k8s.io/context":         "bar-job",
  2396  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2397  						},
  2398  					},
  2399  					Spec: prowapi.ProwJobSpec{
  2400  						Refs: &prowapi.Refs{
  2401  							Org:      "https://gerrit",
  2402  							Repo:     "test-infra",
  2403  							RepoLink: "https://gerrit/test-infra",
  2404  							BaseSHA:  "abc",
  2405  							BaseRef:  "retest-branch",
  2406  							BaseLink: "https://gerrit/test-infra/+/abc",
  2407  							CloneURI: "https://gerrit/test-infra",
  2408  							Pulls: []prowapi.Pull{
  2409  								{
  2410  									SHA:        "1",
  2411  									Link:       "https://gerrit/c/test-infra/+/0",
  2412  									CommitLink: "https://gerrit/test-infra/+/1",
  2413  									AuthorLink: "https://gerrit/q/",
  2414  								},
  2415  							},
  2416  						},
  2417  					},
  2418  				},
  2419  			},
  2420  		},
  2421  		{
  2422  			name: "no comments when no jobs have Report set",
  2423  			change: client.ChangeInfo{
  2424  				CurrentRevision: "1",
  2425  				Project:         "test-infra",
  2426  				Status:          "NEW",
  2427  				Revisions: map[string]client.RevisionInfo{
  2428  					"1": {
  2429  						Ref:     "refs/changes/00/1/1",
  2430  						Created: stampNow,
  2431  					},
  2432  				},
  2433  			},
  2434  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2435  			instance:     testInstance,
  2436  			wantPjs: []*prowapi.ProwJob{
  2437  				{
  2438  					ObjectMeta: metav1.ObjectMeta{
  2439  						Labels: map[string]string{
  2440  							"prow.k8s.io/refs.org":            "gerrit",
  2441  							"prow.k8s.io/refs.pull":           "0",
  2442  							"prow.k8s.io/refs.base_ref":       "",
  2443  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2444  							"created-by-prow":                 "true",
  2445  							"prow.k8s.io/job":                 "always-runs-all-branches",
  2446  							"prow.k8s.io/gerrit-revision":     "1",
  2447  							"prow.k8s.io/gerrit-patchset":     "0",
  2448  							"prow.k8s.io/type":                "presubmit",
  2449  							"prow.k8s.io/context":             "always-runs-all-branches",
  2450  							"prow.k8s.io/refs.repo":           "test-infra",
  2451  						},
  2452  						Annotations: map[string]string{
  2453  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2454  							"prow.k8s.io/gerrit-id":       "",
  2455  							"prow.k8s.io/job":             "always-runs-all-branches",
  2456  							"prow.k8s.io/context":         "always-runs-all-branches",
  2457  							"foo":                         "bar",
  2458  						},
  2459  					},
  2460  					Spec: prowapi.ProwJobSpec{
  2461  						Refs: &prowapi.Refs{
  2462  							Org:      "https://gerrit",
  2463  							Repo:     "test-infra",
  2464  							RepoLink: "https://gerrit/test-infra",
  2465  							BaseSHA:  "abc",
  2466  							BaseLink: "https://gerrit/test-infra/+/abc",
  2467  							CloneURI: "https://gerrit/test-infra",
  2468  							Pulls: []prowapi.Pull{
  2469  								{
  2470  									Ref:        "refs/changes/00/1/1",
  2471  									SHA:        "1",
  2472  									Link:       "https://gerrit/c/test-infra/+/0",
  2473  									CommitLink: "https://gerrit/test-infra/+/1",
  2474  									AuthorLink: "https://gerrit/q/",
  2475  								},
  2476  							},
  2477  						},
  2478  					},
  2479  				},
  2480  				{
  2481  					ObjectMeta: metav1.ObjectMeta{
  2482  						Labels: map[string]string{
  2483  							"prow.k8s.io/gerrit-patchset":     "0",
  2484  							"prow.k8s.io/type":                "presubmit",
  2485  							"prow.k8s.io/refs.org":            "gerrit",
  2486  							"created-by-prow":                 "true",
  2487  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  2488  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  2489  							"prow.k8s.io/refs.base_ref":       "",
  2490  							"prow.k8s.io/gerrit-revision":     "1",
  2491  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2492  							"prow.k8s.io/refs.repo":           "test-infra",
  2493  							"prow.k8s.io/refs.pull":           "0",
  2494  						},
  2495  						Annotations: map[string]string{
  2496  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2497  							"prow.k8s.io/gerrit-id":       "",
  2498  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  2499  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  2500  						},
  2501  					},
  2502  					Spec: prowapi.ProwJobSpec{
  2503  						Refs: &prowapi.Refs{
  2504  							Org:      "https://gerrit",
  2505  							Repo:     "test-infra",
  2506  							RepoLink: "https://gerrit/test-infra",
  2507  							BaseSHA:  "abc",
  2508  							BaseLink: "https://gerrit/test-infra/+/abc",
  2509  							CloneURI: "https://gerrit/test-infra",
  2510  							Pulls: []prowapi.Pull{
  2511  								{
  2512  									Ref:        "refs/changes/00/1/1",
  2513  									SHA:        "1",
  2514  									Link:       "https://gerrit/c/test-infra/+/0",
  2515  									CommitLink: "https://gerrit/test-infra/+/1",
  2516  									AuthorLink: "https://gerrit/q/",
  2517  								},
  2518  							},
  2519  						},
  2520  					},
  2521  				},
  2522  			},
  2523  			wantSkipReport: true,
  2524  		},
  2525  		{
  2526  			name: "comment left when at-least 1 job has Report set",
  2527  			change: client.ChangeInfo{
  2528  				CurrentRevision: "1",
  2529  				Project:         "test-infra",
  2530  				Status:          "NEW",
  2531  				Revisions: map[string]client.RevisionInfo{
  2532  					"1": {
  2533  						Files: map[string]client.FileInfo{
  2534  							"a.foo": {},
  2535  						},
  2536  						Ref:     "refs/changes/00/1/1",
  2537  						Created: stampNow,
  2538  					},
  2539  				},
  2540  			},
  2541  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2542  			instance:     testInstance,
  2543  			wantPjs: []*prowapi.ProwJob{
  2544  				{
  2545  					ObjectMeta: metav1.ObjectMeta{
  2546  						Labels: map[string]string{
  2547  							"prow.k8s.io/context":             "always-runs-all-branches",
  2548  							"prow.k8s.io/refs.base_ref":       "",
  2549  							"prow.k8s.io/type":                "presubmit",
  2550  							"created-by-prow":                 "true",
  2551  							"prow.k8s.io/job":                 "always-runs-all-branches",
  2552  							"prow.k8s.io/refs.org":            "gerrit",
  2553  							"prow.k8s.io/refs.repo":           "test-infra",
  2554  							"prow.k8s.io/refs.pull":           "0",
  2555  							"prow.k8s.io/gerrit-revision":     "1",
  2556  							"prow.k8s.io/gerrit-patchset":     "0",
  2557  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2558  						},
  2559  						Annotations: map[string]string{
  2560  							"foo":                         "bar",
  2561  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2562  							"prow.k8s.io/gerrit-id":       "",
  2563  							"prow.k8s.io/job":             "always-runs-all-branches",
  2564  							"prow.k8s.io/context":         "always-runs-all-branches",
  2565  						},
  2566  					},
  2567  					Spec: prowapi.ProwJobSpec{
  2568  						Refs: &prowapi.Refs{
  2569  							Org:      "https://gerrit",
  2570  							Repo:     "test-infra",
  2571  							RepoLink: "https://gerrit/test-infra",
  2572  							BaseSHA:  "abc",
  2573  							BaseLink: "https://gerrit/test-infra/+/abc",
  2574  							CloneURI: "https://gerrit/test-infra",
  2575  							Pulls: []prowapi.Pull{
  2576  								{
  2577  									Ref:        "refs/changes/00/1/1",
  2578  									SHA:        "1",
  2579  									Link:       "https://gerrit/c/test-infra/+/0",
  2580  									CommitLink: "https://gerrit/test-infra/+/1",
  2581  									AuthorLink: "https://gerrit/q/",
  2582  								},
  2583  							},
  2584  						},
  2585  					},
  2586  				},
  2587  				{
  2588  					ObjectMeta: metav1.ObjectMeta{
  2589  						Labels: map[string]string{
  2590  							"created-by-prow":                 "true",
  2591  							"prow.k8s.io/type":                "presubmit",
  2592  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2593  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  2594  							"prow.k8s.io/refs.base_ref":       "",
  2595  							"prow.k8s.io/refs.org":            "gerrit",
  2596  							"prow.k8s.io/refs.repo":           "test-infra",
  2597  							"prow.k8s.io/gerrit-revision":     "1",
  2598  							"prow.k8s.io/gerrit-patchset":     "0",
  2599  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  2600  							"prow.k8s.io/refs.pull":           "0",
  2601  						},
  2602  						Annotations: map[string]string{
  2603  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2604  							"prow.k8s.io/gerrit-id":       "",
  2605  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  2606  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  2607  						},
  2608  					},
  2609  					Spec: prowapi.ProwJobSpec{
  2610  						Refs: &prowapi.Refs{
  2611  							Org:      "https://gerrit",
  2612  							Repo:     "test-infra",
  2613  							RepoLink: "https://gerrit/test-infra",
  2614  							BaseSHA:  "abc",
  2615  							BaseLink: "https://gerrit/test-infra/+/abc",
  2616  							CloneURI: "https://gerrit/test-infra",
  2617  							Pulls: []prowapi.Pull{
  2618  								{
  2619  									Ref:        "refs/changes/00/1/1",
  2620  									SHA:        "1",
  2621  									Link:       "https://gerrit/c/test-infra/+/0",
  2622  									CommitLink: "https://gerrit/test-infra/+/1",
  2623  									AuthorLink: "https://gerrit/q/",
  2624  								},
  2625  							},
  2626  						},
  2627  					},
  2628  				},
  2629  				{
  2630  					ObjectMeta: metav1.ObjectMeta{
  2631  						Labels: map[string]string{
  2632  							"prow.k8s.io/type":                "presubmit",
  2633  							"prow.k8s.io/refs.repo":           "test-infra",
  2634  							"prow.k8s.io/refs.pull":           "0",
  2635  							"created-by-prow":                 "true",
  2636  							"prow.k8s.io/gerrit-patchset":     "0",
  2637  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2638  							"prow.k8s.io/context":             "foo-job-reported",
  2639  							"prow.k8s.io/refs.org":            "gerrit",
  2640  							"prow.k8s.io/refs.base_ref":       "",
  2641  							"prow.k8s.io/job":                 "reported-job-runs-on-foo-file-change",
  2642  							"prow.k8s.io/gerrit-revision":     "1",
  2643  						},
  2644  						Annotations: map[string]string{
  2645  							"prow.k8s.io/job":             "reported-job-runs-on-foo-file-change",
  2646  							"prow.k8s.io/context":         "foo-job-reported",
  2647  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2648  							"prow.k8s.io/gerrit-id":       "",
  2649  						},
  2650  					},
  2651  					Spec: prowapi.ProwJobSpec{
  2652  						Refs: &prowapi.Refs{
  2653  							Org:      "https://gerrit",
  2654  							Repo:     "test-infra",
  2655  							RepoLink: "https://gerrit/test-infra",
  2656  							BaseSHA:  "abc",
  2657  							BaseLink: "https://gerrit/test-infra/+/abc",
  2658  							CloneURI: "https://gerrit/test-infra",
  2659  							Pulls: []prowapi.Pull{
  2660  								{
  2661  									Ref:        "refs/changes/00/1/1",
  2662  									SHA:        "1",
  2663  									Link:       "https://gerrit/c/test-infra/+/0",
  2664  									CommitLink: "https://gerrit/test-infra/+/1",
  2665  									AuthorLink: "https://gerrit/q/",
  2666  								},
  2667  							},
  2668  						},
  2669  					},
  2670  				},
  2671  			},
  2672  		},
  2673  		{
  2674  			name: "/test ? will leave a comment with the commands to trigger presubmit Prow jobs",
  2675  			change: client.ChangeInfo{
  2676  				CurrentRevision: "1",
  2677  				Project:         "test-infra",
  2678  				Status:          "NEW",
  2679  				Revisions: map[string]client.RevisionInfo{
  2680  					"1": {
  2681  						Number:  1,
  2682  						Created: makeStamp(timeNow.Add(-time.Hour)),
  2683  					},
  2684  				},
  2685  				Messages: []gerrit.ChangeMessageInfo{
  2686  					{
  2687  						Message:        "/test ?",
  2688  						RevisionNumber: 1,
  2689  						Date:           makeStamp(timeNow),
  2690  					},
  2691  				},
  2692  			},
  2693  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2694  			instance:     testInstance,
  2695  		},
  2696  		{
  2697  			name: "InRepoConfig Presubmits are retrieved",
  2698  			change: client.ChangeInfo{
  2699  				CurrentRevision: "1",
  2700  				Project:         "test-infra",
  2701  				Status:          "NEW",
  2702  				Branch:          "inRepoConfig",
  2703  				Revisions: map[string]client.RevisionInfo{
  2704  					"1": {
  2705  						Ref:     "refs/changes/00/1/1",
  2706  						Created: stampNow,
  2707  					},
  2708  				},
  2709  			},
  2710  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2711  			instance:     testInstance,
  2712  			wantPjs: []*prowapi.ProwJob{
  2713  				{
  2714  					ObjectMeta: metav1.ObjectMeta{
  2715  						Labels: map[string]string{
  2716  							"prow.k8s.io/job":                 "always-runs-all-branches",
  2717  							"prow.k8s.io/refs.org":            "gerrit",
  2718  							"prow.k8s.io/type":                "presubmit",
  2719  							"prow.k8s.io/refs.repo":           "test-infra",
  2720  							"prow.k8s.io/refs.pull":           "0",
  2721  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2722  							"created-by-prow":                 "true",
  2723  							"prow.k8s.io/context":             "always-runs-all-branches",
  2724  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  2725  							"prow.k8s.io/gerrit-patchset":     "0",
  2726  							"prow.k8s.io/gerrit-revision":     "1",
  2727  						},
  2728  						Annotations: map[string]string{
  2729  							"prow.k8s.io/context":         "always-runs-all-branches",
  2730  							"foo":                         "bar",
  2731  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2732  							"prow.k8s.io/gerrit-id":       "",
  2733  							"prow.k8s.io/job":             "always-runs-all-branches",
  2734  						},
  2735  					},
  2736  					Spec: prowapi.ProwJobSpec{
  2737  						Refs: &prowapi.Refs{
  2738  							Org:      "https://gerrit",
  2739  							Repo:     "test-infra",
  2740  							RepoLink: "https://gerrit/test-infra",
  2741  							BaseSHA:  "abc",
  2742  							BaseRef:  "inRepoConfig",
  2743  							BaseLink: "https://gerrit/test-infra/+/abc",
  2744  							CloneURI: "https://gerrit/test-infra",
  2745  							Pulls: []prowapi.Pull{
  2746  								{
  2747  									Ref:        "refs/changes/00/1/1",
  2748  									SHA:        "1",
  2749  									Link:       "https://gerrit/c/test-infra/+/0",
  2750  									CommitLink: "https://gerrit/test-infra/+/1",
  2751  									AuthorLink: "https://gerrit/q/",
  2752  								},
  2753  							},
  2754  						},
  2755  					},
  2756  				},
  2757  				{
  2758  					ObjectMeta: metav1.ObjectMeta{
  2759  						Labels: map[string]string{
  2760  							"prow.k8s.io/job":                 "runs-on-all-but-baz-branch",
  2761  							"prow.k8s.io/context":             "runs-on-all-but-baz-branch",
  2762  							"prow.k8s.io/refs.org":            "gerrit",
  2763  							"prow.k8s.io/gerrit-revision":     "1",
  2764  							"prow.k8s.io/type":                "presubmit",
  2765  							"prow.k8s.io/refs.repo":           "test-infra",
  2766  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  2767  							"created-by-prow":                 "true",
  2768  							"prow.k8s.io/gerrit-patchset":     "0",
  2769  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2770  							"prow.k8s.io/refs.pull":           "0",
  2771  						},
  2772  						Annotations: map[string]string{
  2773  							"prow.k8s.io/gerrit-id":       "",
  2774  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2775  							"prow.k8s.io/job":             "runs-on-all-but-baz-branch",
  2776  							"prow.k8s.io/context":         "runs-on-all-but-baz-branch",
  2777  						},
  2778  					},
  2779  					Spec: prowapi.ProwJobSpec{
  2780  						Refs: &prowapi.Refs{
  2781  							Org:      "https://gerrit",
  2782  							Repo:     "test-infra",
  2783  							RepoLink: "https://gerrit/test-infra",
  2784  							BaseSHA:  "abc",
  2785  							BaseRef:  "inRepoConfig",
  2786  							BaseLink: "https://gerrit/test-infra/+/abc",
  2787  							CloneURI: "https://gerrit/test-infra",
  2788  							Pulls: []prowapi.Pull{
  2789  								{
  2790  									Ref:        "refs/changes/00/1/1",
  2791  									SHA:        "1",
  2792  									Link:       "https://gerrit/c/test-infra/+/0",
  2793  									CommitLink: "https://gerrit/test-infra/+/1",
  2794  									AuthorLink: "https://gerrit/q/",
  2795  								},
  2796  							},
  2797  						},
  2798  					},
  2799  				},
  2800  				{
  2801  					ObjectMeta: metav1.ObjectMeta{
  2802  						Labels: map[string]string{
  2803  							"prow.k8s.io/job":                 "always-runs-inRepoConfig",
  2804  							"prow.k8s.io/refs.org":            "gerrit",
  2805  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2806  							"prow.k8s.io/gerrit-revision":     "1",
  2807  							"created-by-prow":                 "true",
  2808  							"prow.k8s.io/type":                "presubmit",
  2809  							"prow.k8s.io/refs.repo":           "test-infra",
  2810  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  2811  							"prow.k8s.io/context":             "always-runs-inRepoConfig",
  2812  							"prow.k8s.io/refs.pull":           "0",
  2813  							"prow.k8s.io/gerrit-patchset":     "0",
  2814  						},
  2815  						Annotations: map[string]string{
  2816  							"prow.k8s.io/job":             "always-runs-inRepoConfig",
  2817  							"prow.k8s.io/context":         "always-runs-inRepoConfig",
  2818  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2819  							"prow.k8s.io/gerrit-id":       "",
  2820  						},
  2821  					},
  2822  					Spec: prowapi.ProwJobSpec{
  2823  						Refs: &prowapi.Refs{
  2824  							Org:      "https://gerrit",
  2825  							Repo:     "test-infra",
  2826  							RepoLink: "https://gerrit/test-infra",
  2827  							BaseSHA:  "abc",
  2828  							BaseRef:  "inRepoConfig",
  2829  							BaseLink: "https://gerrit/test-infra/+/abc",
  2830  							CloneURI: "https://gerrit/test-infra",
  2831  							Pulls: []prowapi.Pull{
  2832  								{
  2833  									Ref:        "refs/changes/00/1/1",
  2834  									SHA:        "1",
  2835  									Link:       "https://gerrit/c/test-infra/+/0",
  2836  									CommitLink: "https://gerrit/test-infra/+/1",
  2837  									AuthorLink: "https://gerrit/q/",
  2838  								},
  2839  							},
  2840  						},
  2841  					},
  2842  				},
  2843  			},
  2844  		},
  2845  		{
  2846  			name: "InRepoConfig Postsubmits are retrieved",
  2847  			change: client.ChangeInfo{
  2848  				CurrentRevision: "1",
  2849  				Project:         "postsubmits-project",
  2850  				Status:          "MERGED",
  2851  				Branch:          "inRepoConfig",
  2852  				Revisions: map[string]client.RevisionInfo{
  2853  					"1": {
  2854  						Ref:     "refs/changes/00/1/1",
  2855  						Created: stampNow,
  2856  					},
  2857  				},
  2858  			},
  2859  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2860  			instance:     testInstance,
  2861  			wantPjs: []*prowapi.ProwJob{
  2862  				{
  2863  					ObjectMeta: metav1.ObjectMeta{
  2864  						Labels: map[string]string{
  2865  							"prow.k8s.io/type":                "postsubmit",
  2866  							"prow.k8s.io/refs.org":            "gerrit",
  2867  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  2868  							"prow.k8s.io/refs.pull":           "0",
  2869  							"created-by-prow":                 "true",
  2870  							"prow.k8s.io/refs.repo":           "postsubmits-project",
  2871  							"prow.k8s.io/gerrit-revision":     "1",
  2872  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2873  							"prow.k8s.io/job":                 "test-bar",
  2874  							"prow.k8s.io/context":             "test-bar",
  2875  							"prow.k8s.io/gerrit-patchset":     "0",
  2876  						},
  2877  						Annotations: map[string]string{
  2878  							"prow.k8s.io/job":             "test-bar",
  2879  							"prow.k8s.io/context":         "test-bar",
  2880  							"prow.k8s.io/gerrit-id":       "",
  2881  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2882  						},
  2883  					},
  2884  					Spec: prowapi.ProwJobSpec{
  2885  						Refs: &prowapi.Refs{
  2886  							Org:      "https://gerrit",
  2887  							Repo:     "postsubmits-project",
  2888  							RepoLink: "https://gerrit/postsubmits-project",
  2889  							BaseSHA:  "abc",
  2890  							BaseRef:  "inRepoConfig",
  2891  							BaseLink: "https://gerrit/postsubmits-project/+/abc",
  2892  							CloneURI: "https://gerrit/postsubmits-project",
  2893  							Pulls: []prowapi.Pull{
  2894  								{
  2895  									Ref:        "refs/changes/00/1/1",
  2896  									SHA:        "1",
  2897  									Link:       "https://gerrit/c/postsubmits-project/+/0",
  2898  									CommitLink: "https://gerrit/postsubmits-project/+/1",
  2899  									AuthorLink: "https://gerrit/q/",
  2900  								},
  2901  							},
  2902  						},
  2903  					},
  2904  				},
  2905  				{
  2906  					ObjectMeta: metav1.ObjectMeta{
  2907  						Labels: map[string]string{
  2908  							"prow.k8s.io/context":             "always-runs-inRepoConfig-Post",
  2909  							"prow.k8s.io/gerrit-patchset":     "0",
  2910  							"created-by-prow":                 "true",
  2911  							"prow.k8s.io/type":                "postsubmit",
  2912  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  2913  							"prow.k8s.io/gerrit-revision":     "1",
  2914  							"prow.k8s.io/job":                 "always-runs-inRepoConfig-Post",
  2915  							"prow.k8s.io/refs.repo":           "postsubmits-project",
  2916  							"prow.k8s.io/refs.pull":           "0",
  2917  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2918  							"prow.k8s.io/refs.org":            "gerrit",
  2919  						},
  2920  						Annotations: map[string]string{
  2921  							"prow.k8s.io/job":             "always-runs-inRepoConfig-Post",
  2922  							"prow.k8s.io/context":         "always-runs-inRepoConfig-Post",
  2923  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2924  							"prow.k8s.io/gerrit-id":       "",
  2925  						},
  2926  					},
  2927  					Spec: prowapi.ProwJobSpec{
  2928  						Refs: &prowapi.Refs{
  2929  							Org:      "https://gerrit",
  2930  							Repo:     "postsubmits-project",
  2931  							RepoLink: "https://gerrit/postsubmits-project",
  2932  							BaseSHA:  "abc",
  2933  							BaseRef:  "inRepoConfig",
  2934  							BaseLink: "https://gerrit/postsubmits-project/+/abc",
  2935  							CloneURI: "https://gerrit/postsubmits-project",
  2936  							Pulls: []prowapi.Pull{
  2937  								{
  2938  									Ref:        "refs/changes/00/1/1",
  2939  									SHA:        "1",
  2940  									Link:       "https://gerrit/c/postsubmits-project/+/0",
  2941  									CommitLink: "https://gerrit/postsubmits-project/+/1",
  2942  									AuthorLink: "https://gerrit/q/",
  2943  								},
  2944  							},
  2945  						},
  2946  					},
  2947  				},
  2948  			},
  2949  		},
  2950  		{
  2951  			name: "InRepoConfig Presubmits are retrieved when repo name format has slash",
  2952  			change: client.ChangeInfo{
  2953  				CurrentRevision: "1",
  2954  				Project:         "kubernetes/test-infra",
  2955  				Status:          "NEW",
  2956  				Branch:          "inRepoConfig",
  2957  				Revisions: map[string]client.RevisionInfo{
  2958  					"1": {
  2959  						Ref:     "refs/changes/00/1/1",
  2960  						Created: stampNow,
  2961  					},
  2962  				},
  2963  			},
  2964  			instancesMap: map[string]*gerrit.AccountInfo{testInstance: {AccountID: 42}},
  2965  			instance:     testInstance,
  2966  			wantPjs: []*prowapi.ProwJob{
  2967  				{
  2968  					ObjectMeta: metav1.ObjectMeta{
  2969  						Labels: map[string]string{
  2970  							"prow.k8s.io/refs.pull":           "0",
  2971  							"prow.k8s.io/gerrit-patchset":     "0",
  2972  							"prow.k8s.io/job":                 "always-runs-inRepoConfig",
  2973  							"prow.k8s.io/refs.repo":           "test-infra",
  2974  							"prow.k8s.io/context":             "always-runs-inRepoConfig",
  2975  							"prow.k8s.io/refs.org":            "gerrit",
  2976  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  2977  							"prow.k8s.io/gerrit-revision":     "1",
  2978  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  2979  							"created-by-prow":                 "true",
  2980  							"prow.k8s.io/type":                "presubmit",
  2981  						},
  2982  						Annotations: map[string]string{
  2983  							"prow.k8s.io/context":         "always-runs-inRepoConfig",
  2984  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  2985  							"prow.k8s.io/gerrit-id":       "",
  2986  							"prow.k8s.io/job":             "always-runs-inRepoConfig",
  2987  						},
  2988  					},
  2989  					Spec: prowapi.ProwJobSpec{
  2990  						Refs: &prowapi.Refs{
  2991  							Org:      "https://gerrit",
  2992  							Repo:     "kubernetes/test-infra",
  2993  							RepoLink: "https://gerrit/kubernetes/test-infra",
  2994  							BaseSHA:  "abc",
  2995  							BaseRef:  "inRepoConfig",
  2996  							BaseLink: "https://gerrit/kubernetes/test-infra/+/abc",
  2997  							CloneURI: "https://gerrit/kubernetes/test-infra",
  2998  							Pulls: []prowapi.Pull{
  2999  								{
  3000  									Ref:        "refs/changes/00/1/1",
  3001  									SHA:        "1",
  3002  									Link:       "https://gerrit/c/kubernetes/test-infra/+/0",
  3003  									CommitLink: "https://gerrit/kubernetes/test-infra/+/1",
  3004  									AuthorLink: "https://gerrit/q/",
  3005  								},
  3006  							},
  3007  						},
  3008  					},
  3009  				},
  3010  				{
  3011  					ObjectMeta: metav1.ObjectMeta{
  3012  						Labels: map[string]string{
  3013  							"prow.k8s.io/refs.base_ref":       "inRepoConfig",
  3014  							"prow.k8s.io/gerrit-revision":     "1",
  3015  							"prow.k8s.io/gerrit-patchset":     "0",
  3016  							"prow.k8s.io/gerrit-report-label": "Code-Review",
  3017  							"prow.k8s.io/refs.repo":           "test-infra",
  3018  							"prow.k8s.io/type":                "presubmit",
  3019  							"prow.k8s.io/job":                 "other-test",
  3020  							"prow.k8s.io/context":             "other-test",
  3021  							"prow.k8s.io/refs.org":            "gerrit",
  3022  							"prow.k8s.io/refs.pull":           "0",
  3023  							"created-by-prow":                 "true",
  3024  						},
  3025  						Annotations: map[string]string{
  3026  							"prow.k8s.io/job":             "other-test",
  3027  							"prow.k8s.io/context":         "other-test",
  3028  							"prow.k8s.io/gerrit-instance": "https://gerrit",
  3029  							"prow.k8s.io/gerrit-id":       "",
  3030  						},
  3031  					},
  3032  					Spec: prowapi.ProwJobSpec{
  3033  						Refs: &prowapi.Refs{
  3034  							Org:      "https://gerrit",
  3035  							Repo:     "kubernetes/test-infra",
  3036  							RepoLink: "https://gerrit/kubernetes/test-infra",
  3037  							BaseSHA:  "abc",
  3038  							BaseRef:  "inRepoConfig",
  3039  							BaseLink: "https://gerrit/kubernetes/test-infra/+/abc",
  3040  							CloneURI: "https://gerrit/kubernetes/test-infra",
  3041  							Pulls: []prowapi.Pull{
  3042  								{
  3043  									Ref:        "refs/changes/00/1/1",
  3044  									SHA:        "1",
  3045  									Link:       "https://gerrit/c/kubernetes/test-infra/+/0",
  3046  									CommitLink: "https://gerrit/kubernetes/test-infra/+/1",
  3047  									AuthorLink: "https://gerrit/q/",
  3048  								},
  3049  							},
  3050  						},
  3051  					},
  3052  				},
  3053  			},
  3054  		},
  3055  	}
  3056  
  3057  	testInfraPresubmits := []config.Presubmit{
  3058  		{
  3059  			JobBase: config.JobBase{
  3060  				Name:        "always-runs-all-branches",
  3061  				Annotations: map[string]string{"foo": "bar"},
  3062  			},
  3063  			AlwaysRun: true,
  3064  			Reporter: config.Reporter{
  3065  				Context:    "always-runs-all-branches",
  3066  				SkipReport: true,
  3067  			},
  3068  		},
  3069  		{
  3070  			JobBase: config.JobBase{
  3071  				Name: "run-if-changed-all-branches",
  3072  			},
  3073  			RegexpChangeMatcher: config.RegexpChangeMatcher{
  3074  				RunIfChanged: "\\.go",
  3075  			},
  3076  			Reporter: config.Reporter{
  3077  				Context:    "run-if-changed-all-branches",
  3078  				SkipReport: true,
  3079  			},
  3080  		},
  3081  		{
  3082  			JobBase: config.JobBase{
  3083  				Name: "runs-on-pony-branch",
  3084  			},
  3085  			Brancher: config.Brancher{
  3086  				Branches: []string{"pony"},
  3087  			},
  3088  			AlwaysRun: true,
  3089  			Reporter: config.Reporter{
  3090  				Context:    "runs-on-pony-branch",
  3091  				SkipReport: true,
  3092  			},
  3093  		},
  3094  		{
  3095  			JobBase: config.JobBase{
  3096  				Name: "runs-on-all-but-baz-branch",
  3097  			},
  3098  			Brancher: config.Brancher{
  3099  				SkipBranches: []string{"baz"},
  3100  			},
  3101  			AlwaysRun: true,
  3102  			Reporter: config.Reporter{
  3103  				Context:    "runs-on-all-but-baz-branch",
  3104  				SkipReport: true,
  3105  			},
  3106  		},
  3107  		{
  3108  			JobBase: config.JobBase{
  3109  				Name: "trigger-regex-all-branches",
  3110  			},
  3111  			Trigger:      `.*/test\s*troll.*`,
  3112  			RerunCommand: "/test troll",
  3113  			Reporter: config.Reporter{
  3114  				Context:    "trigger-regex-all-branches",
  3115  				SkipReport: true,
  3116  			},
  3117  		},
  3118  		{
  3119  			JobBase: config.JobBase{
  3120  				Name: "foo-job",
  3121  			},
  3122  			Reporter: config.Reporter{
  3123  				Context:    "foo-job",
  3124  				SkipReport: true,
  3125  			},
  3126  		},
  3127  		{
  3128  			JobBase: config.JobBase{
  3129  				Name: "bar-job",
  3130  			},
  3131  			Reporter: config.Reporter{
  3132  				Context:    "bar-job",
  3133  				SkipReport: true,
  3134  			},
  3135  		},
  3136  		{
  3137  			JobBase: config.JobBase{
  3138  				Name: "reported-job-runs-on-foo-file-change",
  3139  			},
  3140  			RegexpChangeMatcher: config.RegexpChangeMatcher{
  3141  				RunIfChanged: "\\.foo",
  3142  			},
  3143  			Reporter: config.Reporter{
  3144  				Context: "foo-job-reported",
  3145  			},
  3146  		},
  3147  	}
  3148  	if err := config.SetPresubmitRegexes(testInfraPresubmits); err != nil {
  3149  		t.Fatalf("could not set regexes: %v", err)
  3150  	}
  3151  
  3152  	cfg := &config.Config{
  3153  		JobConfig: config.JobConfig{
  3154  			ProwYAMLGetterWithDefaults: fakeProwYAMLGetter,
  3155  			ProwYAMLGetter:             fakeProwYAMLGetter,
  3156  			PresubmitsStatic: map[string][]config.Presubmit{
  3157  				"https://gerrit/test-infra": testInfraPresubmits,
  3158  				"https://gerrit/kubernetes/test-infra": {
  3159  					{
  3160  						JobBase: config.JobBase{
  3161  							Name: "other-test",
  3162  						},
  3163  						AlwaysRun: true,
  3164  						Reporter: config.Reporter{
  3165  							Context:    "other-test",
  3166  							SkipReport: true,
  3167  						},
  3168  					},
  3169  				},
  3170  				"https://gerrit/other-repo": {
  3171  					{
  3172  						JobBase: config.JobBase{
  3173  							Name: "other-test",
  3174  						},
  3175  						AlwaysRun: true,
  3176  						Reporter: config.Reporter{
  3177  							Context:    "other-test",
  3178  							SkipReport: true,
  3179  						},
  3180  					},
  3181  				},
  3182  			},
  3183  			PostsubmitsStatic: map[string][]config.Postsubmit{
  3184  				"https://gerrit/postsubmits-project": {
  3185  					{
  3186  						JobBase: config.JobBase{
  3187  							Name: "test-bar",
  3188  						},
  3189  						Reporter: config.Reporter{
  3190  							Context:    "test-bar",
  3191  							SkipReport: true,
  3192  						},
  3193  					},
  3194  				},
  3195  			},
  3196  		},
  3197  		ProwConfig: config.ProwConfig{
  3198  			PodNamespace: namespace,
  3199  			InRepoConfig: config.InRepoConfig{
  3200  				Enabled:         map[string]*bool{"*": &trueBool},
  3201  				AllowedClusters: map[string][]string{"*": {kube.DefaultClusterAlias}},
  3202  			},
  3203  		},
  3204  	}
  3205  	fca := &fca{
  3206  		c: cfg,
  3207  	}
  3208  	for _, tc := range testcases {
  3209  		tc := tc // capture range variable
  3210  		t.Run(tc.name, func(t *testing.T) {
  3211  			t.Parallel()
  3212  
  3213  			fakeProwJobClient := prowfake.NewSimpleClientset()
  3214  			fakeLastSync := client.LastSyncState{tc.instance: map[string]time.Time{}}
  3215  			fakeLastSync[tc.instance][tc.change.Project] = timeNow.Add(-time.Minute)
  3216  
  3217  			cache, err := createTestRepoCache(t, fca)
  3218  			if err != nil {
  3219  				t.Errorf("error making test repo cache %v", err)
  3220  			}
  3221  
  3222  			var gc fgc
  3223  			gc.instanceMap = tc.instancesMap
  3224  			c := &Controller{
  3225  				config:                      fca.Config,
  3226  				prowJobClient:               fakeProwJobClient.ProwV1().ProwJobs("prowjobs"),
  3227  				gc:                          &gc,
  3228  				tracker:                     &fakeSync{val: fakeLastSync},
  3229  				inRepoConfigGetter:          cache,
  3230  				inRepoConfigFailuresTracker: make(map[string]bool),
  3231  			}
  3232  
  3233  			err = c.triggerJobs(logrus.WithField("name", tc.name), tc.instance, tc.change)
  3234  			if tc.wantError {
  3235  				if err == nil {
  3236  					t.Fatal("Expected error, got nil.")
  3237  				}
  3238  				return
  3239  			}
  3240  
  3241  			if err != nil {
  3242  				t.Fatalf("Expect no error, but got %v", err)
  3243  			}
  3244  
  3245  			var gotProwjobs []*prowapi.ProwJob
  3246  			for _, action := range fakeProwJobClient.Fake.Actions() {
  3247  				switch action := action.(type) {
  3248  				case clienttesting.CreateActionImpl:
  3249  					if prowjob, ok := action.Object.(*prowapi.ProwJob); ok {
  3250  						// Comparing the entire prowjob struct is not necessary
  3251  						// in this test, so construct only ProwJob structs with
  3252  						// only necessary informations.
  3253  						gotProwjobs = append(gotProwjobs, &prowapi.ProwJob{
  3254  							ObjectMeta: metav1.ObjectMeta{
  3255  								Labels:      prowjob.Labels,
  3256  								Annotations: prowjob.Annotations,
  3257  							},
  3258  							Spec: prowapi.ProwJobSpec{
  3259  								Refs: prowjob.Spec.Refs,
  3260  							},
  3261  						})
  3262  					}
  3263  				}
  3264  			}
  3265  
  3266  			// It seems that the PJs are very deterministic, consider sorting
  3267  			// them if this test becomes flaky.
  3268  			if diff := cmp.Diff(tc.wantPjs, gotProwjobs, cmpopts.SortSlices(func(a, b *prowapi.ProwJob) bool {
  3269  				if b == nil {
  3270  					return true
  3271  				}
  3272  				if a == nil {
  3273  					return false
  3274  				}
  3275  				return a.Labels["prow.k8s.io/job"] < b.Labels["prow.k8s.io/job"]
  3276  			})); diff != "" {
  3277  				t.Fatalf("%q Prowjobs mismatch. Want(-), got(+):\n%s", tc.name, diff)
  3278  			}
  3279  
  3280  			if tc.wantSkipReport {
  3281  				if gc.reviews > 0 {
  3282  					t.Errorf("expected no comments, got: %d", gc.reviews)
  3283  				}
  3284  			}
  3285  		})
  3286  	}
  3287  }
  3288  
  3289  func TestIsProjectExemptFromHelp(t *testing.T) {
  3290  	var testcases = []struct {
  3291  		name                   string
  3292  		projectsExemptFromHelp map[string]sets.Set[string]
  3293  		instance               string
  3294  		project                string
  3295  		expected               bool
  3296  	}{
  3297  		{
  3298  			name:                   "no project is exempt",
  3299  			projectsExemptFromHelp: map[string]sets.Set[string]{},
  3300  			instance:               "foo",
  3301  			project:                "bar",
  3302  			expected:               false,
  3303  		},
  3304  		{
  3305  			name: "the instance does not match",
  3306  			projectsExemptFromHelp: map[string]sets.Set[string]{
  3307  				"foo": sets.New[string]("bar"),
  3308  			},
  3309  			instance: "fuz",
  3310  			project:  "bar",
  3311  			expected: false,
  3312  		},
  3313  		{
  3314  			name: "the instance matches but the project does not",
  3315  			projectsExemptFromHelp: map[string]sets.Set[string]{
  3316  				"foo": sets.New[string]("baz"),
  3317  			},
  3318  			instance: "fuz",
  3319  			project:  "bar",
  3320  			expected: false,
  3321  		},
  3322  		{
  3323  			name: "the project is exempt",
  3324  			projectsExemptFromHelp: map[string]sets.Set[string]{
  3325  				"foo": sets.New[string]("bar"),
  3326  			},
  3327  			instance: "foo",
  3328  			project:  "bar",
  3329  			expected: true,
  3330  		},
  3331  	}
  3332  
  3333  	for _, tc := range testcases {
  3334  		t.Run(tc.name, func(t *testing.T) {
  3335  			got := isProjectOptOutHelp(tc.projectsExemptFromHelp, tc.instance, tc.project)
  3336  			if got != tc.expected {
  3337  				t.Errorf("expected %t for IsProjectExemptFromHelp but got %t", tc.expected, got)
  3338  			}
  3339  		})
  3340  	}
  3341  }
  3342  
  3343  func TestDeckLinkForPR(t *testing.T) {
  3344  	tcs := []struct {
  3345  		name         string
  3346  		deckURL      string
  3347  		refs         prowapi.Refs
  3348  		changeStatus string
  3349  		expected     string
  3350  	}{
  3351  		{
  3352  			name:         "No deck_url specified",
  3353  			changeStatus: client.New,
  3354  			expected:     "",
  3355  		},
  3356  		{
  3357  			name:    "deck_url specified, repo without slash",
  3358  			deckURL: "https://prow.k8s.io/",
  3359  			refs: prowapi.Refs{
  3360  				Org:  "gerrit-review.host.com",
  3361  				Repo: "test-infra",
  3362  				Pulls: []prowapi.Pull{
  3363  					{
  3364  						Number: 42,
  3365  					},
  3366  				},
  3367  			},
  3368  			changeStatus: client.New,
  3369  			expected:     "https://prow.k8s.io/?pull=42&repo=gerrit-review.host.com%2Ftest-infra",
  3370  		},
  3371  		{
  3372  			name:    "deck_url specified, repo with slash",
  3373  			deckURL: "https://prow.k8s.io/",
  3374  			refs: prowapi.Refs{
  3375  				Org:  "gerrit-review.host.com",
  3376  				Repo: "test/infra",
  3377  				Pulls: []prowapi.Pull{
  3378  					{
  3379  						Number: 42,
  3380  					},
  3381  				},
  3382  			},
  3383  			changeStatus: client.New,
  3384  			expected:     "https://prow.k8s.io/?pull=42&repo=gerrit-review.host.com%2Ftest%2Finfra",
  3385  		},
  3386  		{
  3387  			name:    "deck_url specified, change is merged (triggering postsubmits)",
  3388  			deckURL: "https://prow.k8s.io/",
  3389  			refs: prowapi.Refs{
  3390  				Org:  "gerrit-review.host.com",
  3391  				Repo: "test-infra",
  3392  				Pulls: []prowapi.Pull{
  3393  					{
  3394  						Number: 42,
  3395  					},
  3396  				},
  3397  			},
  3398  			changeStatus: client.Merged,
  3399  			expected:     "",
  3400  		},
  3401  	}
  3402  
  3403  	for i := range tcs {
  3404  		tc := tcs[i]
  3405  		t.Run(tc.name, func(t *testing.T) {
  3406  			result, err := deckLinkForPR(tc.deckURL, tc.refs, tc.changeStatus)
  3407  			if err != nil {
  3408  				t.Errorf("unexpected error generating Deck link: %v", err)
  3409  			}
  3410  			if result != tc.expected {
  3411  				t.Errorf("expected deck link %s, but got %s", tc.expected, result)
  3412  			}
  3413  		})
  3414  	}
  3415  }