github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/gerrit/reporter/reporter_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 reporter
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"strings"
    23  	"testing"
    24  
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/labels"
    27  	"k8s.io/test-infra/prow/apis/prowjobs/v1"
    28  	pjlister "k8s.io/test-infra/prow/client/listers/prowjobs/v1"
    29  	"k8s.io/test-infra/prow/gerrit/client"
    30  	"k8s.io/test-infra/prow/kube"
    31  )
    32  
    33  type fgc struct {
    34  	reportMessage string
    35  	reportLabel   map[string]string
    36  	instance      string
    37  }
    38  
    39  func (f *fgc) SetReview(instance, id, revision, message string, labels map[string]string) error {
    40  	if instance != f.instance {
    41  		return fmt.Errorf("wrong instance: %s", instance)
    42  	}
    43  	f.reportMessage = message
    44  	f.reportLabel = labels
    45  	return nil
    46  }
    47  
    48  type fakeLister struct {
    49  	pjs []*v1.ProwJob
    50  }
    51  
    52  func (fl fakeLister) List(selector labels.Selector) (ret []*v1.ProwJob, err error) {
    53  	result := []*v1.ProwJob{}
    54  	for _, pj := range fl.pjs {
    55  		if selector.Matches(labels.Set(pj.ObjectMeta.Labels)) {
    56  			result = append(result, pj)
    57  		}
    58  	}
    59  
    60  	return result, nil
    61  }
    62  
    63  func (fl fakeLister) ProwJobs(namespace string) pjlister.ProwJobNamespaceLister {
    64  	return nil
    65  }
    66  
    67  func TestReport(t *testing.T) {
    68  
    69  	var testcases = []struct {
    70  		name          string
    71  		pj            *v1.ProwJob
    72  		existingPJs   []*v1.ProwJob
    73  		expectReport  bool
    74  		reportInclude []string
    75  		reportExclude []string
    76  		expectLabel   map[string]string
    77  	}{
    78  		{
    79  			name: "1 job, unfinished, should not report",
    80  			pj: &v1.ProwJob{
    81  				Status: v1.ProwJobStatus{
    82  					State: v1.PendingState,
    83  				},
    84  			},
    85  		},
    86  		{
    87  			name: "1 job, finished, no labels, should not report",
    88  			pj: &v1.ProwJob{
    89  				Status: v1.ProwJobStatus{
    90  					State: v1.SuccessState,
    91  				},
    92  			},
    93  		},
    94  		{
    95  			name: "1 job, finished, missing gerrit-id label, should not report",
    96  			pj: &v1.ProwJob{
    97  				ObjectMeta: metav1.ObjectMeta{
    98  					Labels: map[string]string{
    99  						client.GerritRevision: "abc",
   100  						kube.ProwJobTypeLabel: "presubmit",
   101  					},
   102  					Annotations: map[string]string{
   103  						client.GerritInstance: "gerrit",
   104  					},
   105  				},
   106  				Status: v1.ProwJobStatus{
   107  					State: v1.SuccessState,
   108  				},
   109  			},
   110  		},
   111  		{
   112  			name: "1 job, finished, missing gerrit-revision label, should not report",
   113  			pj: &v1.ProwJob{
   114  				ObjectMeta: metav1.ObjectMeta{
   115  					Annotations: map[string]string{
   116  						client.GerritID:       "123-abc",
   117  						client.GerritInstance: "gerrit",
   118  					},
   119  				},
   120  				Status: v1.ProwJobStatus{
   121  					State: v1.SuccessState,
   122  				},
   123  			},
   124  		},
   125  		{
   126  			name: "1 job, finished, missing gerrit-instance label, should not report",
   127  			pj: &v1.ProwJob{
   128  				ObjectMeta: metav1.ObjectMeta{
   129  					Labels: map[string]string{
   130  						client.GerritRevision: "abc",
   131  						kube.ProwJobTypeLabel: "presubmit",
   132  					},
   133  					Annotations: map[string]string{
   134  						client.GerritID: "123-abc",
   135  					},
   136  				},
   137  				Status: v1.ProwJobStatus{
   138  					State: v1.SuccessState,
   139  				},
   140  			},
   141  		},
   142  		{
   143  			name: "1 job, passed, should report",
   144  			pj: &v1.ProwJob{
   145  				ObjectMeta: metav1.ObjectMeta{
   146  					Labels: map[string]string{
   147  						client.GerritRevision: "abc",
   148  						kube.ProwJobTypeLabel: "presubmit",
   149  					},
   150  					Annotations: map[string]string{
   151  						client.GerritID:       "123-abc",
   152  						client.GerritInstance: "gerrit",
   153  					},
   154  				},
   155  				Status: v1.ProwJobStatus{
   156  					State: v1.SuccessState,
   157  					URL:   "guber/foo",
   158  				},
   159  				Spec: v1.ProwJobSpec{
   160  					Refs: &v1.Refs{
   161  						Repo: "foo",
   162  					},
   163  					Job: "ci-foo",
   164  				},
   165  			},
   166  			expectReport:  true,
   167  			reportInclude: []string{"1 out of 1", "ci-foo", "success", "guber/foo"},
   168  			expectLabel:   map[string]string{client.CodeReview: client.LGTM},
   169  		},
   170  		{
   171  			name: "1 job, passed, with customized label, should report to customized label",
   172  			pj: &v1.ProwJob{
   173  				ObjectMeta: metav1.ObjectMeta{
   174  					Labels: map[string]string{
   175  						client.GerritRevision:    "abc",
   176  						client.GerritReportLabel: "foobar-label",
   177  						kube.ProwJobTypeLabel:    "presubmit",
   178  					},
   179  					Annotations: map[string]string{
   180  						client.GerritID:       "123-abc",
   181  						client.GerritInstance: "gerrit",
   182  					},
   183  				},
   184  				Status: v1.ProwJobStatus{
   185  					State: v1.SuccessState,
   186  					URL:   "guber/foo",
   187  				},
   188  				Spec: v1.ProwJobSpec{
   189  					Refs: &v1.Refs{
   190  						Repo: "foo",
   191  					},
   192  					Job: "ci-foo",
   193  				},
   194  			},
   195  			expectReport:  true,
   196  			reportInclude: []string{"1 out of 1", "ci-foo", "success", "guber/foo"},
   197  			expectLabel:   map[string]string{"foobar-label": client.LGTM},
   198  		},
   199  		{
   200  			name: "1 job, failed, should report",
   201  			pj: &v1.ProwJob{
   202  				ObjectMeta: metav1.ObjectMeta{
   203  					Labels: map[string]string{
   204  						client.GerritRevision: "abc",
   205  						kube.ProwJobTypeLabel: "presubmit",
   206  					},
   207  					Annotations: map[string]string{
   208  						client.GerritID:       "123-abc",
   209  						client.GerritInstance: "gerrit",
   210  					},
   211  				},
   212  				Status: v1.ProwJobStatus{
   213  					State: v1.FailureState,
   214  					URL:   "guber/foo",
   215  				},
   216  				Spec: v1.ProwJobSpec{
   217  					Refs: &v1.Refs{
   218  						Repo: "foo",
   219  					},
   220  					Job: "ci-foo",
   221  				},
   222  			},
   223  			expectReport:  true,
   224  			reportInclude: []string{"0 out of 1", "ci-foo", "failure", "guber/foo"},
   225  			expectLabel:   map[string]string{client.CodeReview: client.LBTM},
   226  		},
   227  		{
   228  			name: "1 job, passed, has slash in repo name, should report and handle slash properly",
   229  			pj: &v1.ProwJob{
   230  				ObjectMeta: metav1.ObjectMeta{
   231  					Labels: map[string]string{
   232  						client.GerritRevision: "abc",
   233  						kube.ProwJobTypeLabel: "presubmit",
   234  					},
   235  					Annotations: map[string]string{
   236  						client.GerritID:       "123-abc",
   237  						client.GerritInstance: "gerrit",
   238  					},
   239  				},
   240  				Status: v1.ProwJobStatus{
   241  					State: v1.SuccessState,
   242  					URL:   "guber/foo/bar",
   243  				},
   244  				Spec: v1.ProwJobSpec{
   245  					Refs: &v1.Refs{
   246  						Repo: "foo/bar",
   247  					},
   248  					Job: "ci-foo-bar",
   249  				},
   250  			},
   251  			expectReport:  true,
   252  			reportInclude: []string{"1 out of 1", "ci-foo-bar", "success", "guber/foo/bar"},
   253  			reportExclude: []string{"foo_bar"},
   254  			expectLabel:   map[string]string{client.CodeReview: client.LGTM},
   255  		},
   256  		{
   257  			name: "2 jobs, one passed, other job finished but on different revision, should report",
   258  			pj: &v1.ProwJob{
   259  				ObjectMeta: metav1.ObjectMeta{
   260  					Labels: map[string]string{
   261  						client.GerritRevision: "abc",
   262  						kube.ProwJobTypeLabel: "presubmit",
   263  					},
   264  					Annotations: map[string]string{
   265  						client.GerritID:       "123-abc",
   266  						client.GerritInstance: "gerrit",
   267  					},
   268  				},
   269  				Status: v1.ProwJobStatus{
   270  					State: v1.SuccessState,
   271  					URL:   "guber/foo",
   272  				},
   273  				Spec: v1.ProwJobSpec{
   274  					Refs: &v1.Refs{
   275  						Repo: "foo",
   276  					},
   277  					Job: "ci-foo",
   278  				},
   279  			},
   280  			existingPJs: []*v1.ProwJob{
   281  				{
   282  					ObjectMeta: metav1.ObjectMeta{
   283  						Labels: map[string]string{
   284  							client.GerritRevision: "def",
   285  							kube.ProwJobTypeLabel: "presubmit",
   286  						},
   287  						Annotations: map[string]string{
   288  							client.GerritID:       "123-def",
   289  							client.GerritInstance: "gerrit",
   290  						},
   291  					},
   292  					Status: v1.ProwJobStatus{
   293  						State: v1.SuccessState,
   294  						URL:   "guber/bar",
   295  					},
   296  					Spec: v1.ProwJobSpec{
   297  						Refs: &v1.Refs{
   298  							Repo: "bar",
   299  						},
   300  						Job: "ci-bar",
   301  					},
   302  				},
   303  			},
   304  			expectReport:  true,
   305  			reportInclude: []string{"1 out of 1", "ci-foo", "success", "guber/foo"},
   306  			reportExclude: []string{"2", "bar"},
   307  			expectLabel:   map[string]string{client.CodeReview: client.LGTM},
   308  		},
   309  		{
   310  			name: "2 jobs, one passed, other job unfinished, should not report",
   311  			pj: &v1.ProwJob{
   312  				ObjectMeta: metav1.ObjectMeta{
   313  					Labels: map[string]string{
   314  						client.GerritRevision: "abc",
   315  						kube.ProwJobTypeLabel: "presubmit",
   316  					},
   317  					Annotations: map[string]string{
   318  						client.GerritID:       "123-abc",
   319  						client.GerritInstance: "gerrit",
   320  					},
   321  				},
   322  				Status: v1.ProwJobStatus{
   323  					State: v1.SuccessState,
   324  					URL:   "guber/foo",
   325  				},
   326  				Spec: v1.ProwJobSpec{
   327  					Refs: &v1.Refs{
   328  						Repo: "foo",
   329  					},
   330  					Job: "ci-foo",
   331  				},
   332  			},
   333  			existingPJs: []*v1.ProwJob{
   334  				{
   335  					ObjectMeta: metav1.ObjectMeta{
   336  						Labels: map[string]string{
   337  							client.GerritRevision: "abc",
   338  							kube.ProwJobTypeLabel: "presubmit",
   339  						},
   340  						Annotations: map[string]string{
   341  							client.GerritID:       "123-abc",
   342  							client.GerritInstance: "gerrit",
   343  						},
   344  					},
   345  					Status: v1.ProwJobStatus{
   346  						State: v1.PendingState,
   347  						URL:   "guber/bar",
   348  					},
   349  					Spec: v1.ProwJobSpec{
   350  						Refs: &v1.Refs{
   351  							Repo: "bar",
   352  						},
   353  						Job: "ci-bar",
   354  					},
   355  				},
   356  			},
   357  		},
   358  		{
   359  			name: "2 jobs, one passed, other job failed, should report",
   360  			pj: &v1.ProwJob{
   361  				ObjectMeta: metav1.ObjectMeta{
   362  					Labels: map[string]string{
   363  						client.GerritRevision: "abc",
   364  						kube.ProwJobTypeLabel: "presubmit",
   365  					},
   366  					Annotations: map[string]string{
   367  						client.GerritID:       "123-abc",
   368  						client.GerritInstance: "gerrit",
   369  					},
   370  				},
   371  				Status: v1.ProwJobStatus{
   372  					State: v1.SuccessState,
   373  					URL:   "guber/foo",
   374  				},
   375  				Spec: v1.ProwJobSpec{
   376  					Refs: &v1.Refs{
   377  						Repo: "foo",
   378  					},
   379  					Job: "ci-foo",
   380  				},
   381  			},
   382  			existingPJs: []*v1.ProwJob{
   383  				{
   384  					ObjectMeta: metav1.ObjectMeta{
   385  						Labels: map[string]string{
   386  							client.GerritRevision: "abc",
   387  							kube.ProwJobTypeLabel: "presubmit",
   388  						},
   389  						Annotations: map[string]string{
   390  							client.GerritID:       "123-abc",
   391  							client.GerritInstance: "gerrit",
   392  						},
   393  					},
   394  					Status: v1.ProwJobStatus{
   395  						State: v1.FailureState,
   396  						URL:   "guber/bar",
   397  					},
   398  					Spec: v1.ProwJobSpec{
   399  						Refs: &v1.Refs{
   400  							Repo: "bar",
   401  						},
   402  						Job: "ci-bar",
   403  					},
   404  				},
   405  			},
   406  			expectReport:  true,
   407  			reportInclude: []string{"1 out of 2", "ci-foo", "success", "ci-bar", "failure", "guber/foo", "guber/bar"},
   408  			reportExclude: []string{"0", "2 out of 2"},
   409  			expectLabel:   map[string]string{client.CodeReview: client.LBTM},
   410  		},
   411  		{
   412  			name: "2 jobs, both passed, should report",
   413  			pj: &v1.ProwJob{
   414  				ObjectMeta: metav1.ObjectMeta{
   415  					Labels: map[string]string{
   416  						client.GerritRevision: "abc",
   417  						kube.ProwJobTypeLabel: "presubmit",
   418  					},
   419  					Annotations: map[string]string{
   420  						client.GerritID:       "123-abc",
   421  						client.GerritInstance: "gerrit",
   422  					},
   423  				},
   424  				Status: v1.ProwJobStatus{
   425  					State: v1.SuccessState,
   426  					URL:   "guber/foo",
   427  				},
   428  				Spec: v1.ProwJobSpec{
   429  					Refs: &v1.Refs{
   430  						Repo: "foo",
   431  					},
   432  					Job: "ci-foo",
   433  				},
   434  			},
   435  			existingPJs: []*v1.ProwJob{
   436  				{
   437  					ObjectMeta: metav1.ObjectMeta{
   438  						Labels: map[string]string{
   439  							client.GerritRevision: "abc",
   440  							kube.ProwJobTypeLabel: "presubmit",
   441  						},
   442  						Annotations: map[string]string{
   443  							client.GerritID:       "123-abc",
   444  							client.GerritInstance: "gerrit",
   445  						},
   446  					},
   447  					Status: v1.ProwJobStatus{
   448  						State: v1.SuccessState,
   449  						URL:   "guber/bar",
   450  					},
   451  					Spec: v1.ProwJobSpec{
   452  						Refs: &v1.Refs{
   453  							Repo: "bar",
   454  						},
   455  						Job: "ci-bar",
   456  					},
   457  				},
   458  			},
   459  			expectReport:  true,
   460  			reportInclude: []string{"2 out of 2", "ci-foo", "success", "ci-bar", "guber/foo", "guber/bar"},
   461  			reportExclude: []string{"1", "0", "failure"},
   462  			expectLabel:   map[string]string{client.CodeReview: client.LGTM},
   463  		},
   464  		{
   465  			name: "postsubmit after presubmit on same revision, should report separately",
   466  			pj: &v1.ProwJob{
   467  				ObjectMeta: metav1.ObjectMeta{
   468  					Labels: map[string]string{
   469  						client.GerritRevision:    "abc",
   470  						client.GerritReportLabel: "postsubmit-label",
   471  						kube.ProwJobTypeLabel:    "postsubmit",
   472  					},
   473  					Annotations: map[string]string{
   474  						client.GerritID:       "123-abc",
   475  						client.GerritInstance: "gerrit",
   476  					},
   477  				},
   478  				Status: v1.ProwJobStatus{
   479  					State: v1.SuccessState,
   480  					URL:   "guber/foo",
   481  				},
   482  				Spec: v1.ProwJobSpec{
   483  					Refs: &v1.Refs{
   484  						Repo: "foo",
   485  					},
   486  					Job: "ci-foo",
   487  				},
   488  			},
   489  			existingPJs: []*v1.ProwJob{
   490  				{
   491  					ObjectMeta: metav1.ObjectMeta{
   492  						Labels: map[string]string{
   493  							client.GerritRevision: "abc",
   494  							kube.ProwJobTypeLabel: "presubmit",
   495  						},
   496  						Annotations: map[string]string{
   497  							client.GerritID:       "123-abc",
   498  							client.GerritInstance: "gerrit",
   499  						},
   500  					},
   501  					Status: v1.ProwJobStatus{
   502  						State: v1.SuccessState,
   503  						URL:   "guber/bar",
   504  					},
   505  					Spec: v1.ProwJobSpec{
   506  						Refs: &v1.Refs{
   507  							Repo: "bar",
   508  						},
   509  						Job: "ci-bar",
   510  					},
   511  				},
   512  			},
   513  			expectReport:  true,
   514  			reportInclude: []string{"1 out of 1", "ci-foo", "success", "guber/foo"},
   515  			expectLabel:   map[string]string{"postsubmit-label": client.LGTM},
   516  		},
   517  	}
   518  
   519  	for _, tc := range testcases {
   520  		fgc := &fgc{instance: "gerrit"}
   521  		allpj := []*v1.ProwJob{tc.pj}
   522  		if tc.existingPJs != nil {
   523  			allpj = append(allpj, tc.existingPJs...)
   524  		}
   525  
   526  		fl := &fakeLister{pjs: allpj}
   527  		reporter := &Client{gc: fgc, lister: fl}
   528  
   529  		shouldReport := reporter.ShouldReport(tc.pj)
   530  		if shouldReport != tc.expectReport {
   531  			t.Errorf("test: %s: shouldReport: %v, expectReport: %v", tc.name, shouldReport, tc.expectReport)
   532  		}
   533  
   534  		if !shouldReport {
   535  			continue
   536  		}
   537  
   538  		err := reporter.Report(tc.pj)
   539  		if err != nil {
   540  			t.Errorf("test: %s: expect no error but got error %v", tc.name, err)
   541  		}
   542  
   543  		if err == nil {
   544  			for _, include := range tc.reportInclude {
   545  				if !strings.Contains(fgc.reportMessage, include) {
   546  					t.Errorf("test: %s: reported with: %s, should contain: %s", tc.name, fgc.reportMessage, include)
   547  				}
   548  			}
   549  			for _, exclude := range tc.reportExclude {
   550  				if strings.Contains(fgc.reportMessage, exclude) {
   551  					t.Errorf("test: %s: reported with: %s, should not contain: %s", tc.name, fgc.reportMessage, exclude)
   552  				}
   553  			}
   554  
   555  			if !reflect.DeepEqual(tc.expectLabel, fgc.reportLabel) {
   556  				t.Errorf("test: %s: reported with %s label, should have %s label", tc.name, fgc.reportLabel, tc.expectLabel)
   557  			}
   558  		}
   559  	}
   560  }