@@ -68,6 +68,15 @@ pipeline {
68
68
TEST_ETCD_TMPFS = " ${ WORKSPACE} /_work/${ env.CLUSTER} /data/pmem-csi-${ env.CLUSTER} -master/etcd-tmpfs"
69
69
TEST_ETCD_VOLUME = " ${ env.TEST_ETCD_TMPFS} /etcd-volume"
70
70
TEST_ETCD_VOLUME_SIZE = " 1073741824" // 1GB
71
+
72
+ // Tests that will get skipped when collecting coverage information.
73
+ //
74
+ // The operator itself installs without enabling coverage collection,
75
+ // so running those tests doesn't help us. The relevant test is
76
+ // "operator API".
77
+ //
78
+ // Testing with OLM doesn't add much additional coverage.
79
+ COVERAGE_SKIP = " [email protected] @Top.Level..olm"
71
80
}
72
81
73
82
stages {
@@ -183,7 +192,21 @@ pipeline {
183
192
stage(' 1.22' ) {
184
193
steps {
185
194
// Skip production, i.e. run testing.
186
- TestInVM (" " , " fedora" , " " , " 1.22" , " Top.Level..[[:alpha:]]*-production[[:space:]]" )
195
+ TestInVM (" " , " " , " fedora" , " " , " 1.22" , " Top.Level..[[:alpha:]]*-production[[:space:]]" , " " )
196
+ }
197
+ }
198
+
199
+ // When adding or removing coverage workers, update the "Code Coverage" step below!
200
+ stage(' coverage-1.22' ) {
201
+ when {
202
+ beforeAgent true
203
+ not { changeRequest() }
204
+ }
205
+ agent {
206
+ label " pmem-csi"
207
+ }
208
+ steps {
209
+ TestInVM (" fedora-coverage-1.22" , " coverage-" , " fedora" , " " , " 1.22" , " " , " ${ env.COVERAGE_SKIP} " )
187
210
}
188
211
}
189
212
@@ -197,7 +220,7 @@ pipeline {
197
220
label " pmem-csi"
198
221
}
199
222
steps {
200
- TestInVM (" fedora-1.21" , " fedora" , " " , " 1.21" , " " )
223
+ TestInVM (" fedora-1.21" , " " , " fedora" , " " , " 1.21" , " " , " " )
201
224
}
202
225
}
203
226
stage(' 1.20' ) {
@@ -209,7 +232,7 @@ pipeline {
209
232
label " pmem-csi"
210
233
}
211
234
steps {
212
- TestInVM (" fedora-1.20" , " fedora" , " " , " 1.20" , " " )
235
+ TestInVM (" fedora-1.20" , " " , " fedora" , " " , " 1.20" , " " , " " )
213
236
}
214
237
}
215
238
stage(' 1.19' ) {
@@ -218,7 +241,19 @@ pipeline {
218
241
}
219
242
steps {
220
243
// Skip testing, i.e. run production.
221
- TestInVM (" fedora-1.19" , " fedora" , " " , " 1.19" , " Top.Level..[[:alpha:]]*-testing[[:space:]]" )
244
+ TestInVM (" fedora-1.19" , " " , " fedora" , " " , " 1.19" , " Top.Level..[[:alpha:]]*-testing[[:space:]]" , " " )
245
+ }
246
+ }
247
+ stage(' coverage-1.19' ) {
248
+ when {
249
+ beforeAgent true
250
+ not { changeRequest() }
251
+ }
252
+ agent {
253
+ label " pmem-csi"
254
+ }
255
+ steps {
256
+ TestInVM (" fedora-coverage-1.19" , " coverage-" , " fedora" , " " , " 1.19" , " " , " ${ env.COVERAGE_SKIP} " )
222
257
}
223
258
}
224
259
}
@@ -291,6 +326,43 @@ git push origin HEAD:master
291
326
sh " ${ RunInBuilder()} ${ env.BUILD_CONTAINER} docker image push ${ env.BUILD_IMAGE} "
292
327
}
293
328
}
329
+
330
+ // Merge and publish coverage data.
331
+ stage(' Code Coverage' ) {
332
+ when {
333
+ not { changeRequest() }
334
+ }
335
+ steps {
336
+ // Restore <cluster>-coverage.out files.
337
+ unstash ' 1.22-coverage'
338
+ unstash ' 1.19-coverage'
339
+
340
+ // Merge and convert to Cobertura XML.
341
+ sh " ${ RunInBuilder()} ${ env.BUILD_CONTAINER} make _work/gocovmerge _work/gocover-cobertura"
342
+ sh " ${ RunInBuilder()} ${ env.BUILD_CONTAINER} _work/gocovmerge *-coverage.out >coverage.out"
343
+ sh " ${ RunInBuilder()} ${ env.BUILD_CONTAINER} go tool cover -func coverage.out"
344
+ sh " ${ RunInBuilder()} ${ env.BUILD_CONTAINER} _work/gocover-cobertura <coverage.out >coverage.xml"
345
+
346
+ // Simplify relative paths ("github.com/intel/pmem-csi/...").
347
+ // To view source code (https://stackoverflow.com/a/59951809):
348
+ // - Jenkins users must be logged in.
349
+ // - A job must complete successfully.
350
+ sh " sed -i -e 's;filename=\" github.com/intel/pmem-csi/;filename=\" ;g' coverage.xml"
351
+
352
+ // The relationship between "Code Coverage API Plugin" and "Cobertura" plugin is not clear
353
+ // (https://stackoverflow.com/questions/71133394/what-is-the-relationship-between-the-jenkins-cobertura-and-code-coverage-api).
354
+ //
355
+ // With just "Code Coverage API Plugin" installed, this here works, but doesn't show source code
356
+ // (old UI?):
357
+ // publishCoverage adapters: [cobertura(path: 'coverage.xml')], tag: 't'
358
+
359
+ // When both are installed, this here works (note the different coberura parameter!)
360
+ // and shows source code.
361
+ publishCoverage adapters : [cobertura(coberturaReportFile : ' coverage.xml' )]
362
+
363
+ // There is also a "coberturaAdapter". That one hasn't been tested.
364
+ }
365
+ }
294
366
}
295
367
}
296
368
@@ -313,6 +385,7 @@ git push origin HEAD:master
313
385
String RunInBuilder () {
314
386
" \
315
387
docker exec \
388
+ -i \
316
389
-e CACHEBUST=${ env.CACHEBUST} \
317
390
-e 'BUILD_ARGS=--cache-from ${ env.BUILD_IMAGE} --cache-from ${ env.PMEM_CSI_IMAGE} ' \
318
391
-e DOCKER_CONFIG=${ WORKSPACE} /_work/docker-config \
@@ -436,10 +509,13 @@ void RestoreEnv() {
436
509
done"
437
510
}
438
511
439
- void TestInVM (worker , distro , distroVersion , kubernetesVersion , skipIfPR ) {
512
+ void TestInVM (worker , coverage , distro , distroVersion , kubernetesVersion , skipIfPR , skipAlways ) {
440
513
if (worker) {
441
514
RestoreEnv ()
442
515
}
516
+ if (coverage) {
517
+ sh " ${ RunInBuilder()} -e CLUSTER=${ env.CLUSTER} ${ env.BUILD_CONTAINER} make kustomize KUSTOMIZE_WITH_COVERAGE=true"
518
+ }
443
519
try { timeout(unit : " HOURS" , time : TestTimeoutHours ()) {
444
520
/*
445
521
We have to run "make start" in the current directory
@@ -463,7 +539,7 @@ void TestInVM(worker, distro, distroVersion, kubernetesVersion, skipIfPR) {
463
539
so for now we disable VMX with -vmx.
464
540
*/
465
541
sh " #!/bin/bash\n \
466
- echo Note: job output is filtered, see joblog-${ BUILD_TAG} -test-${ kubernetesVersion} .log artifact for full output. && \
542
+ echo Note: job output is filtered, see joblog-${ BUILD_TAG} -test-${ coverage }${ kubernetesVersion} .log artifact for full output. && \
467
543
set -o pipefail && \
468
544
( \
469
545
loggers=; \
@@ -508,10 +584,10 @@ void TestInVM(worker, distro, distroVersion, kubernetesVersion, skipIfPR) {
508
584
done | sed -e \" s/^/\$ hostname: /\" ) & \
509
585
loggers=\"\$ loggers \$ !\" ; \
510
586
done && \
511
- testrun=\$ (echo '${ distro} -${ distroVersion} -${ kubernetesVersion} ' | sed -e s/--*/-/g | tr . _ ) && \
587
+ testrun=\$ (echo '${ distro} -${ distroVersion} -${ coverage }${ kubernetesVersion} ' | sed -e s/--*/-/g | tr . _ ) && \
512
588
make test_e2e TEST_E2E_REPORT_DIR=${ WORKSPACE} /build/reports.tmp/\$ testrun \
513
- TEST_E2E_SKIP=\$ (if [ \" ${ env.CHANGE_ID} \" ] && [ \" ${ env.CHANGE_ID} \" != null ]; then echo \\\\ [Slow\\\\ ]@${ skipIfPR} ; fi) \
514
- ') 2>&1 | tee joblog-${ BUILD_TAG} -test-${ kubernetesVersion} .log | grep --line-buffered -E -e 'checking for test|Passed|FAIL:|^ERROR' \
589
+ TEST_E2E_SKIP=${ skipAlways } @ \$ (if [ \" ${ env.CHANGE_ID} \" ] && [ \" ${ env.CHANGE_ID} \" != null ]; then echo \\\\ [Slow\\\\ ]@${ skipIfPR} ; fi) \
590
+ ') 2>&1 | tee joblog-${ BUILD_TAG} -test-${ coverage }${ kubernetesVersion} .log | grep --line-buffered -E -e 'checking for test|Passed|FAIL:|^ERROR' \
515
591
"
516
592
} } finally {
517
593
echo " Writing cluster state and kubelet logs into files."
@@ -545,6 +621,20 @@ void TestInVM(worker, distro, distroVersion, kubernetesVersion, skipIfPR) {
545
621
done'''
546
622
archiveArtifacts(' **/joblog-*' )
547
623
junit ' build/reports/**/*.xml'
624
+
625
+ if (coverage) {
626
+ // https://stackoverflow.com/questions/36918370/cobertura-code-coverage-report-for-jenkins-pipeline-jobs
627
+ // https://www.jenkins.io/doc/pipeline/steps/cobertura/
628
+ sh " ${ RunInBuilder()} -e CLUSTER=${ env.CLUSTER} ${ env.BUILD_CONTAINER} make _work/coverage/coverage.txt"
629
+ sh " cat _work/coverage/coverage.txt"
630
+
631
+ // https://plugins.jenkins.io/code-coverage-api/#plugin-content-reports-combining-support
632
+ // claims that different reports can be merged, but that didn't work in practice
633
+ // (two "coverage reports" listed in the job UI with the same URL and unmerged data from
634
+ // one worker). Therefore we stash the individual results and merge later.
635
+ sh " mv _work/coverage/coverage.out ${ kubernetesVersion} -coverage.out"
636
+ stash includes : " ${ kubernetesVersion} -coverage.out" , name : " ${ kubernetesVersion} -coverage"
637
+ }
548
638
}
549
639
}
550
640
0 commit comments