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 }