Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-72448] Make sure that logging statements are in correct order #47

Merged
merged 1 commit into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ void perform(final Run<?, ?> run, final FilePath workspace, final TaskListener t
else {
perform(run, workspace, taskListener, resultHandler, log, logHandler);
}

}
else {
logHandler.log("Skipping execution of coverage recorder since overall result is '%s'", overallResult);
Expand All @@ -410,7 +409,7 @@ void perform(final Run<?, ?> run, final FilePath workspace, final TaskListener t

private void perform(final Run<?, ?> run, final FilePath workspace, final TaskListener taskListener,
final StageResultHandler resultHandler, final FilteredLog log, final LogHandler logHandler) throws InterruptedException {
var results = recordCoverageResults(run, workspace, taskListener, resultHandler, log);
var results = recordCoverageResults(run, workspace, resultHandler, log, logHandler);
Node aggregatedResult = aggregateResults(log, results);

if (!aggregatedResult.isEmpty()) {
Expand All @@ -424,7 +423,9 @@ private void perform(final Run<?, ?> run, final FilePath workspace, final TaskLi

var action = reporter.publishAction(getActualId(), getName(), getIcon(), aggregatedResult, run,
workspace, taskListener, getQualityGates(), getScm(),
getSourceCodeEncoding(), getSourceCodeRetention(), resultHandler);
getSourceCodeEncoding(), getSourceCodeRetention(), resultHandler, log);
logHandler.log(log);

if (!skipPublishingChecks) {
var checksPublisher = new CoverageChecksPublisher(action, aggregatedResult, getChecksName(), getChecksAnnotationScope());
checksPublisher.publishCoverageReport(taskListener);
Expand Down Expand Up @@ -462,15 +463,15 @@ private static void failStage(final StageResultHandler resultHandler, final LogH
logHandler.log(log);
}

private Map<Parser, List<ModuleNode>> recordCoverageResults(final Run<?, ?> run, final FilePath workspace, final TaskListener taskListener,
final StageResultHandler resultHandler, final FilteredLog log) throws InterruptedException {
private Map<Parser, List<ModuleNode>> recordCoverageResults(final Run<?, ?> run, final FilePath workspace,
final StageResultHandler resultHandler, final FilteredLog log, final LogHandler logHandler) throws InterruptedException {
Map<Parser, List<ModuleNode>> results = new HashMap<>();

for (CoverageTool tool : tools) {
LogHandler toolHandler = new LogHandler(taskListener, tool.getDisplayName());
Parser parser = tool.getParser();
log.logInfo("Creating parser for %s", tool.getDisplayName());
if (StringUtils.isBlank(tool.getPattern())) {
toolHandler.log("Using default pattern '%s' since user defined pattern is not set",
log.logInfo("Using default pattern '%s' since user defined pattern is not set",
parser.getDefaultPattern());
}

Expand Down Expand Up @@ -502,7 +503,7 @@ private Map<Parser, List<ModuleNode>> recordCoverageResults(final Run<?, ?> run,
log.logException(exception, "Exception while parsing with tool " + tool);
}

toolHandler.log(log);
logHandler.log(log);
}

return results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import io.jenkins.plugins.forensics.delta.FileChanges;
import io.jenkins.plugins.forensics.reference.ReferenceFinder;
import io.jenkins.plugins.prism.SourceCodeRetention;
import io.jenkins.plugins.util.LogHandler;
import io.jenkins.plugins.util.QualityGateResult;
import io.jenkins.plugins.util.StageResultHandler;

Expand All @@ -41,96 +40,131 @@
private static final List<Value> EMPTY_VALUES = List.of();

@SuppressWarnings({"checkstyle:ParameterNumber", "checkstyle:JavaNCSS"})
CoverageBuildAction publishAction(final String id, final String optionalName, final String icon, final Node rootNode,
CoverageBuildAction publishAction(final String id, final String optionalName, final String icon,
final Node rootNode,
final Run<?, ?> build, final FilePath workspace, final TaskListener listener,
final List<CoverageQualityGate> qualityGates, final String scm, final String sourceCodeEncoding,
final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler)
final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler,
final FilteredLog log)
throws InterruptedException {
FilteredLog log = new FilteredLog("Errors while reporting code coverage results:");

Optional<CoverageBuildAction> possibleReferenceResult = getReferenceBuildAction(build, id, log);

List<FileNode> filesToStore;
CoverageBuildAction action;
if (possibleReferenceResult.isPresent()) {
CoverageBuildAction referenceAction = possibleReferenceResult.get();
Node referenceRoot = referenceAction.getResult();

log.logInfo("Calculating the code delta...");
CodeDeltaCalculator codeDeltaCalculator = new CodeDeltaCalculator(build, workspace, listener, scm);
Optional<Delta> delta = codeDeltaCalculator.calculateCodeDeltaToReference(referenceAction.getOwner(), log);
delta.ifPresent(value -> createDeltaReports(rootNode, log, referenceRoot, codeDeltaCalculator, value));
action = computeCoverageBasedOnReferenceBuild(id, optionalName, icon, rootNode, build, workspace,
qualityGates, sourceCodeEncoding, sourceCodeRetention, resultHandler, possibleReferenceResult.get(),
scm,
listener,
log);
}
else {
action = computeActionWithoutHistory(id, optionalName, icon, rootNode, build, workspace, qualityGates,
sourceCodeEncoding,
sourceCodeRetention, resultHandler, log);
}

log.logInfo("Calculating coverage deltas...");
build.addAction(action);
return action;
}

Node modifiedLinesCoverageRoot = rootNode.filterByModifiedLines();
@SuppressWarnings("checkstyle:ParameterNumber")
private CoverageBuildAction computeActionWithoutHistory(
final String id, final String optionalName, final String icon,
final Node rootNode, final Run<?, ?> build, final FilePath workspace,
final List<CoverageQualityGate> qualityGates, final String sourceCodeEncoding,
final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler,
final FilteredLog log) throws InterruptedException {

Check warning on line 76 in plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java

View check run for this annotation

ci.jenkins.io / CPD

CPD

LOW: Found duplicated code.
Raw output
<pre><code>private CoverageBuildAction computeActionWithoutHistory( final String id, final String optionalName, final String icon, final Node rootNode, final Run&lt;?, ?&gt; build, final FilePath workspace, final List&lt;CoverageQualityGate&gt; qualityGates, final String sourceCodeEncoding, final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler, final FilteredLog log) throws InterruptedException {<!-- --></code></pre>
var statistics = new CoverageStatistics(rootNode.aggregateValues(),
EMPTY_DELTA, EMPTY_VALUES, EMPTY_DELTA, EMPTY_VALUES, EMPTY_DELTA);
QualityGateResult qualityGateStatus = evaluateQualityGates(qualityGates,
statistics, resultHandler, log);

paintSourceFiles(build, workspace, sourceCodeEncoding, sourceCodeRetention, id, rootNode,
rootNode.getAllFileNodes(), log);

return new CoverageBuildAction(build, id, optionalName, icon, rootNode, qualityGateStatus, log);
}

NavigableMap<Metric, Fraction> modifiedLinesDelta;
List<Value> modifiedFilesValues;
NavigableMap<Metric, Fraction> modifiedFilesDelta;
if (hasModifiedLinesCoverage(modifiedLinesCoverageRoot)) {
Node modifiedFilesCoverageRoot = rootNode.filterByModifiedFiles();
modifiedFilesValues = modifiedFilesCoverageRoot.aggregateValues();
modifiedFilesDelta = modifiedFilesCoverageRoot.computeDelta(
referenceRoot.filterByFileNames(modifiedFilesCoverageRoot.getFiles()));
@SuppressWarnings("checkstyle:ParameterNumber")
private CoverageBuildAction computeCoverageBasedOnReferenceBuild(
final String id, final String optionalName, final String icon,
final Node rootNode, final Run<?, ?> build, final FilePath workspace,
final List<CoverageQualityGate> qualityGates, final String sourceCodeEncoding,
final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler,
final CoverageBuildAction referenceAction, final String scm,

Check warning on line 94 in plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java

View check run for this annotation

ci.jenkins.io / CPD

CPD

LOW: Found duplicated code.
Raw output
<pre><code>private CoverageBuildAction computeActionWithoutHistory( final String id, final String optionalName, final String icon, final Node rootNode, final Run&lt;?, ?&gt; build, final FilePath workspace, final List&lt;CoverageQualityGate&gt; qualityGates, final String sourceCodeEncoding, final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler, final FilteredLog log) throws InterruptedException {<!-- --></code></pre>
final TaskListener listener, final FilteredLog log) throws InterruptedException {
log.logInfo("Calculating the code delta...");
CodeDeltaCalculator codeDeltaCalculator = new CodeDeltaCalculator(build, workspace, listener, scm);
Optional<Delta> delta = codeDeltaCalculator.calculateCodeDeltaToReference(referenceAction.getOwner(), log);

Node referenceRoot = referenceAction.getResult();
delta.ifPresent(value -> createDeltaReports(rootNode, log, referenceRoot, codeDeltaCalculator, value));

log.logInfo("Calculating coverage deltas...");

Node modifiedLinesCoverageRoot = rootNode.filterByModifiedLines();

NavigableMap<Metric, Fraction> modifiedLinesDelta;
List<Value> modifiedFilesValues;
NavigableMap<Metric, Fraction> modifiedFilesDelta;
if (hasModifiedLinesCoverage(modifiedLinesCoverageRoot)) {
Node modifiedFilesCoverageRoot = rootNode.filterByModifiedFiles();
modifiedFilesValues = modifiedFilesCoverageRoot.aggregateValues();
modifiedFilesDelta = modifiedFilesCoverageRoot.computeDelta(
referenceRoot.filterByFileNames(modifiedFilesCoverageRoot.getFiles()));

modifiedLinesDelta = modifiedLinesCoverageRoot.computeDelta(modifiedFilesCoverageRoot);
}
else {
modifiedLinesDelta = EMPTY_DELTA;
modifiedFilesValues = EMPTY_VALUES;
modifiedFilesDelta = EMPTY_DELTA;

modifiedLinesDelta = modifiedLinesCoverageRoot.computeDelta(modifiedFilesCoverageRoot);
if (rootNode.hasModifiedLines()) {
log.logInfo("No detected code changes affect the code coverage");

Check warning on line 124 in plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java

View check run for this annotation

Codecov / codecov/patch

plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java#L124

Added line #L124 was not covered by tests
}
else {
modifiedLinesDelta = EMPTY_DELTA;
modifiedFilesValues = EMPTY_VALUES;
modifiedFilesDelta = EMPTY_DELTA;
}

if (rootNode.hasModifiedLines()) {
log.logInfo("No detected code changes affect the code coverage");
}
}
var overallValues = rootNode.aggregateValues();
NavigableMap<Metric, Fraction> overallDelta = rootNode.computeDelta(referenceRoot);
var modifiedLinesValues = modifiedLinesCoverageRoot.aggregateValues();

var overallValues = rootNode.aggregateValues();
NavigableMap<Metric, Fraction> overallDelta = rootNode.computeDelta(referenceRoot);
var modifiedLinesValues = modifiedLinesCoverageRoot.aggregateValues();
var statistics = new CoverageStatistics(overallValues, overallDelta,
modifiedLinesValues, modifiedLinesDelta, modifiedFilesValues, modifiedFilesDelta);
QualityGateResult qualityGateResult = evaluateQualityGates(qualityGates, statistics, resultHandler, log);

var statistics = new CoverageStatistics(overallValues, overallDelta,
modifiedLinesValues, modifiedLinesDelta, modifiedFilesValues, modifiedFilesDelta);
QualityGateResult qualityGateResult = evaluateQualityGates(qualityGates, statistics, resultHandler, log);
var filesToStore = computePaintedFiles(rootNode, sourceCodeRetention, log, modifiedLinesCoverageRoot);
paintSourceFiles(build, workspace, sourceCodeEncoding, sourceCodeRetention, id, rootNode, filesToStore, log);

if (sourceCodeRetention == SourceCodeRetention.MODIFIED) {
filesToStore = modifiedLinesCoverageRoot.getAllFileNodes();
log.logInfo("-> Selecting %d modified files for source code painting", filesToStore.size());
}
else {
filesToStore = rootNode.getAllFileNodes();
}
return new CoverageBuildAction(build, id, optionalName, icon, rootNode, qualityGateResult, log,
referenceAction.getOwner().getExternalizableId(), overallDelta,
modifiedLinesValues, modifiedLinesDelta,
modifiedFilesValues, modifiedFilesDelta,
rootNode.filterByIndirectChanges().aggregateValues());
}

action = new CoverageBuildAction(build, id, optionalName, icon, rootNode, qualityGateResult, log,
referenceAction.getOwner().getExternalizableId(), overallDelta,
modifiedLinesValues, modifiedLinesDelta,
modifiedFilesValues, modifiedFilesDelta,
rootNode.filterByIndirectChanges().aggregateValues());
private List<FileNode> computePaintedFiles(final Node rootNode, final SourceCodeRetention sourceCodeRetention,
final FilteredLog log, final Node modifiedLinesCoverageRoot) {
List<FileNode> filesToStore;
if (sourceCodeRetention == SourceCodeRetention.MODIFIED) {
filesToStore = modifiedLinesCoverageRoot.getAllFileNodes();
log.logInfo("-> Selecting %d modified files for source code painting", filesToStore.size());
}
else {
var statistics = new CoverageStatistics(rootNode.aggregateValues(),
EMPTY_DELTA, EMPTY_VALUES, EMPTY_DELTA, EMPTY_VALUES, EMPTY_DELTA);
QualityGateResult qualityGateStatus = evaluateQualityGates(qualityGates,
statistics, resultHandler, log);

filesToStore = rootNode.getAllFileNodes();

action = new CoverageBuildAction(build, id, optionalName, icon, rootNode, qualityGateStatus, log);
}
return filesToStore;
}

@SuppressWarnings("checkstyle:ParameterNumber")
private void paintSourceFiles(final Run<?, ?> build, final FilePath workspace, final String sourceCodeEncoding,
final SourceCodeRetention sourceCodeRetention, final String id, final Node rootNode,
final List<FileNode> filesToStore, final FilteredLog log) throws InterruptedException {
log.logInfo("Executing source code painting...");
SourceCodePainter sourceCodePainter = new SourceCodePainter(build, workspace, id);
sourceCodePainter.processSourceCodePainting(rootNode, filesToStore,
sourceCodeEncoding, sourceCodeRetention, log);

log.logInfo("Finished coverage processing - adding the action to the build...");

LogHandler logHandler = new LogHandler(listener, "Coverage");
logHandler.log(log);

build.addAction(action);
return action;
}

private void createDeltaReports(final Node rootNode, final FilteredLog log, final Node referenceRoot,
Expand Down Expand Up @@ -198,7 +232,8 @@
return ((edu.hm.hafner.coverage.Coverage) value).isSet();
}

private Optional<CoverageBuildAction> getReferenceBuildAction(final Run<?, ?> build, final String id, final FilteredLog log) {
private Optional<CoverageBuildAction> getReferenceBuildAction(final Run<?, ?> build, final String id,
final FilteredLog log) {
log.logInfo("Obtaining action of reference build");

ReferenceFinder referenceFinder = new ReferenceFinder();
Expand Down Expand Up @@ -236,7 +271,8 @@
return Optional.of(referenceAction);
}

private Optional<CoverageBuildAction> getPreviousResult(final String id, @CheckForNull final Run<?, ?> startSearch) {
private Optional<CoverageBuildAction> getPreviousResult(final String id,
@CheckForNull final Run<?, ?> startSearch) {
for (Run<?, ?> build = startSearch; build != null; build = build.getPreviousBuild()) {
List<CoverageBuildAction> actions = build.getActions(CoverageBuildAction.class);
for (CoverageBuildAction action : actions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import edu.hm.hafner.coverage.Percentage;
import edu.hm.hafner.echarts.LabeledTreeMapNode;
import edu.hm.hafner.util.FilteredLog;
import edu.hm.hafner.util.VisibleForTesting;
import edu.umd.cs.findbugs.annotations.CheckForNull;

import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -117,6 +118,11 @@
this.trendChartFunction = trendChartFunction;
}

@VisibleForTesting
FilteredLog getLog() {
return log;

Check warning on line 123 in plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 123 is not covered by tests

Check warning on line 123 in plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java

View check run for this annotation

Codecov / codecov/patch

plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java#L123

Added line #L123 was not covered by tests
}

public String getId() {
return id;
}
Expand Down Expand Up @@ -440,16 +446,16 @@
}

/**
* Returns a new sub-page for the selected link.
* Returns a new subpage for the selected link.
*
* @param link
* the link to identify the sub-page to show
* the link to identify the subpage to show
* @param request
* Stapler request
* @param response
* Stapler response
*
* @return the new sub-page
* @return the new subpage
*/
@SuppressWarnings("unused") // Called by jelly view
@CheckForNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ else if (sourceDirectories.size() == 1) {
mapping.size(), relativePaths.size() - mapping.size());
}

var changedFilesMapping = mapping.entrySet()
var changedFileMapping = mapping.entrySet()
.stream()
.filter(entry -> !entry.getKey().equals(entry.getValue()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
var result = new RemoteResultWrapper<>(new HashMap<>(changedFilesMapping), "Errors during source path resolving:");
var result = new RemoteResultWrapper<>(new HashMap<>(changedFileMapping), "Errors during source path resolving:");
result.merge(log);
return result;
}
Expand All @@ -149,7 +149,6 @@ private Set<String> filterSourceDirectories(final File workspace, final Filtered

private Optional<String> locateSource(final String relativePath, final FilePath workspace,
final Set<String> sourceSearchDirectories, final FilteredLog log) {

try {
FilePath absolutePath = new FilePath(new File(relativePath));
if (absolutePath.exists()) {
Expand Down
Loading
Loading