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 }