diff --git a/pom.xml b/pom.xml index 0997a5db0..84fc309f1 100644 --- a/pom.xml +++ b/pom.xml @@ -18,13 +18,14 @@ - 2.361.4 + 2.387.3 11 0.16.0 2.0.7 0.10 + 4.7.0 4.1.6.1 2.21 @@ -47,6 +48,9 @@ + + Waschndolos + devguy Marky Jackson @@ -79,8 +83,8 @@ io.jenkins.tools.bom - bom-2.319.x - 1654.vcb_69d035fa_20 + bom-2.387.x + 2329.v078520e55c19 import pom @@ -120,6 +124,12 @@ ${cloudbees-disk-usage-simple.version} true + + io.jenkins.plugins + code-coverage-api + ${code-coverage-api.version} + true + org.jenkins-ci.plugins junit diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/BaseCollector.java b/src/main/java/org/jenkinsci/plugins/prometheus/BaseCollector.java new file mode 100644 index 000000000..571733658 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/BaseCollector.java @@ -0,0 +1,19 @@ +package org.jenkinsci.plugins.prometheus; + +import io.prometheus.client.Collector; +import io.prometheus.client.Gauge; +import org.jenkinsci.plugins.prometheus.util.ConfigurationUtils; + +public abstract class BaseCollector extends Collector { + + + protected static Gauge.Builder newGaugeBuilder(String... labels) { + return newGaugeBuilder().labelNames(labels); + } + + protected static Gauge.Builder newGaugeBuilder() { + return Gauge.build() + .namespace(ConfigurationUtils.getNamespace()) + .subsystem(ConfigurationUtils.getSubSystem()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/CodeCoverageCollector.java b/src/main/java/org/jenkinsci/plugins/prometheus/CodeCoverageCollector.java new file mode 100644 index 000000000..a557647c7 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/CodeCoverageCollector.java @@ -0,0 +1,94 @@ +package org.jenkinsci.plugins.prometheus; + +import hudson.model.Job; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.steps.CoverageBuildAction; +import io.prometheus.client.Collector; +import jenkins.model.Jenkins; +import org.apache.commons.collections.CollectionUtils; +import org.jenkinsci.plugins.prometheus.collectors.CollectorFactory; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; +import org.jenkinsci.plugins.prometheus.collectors.MetricCollector; +import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration; +import org.jenkinsci.plugins.prometheus.util.Jobs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class CodeCoverageCollector extends BaseCollector { + + private static final Logger LOGGER = LoggerFactory.getLogger(CodeCoverageCollector.class); + + @Override + public List collect() { + + if (!isCodeCoverageAPIPluginLoaded()) { + LOGGER.warn("Cannot collect code coverage data because plugin Code Coverage API (shortname: 'code-coverage-api') is not loaded."); + return Collections.emptyList(); + } + + if (!isCodeCoverageCollectionConfigured()) { + return Collections.emptyList(); + } + + List> samples = new ArrayList<>(); + Jobs.forEachJob(job -> CollectionUtils.addIgnoreNull(samples, collectCoverageMetricForJob(job))); + + + return samples.stream().flatMap(Collection::stream).collect(Collectors.toList()); + } + + private List collectCoverageMetricForJob(Job job) { + if (job == null) { + return Collections.emptyList(); + } + + Run lastBuild = job.getLastBuild(); + if (lastBuild == null || lastBuild.isBuilding()) { + return Collections.emptyList(); + } + + CoverageBuildAction coverageBuildAction = lastBuild.getAction(CoverageBuildAction.class); + if (coverageBuildAction == null) { + return Collections.emptyList(); + } + + CollectorFactory factory = new CollectorFactory(); + List, ? extends Collector>> collectors = new ArrayList<>(); + + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_CLASS_COVERED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_CLASS_MISSED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_CLASS_TOTAL, new String[]{"job_name"})); + + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_BRANCH_COVERED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_BRANCH_MISSED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_BRANCH_TOTAL, new String[]{"job_name"})); + + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_INSTRUCTION_COVERED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_INSTRUCTION_MISSED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_INSTRUCTION_TOTAL, new String[]{"job_name"})); + + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_FILE_COVERED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_FILE_MISSED, new String[]{"job_name"})); + collectors.add(factory.createCoverageRunCollector(CollectorType.COVERAGE_FILE_TOTAL, new String[]{"job_name"})); + + collectors.forEach(c -> c.calculateMetric(lastBuild, new String[]{job.getName()})); + + return collectors.stream() + .map(MetricCollector::collect) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + private boolean isCodeCoverageAPIPluginLoaded() { + return Jenkins.get().getPlugin("code-coverage-api") != null; + } + + private boolean isCodeCoverageCollectionConfigured() { + return PrometheusConfiguration.get().isCollectCodeCoverage(); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorFactory.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorFactory.java index 2a58152b9..756dd396a 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorFactory.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorFactory.java @@ -8,10 +8,12 @@ import io.prometheus.client.Collector; import jenkins.model.Jenkins; import org.jenkinsci.plugins.prometheus.collectors.builds.BuildCollectorFactory; +import org.jenkinsci.plugins.prometheus.collectors.coverage.CoverageCollectorFactory; import org.jenkinsci.plugins.prometheus.collectors.disk.DiskCollectorFactory; import org.jenkinsci.plugins.prometheus.collectors.executors.ExecutorCollectorFactory; import org.jenkinsci.plugins.prometheus.collectors.jenkins.JenkinsCollectorFactory; import org.jenkinsci.plugins.prometheus.collectors.jobs.JobCollectorFactory; +import org.json.Cookie; import java.nio.file.FileStore; @@ -23,12 +25,19 @@ public class CollectorFactory { private final ExecutorCollectorFactory executorCollectorFactory; private final DiskCollectorFactory diskCollectorFactory; + private final CoverageCollectorFactory coverageCollectorFactory; + public CollectorFactory() { buildCollectorFactory = new BuildCollectorFactory(); jobCollectorFactory = new JobCollectorFactory(); jenkinsCollectorFactory = new JenkinsCollectorFactory(); executorCollectorFactory = new ExecutorCollectorFactory(); diskCollectorFactory = new DiskCollectorFactory(); + coverageCollectorFactory = new CoverageCollectorFactory(); + } + + public MetricCollector, ? extends Collector> createCoverageRunCollector(CollectorType type, String[] labelNames) { + return coverageCollectorFactory.createCollector(type, labelNames); } public MetricCollector, ? extends Collector> createRunCollector(CollectorType type, String[] labelNames, String prefix) { diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java index cb3d6261a..fd19083e3 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java @@ -34,7 +34,27 @@ public enum CollectorType { FILE_STORE_CAPACITY_GAUGE("file_store_capacity_bytes"), JOB_USAGE_BYTES_GAUGE("job_usage_bytes"), - BUILD_FAILED_TESTS("build_tests_failing"); + BUILD_FAILED_TESTS("build_tests_failing"), + + COVERAGE_CLASS_COVERED("coverage_class_covered"), + COVERAGE_CLASS_MISSED("coverage_class_missed"), + COVERAGE_CLASS_TOTAL("coverage_class_total"), + + COVERAGE_BRANCH_COVERED("coverage_branch_covered"), + COVERAGE_BRANCH_MISSED("coverage_branch_missed"), + COVERAGE_BRANCH_TOTAL("coverage_branch_total"), + + COVERAGE_INSTRUCTION_COVERED("coverage_instruction_covered"), + COVERAGE_INSTRUCTION_MISSED("coverage_instruction_missed"), + COVERAGE_INSTRUCTION_TOTAL("coverage_instruction_total"), + + COVERAGE_FILE_COVERED("coverage_file_covered"), + COVERAGE_FILE_MISSED("coverage_file_missed"), + COVERAGE_FILE_TOTAL("coverage_file_total"), + + + + ; private final String name; diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchCoveredGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchCoveredGauge.java new file mode 100644 index 000000000..2b51d24a8 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchCoveredGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageBranchCoveredGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageBranchCoveredGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_BRANCH_COVERED; + } + + @Override + protected String getHelpText() { + return "Returns the number of branches covered"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.BRANCH, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getCovered()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchMissedGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchMissedGauge.java new file mode 100644 index 000000000..647304f9c --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchMissedGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageBranchMissedGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageBranchMissedGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_BRANCH_MISSED; + } + + @Override + protected String getHelpText() { + return "Returns the number of branches missed"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.BRANCH, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getMissed()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchTotalGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchTotalGauge.java new file mode 100644 index 000000000..22dea4ab5 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchTotalGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageBranchTotalGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageBranchTotalGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_BRANCH_TOTAL; + } + + @Override + protected String getHelpText() { + return "Returns the number of branches total"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.BRANCH, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getTotal()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassCoveredGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassCoveredGauge.java new file mode 100644 index 000000000..d211f3a05 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassCoveredGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageClassCoveredGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageClassCoveredGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_CLASS_COVERED; + } + + @Override + protected String getHelpText() { + return "Returns the number of classes covered"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.CLASS, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getCovered()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassMissedGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassMissedGauge.java new file mode 100644 index 000000000..3e665eedf --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassMissedGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageClassMissedGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageClassMissedGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_CLASS_MISSED; + } + + @Override + protected String getHelpText() { + return "Returns the number of classes missed"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.CLASS, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getMissed()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassTotalGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassTotalGauge.java new file mode 100644 index 000000000..b395cdd53 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassTotalGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageClassTotalGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageClassTotalGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_CLASS_TOTAL; + } + + @Override + protected String getHelpText() { + return "Returns the number of classes total"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.CLASS, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getTotal()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageCollectorFactory.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageCollectorFactory.java new file mode 100644 index 000000000..10c999caf --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageCollectorFactory.java @@ -0,0 +1,42 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import hudson.model.Run; +import io.prometheus.client.Collector; +import org.jenkinsci.plugins.prometheus.collectors.BaseCollectorFactory; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; +import org.jenkinsci.plugins.prometheus.collectors.MetricCollector; +import org.jenkinsci.plugins.prometheus.collectors.NoOpMetricCollector; + +public class CoverageCollectorFactory extends BaseCollectorFactory { + + public MetricCollector, ? extends Collector> createCollector(CollectorType type, String[] labelNames) { + switch (type) { + case COVERAGE_CLASS_COVERED: + return saveBuildCollector(new CoverageClassCoveredGauge(labelNames, namespace, subsystem)); + case COVERAGE_CLASS_MISSED: + return saveBuildCollector(new CoverageClassMissedGauge(labelNames, namespace, subsystem)); + case COVERAGE_CLASS_TOTAL: + return saveBuildCollector(new CoverageClassTotalGauge(labelNames, namespace, subsystem)); + case COVERAGE_BRANCH_COVERED: + return saveBuildCollector(new CoverageBranchCoveredGauge(labelNames, namespace, subsystem)); + case COVERAGE_BRANCH_MISSED: + return saveBuildCollector(new CoverageBranchMissedGauge(labelNames, namespace, subsystem)); + case COVERAGE_BRANCH_TOTAL: + return saveBuildCollector(new CoverageBranchTotalGauge(labelNames, namespace, subsystem)); + case COVERAGE_INSTRUCTION_COVERED: + return saveBuildCollector(new CoverageInstructionCoveredGauge(labelNames, namespace, subsystem)); + case COVERAGE_INSTRUCTION_MISSED: + return saveBuildCollector(new CoverageInstructionMissedGauge(labelNames, namespace, subsystem)); + case COVERAGE_INSTRUCTION_TOTAL: + return saveBuildCollector(new CoverageInstructionTotalGauge(labelNames, namespace, subsystem)); + case COVERAGE_FILE_COVERED: + return saveBuildCollector(new CoverageFileCoveredGauge(labelNames, namespace, subsystem)); + case COVERAGE_FILE_MISSED: + return saveBuildCollector(new CoverageFileMissedGauge(labelNames, namespace, subsystem)); + case COVERAGE_FILE_TOTAL: + return saveBuildCollector(new CoverageFileTotalGauge(labelNames, namespace, subsystem)); + default: + return new NoOpMetricCollector<>(); + } + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileCoveredGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileCoveredGauge.java new file mode 100644 index 000000000..1750e5843 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileCoveredGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageFileCoveredGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageFileCoveredGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_FILE_COVERED; + } + + @Override + protected String getHelpText() { + return "Returns the number of files covered"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.FILE, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getCovered()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileMissedGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileMissedGauge.java new file mode 100644 index 000000000..d34655ee6 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileMissedGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageFileMissedGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageFileMissedGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_FILE_MISSED; + } + + @Override + protected String getHelpText() { + return "Returns the number of files missed"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.FILE, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getMissed()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileTotalGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileTotalGauge.java new file mode 100644 index 000000000..bee019f00 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileTotalGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageFileTotalGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageFileTotalGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_FILE_TOTAL; + } + + @Override + protected String getHelpText() { + return "Returns the number of files total"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.FILE, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getTotal()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionCoveredGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionCoveredGauge.java new file mode 100644 index 000000000..7bd77dace --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionCoveredGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageInstructionCoveredGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageInstructionCoveredGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_INSTRUCTION_COVERED; + } + + @Override + protected String getHelpText() { + return "Returns the number of instructions covered"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.INSTRUCTION, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getCovered()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionMissedGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionMissedGauge.java new file mode 100644 index 000000000..4fc941123 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionMissedGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageInstructionMissedGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageInstructionMissedGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_INSTRUCTION_MISSED; + } + + @Override + protected String getHelpText() { + return "Returns the number of instructions missed"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.INSTRUCTION, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getMissed()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionTotalGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionTotalGauge.java new file mode 100644 index 000000000..75e4af0dd --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionTotalGauge.java @@ -0,0 +1,45 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; + +import java.util.Optional; + +public class CoverageInstructionTotalGauge extends CoverageMetricsCollector, Gauge> { + + protected CoverageInstructionTotalGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.COVERAGE_INSTRUCTION_TOTAL; + } + + @Override + protected String getHelpText() { + return "Returns the number of instructions total"; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Run jenkinsObject, String[] labelValues) { + + Optional optional = getCoverage(jenkinsObject, Metric.INSTRUCTION, Baseline.PROJECT); + if (optional.isEmpty()) { + return; + } + + Coverage coverage = optional.get(); + collector.labels(labelValues).set(coverage.getTotal()); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageMetricsCollector.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageMetricsCollector.java new file mode 100644 index 000000000..05062666c --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageMetricsCollector.java @@ -0,0 +1,30 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import hudson.model.Run; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.jenkins.plugins.coverage.metrics.steps.CoverageBuildAction; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.builds.BuildsMetricCollector; + +import java.util.Optional; + +public abstract class CoverageMetricsCollector> extends BuildsMetricCollector { + protected CoverageMetricsCollector(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + protected Optional getCoverage(Run jenkinsRun, Metric metric, Baseline baseline) { + + CoverageBuildAction coverageBuildAction = jenkinsRun.getAction(CoverageBuildAction.class); + if (coverageBuildAction == null) { + return Optional.empty(); + } + + return coverageBuildAction.getAllValues(baseline).stream() + .filter(value -> metric.equals(value.getMetric()) && value instanceof Coverage) + .map(x -> (Coverage)x) + .findFirst(); + } +} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java b/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java index 9048ff2ea..8d04b1d57 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration.java @@ -56,6 +56,7 @@ public class PrometheusConfiguration extends GlobalConfiguration { private String labeledBuildParameterNames = ""; private boolean collectDiskUsage = true; + private boolean collectCodeCoverage = false; private boolean collectNodeStatus = true; private DisabledMetricConfig disabledMetricConfig = new DisabledMetricConfig(new ArrayList<>()); @@ -296,6 +297,18 @@ public void setDisabledMetricConfig(DisabledMetricConfig disabledMetricConfig) { this.disabledMetricConfig = disabledMetricConfig; } + public boolean isCollectCodeCoverage() { + return collectCodeCoverage; + } + + public boolean isCodeCoverageApiPluginInstalled() { + return Jenkins.get().getPlugin("code-coverage-api") != null; + } + + public void setCollectCodeCoverage(boolean collectCodeCoverage) { + this.collectCodeCoverage = collectCodeCoverage; + } + public FormValidation doCheckPath(@QueryParameter String value) { if (StringUtils.isEmpty(value)) { return FormValidation.error(Messages.path_required()); diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java index e864a771b..99259f1f8 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java @@ -7,10 +7,7 @@ import io.prometheus.client.exporter.common.TextFormat; import io.prometheus.client.hotspot.DefaultExports; import jenkins.metrics.api.Metrics; -import org.jenkinsci.plugins.prometheus.DiskUsageCollector; -import org.jenkinsci.plugins.prometheus.ExecutorCollector; -import org.jenkinsci.plugins.prometheus.JenkinsStatusCollector; -import org.jenkinsci.plugins.prometheus.JobCollector; +import org.jenkinsci.plugins.prometheus.*; import org.jenkinsci.plugins.prometheus.util.JenkinsNodeBuildsSampleBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,6 +30,7 @@ public DefaultPrometheusMetrics() { collectorRegistry.register(new DropwizardExports(Metrics.metricRegistry(), new JenkinsNodeBuildsSampleBuilder())); collectorRegistry.register(new DiskUsageCollector()); collectorRegistry.register(new ExecutorCollector()); + collectorRegistry.register(new CodeCoverageCollector()); // other collectors from other plugins ExtensionList.lookup(Collector.class).forEach(collectorRegistry::register); diff --git a/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/config.jelly b/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/config.jelly index d5bd14a49..24bf961e0 100644 --- a/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/config.jelly +++ b/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/config.jelly @@ -59,5 +59,9 @@ + + + + diff --git a/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/help-collectCodeCoverage.jelly b/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/help-collectCodeCoverage.jelly new file mode 100644 index 000000000..8b150441e --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/prometheus/config/PrometheusConfiguration/help-collectCodeCoverage.jelly @@ -0,0 +1,9 @@ + + +
+

+ If prometheus should collect code coverage metrics from code-coverage-api plugin. + This option is disabled when code-coverage-api plugin is not installed. +

+
+
diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchCoveredGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchCoveredGaugeTest.java new file mode 100644 index 000000000..2047ffdda --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchCoveredGaugeTest.java @@ -0,0 +1,61 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageBranchCoveredGaugeTest extends CoverageTest { + + + public CoverageBranchCoveredGaugeTest() { + super(Baseline.PROJECT, Metric.BRANCH); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForCovered(); + CoverageBranchCoveredGauge sut = new CoverageBranchCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of branches covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_branch_covered", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(10.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageBranchCoveredGauge sut = new CoverageBranchCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of branches covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_branch_covered", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchMissedGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchMissedGaugeTest.java new file mode 100644 index 000000000..b0eec30ae --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchMissedGaugeTest.java @@ -0,0 +1,63 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageBranchMissedGaugeTest extends CoverageTest { + + + + public CoverageBranchMissedGaugeTest() { + super(Baseline.PROJECT, Metric.BRANCH); + } + + @Test + public void testMissed() { + setUpSuccessfulMocksForMissed(); + CoverageBranchMissedGauge sut = new CoverageBranchMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of branches missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_branch_missed", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(5.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageBranchMissedGauge sut = new CoverageBranchMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of branches missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_branch_missed", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchTotalGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchTotalGaugeTest.java new file mode 100644 index 000000000..848bce785 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageBranchTotalGaugeTest.java @@ -0,0 +1,61 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageBranchTotalGaugeTest extends CoverageTest { + + + public CoverageBranchTotalGaugeTest() { + super(Baseline.PROJECT, Metric.BRANCH); + } + + @Test + public void testMissed() { + setUpSuccessfulMocksForTotal(); + CoverageBranchTotalGauge sut = new CoverageBranchTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of branches total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_branch_total", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(15.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageBranchTotalGauge sut = new CoverageBranchTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of branches total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_branch_total", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassCoveredGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassCoveredGaugeTest.java new file mode 100644 index 000000000..1913451fd --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassCoveredGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageClassCoveredGaugeTest extends CoverageTest { + + + public CoverageClassCoveredGaugeTest() { + super(Baseline.PROJECT, Metric.CLASS); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForCovered(); + CoverageClassCoveredGauge sut = new CoverageClassCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of classes covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_class_covered", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(10.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageClassCoveredGauge sut = new CoverageClassCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of classes covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_class_covered", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassMissedGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassMissedGaugeTest.java new file mode 100644 index 000000000..9785fe218 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassMissedGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageClassMissedGaugeTest extends CoverageTest { + + + public CoverageClassMissedGaugeTest() { + super(Baseline.PROJECT, Metric.CLASS); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForMissed(); + CoverageClassMissedGauge sut = new CoverageClassMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of classes missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_class_missed", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(5.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageClassMissedGauge sut = new CoverageClassMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of classes missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_class_missed", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassTotalGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassTotalGaugeTest.java new file mode 100644 index 000000000..87abafa95 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageClassTotalGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageClassTotalGaugeTest extends CoverageTest { + + + public CoverageClassTotalGaugeTest() { + super(Baseline.PROJECT, Metric.CLASS); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForTotal(); + CoverageClassTotalGauge sut = new CoverageClassTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of classes total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_class_total", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(15.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageClassTotalGauge sut = new CoverageClassTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of classes total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_class_total", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileCoveredGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileCoveredGaugeTest.java new file mode 100644 index 000000000..16670222d --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileCoveredGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageFileCoveredGaugeTest extends CoverageTest { + + + public CoverageFileCoveredGaugeTest() { + super(Baseline.PROJECT, Metric.FILE); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForCovered(); + CoverageFileCoveredGauge sut = new CoverageFileCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of files covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_file_covered", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(10.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageFileCoveredGauge sut = new CoverageFileCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of files covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_file_covered", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileMissedGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileMissedGaugeTest.java new file mode 100644 index 000000000..e363ba734 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileMissedGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageFileMissedGaugeTest extends CoverageTest { + + + public CoverageFileMissedGaugeTest() { + super(Baseline.PROJECT, Metric.FILE); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForMissed(); + CoverageFileMissedGauge sut = new CoverageFileMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of files missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_file_missed", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(5.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageFileMissedGauge sut = new CoverageFileMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of files missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_file_missed", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileTotalGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileTotalGaugeTest.java new file mode 100644 index 000000000..46ff61486 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageFileTotalGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageFileTotalGaugeTest extends CoverageTest { + + + public CoverageFileTotalGaugeTest() { + super(Baseline.PROJECT, Metric.FILE); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForTotal(); + CoverageFileTotalGauge sut = new CoverageFileTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of files total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_file_total", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(15.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageFileTotalGauge sut = new CoverageFileTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of files total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_file_total", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionCoveredGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionCoveredGaugeTest.java new file mode 100644 index 000000000..521bb4a34 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionCoveredGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageInstructionCoveredGaugeTest extends CoverageTest { + + + public CoverageInstructionCoveredGaugeTest() { + super(Baseline.PROJECT, Metric.INSTRUCTION); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForCovered(); + CoverageInstructionCoveredGauge sut = new CoverageInstructionCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of instructions covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_instruction_covered", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(10.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageInstructionCoveredGauge sut = new CoverageInstructionCoveredGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of instructions covered", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_instruction_covered", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionMissedGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionMissedGaugeTest.java new file mode 100644 index 000000000..0793a4830 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionMissedGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageInstructionMissedGaugeTest extends CoverageTest { + + + public CoverageInstructionMissedGaugeTest() { + super(Baseline.PROJECT, Metric.INSTRUCTION); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForMissed(); + CoverageInstructionMissedGauge sut = new CoverageInstructionMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of instructions missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_instruction_missed", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(5.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageInstructionMissedGauge sut = new CoverageInstructionMissedGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of instructions missed", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_instruction_missed", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionTotalGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionTotalGaugeTest.java new file mode 100644 index 000000000..4d520a347 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageInstructionTotalGaugeTest.java @@ -0,0 +1,62 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.prometheus.client.Collector; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.util.List; + +public class CoverageInstructionTotalGaugeTest extends CoverageTest { + + + public CoverageInstructionTotalGaugeTest() { + super(Baseline.PROJECT, Metric.INSTRUCTION); + } + + @Test + public void testCovered() { + setUpSuccessfulMocksForTotal(); + CoverageInstructionTotalGauge sut = new CoverageInstructionTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of instructions total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_instruction_total", familySamples.name); + + List samples = familySamples.samples; + + Assertions.assertEquals(1, samples.size()); + + Collector.MetricFamilySamples.Sample sample = samples.get(0); + Assertions.assertEquals(15.0, sample.value); + Assertions.assertEquals("myJob", sample.labelValues.get(0)); + + } + + @Test + public void testNothingFailsIfNoCoverageFound() { + setUpUnsuccessfulMocks(); + + CoverageInstructionTotalGauge sut = new CoverageInstructionTotalGauge(new String[]{"job"}, getNamespace(), getSubSystem()); + + sut.calculateMetric(mock, new String[]{"myJob"}); + + List metricFamilySamples = sut.collect(); + Assertions.assertEquals(1, metricFamilySamples.size()); + + Collector.MetricFamilySamples familySamples = metricFamilySamples.get(0); + + Assertions.assertEquals("Returns the number of instructions total", familySamples.help); + Assertions.assertEquals("default_jenkins_builds_coverage_instruction_total", familySamples.name); + + Assertions.assertEquals(0, familySamples.samples.size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageTest.java new file mode 100644 index 000000000..4409f48a9 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/coverage/CoverageTest.java @@ -0,0 +1,61 @@ +package org.jenkinsci.plugins.prometheus.collectors.coverage; + +import edu.hm.hafner.coverage.Coverage; +import edu.hm.hafner.coverage.Metric; +import io.jenkins.plugins.coverage.metrics.model.Baseline; +import io.jenkins.plugins.coverage.metrics.steps.CoverageBuildAction; +import org.jenkinsci.plugins.prometheus.collectors.testutils.MockedRunCollectorTest; +import org.mockito.Mockito; + +import java.util.List; + +import static org.mockito.Mockito.when; + +public abstract class CoverageTest extends MockedRunCollectorTest { + + private final Baseline baseline; + private final Metric metric; + + public CoverageTest(Baseline baseline, Metric metric) { + this.baseline = baseline; + this.metric = metric; + } + + + protected void setUpSuccessfulMocksForCovered() { + CoverageBuildAction mockedCoverageBuildAction = Mockito.mock(CoverageBuildAction.class); + Coverage mockedCoverage = Mockito.mock(Coverage.class); + when(mockedCoverage.getMetric()).thenReturn(metric); + when(mockedCoverage.getCovered()).thenReturn(10); + when(mockedCoverageBuildAction.getAllValues(baseline)).thenReturn(List.of(mockedCoverage)); + when(mock.getAction(CoverageBuildAction.class)).thenReturn(mockedCoverageBuildAction); + } + + protected void setUpSuccessfulMocksForMissed() { + CoverageBuildAction mockedCoverageBuildAction = Mockito.mock(CoverageBuildAction.class); + Coverage mockedCoverage = Mockito.mock(Coverage.class); + when(mockedCoverage.getMetric()).thenReturn(metric); + when(mockedCoverage.getMissed()).thenReturn(5); + when(mockedCoverageBuildAction.getAllValues(baseline)).thenReturn(List.of(mockedCoverage)); + when(mock.getAction(CoverageBuildAction.class)).thenReturn(mockedCoverageBuildAction); + } + + protected void setUpSuccessfulMocksForTotal() { + CoverageBuildAction mockedCoverageBuildAction = Mockito.mock(CoverageBuildAction.class); + Coverage mockedCoverage = Mockito.mock(Coverage.class); + when(mockedCoverage.getMetric()).thenReturn(metric); + when(mockedCoverage.getTotal()).thenReturn(15); + when(mockedCoverageBuildAction.getAllValues(baseline)).thenReturn(List.of(mockedCoverage)); + when(mock.getAction(CoverageBuildAction.class)).thenReturn(mockedCoverageBuildAction); + } + + + + protected void setUpUnsuccessfulMocks() { + CoverageBuildAction mockedCoverageBuildAction = Mockito.mock(CoverageBuildAction.class); + Coverage mockedCoverage = Mockito.mock(Coverage.class); + when(mockedCoverageBuildAction.getAllValues(baseline)).thenReturn(List.of(mockedCoverage)); + when(mock.getAction(CoverageBuildAction.class)).thenReturn(mockedCoverageBuildAction); + } + +}