github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/gerrit/gerrit_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 gerrit
    18  
    19  import (
    20  	"reflect"
    21  	"sort"
    22  	"strings"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/andygrunwald/go-gerrit"
    28  
    29  	"k8s.io/test-infra/prow/config"
    30  	"k8s.io/test-infra/prow/kube"
    31  )
    32  
    33  type fca struct {
    34  	sync.Mutex
    35  	c *config.Config
    36  }
    37  
    38  func (f *fca) Config() *config.Config {
    39  	f.Lock()
    40  	defer f.Unlock()
    41  	return f.c
    42  }
    43  
    44  type fkc struct {
    45  	sync.Mutex
    46  	prowjobs []kube.ProwJob
    47  }
    48  
    49  func (f *fkc) CreateProwJob(pj kube.ProwJob) (kube.ProwJob, error) {
    50  	f.Lock()
    51  	defer f.Unlock()
    52  	f.prowjobs = append(f.prowjobs, pj)
    53  	return pj, nil
    54  }
    55  
    56  type fgc struct {
    57  	changes  map[string][]gerrit.ChangeInfo
    58  	instance string
    59  }
    60  
    61  func (f *fgc) QueryChanges(opt *gerrit.QueryChangeOptions) (*[]gerrit.ChangeInfo, *gerrit.Response, error) {
    62  	changes := []gerrit.ChangeInfo{}
    63  
    64  	project := ""
    65  	for _, query := range opt.Query {
    66  		for _, q := range strings.Split(query, "+") {
    67  			if strings.HasPrefix(q, "project:") {
    68  				project = q[8:]
    69  			}
    70  		}
    71  	}
    72  
    73  	if changeInfos, ok := f.changes[project]; !ok {
    74  		return &changes, nil, nil
    75  	} else {
    76  		for idx, change := range changeInfos {
    77  			if idx >= opt.Start && len(changes) <= opt.Limit {
    78  				changes = append(changes, change)
    79  			}
    80  		}
    81  	}
    82  
    83  	return &changes, nil, nil
    84  }
    85  
    86  func (f *fgc) SetReview(changeID, revisionID string, input *gerrit.ReviewInput) (*gerrit.ReviewResult, *gerrit.Response, error) {
    87  	return nil, nil, nil
    88  }
    89  
    90  func TestQueryChange(t *testing.T) {
    91  	now := time.Now().UTC()
    92  	layout := "2006-01-02 15:04:05"
    93  
    94  	var testcases = []struct {
    95  		name       string
    96  		limit      int
    97  		lastUpdate time.Time
    98  		changes    map[string][]gerrit.ChangeInfo
    99  		revisions  []string
   100  	}{
   101  		{
   102  			name:       "no changes",
   103  			limit:      2,
   104  			lastUpdate: now,
   105  			revisions:  []string{},
   106  		},
   107  		{
   108  			name:       "one outdated change",
   109  			limit:      2,
   110  			lastUpdate: now,
   111  			changes: map[string][]gerrit.ChangeInfo{
   112  				"foo": {
   113  					{
   114  						ID:              "1",
   115  						CurrentRevision: "1-1",
   116  						Updated:         now.Add(-time.Hour).Format(layout),
   117  						Revisions: map[string]gerrit.RevisionInfo{
   118  							"1-1": {
   119  								Created: now.Add(-time.Hour).Format(layout),
   120  							},
   121  						},
   122  					},
   123  				},
   124  			},
   125  			revisions: []string{},
   126  		},
   127  		{
   128  			name:       "one up-to-date change",
   129  			limit:      2,
   130  			lastUpdate: now.Add(-time.Minute),
   131  			changes: map[string][]gerrit.ChangeInfo{
   132  				"foo": {
   133  					{
   134  						ID:              "1",
   135  						CurrentRevision: "1-1",
   136  						Updated:         now.Format(layout),
   137  						Revisions: map[string]gerrit.RevisionInfo{
   138  							"1-1": {
   139  								Created: now.Format(layout),
   140  							},
   141  						},
   142  					},
   143  				},
   144  			},
   145  			revisions: []string{"1-1"},
   146  		},
   147  		{
   148  			name:       "one up-to-date change but stale commit",
   149  			limit:      2,
   150  			lastUpdate: now.Add(-time.Minute),
   151  			changes: map[string][]gerrit.ChangeInfo{
   152  				"foo": {
   153  					{
   154  						ID:              "1",
   155  						CurrentRevision: "1-1",
   156  						Updated:         now.Format(layout),
   157  						Revisions: map[string]gerrit.RevisionInfo{
   158  							"1-1": {
   159  								Created: now.Add(-time.Hour).Format(layout),
   160  							},
   161  						},
   162  					},
   163  				},
   164  			},
   165  			revisions: []string{},
   166  		},
   167  		{
   168  			name:       "one up-to-date change, wrong project",
   169  			limit:      2,
   170  			lastUpdate: now.Add(-time.Minute),
   171  			changes: map[string][]gerrit.ChangeInfo{
   172  				"evil": {
   173  					{
   174  						ID:              "1",
   175  						CurrentRevision: "1-1",
   176  						Updated:         now.Format(layout),
   177  						Revisions: map[string]gerrit.RevisionInfo{
   178  							"1-1": {
   179  								Created: now.Format(layout),
   180  							},
   181  						},
   182  					},
   183  				},
   184  			},
   185  			revisions: []string{},
   186  		},
   187  		{
   188  			name:       "two up-to-date changes, two projects",
   189  			limit:      2,
   190  			lastUpdate: now.Add(-time.Minute),
   191  			changes: map[string][]gerrit.ChangeInfo{
   192  				"foo": {
   193  					{
   194  						ID:              "1",
   195  						CurrentRevision: "1-1",
   196  						Updated:         now.Format(layout),
   197  						Revisions: map[string]gerrit.RevisionInfo{
   198  							"1-1": {
   199  								Created: now.Format(layout),
   200  							},
   201  						},
   202  					},
   203  				},
   204  				"bar": {
   205  					{
   206  						ID:              "2",
   207  						CurrentRevision: "2-1",
   208  						Updated:         now.Format(layout),
   209  						Revisions: map[string]gerrit.RevisionInfo{
   210  							"2-1": {
   211  								Created: now.Format(layout),
   212  							},
   213  						},
   214  					},
   215  				},
   216  			},
   217  			revisions: []string{"1-1", "2-1"},
   218  		},
   219  		{
   220  			name:       "one good one bad",
   221  			limit:      2,
   222  			lastUpdate: now.Add(-time.Minute),
   223  			changes: map[string][]gerrit.ChangeInfo{
   224  				"foo": {
   225  					{
   226  						ID:              "1",
   227  						CurrentRevision: "1-1",
   228  						Updated:         now.Format(layout),
   229  						Revisions: map[string]gerrit.RevisionInfo{
   230  							"1-1": {
   231  								Created: now.Format(layout),
   232  							},
   233  						},
   234  					},
   235  					{
   236  						ID:              "2",
   237  						CurrentRevision: "2-1",
   238  						Updated:         now.Add(-time.Hour).Format(layout),
   239  						Revisions: map[string]gerrit.RevisionInfo{
   240  							"2-1": {
   241  								Created: now.Add(-time.Hour).Format(layout),
   242  							},
   243  						},
   244  					},
   245  				},
   246  			},
   247  			revisions: []string{"1-1"},
   248  		},
   249  		{
   250  			name:       "multiple up-to-date changes",
   251  			limit:      2,
   252  			lastUpdate: now.Add(-time.Minute),
   253  			changes: map[string][]gerrit.ChangeInfo{
   254  				"foo": {
   255  					{
   256  						ID:              "1",
   257  						CurrentRevision: "1-1",
   258  						Updated:         now.Format(layout),
   259  						Revisions: map[string]gerrit.RevisionInfo{
   260  							"1-1": {
   261  								Created: now.Format(layout),
   262  							},
   263  						},
   264  					},
   265  					{
   266  						ID:              "2",
   267  						CurrentRevision: "2-1",
   268  						Updated:         now.Format(layout),
   269  						Revisions: map[string]gerrit.RevisionInfo{
   270  							"2-1": {
   271  								Created: now.Format(layout),
   272  							},
   273  						},
   274  					},
   275  					{
   276  						ID:              "3",
   277  						CurrentRevision: "3-2",
   278  						Updated:         now.Format(layout),
   279  						Revisions: map[string]gerrit.RevisionInfo{
   280  							"3-2": {
   281  								Created: now.Format(layout),
   282  							},
   283  							"3-1": {
   284  								Created: now.Format(layout),
   285  							},
   286  						},
   287  					},
   288  					{
   289  						ID:              "4",
   290  						CurrentRevision: "4-1",
   291  						Updated:         now.Add(-time.Hour).Format(layout),
   292  						Revisions: map[string]gerrit.RevisionInfo{
   293  							"4-1": {
   294  								Created: now.Add(-time.Hour).Format(layout),
   295  							},
   296  						},
   297  					},
   298  				},
   299  			},
   300  			revisions: []string{"1-1", "2-1", "3-2"},
   301  		},
   302  	}
   303  
   304  	for _, tc := range testcases {
   305  		fgc := &fgc{
   306  			changes: tc.changes,
   307  		}
   308  
   309  		fca := &fca{
   310  			c: &config.Config{
   311  				ProwConfig: config.ProwConfig{
   312  					Gerrit: config.Gerrit{
   313  						RateLimit: tc.limit,
   314  					},
   315  				},
   316  			},
   317  		}
   318  
   319  		c := &Controller{
   320  			ca:         fca,
   321  			gc:         fgc,
   322  			projects:   []string{"foo", "bar"},
   323  			lastUpdate: tc.lastUpdate,
   324  		}
   325  
   326  		changes := c.QueryChanges()
   327  
   328  		revisions := []string{}
   329  		for _, change := range changes {
   330  			revisions = append(revisions, change.CurrentRevision)
   331  		}
   332  		sort.Strings(revisions)
   333  
   334  		if !reflect.DeepEqual(revisions, tc.revisions) {
   335  			t.Errorf("tc %s - wrong revisions: got %#v, expect %#v", tc.name, revisions, tc.revisions)
   336  		}
   337  	}
   338  }
   339  
   340  func TestProcessChange(t *testing.T) {
   341  	var testcases = []struct {
   342  		name        string
   343  		change      gerrit.ChangeInfo
   344  		numPJ       int
   345  		pjRef       string
   346  		shouldError bool
   347  	}{
   348  		{
   349  			name: "no revisions",
   350  			change: gerrit.ChangeInfo{
   351  				CurrentRevision: "1",
   352  				Project:         "test-infra",
   353  			},
   354  			shouldError: true,
   355  		},
   356  		{
   357  			name: "wrong project",
   358  			change: gerrit.ChangeInfo{
   359  				CurrentRevision: "1",
   360  				Project:         "woof",
   361  				Revisions: map[string]gerrit.RevisionInfo{
   362  					"1": {},
   363  				},
   364  			},
   365  		},
   366  		{
   367  			name: "normal",
   368  			change: gerrit.ChangeInfo{
   369  				CurrentRevision: "1",
   370  				Project:         "test-infra",
   371  				Revisions: map[string]gerrit.RevisionInfo{
   372  					"1": {
   373  						Ref: "refs/changes/00/1/1",
   374  					},
   375  				},
   376  			},
   377  			numPJ: 1,
   378  			pjRef: "refs/changes/00/1/1",
   379  		},
   380  		{
   381  			name: "multiple revisions",
   382  			change: gerrit.ChangeInfo{
   383  				CurrentRevision: "2",
   384  				Project:         "test-infra",
   385  				Revisions: map[string]gerrit.RevisionInfo{
   386  					"1": {
   387  						Ref: "refs/changes/00/2/1",
   388  					},
   389  					"2": {
   390  						Ref: "refs/changes/00/2/2",
   391  					},
   392  				},
   393  			},
   394  			numPJ: 1,
   395  			pjRef: "refs/changes/00/2/2",
   396  		},
   397  	}
   398  
   399  	for _, tc := range testcases {
   400  		fca := &fca{
   401  			c: &config.Config{
   402  				JobConfig: config.JobConfig{
   403  					Presubmits: map[string][]config.Presubmit{
   404  						"gerrit/test-infra": {
   405  							{
   406  								Name: "test-foo",
   407  							},
   408  						},
   409  					},
   410  				},
   411  			},
   412  		}
   413  
   414  		fkc := &fkc{}
   415  		fgc := &fgc{}
   416  
   417  		c := &Controller{
   418  			ca:       fca,
   419  			kc:       fkc,
   420  			gc:       fgc,
   421  			instance: "gerrit",
   422  		}
   423  
   424  		err := c.ProcessChange(tc.change)
   425  		if err != nil && !tc.shouldError {
   426  			t.Errorf("tc %s, expect no error, but got %v", tc.name, err)
   427  			continue
   428  		} else if err == nil && tc.shouldError {
   429  			t.Errorf("tc %s, expect error, but got none", tc.name)
   430  			continue
   431  		}
   432  
   433  		if len(fkc.prowjobs) != tc.numPJ {
   434  			t.Errorf("tc %s - should make %d prowjob, got %d", tc.name, tc.numPJ, len(fkc.prowjobs))
   435  		}
   436  
   437  		if len(fkc.prowjobs) > 0 {
   438  			if fkc.prowjobs[0].Spec.Refs.Pulls[0].Ref != tc.pjRef {
   439  				t.Errorf("tc %s - ref should be %s, got %s", tc.name, tc.pjRef, fkc.prowjobs[0].Spec.Refs.Pulls[0].Ref)
   440  			}
   441  		}
   442  	}
   443  }