From 7e75d1a17af764857c81e7e7b47055bef07ec0ed Mon Sep 17 00:00:00 2001 From: fesc7420 <17569373+Pfoerd@users.noreply.github.com> Date: Wed, 16 Nov 2022 17:33:29 +0100 Subject: [PATCH] [#319] Add support for thresholds of aggregated metrics on-behalf-of: @e-solutions-GmbH --- build.gradle | 2 +- ...sInSeparateSubprojectFunctionalSpec.groovy | 2 ++ .../multiproject/build-report.gradle | 5 +++ .../pitest/AggregateReportGenerator.groovy | 31 ++++++++++++++++++- .../gradle/pitest/AggregateReportTask.groovy | 18 +++++++++++ .../AggregateReportWorkParameters.groovy | 3 ++ .../pitest/PitestAggregatorPlugin.groovy | 3 ++ .../gradle/pitest/PitestPlugin.groovy | 2 +- .../pitest/PitestPluginExtension.groovy | 8 +++++ .../pitest/ReportAggregatorProperties.groovy | 23 ++++++++++++++ 10 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/main/groovy/info/solidsoft/gradle/pitest/ReportAggregatorProperties.groovy diff --git a/build.gradle b/build.gradle index c104c063..b42189e5 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ buildscript { sourceCompatibility = 1.8 -ext.pitestAggregatorVersion = "1.9.4" //Must be equal to default PIT version in PitestPlugin +ext.pitestAggregatorVersion = "1.9.10" //Must be equal to default PIT version in PitestPlugin repositories { mavenCentral() diff --git a/src/funcTest/groovy/info/solidsoft/gradle/pitest/functional/AcceptanceTestsInSeparateSubprojectFunctionalSpec.groovy b/src/funcTest/groovy/info/solidsoft/gradle/pitest/functional/AcceptanceTestsInSeparateSubprojectFunctionalSpec.groovy index 79644030..8a590c86 100644 --- a/src/funcTest/groovy/info/solidsoft/gradle/pitest/functional/AcceptanceTestsInSeparateSubprojectFunctionalSpec.groovy +++ b/src/funcTest/groovy/info/solidsoft/gradle/pitest/functional/AcceptanceTestsInSeparateSubprojectFunctionalSpec.groovy @@ -44,9 +44,11 @@ class AcceptanceTestsInSeparateSubprojectFunctionalSpec extends AbstractPitestFu assertHtmlContains("Number of Classes") assertHtmlContains("Line Coverage") assertHtmlContains("Mutation Coverage") + assertHtmlContains("Test Strength") assertHtmlContains("2") assertHtmlContains("95% ") assertHtmlContains("40% ") + assertHtmlContains("50% ") assertHtmlContains("pitest.sample.multimodule.forreport") assertHtmlContains("pitest.sample.multimodule.shared") } diff --git a/src/funcTest/resources/testProjects/multiproject/build-report.gradle b/src/funcTest/resources/testProjects/multiproject/build-report.gradle index 13587f40..cde852d4 100644 --- a/src/funcTest/resources/testProjects/multiproject/build-report.gradle +++ b/src/funcTest/resources/testProjects/multiproject/build-report.gradle @@ -42,6 +42,11 @@ subprojects { outputFormats = ["HTML","XML"] timestampedReports = false exportLineCoverage = true + reportAggregator { + aggregatedTestStrengthThreshold.set(50) + aggregatedMutationThreshold.set(40) + aggregatedMaxSurviving.set(3) + } } } } diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportGenerator.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportGenerator.groovy index f3e265c6..c3e04bcf 100644 --- a/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportGenerator.groovy +++ b/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportGenerator.groovy @@ -2,9 +2,11 @@ package info.solidsoft.gradle.pitest import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import org.gradle.api.GradleException import org.gradle.api.Incubating import org.gradle.api.provider.Property import org.gradle.workers.WorkAction +import org.pitest.aggregate.AggregationResult import org.pitest.aggregate.ReportAggregator import org.pitest.mutationtest.config.DirectoryResultOutputStrategy import org.pitest.mutationtest.config.UndatedReportDirCreationStrategy @@ -33,9 +35,36 @@ abstract class AggregateReportGenerator implements WorkAction + if (aggregationResult.testStrength < threshold) { + throw new GradleException( + "Aggregated test strength score of ${aggregationResult.testStrength} " + + "is below threshold of $threshold" + ) + } + } + + consumeIfPropertyIsSet(parameters.aggregatedMutationThreshold) { threshold -> + if (aggregationResult.mutationCoverage < threshold) { + throw new GradleException( + "Aggregated mutation score of ${aggregationResult.mutationCoverage} " + + "is below threshold of $threshold" + ) + } + } + + consumeIfPropertyIsSet(parameters.aggregatedMaxSurviving) { threshold -> + if (aggregationResult.mutationsSurvived > threshold) { + throw new GradleException( + "Had ${aggregationResult.mutationsSurvived} " + + "surviving mutants, but only $threshold survivors allowed" + ) + } + } } private static void consumeIfPropertyIsSet(Property property, Consumer applyPropertyCode) { diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportTask.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportTask.groovy index 743ea88d..caf06522 100644 --- a/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportTask.groovy +++ b/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportTask.groovy @@ -72,6 +72,18 @@ abstract class AggregateReportTask extends DefaultTask { @Optional final Property outputCharset + @Input + @Optional + final Property aggregatedTestStrengthThreshold + + @Input + @Optional + final Property aggregatedMutationThreshold + + @Input + @Optional + final Property aggregatedMaxSurviving + @Inject abstract WorkerExecutor getWorkerExecutor() @@ -85,6 +97,9 @@ abstract class AggregateReportTask extends DefaultTask { lineCoverageFiles = of.fileCollection() inputCharset = of.property(Charset) outputCharset = of.property(Charset) + aggregatedTestStrengthThreshold = of.property(Integer) + aggregatedMutationThreshold = of.property(Integer) + aggregatedMaxSurviving = of.property(Integer) } @TaskAction @@ -103,6 +118,9 @@ abstract class AggregateReportTask extends DefaultTask { parameters.lineCoverageFiles.from(lineCoverageFiles) parameters.inputCharset.set(this.inputCharset) parameters.outputCharset.set(this.outputCharset) + parameters.aggregatedTestStrengthThreshold.set(this.aggregatedTestStrengthThreshold) + parameters.aggregatedMutationThreshold.set(this.aggregatedMutationThreshold) + parameters.aggregatedMaxSurviving.set(this.aggregatedMaxSurviving) } } diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportWorkParameters.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportWorkParameters.groovy index 2a44119d..dead7ad1 100644 --- a/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportWorkParameters.groovy +++ b/src/main/groovy/info/solidsoft/gradle/pitest/AggregateReportWorkParameters.groovy @@ -20,5 +20,8 @@ interface AggregateReportWorkParameters extends WorkParameters { ConfigurableFileCollection getLineCoverageFiles() Property getInputCharset() Property getOutputCharset() + Property getAggregatedTestStrengthThreshold() + Property getAggregatedMutationThreshold() + Property getAggregatedMaxSurviving() } diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/PitestAggregatorPlugin.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/PitestAggregatorPlugin.groovy index 67bc8b00..76e7c7b8 100644 --- a/src/main/groovy/info/solidsoft/gradle/pitest/PitestAggregatorPlugin.groovy +++ b/src/main/groovy/info/solidsoft/gradle/pitest/PitestAggregatorPlugin.groovy @@ -80,6 +80,9 @@ class PitestAggregatorPlugin implements Plugin { findPluginExtension().ifPresent({ PitestPluginExtension extension -> inputCharset.set(extension.inputCharset) outputCharset.set(extension.outputCharset) + aggregatedTestStrengthThreshold.set(extension.reportAggregatorProperties.aggregatedTestStrengthThreshold) + aggregatedMutationThreshold.set(extension.reportAggregatorProperties.aggregatedMutationThreshold) + aggregatedMaxSurviving.set(extension.reportAggregatorProperties.aggregatedMaxSurviving) } as Consumer) //Simplify with Groovy 3+ } } diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/PitestPlugin.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/PitestPlugin.groovy index 7b23330c..972ea50c 100644 --- a/src/main/groovy/info/solidsoft/gradle/pitest/PitestPlugin.groovy +++ b/src/main/groovy/info/solidsoft/gradle/pitest/PitestPlugin.groovy @@ -52,7 +52,7 @@ class PitestPlugin implements Plugin { public final static String PITEST_REPORT_DIRECTORY_NAME = 'pitest' public final static String PITEST_CONFIGURATION_NAME = 'pitest' - public final static String DEFAULT_PITEST_VERSION = '1.9.4' + public final static String DEFAULT_PITEST_VERSION = '1.9.10' @Internal //6.4 due to main -> mainClass change to avoid deprecation warning in Gradle 7.x - https://github.com/szpak/gradle-pitest-plugin/pull/289 public static final GradleVersion MINIMAL_SUPPORTED_GRADLE_VERSION = GradleVersion.version("6.4") //public as used also in regression tests diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/PitestPluginExtension.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/PitestPluginExtension.groovy index 722398c4..760333a2 100644 --- a/src/main/groovy/info/solidsoft/gradle/pitest/PitestPluginExtension.groovy +++ b/src/main/groovy/info/solidsoft/gradle/pitest/PitestPluginExtension.groovy @@ -16,6 +16,7 @@ package info.solidsoft.gradle.pitest import groovy.transform.CompileStatic +import org.gradle.api.Action import org.gradle.api.Incubating import org.gradle.api.Project import org.gradle.api.file.DirectoryProperty @@ -220,6 +221,8 @@ class PitestPluginExtension { @Incubating final ListProperty fileExtensionsToFilter + final ReportAggregatorProperties reportAggregatorProperties + PitestPluginExtension(Project project) { ObjectFactory of = project.objects Project p = project @@ -270,6 +273,11 @@ class PitestPluginExtension { outputCharset = of.property(Charset) features = nullListPropertyOf(p, String) fileExtensionsToFilter = nullListPropertyOf(p, String) + reportAggregatorProperties = new ReportAggregatorProperties(of) + } + + void reportAggregator(Action action) { + action.execute(reportAggregatorProperties) } void setReportDir(File reportDir) { diff --git a/src/main/groovy/info/solidsoft/gradle/pitest/ReportAggregatorProperties.groovy b/src/main/groovy/info/solidsoft/gradle/pitest/ReportAggregatorProperties.groovy new file mode 100644 index 00000000..0234027e --- /dev/null +++ b/src/main/groovy/info/solidsoft/gradle/pitest/ReportAggregatorProperties.groovy @@ -0,0 +1,23 @@ +package info.solidsoft.gradle.pitest + +import groovy.transform.CompileStatic +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property + +import javax.inject.Inject + +@CompileStatic +class ReportAggregatorProperties { + + final Property aggregatedTestStrengthThreshold + final Property aggregatedMutationThreshold + final Property aggregatedMaxSurviving + + @Inject + ReportAggregatorProperties(ObjectFactory objects) { + aggregatedTestStrengthThreshold = objects.property(Integer) + aggregatedMutationThreshold = objects.property(Integer) + aggregatedMaxSurviving = objects.property(Integer) + } + +}