Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0ea0300
Create a first skeleton of the new recorder.
uhafner Sep 30, 2022
cf68973
Make parsers selectable.
uhafner Oct 1, 2022
c111f74
Reuse warnings plugin tools to scan the workspace for files and move …
uhafner Oct 9, 2022
076631e
Fix most of the unit tests. Started to migrate one integration test.
uhafner Oct 15, 2022
bfbd00f
Converted freestyle integration tests.
uhafner Oct 17, 2022
7637f6a
Convert some more pipelines and freestyle jobs.
uhafner Oct 17, 2022
a415091
Add a parameterized test for all parsers that have no input files.
uhafner Oct 17, 2022
12268d0
Simplify creation of jobs.
uhafner Oct 17, 2022
6194b95
Introduce a label provider for metrics.
uhafner Oct 20, 2022
c4123fc
Fix serialization of delta values (using Fraction instances).
uhafner Oct 20, 2022
61a05fb
Verify branch coverage in delta test.
uhafner Oct 21, 2022
cc4e3e7
Verify LOC and COMPLEXITY in delta test.
uhafner Oct 21, 2022
3ef4f23
Move and fix test for declarative pipelines.
uhafner Oct 21, 2022
64acf68
Fix summary: now also LOC and COMPLEXITY will be shown.
uhafner Oct 21, 2022
54f0e0f
Fix creation of coverage tree.
uhafner Oct 21, 2022
a3b3304
Fix creation of coverage tree.
uhafner Oct 22, 2022
a58ebb5
Restore source code coloring.
uhafner Oct 23, 2022
296bd67
Simplify code.
uhafner Oct 24, 2022
799e7d8
Create delta tree on the fly without removing nodes.
uhafner Oct 25, 2022
8c20115
Improve storage of coverages per line.
uhafner Nov 1, 2022
4aae7da
Rework coverage trees.
uhafner Nov 2, 2022
8a37843
Store values on all levels if available.
uhafner Nov 2, 2022
7f3115f
Fix splitting of packages with values in the package nodes.
uhafner Nov 4, 2022
acba09b
Fix tests with old model.
uhafner Nov 4, 2022
6ace53a
Integrate mixed Cobertura and JaCoCo tests.
uhafner Nov 5, 2022
a9a51cb
Improve source code integration tests.
uhafner Nov 5, 2022
de6f2d2
Fix delta test.
uhafner Nov 5, 2022
f705035
Move new code to metrics package.
uhafner Nov 6, 2022
c976447
Bump version of coverage model to 0.1.0.
uhafner Nov 6, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@
<url>https://github.com/jenkinsci/code-coverage-api-plugin</url>

<properties>
<revision>3.3.0</revision>
<revision>4.0.0</revision>
<changelist>-SNAPSHOT</changelist>
<gitHubRepo>jenkinsci/code-coverage-api-plugin</gitHubRepo>

<jenkins.baseline>2.361</jenkins.baseline>
<jenkins.version>2.361.2</jenkins.version>
<jdk>11</jdk>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.release>11</maven.compiler.release>
<maven.compiler.testRelease>11</maven.compiler.testRelease>

<trove4j.version>3.0.3</trove4j.version>
<saxon-he.version>11.4</saxon-he.version>

Expand Down Expand Up @@ -58,6 +66,11 @@
</licenses>

<dependencies>
<dependency>
<groupId>edu.hm.hafner</groupId>
<artifactId>coverage-model</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>ionicons-api</artifactId>
Expand Down Expand Up @@ -142,6 +155,10 @@
<artifactId>prism-api</artifactId>
<version>${prism-api.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-api</artifactId>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
Expand Down Expand Up @@ -199,11 +216,6 @@
<artifactId>workflow-durable-task-step</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
Expand Down Expand Up @@ -302,6 +314,7 @@
<artifactId>assertj-assertions-generator-maven-plugin</artifactId>
<configuration>
<packages combine.children="append">
<package>io.jenkins.plugins.coverage.metrics</package>
<package>io.jenkins.plugins.coverage.model</package>
</packages>
<excludes combine.children="append">
Expand All @@ -316,6 +329,14 @@
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>10</source>
<target>10</target>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import java.util.Collection;
import java.util.Collections;

import org.apache.commons.lang.StringUtils;

import edu.umd.cs.findbugs.annotations.CheckForNull;

import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.StaplerProxy;
import hudson.model.Action;
import hudson.model.HealthReport;
Expand All @@ -16,7 +17,7 @@
import jenkins.model.RunAction2;
import jenkins.tasks.SimpleBuildStep;

import io.jenkins.plugins.coverage.model.CoverageBuildAction;
import io.jenkins.plugins.coverage.metrics.CoverageBuildAction;
import io.jenkins.plugins.coverage.targets.CoverageResult;

public class CoverageAction implements StaplerProxy, SimpleBuildStep.LastBuildAction, RunAction2, HealthReportingAction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import io.jenkins.plugins.coverage.detector.Detectable;
import io.jenkins.plugins.coverage.detector.ReportDetector;
import io.jenkins.plugins.coverage.exception.CoverageException;
import io.jenkins.plugins.coverage.model.CoverageReporter;
import io.jenkins.plugins.coverage.source.SourceFileResolver;
import io.jenkins.plugins.coverage.source.SourceFileResolver.SourceFileResolverLevel;
import io.jenkins.plugins.coverage.targets.CoverageElement;
Expand Down Expand Up @@ -128,14 +127,16 @@ public void performCoverageReport(final List<CoverageReportAdapter> reportAdapte
HealthReport healthReport = processThresholds(results, globalThresholds, action);
action.setHealthReport(healthReport);

// Transform the old model to the new model
// FIXME: Transform the old model to the new model
/*
CoverageReporter coverageReporter = new CoverageReporter();
coverageReporter.run(coverageReport.getRoot(), run, workspace, listener, healthReport, scm,
sourceDirectories, sourceCodeEncoding, mapSourceCodeRetention());

if (failBuildIfCoverageDecreasedInChangeRequest) {
failBuildIfChangeRequestDecreasedCoverage(coverageReport, action);
}
*/
}

private SourceCodeRetention mapSourceCodeRetention() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.jenkins.plugins.coverage.metrics;

import java.io.Serializable;

import edu.hm.hafner.metric.Node;
import edu.hm.hafner.util.FilteredLog;

/**
* Combines the root node of a coverage tree with the log that contains useful information gathered during parsing on an
* agent.
*
* @author Ullrich Hafner
*/
class AggregatedResult implements Serializable {
private static final long serialVersionUID = 2122230867938547733L;

private final FilteredLog log;
private final Node root;

AggregatedResult(final FilteredLog log, final Node root) {
this.log = log;
this.root = root;
}

public FilteredLog getLog() {
return log;
}

public Node getRoot() {
return root;
}

public boolean hasErrors() {
return !getLog().getErrorMessages().isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package io.jenkins.plugins.coverage.model;
package io.jenkins.plugins.coverage.metrics;

import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.SortedSet;
import java.util.stream.Collectors;

import org.apache.commons.lang3.math.Fraction;
import edu.hm.hafner.metric.Coverage;
import edu.hm.hafner.metric.FileNode;
import edu.hm.hafner.metric.Metric;
import edu.hm.hafner.metric.Node;

import hudson.Functions;

import io.jenkins.plugins.coverage.model.visualization.colorization.ColorProvider;
import io.jenkins.plugins.coverage.metrics.visualization.colorization.ColorProvider;
import io.jenkins.plugins.datatables.DetailedCell;
import io.jenkins.plugins.datatables.TableConfiguration;
import io.jenkins.plugins.datatables.TableConfiguration.SelectStyle;
Expand All @@ -20,7 +23,7 @@
* @since 3.0.0
*/
class ChangeCoverageTableModel extends CoverageTableModel {
private final CoverageNode changeRoot;
private final Node changeRoot;

/**
* Creates a change coverage table model.
Expand All @@ -36,7 +39,7 @@ class ChangeCoverageTableModel extends CoverageTableModel {
* @param colorProvider
* The {@link ColorProvider} which provides the used colors
*/
ChangeCoverageTableModel(final String id, final CoverageNode root, final CoverageNode changeRoot,
ChangeCoverageTableModel(final String id, final Node root, final Node changeRoot,
final RowRenderer renderer, final ColorProvider colorProvider) {
super(id, root, renderer, colorProvider);

Expand All @@ -51,18 +54,18 @@ public TableConfiguration getTableConfiguration() {
@Override
public List<Object> getRows() {
Locale browserLocale = Functions.getCurrentLocale();
return changeRoot.getAllFileCoverageNodes().stream()
return changeRoot.getAllFileNodes().stream()
.map(file -> new ChangeCoverageRow(
getOriginalNode(file), file, browserLocale, getRenderer(), getColorProvider()))
.collect(Collectors.toList());
}

private FileCoverageNode getOriginalNode(final FileCoverageNode fileNode) {
Optional<FileCoverageNode> reference = getRoot().getAllFileCoverageNodes().stream()
private FileNode getOriginalNode(final FileNode fileNode) {
return getRoot().getAllFileNodes().stream()
.filter(node -> node.getPath().equals(fileNode.getPath())
&& node.getName().equals(fileNode.getName()))
.findFirst();
return reference.orElse(fileNode); // return this as fallback to prevent exceptions
.findFirst()
.orElse(fileNode); // return this as fallback to prevent exceptions
}

/**
Expand All @@ -71,51 +74,36 @@ private FileCoverageNode getOriginalNode(final FileCoverageNode fileNode) {
* @since 3.0.0
*/
private static class ChangeCoverageRow extends CoverageRow {
private final FileCoverageNode changedFileNode;
private final FileNode originalFile;

ChangeCoverageRow(final FileCoverageNode root, final FileCoverageNode changedFileNode,
ChangeCoverageRow(final FileNode originalFile, final FileNode changedFileNode,
final Locale browserLocale, final RowRenderer renderer, final ColorProvider colorProvider) {
super(root, browserLocale, renderer, colorProvider);
super(changedFileNode, browserLocale, renderer, colorProvider);

this.changedFileNode = changedFileNode;
}

@Override
public DetailedCell<?> getLineCoverage() {
Coverage coverage = changedFileNode.getCoverage(CoverageMetric.LINE);
return createColoredCoverageColumn(coverage, "The line change coverage");
}

@Override
public DetailedCell<?> getBranchCoverage() {
Coverage coverage = changedFileNode.getCoverage(CoverageMetric.BRANCH);
return createColoredCoverageColumn(coverage, "The branch change coverage");
this.originalFile = originalFile;
}

@Override
public DetailedCell<?> getLineCoverageDelta() {
return createColoredChangeCoverageDeltaColumn(CoverageMetric.LINE);
return createColoredChangeCoverageDeltaColumn(Metric.LINE);
}

@Override
public DetailedCell<?> getBranchCoverageDelta() {
return createColoredChangeCoverageDeltaColumn(CoverageMetric.BRANCH);
return createColoredChangeCoverageDeltaColumn(Metric.BRANCH);
}

@Override
public int getLoc() {
return (int) changedFileNode.getChangedCodeLines().stream()
.filter(line -> changedFileNode.getCoveragePerLine().containsKey(line))
.count();
SortedSet<Integer> coveredDelta = getFile().getCoveredLinesOfChangeSet();
return coveredDelta.size();
}

private DetailedCell<?> createColoredChangeCoverageDeltaColumn(final CoverageMetric coverageMetric) {
Coverage changeCoverage = changedFileNode.getCoverage(coverageMetric);
private DetailedCell<?> createColoredChangeCoverageDeltaColumn(final Metric metric) {
Coverage changeCoverage = getFile().getTypedValue(metric, Coverage.nullObject(metric));
if (changeCoverage.isSet()) {
Fraction delta = changeCoverage.getCoveredFraction()
.subtract(getRoot().getCoverage(coverageMetric).getCoveredFraction());
return createColoredCoverageDeltaColumn(CoveragePercentage.valueOf(delta),
"The change coverage within the file against the total file coverage");
return createColoredCoverageDeltaColumn(metric,
changeCoverage.delta(originalFile.getTypedValue(metric, Coverage.nullObject(metric))));
}
return NO_COVERAGE;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.jenkins.plugins.coverage.model;
package io.jenkins.plugins.coverage.metrics;

import java.util.Collection;
import java.util.Comparator;
Expand All @@ -12,6 +12,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import edu.hm.hafner.metric.Node;
import edu.hm.hafner.util.FilteredLog;

import one.util.streamex.StreamEx;
Expand All @@ -20,7 +21,6 @@
import hudson.model.Run;
import hudson.model.TaskListener;

import io.jenkins.plugins.coverage.model.exception.CodeDeltaException;
import io.jenkins.plugins.forensics.delta.DeltaCalculatorFactory;
import io.jenkins.plugins.forensics.delta.model.Delta;
import io.jenkins.plugins.forensics.delta.model.FileChanges;
Expand All @@ -32,7 +32,6 @@
* @author Florian Orendi
*/
public class CodeDeltaCalculator {

static final String AMBIGUOUS_PATHS_ERROR =
"Failed to map SCM paths with coverage report paths due to ambiguous fully qualified names";
static final String AMBIGUOUS_OLD_PATHS_ERROR =
Expand Down Expand Up @@ -108,24 +107,20 @@ public Set<FileChanges> getCoverageRelevantChanges(final Delta delta) {
* the coverage reporting tools - usually the fully qualified name of the file.
*
* @param changes
* The code changes
* the code changes
* @param root
* The root of the coverage tree
* the root of the coverage tree
* @param log
* The log
* logger
*
* @return the create code changes mapping
* @return the created mapping of code changes
* @throws CodeDeltaException
* when creating the mapping failed due to ambiguous paths
*/
public Map<String, FileChanges> mapScmChangesToReportPaths(
final Set<FileChanges> changes, final CoverageNode root, final FilteredLog log) throws CodeDeltaException {
Set<String> reportPaths = root.getAllFileCoverageNodes().stream()
.map(FileCoverageNode::getPath)
.collect(Collectors.toSet());
Set<String> scmPaths = changes.stream()
.map(FileChanges::getFileName)
.collect(Collectors.toSet());
final Set<FileChanges> changes, final Node root, final FilteredLog log) throws CodeDeltaException {
Set<String> reportPaths = new HashSet<>(root.getFiles());
Set<String> scmPaths = changes.stream().map(FileChanges::getFileName).collect(Collectors.toSet());

Map<String, String> pathMapping = getScmToReportPathMapping(scmPaths, reportPaths);
verifyScmToReportPathMapping(pathMapping, log);
Expand Down Expand Up @@ -157,19 +152,17 @@ public Map<String, FileChanges> mapScmChangesToReportPaths(
* @throws CodeDeltaException
* if the SCM path mapping is ambiguous
*/
public Map<String, String> createOldPathMapping(final CoverageNode root, final CoverageNode referenceRoot,
public Map<String, String> createOldPathMapping(final Node root, final Node referenceRoot,
final Map<String, FileChanges> changes, final FilteredLog log)
throws CodeDeltaException {
Set<String> oldReportPaths = referenceRoot.getAllFileCoverageNodes().stream()
.map(FileCoverageNode::getPath)
.collect(Collectors.toSet());
Set<String> oldReportPaths = new HashSet<>(referenceRoot.getFiles());
// mapping between reference and current file paths which initially contains the SCM paths with renamings
Map<String, String> oldPathMapping = changes.entrySet().stream()
.filter(entry -> FileEditType.RENAME.equals(entry.getValue().getFileEditType()))
.collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getOldFileName()));
// the SCM paths and the coverage report paths from the reference
Map<String, String> oldScmToOldReportPathMapping =
getScmToReportPathMapping(oldPathMapping.values(), oldReportPaths);
Map<String, String> oldScmToOldReportPathMapping
= getScmToReportPathMapping(oldPathMapping.values(), oldReportPaths);

// replacing the old SCM paths with the old report paths
Set<String> newReportPathsWithRename = oldPathMapping.keySet();
Expand All @@ -182,10 +175,9 @@ public Map<String, String> createOldPathMapping(final CoverageNode root, final C
}

// adding the paths, which exist in both trees and contain no changes, to the mapping
root.getAllFileCoverageNodes().stream()
.filter(node -> !oldPathMapping.containsKey(node.getPath()) && oldReportPaths.contains(
node.getPath()))
.forEach(node -> oldPathMapping.put(node.getPath(), node.getPath()));
root.getFiles().stream()
.filter(file -> !oldPathMapping.containsKey(file) && oldReportPaths.contains(file))
.forEach(file -> oldPathMapping.put(file, file));

removeMissingReferences(oldPathMapping, log);
verifyOldPathMapping(oldPathMapping, log);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.jenkins.plugins.coverage.model.exception;
package io.jenkins.plugins.coverage.metrics;

/**
* Exception which is thrown when preprocessing the code delta failed.
Expand Down
Loading