Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
Add test result and coverage reports to :buildSrc
Browse files Browse the repository at this point in the history
* :buildSrc is also included in the aggregate reports.
  • Loading branch information
cwardgar committed Jan 23, 2016
1 parent 88a9f77 commit 4330d75
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
31 changes: 31 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,34 @@ dependencies {
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
}

// Configure Jacoco
// This code duplicates much of coverage.gradle. However, since :buildSrc is a separate build from thredds, it's not
// appropriate to just apply that build script here (it references properties defined in thredds rootProject).
// TODO: Can that script be modified so that it can be applied to both projects?
// TODO: Alternately, can some of that code be moved to classes in :buildSrc? Would we then be able to use those
// classes in this script?

// The jacoco plugin adds the jacocoTestReport task, but only if the java or groovy plugin is already applied.
apply plugin: "jacoco"

jacoco {
toolVersion = '0.7.5.201505241946' // The latest version as of 2015-06-26.
}

jacocoTestReport {
dependsOn tasks.test

reports {
xml.enabled = true
html.enabled = true
csv.enabled = false
}
}

tasks.test {
finalizedBy tasks.jacocoTestReport

// Add the execution data that Jacoco generates as a task output.
outputs.file jacoco.destinationFile
}
26 changes: 15 additions & 11 deletions gradle/coverage.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,26 @@ configure(javaProjects + rootProject) {
}

///////////////////////////////////////////////// Root /////////////////////////////////////////////////

task rootJacocoReport(type: JacocoReport, group: 'Reports') {
description = 'Generates an aggregate coverage report from all subprojects'

// Add source and class directories for the :buildSrc project. Note that by this time in the 'thredds' config,
// :buildSrc has already run as a *separate* build (see http://stackoverflow.com/questions/26597147),
// so we cannot programmatically access its Project object to retrieve these paths.
sourceDirectories = sourceDirectories + files('buildSrc/src/main/groovy')
classDirectories = classDirectories + files('buildSrc/build/classes/main')

// :buildSrc:test always runs and produces execution data, no matter what.
assert file('buildSrc/build/jacoco/test.exec').exists() : "Can't find :buildSrc Jacoco execution data."

// By default, JacocoReport will be skipped if ANY of its executionData are non-existent: http://goo.gl/pHuwyg
// This is a problem: we don't know which data we have until execution time. So, we're temporarily assigning an
// empty collection (leaving it null causes an exception), and assigning the real values later.
executionData = files()
// So, we're going to start off with the only executionData we KNOW exists. As for the subprojects' executionData,
// we won't know what's available until after they run their 'test' tasks (if they run at all). So, delay that
// config until doFirst{}, which will run during Gradle's execution phase.
executionData = files('buildSrc/build/jacoco/test.exec')

// Causes rootJacocoReport to always be executed. This is necessary because JacocoReport uses executionData as one
// of its Inputs, and by assigning an empty collection above, the normal UP-TO-DATE machinery has been subverted.
// of its Inputs, and by assigning an incomplete set above, the normal UP-TO-DATE machinery has been subverted.
// As a result, rootJacocoReport can't properly determine when subprojects have generated new coverage data
// (it thinks its executionData Inputs are always UP-TO-DATE). We'll try to detect those changes manually below.
outputs.upToDateWhen { false } // Evaluated at configuration time (onlyIf{} is evaluated at execution time)
Expand All @@ -52,12 +61,7 @@ task rootJacocoReport(type: JacocoReport, group: 'Reports') {
Collection<File> exeData = tasksExtendedByJacoco*.jacoco*.destinationFile

// Add all subproject executionData that actually exist.
executionData = files(exeData.findAll { it.exists() })

// Skip task if NO executionData exists. This is how JacocoReport ought to work in the first place.
if (executionData.isEmpty()) {
throw new StopExecutionException("SKIPPING $name: no execution data found.")
}
executionData = executionData + files(exeData.findAll { it.exists() })

boolean allOutputsExist = outputs.files.every { it.exists() }
boolean anyJacocoTaskDidWork = tasksExtendedByJacoco.any { it.didWork }
Expand Down
8 changes: 8 additions & 0 deletions gradle/testing.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@ gradle.projectsEvaluated {
// All Test tasks will be finalized by this task. As a result, this task needn't be invoked directly.
subprojectTestTasks*.finalizedBy it

// :buildSrc:test always runs and produces a binary results directory, no matter what.
assert file('buildSrc/build/test-results/binary/test').exists() : "Can't find :buildSrc test result dir."

// Add test results of the :buildSrc project. Note that by this time in the 'thredds' config,
// :buildSrc has already run as a *separate* build (see http://stackoverflow.com/questions/26597147),
// so we cannot programmatically access its Project object to retrieve this paths.
reportOn file('buildSrc/build/test-results/binary/test')

// We could also do "reportOn subprojectTestTasks" here, but that would cause this task to be dependent on
// all subproject Tests. So, we couldn't do something like ":grib:test" and expect only GRIB tests to run
// because:
Expand Down

0 comments on commit 4330d75

Please sign in to comment.