diff --git a/plugin/pom.xml b/plugin/pom.xml index ecc47ed21b..0f0e77611b 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -4,7 +4,7 @@ org.jvnet.hudson.plugins analysis-pom - 6.17.0 + 7.1.0 @@ -41,8 +41,8 @@ 1.19.3 - 2.4.0-rc1560.b_4b_993ec6a_9f - 2.1.0-20240205.180020-1 + 2.4.0-rc1561.1f746b_248f63 + 2.1.0-20240207.074913-2 3.22 1.84 diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/AnalysisHistory.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/AnalysisHistory.java index 8e536222bd..0dcf507200 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/AnalysisHistory.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/AnalysisHistory.java @@ -9,22 +9,17 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; -import hudson.model.Result; import hudson.model.Run; import io.jenkins.plugins.analysis.core.charts.JenkinsBuild; import io.jenkins.plugins.analysis.core.util.AnalysisBuildResult; -import static io.jenkins.plugins.analysis.core.model.AnalysisHistory.JobResultEvaluationMode.*; -import static io.jenkins.plugins.analysis.core.model.AnalysisHistory.QualityGateEvaluationMode.*; - /** * Provides a history of static analysis results. The history starts from a baseline build and provides access to a * historical build result of the same type (or to all historical results using the provided {@link * AnalysisResultIterator interator} implementation). The results are filtered by a {@link ResultSelector}, so a history - * returns only results of the same type. This history can be configured to ignore the overall result of the associated - * Jenkins builds (see {@link JobResultEvaluationMode JobResultEvaluationMode}). Additionally, this history can be - * configured to ignore the builds that did not pass the quality gate (see {@link QualityGateEvaluationMode + * returns only results of the same type. This history can be configured to ignore the builds that did not pass the quality + * gate (see {@link QualityGateEvaluationMode * QualityGateEvaluationMode}). Note that the baseline run might still be in progress and thus has not yet a result * attached: i.e., the result of the {@code getPrevious*} methods may return different results on subsequent calls. * @@ -38,46 +33,8 @@ public class AnalysisHistory implements History { /** Selects a result of the same type. */ private final ResultSelector selector; - private final QualityGateEvaluationMode qualityGateEvaluationMode; - private final JobResultEvaluationMode jobResultEvaluationMode; - - /** - * Determines how the evaluation of the quality gates is taken into account when the previous result is - * searched for. - */ - public enum QualityGateEvaluationMode { - /** - * The quality gate result is ignored. The previous build with results of the same type is selected. - */ - IGNORE_QUALITY_GATE, - /** - * The quality gate result must be successful. I.e., the history is searched for a - * build that either passed the quality gate or has deactivated the quality gate. - */ - SUCCESSFUL_QUALITY_GATE - } - /** - * Determines how the overall build {@link Result} of the {@link Run} is taken into account when the previous result - * is searched for. - */ - public enum JobResultEvaluationMode { - /** - * Only those jobs are considered that did not fail. I.e., jobs with result {@link Result#UNSTABLE} or {@link - * Result#SUCCESS}. - */ - NO_JOB_FAILURE, - - /** - * All jobs are considered regardless of the result. If the job has an overall result of {@link Result#FAILURE} - * then it will be considered as well. - */ - IGNORE_JOB_RESULT - } - - /** - * Creates a new instance of {@link AnalysisHistory}. This history ignores the results of the - * quality gate and the {@link Result} of the associated {@link Run}. + * Creates a new instance of {@link AnalysisHistory}. * * @param baseline * the build to start the history from @@ -85,34 +42,8 @@ public enum JobResultEvaluationMode { * selects the associated action from a build */ public AnalysisHistory(final Run baseline, final ResultSelector selector) { - this(baseline, selector, IGNORE_QUALITY_GATE, IGNORE_JOB_RESULT); - } - - /** - * Creates a new instance of {@link AnalysisHistory}. - * - * @param baseline - * the run to start the history from - * @param selector - * selects the type of the result (to get a result for the same type of static analysis) - * @param qualityGateEvaluationMode - * If set to {@link QualityGateEvaluationMode#IGNORE_QUALITY_GATE}, then the result of the quality gate is - * ignored when selecting a reference build. If set to {@link QualityGateEvaluationMode#SUCCESSFUL_QUALITY_GATE} - * a failing quality gate will be passed from build to build until the original reason for the failure has - * been resolved. - * @param jobResultEvaluationMode - * If set to {@link JobResultEvaluationMode#NO_JOB_FAILURE}, then only successful or unstable reference - * builds will be considered (since analysis results might be inaccurate if the build failed). If set to - * {@link JobResultEvaluationMode#IGNORE_JOB_RESULT}, then every build that contains a static analysis - * result is considered, even if the build failed. - */ - public AnalysisHistory(final Run baseline, final ResultSelector selector, - final QualityGateEvaluationMode qualityGateEvaluationMode, - final JobResultEvaluationMode jobResultEvaluationMode) { this.baseline = baseline; this.selector = selector; - this.qualityGateEvaluationMode = qualityGateEvaluationMode; - this.jobResultEvaluationMode = jobResultEvaluationMode; } @Override @@ -141,46 +72,24 @@ public Report getIssues() { } private Optional getPreviousAction() { - Optional> run = getRunWithResult(baseline, selector, qualityGateEvaluationMode, - jobResultEvaluationMode); + Optional> run = getRunWithResult(baseline, selector); if (run.isPresent()) { return selector.get(run.get()); } return Optional.empty(); } - private static Optional> getRunWithResult(final @CheckForNull Run start, - final ResultSelector selector, - final QualityGateEvaluationMode qualityGateEvaluationMode, - final JobResultEvaluationMode jobResultEvaluationMode) { + private static Optional> getRunWithResult( + final @CheckForNull Run start, final ResultSelector selector) { for (Run run = start; run != null; run = run.getPreviousBuild()) { Optional action = selector.get(run); if (action.isPresent()) { - ResultAction resultAction = action.get(); - if (hasCorrectJobResult(run, jobResultEvaluationMode) - && hasCorrectQualityGateStatus(resultAction, qualityGateEvaluationMode)) { - return Optional.of(run); - } + return Optional.of(run); } } return Optional.empty(); } - private static boolean hasCorrectQualityGateStatus(final ResultAction action, - final QualityGateEvaluationMode qualityGateEvaluationMode) { - return action.isSuccessful() || qualityGateEvaluationMode == IGNORE_QUALITY_GATE; - } - - private static boolean hasCorrectJobResult(final Run run, - final JobResultEvaluationMode jobResultEvaluationMode) { - if (jobResultEvaluationMode == NO_JOB_FAILURE) { - Result result = run.getResult(); - - return result != null && result.isBetterThan(Result.FAILURE); - } - return true; - } - @Override public boolean hasMultipleResults() { Iterator> iterator = iterator(); @@ -195,7 +104,7 @@ public boolean hasMultipleResults() { @Override public String toString() { - return String.format("%s - %s", jobResultEvaluationMode, qualityGateEvaluationMode); + return String.format("%s - %s", baseline.getFullDisplayName(), selector); } @Override @@ -221,7 +130,7 @@ private static class AnalysisResultIterator implements Iterator baseline, final ResultSelector selector) { - cursor = getRunWithResult(baseline, selector, IGNORE_QUALITY_GATE, IGNORE_JOB_RESULT); + cursor = getRunWithResult(baseline, selector); this.selector = selector; } @@ -236,7 +145,7 @@ public BuildResult next() { Run run = cursor.get(); Optional resultAction = selector.get(run); - cursor = getRunWithResult(run.getPreviousBuild(), selector, IGNORE_QUALITY_GATE, IGNORE_JOB_RESULT); + cursor = getRunWithResult(run.getPreviousBuild(), selector); if (resultAction.isPresent()) { return new BuildResult<>(new JenkinsBuild(run), resultAction.get().getResult()); diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/QualityGateEvaluationMode.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/QualityGateEvaluationMode.java new file mode 100644 index 0000000000..5590484eef --- /dev/null +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/model/QualityGateEvaluationMode.java @@ -0,0 +1,16 @@ +package io.jenkins.plugins.analysis.core.model; + +/** + * Determines how the evaluation of the quality gates is taken into account when the previous result is searched for. + */ +public enum QualityGateEvaluationMode { + /** + * The quality gate result is ignored. The previous build with results of the same type is selected. + */ + IGNORE_QUALITY_GATE, + /** + * The quality gate result must be successful. I.e., the history is searched for a build that either passed the + * quality gate or has deactivated the quality gate. + */ + SUCCESSFUL_QUALITY_GATE +} diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesPublisher.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesPublisher.java index 4b1cf57379..8c5d2e5b74 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesPublisher.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesPublisher.java @@ -12,13 +12,10 @@ import io.jenkins.plugins.analysis.core.model.AggregationAction; import io.jenkins.plugins.analysis.core.model.AnalysisHistory; -import io.jenkins.plugins.analysis.core.model.AnalysisHistory.JobResultEvaluationMode; -import io.jenkins.plugins.analysis.core.model.AnalysisHistory.QualityGateEvaluationMode; import io.jenkins.plugins.analysis.core.model.AnalysisResult; import io.jenkins.plugins.analysis.core.model.ByIdResultSelector; import io.jenkins.plugins.analysis.core.model.DeltaReport; -import io.jenkins.plugins.analysis.core.model.History; -import io.jenkins.plugins.analysis.core.model.NullAnalysisHistory; +import io.jenkins.plugins.analysis.core.model.QualityGateEvaluationMode; import io.jenkins.plugins.analysis.core.model.ResetReferenceAction; import io.jenkins.plugins.analysis.core.model.ResultAction; import io.jenkins.plugins.analysis.core.model.ResultSelector; @@ -26,13 +23,13 @@ import io.jenkins.plugins.analysis.core.util.TrendChartType; import io.jenkins.plugins.analysis.core.util.WarningsQualityGate; import io.jenkins.plugins.analysis.core.util.WarningsQualityGateEvaluator; +import io.jenkins.plugins.forensics.reference.ReferenceBuild; import io.jenkins.plugins.forensics.reference.ReferenceFinder; import io.jenkins.plugins.util.LogHandler; import io.jenkins.plugins.util.QualityGateResult; import io.jenkins.plugins.util.ResultHandler; -import static io.jenkins.plugins.analysis.core.model.AnalysisHistory.JobResultEvaluationMode.*; -import static io.jenkins.plugins.analysis.core.model.AnalysisHistory.QualityGateEvaluationMode.*; +import static io.jenkins.plugins.analysis.core.model.QualityGateEvaluationMode.*; /** * Publishes issues: Stores the created issues in an {@link AnalysisResult}. The result is attached to the {@link Run} @@ -49,7 +46,6 @@ class IssuesPublisher { private final Charset sourceCodeEncoding; private final List qualityGates; private final QualityGateEvaluationMode qualityGateEvaluationMode; - private final JobResultEvaluationMode jobResultEvaluationMode; private final LogHandler logger; private final ResultHandler notifier; private final boolean failOnErrors; @@ -57,9 +53,8 @@ class IssuesPublisher { @SuppressWarnings("ParameterNumber") IssuesPublisher(final Run run, final AnnotatedReport report, final HealthDescriptor healthDescriptor, final List qualityGates, - final String name, final boolean ignoreQualityGate, final boolean ignoreFailedBuilds, - final Charset sourceCodeEncoding, final LogHandler logger, - final ResultHandler notifier, final boolean failOnErrors) { + final String name, final boolean ignoreQualityGate, final Charset sourceCodeEncoding, + final LogHandler logger, final ResultHandler notifier, final boolean failOnErrors) { this.report = report; this.run = run; this.healthDescriptor = healthDescriptor; @@ -67,7 +62,6 @@ class IssuesPublisher { this.sourceCodeEncoding = sourceCodeEncoding; this.qualityGates = qualityGates; qualityGateEvaluationMode = ignoreQualityGate ? IGNORE_QUALITY_GATE : SUCCESSFUL_QUALITY_GATE; - jobResultEvaluationMode = ignoreFailedBuilds ? NO_JOB_FAILURE : IGNORE_JOB_RESULT; this.logger = logger; this.notifier = notifier; this.failOnErrors = failOnErrors; @@ -87,17 +81,8 @@ private String getId() { * @return the created result action */ ResultAction attachAction(final TrendChartType trendChartType) { - ResultSelector selector = ensureThatIdIsUnique(); - Report issues = report.getReport(); - var history = createAnalysisHistory(selector, issues); - DeltaReport deltaReport; - if (history.getBuild().isPresent()) { - deltaReport = new DeltaReport(issues, history.getBuild().get(), run.getNumber(), history.getIssues()); - } - else { - deltaReport = new DeltaReport(issues, run.getNumber()); - } + var deltaReport = computeDelta(issues); QualityGateResult qualityGateResult = evaluateQualityGate(issues, deltaReport); reportHealth(issues); @@ -121,7 +106,7 @@ ResultAction attachAction(final TrendChartType trendChartType) { logger.logInfoMessages(issues.getInfoMessages()); logger.logErrorMessages(issues.getErrorMessages()); - AnalysisResult result = new AnalysisHistory(run, selector).getResult() + AnalysisResult result = new AnalysisHistory(run, ensureThatIdIsUnique()).getResult() .map(previous -> new AnalysisResult(run, getId(), deltaReport, report.getBlames(), report.getStatistics(), qualityGateResult, report.getSizeOfOrigin(), previous)) @@ -138,6 +123,20 @@ ResultAction attachAction(final TrendChartType trendChartType) { return action; } + private DeltaReport computeDelta(final Report issues) { + ResultSelector selector = ensureThatIdIsUnique(); + var possibleReferenceBuild = findReferenceBuild(selector, issues); + if (possibleReferenceBuild.isPresent()) { + Run build = possibleReferenceBuild.get(); + var resultAction = selector.get(build) + .orElseThrow(() -> new IllegalStateException("Reference build does not contain a result action")); + return new DeltaReport(issues, build, run.getNumber(), resultAction.getResult().getIssues()); + } + else { + return new DeltaReport(issues, run.getNumber()); + } + } + private ResultSelector ensureThatIdIsUnique() { ResultSelector selector = new ByIdResultSelector(getId()); Optional other = selector.get(run); @@ -170,22 +169,67 @@ private QualityGateResult evaluateQualityGate(final Report issues, final DeltaRe return qualityGateStatus; } - private History createAnalysisHistory(final ResultSelector selector, final Report issues) { - var reference = findReference(issues); + private Optional> findReferenceBuild(final ResultSelector selector, final Report logger) { + FilteredLog log = new FilteredLog("Errors while resolving the reference build:"); + var reference = new ReferenceFinder().findReference(run, log); + logger.mergeLogMessages(log); + if (reference.isPresent()) { - return new AnalysisHistory(reference.get(), selector, - determineQualityGateEvaluationMode(issues), jobResultEvaluationMode); + return refineReferenceBasedOnQualityGate(selector, logger, reference.get()); } - else { - return new NullAnalysisHistory(); + return Optional.empty(); + } + + private Optional> refineReferenceBasedOnQualityGate(final ResultSelector selector, final Report issues, + final Run reference) { + boolean isSkipped = false; + var gateEvaluationMode = determineQualityGateEvaluationMode(issues); + for (Run r = reference; r != null; r = r.getPreviousBuild()) { + var result = r.getResult(); + if (result != null && result.isBetterOrEqualTo(getRequiredResult())) { + var displayName = r.getFullDisplayName(); + Optional action = selector.get(r); + if (action.isPresent()) { + ResultAction resultAction = action.get(); + if (resultAction.isSuccessful()) { + issues.logInfo( + "Quality gate successful for reference build '%s', using this build as reference", + displayName); + return Optional.of(r); + } + if (gateEvaluationMode == IGNORE_QUALITY_GATE) { + issues.logInfo( + "Quality gate has been missed for reference build '%s', but is configured to be ignored", + displayName); + return Optional.of(r); + } + if (!isSkipped) { + issues.logInfo("Quality gate failed for reference build '%s', analyzing previous builds", + displayName); + isSkipped = true; + } + } + else { + if (!isSkipped) { + issues.logInfo( + "Reference build '%s' does not contain a result action, analyzing previous builds", + displayName); + isSkipped = true; + } + } + } } + issues.logInfo("No reference build with successful quality gate found, skipping delta computation"); + + return Optional.empty(); } - private Optional> findReference(final Report issues) { - FilteredLog log = new FilteredLog("Errors while resolving the reference build:"); - Optional> reference = new ReferenceFinder().findReference(run, log); - issues.mergeLogMessages(log); - return reference; + private Result getRequiredResult() { + ReferenceBuild action = run.getAction(ReferenceBuild.class); + if (action == null) { + return Result.UNSTABLE; + } + return action.getRequiredResult(); } private QualityGateEvaluationMode determineQualityGateEvaluationMode(final Report filtered) { diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java index a4c454f258..914670ff27 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java @@ -97,7 +97,6 @@ public class IssuesRecorder extends Recorder { private SourceCodeRetention sourceCodeRetention = SourceCodeRetention.EVERY_BUILD; private boolean ignoreQualityGate = false; // by default, a successful quality gate is mandatory; - private boolean ignoreFailedBuilds = true; // by default, failed builds are ignored; private boolean failOnError = false; @@ -511,24 +510,6 @@ public boolean getIgnoreQualityGate() { return ignoreQualityGate; } - /** - * If {@code true}, then only successful or unstable reference builds will be considered. This option is enabled by - * default, since analysis results might be inaccurate if the build failed. If {@code false}, every build that - * contains a static analysis result is considered, even if the build failed. - * - * @param ignoreFailedBuilds - * if {@code true} then a stable build is used as reference - */ - @DataBoundSetter - public void setIgnoreFailedBuilds(final boolean ignoreFailedBuilds) { - this.ignoreFailedBuilds = ignoreFailedBuilds; - } - - @SuppressWarnings("PMD.BooleanGetMethodName") - public boolean getIgnoreFailedBuilds() { - return ignoreFailedBuilds; - } - public int getHealthy() { return healthy; } @@ -747,8 +728,7 @@ AnalysisResult publishResult(final Run run, final TaskListener listener, f IssuesPublisher publisher = new IssuesPublisher(run, annotatedReport, new HealthDescriptor(healthy, unhealthy, minimumSeverity), qualityGates, - reportName, ignoreQualityGate, ignoreFailedBuilds, - getSourceCodeCharset(), logHandler, resultHandler, failOnError); + reportName, ignoreQualityGate, getSourceCodeCharset(), logHandler, resultHandler, failOnError); ResultAction action = publisher.attachAction(trendChartType); if (!skipPublishingChecks) { diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java index 2f41e08ceb..c49e45d372 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java @@ -55,9 +55,6 @@ public class PublishIssuesStep extends Step implements Serializable { private String sourceCodeEncoding = StringUtils.EMPTY; private boolean ignoreQualityGate = false; // by default, a successful quality gate is mandatory - private boolean ignoreFailedBuilds = true; // by default, failed builds are ignored - private String referenceJobName = StringUtils.EMPTY; - private final String referenceBuildId = StringUtils.EMPTY; private boolean failOnError = false; // by default, it should not fail on error private boolean skipPublishingChecks; // by default, warnings should be published to SCM platforms @@ -203,25 +200,6 @@ public boolean getIgnoreQualityGate() { return ignoreQualityGate; } - /** - * If {@code true}, then only successful or unstable reference builds will be considered. This option is enabled by - * default, since analysis results might be inaccurate if the build failed. If {@code false}, every build that - * contains a static analysis result is considered, even if the build failed. - * - * @param ignoreFailedBuilds - * if {@code true} then a stable build is used as reference - */ - @DataBoundSetter - @SuppressWarnings("unused") // Used by Stapler - public void setIgnoreFailedBuilds(final boolean ignoreFailedBuilds) { - this.ignoreFailedBuilds = ignoreFailedBuilds; - } - - @SuppressWarnings({"PMD.BooleanGetMethodName", "WeakerAccess"}) - public boolean getIgnoreFailedBuilds() { - return ignoreFailedBuilds; - } - /** * If {@code true}, then logger content is muted * If {@code false}, then logger content goes to loghandler output. @@ -239,20 +217,6 @@ public boolean isQuiet() { return quiet; } - /** - * Sets the reference job to get the results for the issue difference computation. - * - * @param referenceJobName - * the name of reference job - */ - @DataBoundSetter - public void setReferenceJobName(final String referenceJobName) { - if (IssuesRecorder.NO_REFERENCE_DEFINED.equals(referenceJobName)) { - this.referenceJobName = StringUtils.EMPTY; - } - this.referenceJobName = referenceJobName; - } - @CheckForNull public String getSourceCodeEncoding() { return sourceCodeEncoding; @@ -411,8 +375,7 @@ protected ResultAction run() throws IOException, InterruptedException, IllegalSt IssuesPublisher publisher = new IssuesPublisher(getRun(), report, new HealthDescriptor(step.getHealthy(), step.getUnhealthy(), step.getMinimumSeverityAsSeverity()), step.getQualityGates(), - StringUtils.defaultString(step.getName()), - step.getIgnoreQualityGate(), step.getIgnoreFailedBuilds(), + StringUtils.defaultString(step.getName()), step.getIgnoreQualityGate(), getCharset(step.getSourceCodeEncoding()), getLogger(report), notifier, step.getFailOnError()); ResultAction action = publisher.attachAction(step.getTrendChartType()); diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java index cdc98e808a..9782affe61 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java @@ -74,8 +74,6 @@ public class RecordIssuesStep extends Step implements Serializable { private SourceCodeRetention sourceCodeRetention = SourceCodeRetention.EVERY_BUILD; private boolean ignoreQualityGate = false; // by default, a successful quality gate is mandatory; - private boolean ignoreFailedBuilds = true; // by default, failed builds are ignored; - private final String referenceBuildId = StringUtils.EMPTY; private int healthy; private int unhealthy; @@ -470,24 +468,6 @@ public boolean getIgnoreQualityGate() { return ignoreQualityGate; } - /** - * If {@code true}, then only successful or unstable reference builds will be considered. This option is enabled by - * default, since analysis results might be inaccurate if the build failed. If {@code false}, every build that - * contains a static analysis result is considered, even if the build failed. - * - * @param ignoreFailedBuilds - * if {@code true} then a stable build is used as reference - */ - @DataBoundSetter - public void setIgnoreFailedBuilds(final boolean ignoreFailedBuilds) { - this.ignoreFailedBuilds = ignoreFailedBuilds; - } - - @SuppressWarnings("PMD.BooleanGetMethodName") - public boolean getIgnoreFailedBuilds() { - return ignoreFailedBuilds; - } - /** * Determines whether to fail the step on errors during the step of recording issues. * @@ -602,7 +582,6 @@ protected List run() throws IOException, InterruptedException { recorder.setTools(step.getTools()); recorder.setSourceCodeEncoding(step.getSourceCodeEncoding()); recorder.setIgnoreQualityGate(step.getIgnoreQualityGate()); - recorder.setIgnoreFailedBuilds(step.getIgnoreFailedBuilds()); recorder.setHealthy(step.getHealthy()); recorder.setUnhealthy(step.getUnhealthy()); recorder.setMinimumSeverity(step.getMinimumSeverity()); diff --git a/plugin/src/test/java/io/jenkins/plugins/analysis/core/model/AnalysisHistoryTest.java b/plugin/src/test/java/io/jenkins/plugins/analysis/core/model/AnalysisHistoryTest.java index 07036d88d0..2c0dd1143a 100644 --- a/plugin/src/test/java/io/jenkins/plugins/analysis/core/model/AnalysisHistoryTest.java +++ b/plugin/src/test/java/io/jenkins/plugins/analysis/core/model/AnalysisHistoryTest.java @@ -15,16 +15,12 @@ import hudson.model.Result; import hudson.model.Run; -import io.jenkins.plugins.analysis.core.model.AnalysisHistory.JobResultEvaluationMode; -import io.jenkins.plugins.analysis.core.model.AnalysisHistory.QualityGateEvaluationMode; import io.jenkins.plugins.analysis.core.util.WarningsQualityGate; import io.jenkins.plugins.analysis.core.util.WarningsQualityGate.QualityGateType; import io.jenkins.plugins.util.QualityGate.QualityGateCriticality; import io.jenkins.plugins.util.QualityGateResult; import io.jenkins.plugins.util.QualityGateStatus; -import static io.jenkins.plugins.analysis.core.model.AnalysisHistory.JobResultEvaluationMode.*; -import static io.jenkins.plugins.analysis.core.model.AnalysisHistory.QualityGateEvaluationMode.*; import static io.jenkins.plugins.analysis.core.model.AnalysisHistoryTest.ExpectedResult.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -122,41 +118,14 @@ void baselineResultIsPreviousResultIfAlreadySet() { @DisplayName("Ignore job result + ignore quality gate -> history with one previous build") void shouldTestFirstIterationOfLoopIgnoreStatusAndResult(final String name, final ExpectedResult expectedResult, final QualityGateResult qualityGateStatus, final Result jobStatus) { - runTest(IGNORE_QUALITY_GATE, IGNORE_JOB_RESULT, qualityGateStatus, jobStatus, expectedResult); + runTest(qualityGateStatus, jobStatus, expectedResult); } - @ParameterizedTest(name = "{0}") - @MethodSource("createTestDataForIgnoredQualityGateAndNoFailedBuild") - @DisplayName("No job failure + ignore quality gate -> history with one previous build") - void shouldTestFirstIterationOfLoopIgnoreStatus(final String name, - final ExpectedResult expectedResult, final QualityGateResult qualityGateStatus, final Result jobStatus) { - runTest(IGNORE_QUALITY_GATE, NO_JOB_FAILURE, qualityGateStatus, jobStatus, expectedResult); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("createTestDataForSuccessfulQualityGateAndIgnoredBuildResult") - @DisplayName("Ignore job result + successful quality gate -> history with one previous build") - void shouldTestFirstIterationOfLoopIgnoreResult(final String name, - final ExpectedResult expectedResult, final QualityGateResult qualityGateStatus, final Result jobStatus) { - runTest(SUCCESSFUL_QUALITY_GATE, IGNORE_JOB_RESULT, qualityGateStatus, jobStatus, expectedResult); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("createTestDataForSuccessfulQualityGateAndNoFailedBuild") - @DisplayName("No job failure + successful quality gate -> history with one previous build") - void shouldTestFirstIterationOfLoop(final String name, - final ExpectedResult expectedResult, final QualityGateResult qualityGateStatus, final Result jobStatus) { - runTest(SUCCESSFUL_QUALITY_GATE, NO_JOB_FAILURE, qualityGateStatus, jobStatus, expectedResult); - } - - private void runTest(final QualityGateEvaluationMode qualityGateEvaluationMode, - final JobResultEvaluationMode jobResultEvaluationMode, - final QualityGateResult qualityGateStatus, final Result jobStatus, final ExpectedResult expectedResult) { + private void runTest(final QualityGateResult qualityGateStatus, final Result jobStatus, final ExpectedResult expectedResult) { ResultSelector resultSelector = mock(ResultSelector.class); Run baseline = createBuild(qualityGateStatus, jobStatus, resultSelector); - AnalysisHistory history = new AnalysisHistory(baseline, resultSelector, qualityGateEvaluationMode, - jobResultEvaluationMode); + AnalysisHistory history = new AnalysisHistory(baseline, resultSelector); if (expectedResult == NONE) { assertThat(history.getResult()).isEmpty(); diff --git a/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/integrations/JobDslITest.java b/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/integrations/JobDslITest.java index b06aa1c561..88d864ca8f 100644 --- a/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/integrations/JobDslITest.java +++ b/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/integrations/JobDslITest.java @@ -59,7 +59,6 @@ void shouldCreateFreestyleJobUsingJobDslAndVerifyIssueRecorderWithDefaultConfigu assertThat(recorder.getEnabledForFailure()).isFalse(); assertThat(recorder.getHealthy()).isEqualTo(0); assertThat(recorder.getId()).isNull(); - assertThat(recorder.getIgnoreFailedBuilds()).isTrue(); assertThat(recorder.getIgnoreQualityGate()).isFalse(); assertThat(recorder.getMinimumSeverity()).isEqualTo("LOW"); assertThat(recorder.getName()).isNull(); @@ -101,7 +100,6 @@ void shouldCreateFreestyleJobUsingJobDslAndVerifyIssueRecorderWithValuesSet() { assertThat(recorder.getEnabledForFailure()).isTrue(); assertThat(recorder.getHealthy()).isEqualTo(10); assertThat(recorder.getId()).isEqualTo("test-id"); - assertThat(recorder.getIgnoreFailedBuilds()).isFalse(); assertThat(recorder.getIgnoreQualityGate()).isTrue(); assertThat(recorder.isSkipPublishingChecks()).isTrue(); assertThat(recorder.getMinimumSeverity()).isEqualTo("ERROR"); diff --git a/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/ReferenceFinderITest.java b/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/ReferenceFinderITest.java index b2beaeb0c1..cafceae608 100644 --- a/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/ReferenceFinderITest.java +++ b/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/ReferenceFinderITest.java @@ -4,6 +4,7 @@ import java.util.Optional; import java.util.function.Consumer; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -68,7 +69,8 @@ void shouldUseOtherJobAsReference() { assertThat(getConsoleLog(result)).contains( "[ReferenceFinder] Configured reference job: 'reference'", - "[ReferenceFinder] Found reference build '#1' of reference job 'reference'", + "[ReferenceFinder] Found last completed build '#1' of reference job 'reference'", + "[ReferenceFinder] -> Build '#1' has a result SUCCESS", "Obtaining reference build from reference recorder", "-> Found 'reference #1'"); } @@ -101,12 +103,12 @@ void shouldHandleMissingJobBuildAsReference() { } /** - * Checks if the reference will be reset just for one build. + * Checks if the reference is reset just for one build. */ @Test void shouldResetReference() { // #1 SUCCESS - FreeStyleProject project = createReferenceJob(); + FreeStyleProject project = createEmptyReferenceJob(); enableWarnings(project, recorder -> recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE)))); scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -171,7 +173,7 @@ void shouldResetReference() { @Test void shouldCreateSuccessResultWithIgnoredUnstableInBetween() { // #1 SUCCESS - FreeStyleProject project = createReferenceJob(); + FreeStyleProject project = createEmptyReferenceJob(); enableWarnings(project, recorder -> recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE)))); Run expectedReference = scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -199,22 +201,18 @@ void shouldCreateSuccessResultWithIgnoredUnstableInBetween() { .hasReferenceBuild(Optional.of(expectedReference))); } - private FreeStyleProject createReferenceJob() { - return createJob(JOB_NAME, "eclipse2Warnings.txt"); - } - private void createResetAction(final Run unstable, final String id) { ResetQualityGateCommand resetCommand = new ResetQualityGateCommand(); resetCommand.resetReferenceBuild(unstable, id); } /** - * Checks if the reference is taken from the last successful build and therefore returns an unstable in the end. + * Checks if the reference is taken from the last successful build and therefore returns an unstable build in the end. */ @Test void shouldCreateUnstableResultWithIgnoredUnstableInBetween() { // #1 SUCCESS - FreeStyleProject project = createReferenceJob(); + FreeStyleProject project = createEmptyReferenceJob(); enableWarnings(project, recorder -> recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE)))); Run expectedReference = scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -244,7 +242,7 @@ void shouldCreateUnstableResultWithIgnoredUnstableInBetween() { @Test void shouldCreateSuccessResultWithNotIgnoredUnstableInBetween() { // #1 SUCCESS - FreeStyleProject project = createReferenceJob(); + FreeStyleProject project = createEmptyReferenceJob(); enableWarnings(project, recorder -> { recorder.setIgnoreQualityGate(true); recorder.setQualityGates(List.of( @@ -272,12 +270,12 @@ void shouldCreateSuccessResultWithNotIgnoredUnstableInBetween() { } /** - * Checks if the reference ignores the quality gate status and therefore returns an unstable in the end. + * Checks if the reference ignores the quality gate status and therefore returns an unstable build in the end. */ @Test void shouldCreateUnstableResultWithNotIgnoredUnstableInBetween() { // #1 INACTIVE - FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse6Warnings.txt"); IssuesRecorder issuesRecorder = enableWarnings(project, recorder -> recorder.setIgnoreQualityGate(true)); scheduleBuildAndAssertStatus(project, Result.SUCCESS, analysisResult -> assertThat(analysisResult).hasTotalSize(6) @@ -312,9 +310,8 @@ void shouldCreateUnstableResultWithNotIgnoredUnstableInBetween() { @Test void shouldCreateUnstableResultWithOverAllMustBeSuccess() { // #1 SUCCESS - FreeStyleProject project = createReferenceJob(); + FreeStyleProject project = createEmptyReferenceJob(); enableWarnings(project, recorder -> { - recorder.setIgnoreFailedBuilds(true); recorder.setEnabledForFailure(true); recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); @@ -344,14 +341,13 @@ void shouldCreateUnstableResultWithOverAllMustBeSuccess() { /** * Checks if the reference only looks at complete success builds instead of just looking at the eclipse result. - * Should return an success result. + * Should return a success result. */ @Test void shouldCreateSuccessResultWithOverAllMustBeSuccess() { // #1 SUCCESS - FreeStyleProject project = createJob(JOB_NAME, "eclipse4Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse4Warnings.txt"); IssuesRecorder issuesRecorder = enableWarnings(project, recorder -> { - recorder.setIgnoreFailedBuilds(true); recorder.setEnabledForFailure(true); }); Run expectedReference = scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -386,9 +382,8 @@ void shouldCreateSuccessResultWithOverAllMustBeSuccess() { @Test void shouldCreateUnstableResultWithOverAllMustNotBeSuccess() { // #1 SUCCESS - FreeStyleProject project = createJob(JOB_NAME, "eclipse4Warnings.txt"); + FreeStyleProject project = createJob(JOB_NAME, "eclipse4Warnings.txt", Result.FAILURE, StringUtils.EMPTY); IssuesRecorder issuesRecorder = enableWarnings(project, recorder -> { - recorder.setIgnoreFailedBuilds(false); recorder.setEnabledForFailure(true); }); scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -418,15 +413,14 @@ void shouldCreateUnstableResultWithOverAllMustNotBeSuccess() { } /** - * Checks if the reference only looks at the eclipse result of a build and not the overall success. Should return an + * Checks if the reference only looks at the eclipse result of a build and not the overall success. Should return a * success result. */ @Test void shouldCreateSuccessResultWithOverAllMustNotBeSuccess() { // #1 SUCCESS - FreeStyleProject project = createReferenceJob(); + FreeStyleProject project = createEmptyReferenceJob(Result.FAILURE); enableWarnings(project, recorder -> { - recorder.setIgnoreFailedBuilds(false); recorder.setEnabledForFailure(true); recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); @@ -461,7 +455,7 @@ void shouldCreateSuccessResultWithOverAllMustNotBeSuccess() { @Test void shouldCreateSuccessResultWithIgnoredUnstableInBetweenWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); enableWarnings(reference, recorder -> recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE)))); @@ -478,7 +472,7 @@ void shouldCreateSuccessResultWithIgnoredUnstableInBetweenWithReferenceBuild() { .hasQualityGateStatus(QualityGateStatus.WARNING)); // #1 SUCCESS (Reference #1) - FreeStyleProject project = createJob(JOB_NAME, "eclipse4Warnings.txt"); + FreeStyleProject project = createJob(JOB_NAME, "eclipse4Warnings.txt", Result.SUCCESS, REFERENCE_JOB_NAME); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( @@ -494,13 +488,13 @@ void shouldCreateSuccessResultWithIgnoredUnstableInBetweenWithReferenceBuild() { } /** - * Checks if the reference is taken from the last successful build and therefore returns an unstable in the end. + * Checks if the reference is taken from the last successful build and therefore returns an unstable build in the end. * Uses a different freestyle project for the reference. */ @Test void shouldCreateUnstableResultWithIgnoredUnstableInBetweenWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); enableWarnings(reference, recorder -> { recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); @@ -519,7 +513,7 @@ void shouldCreateUnstableResultWithIgnoredUnstableInBetweenWithReferenceBuild() .hasQualityGateStatus(QualityGateStatus.WARNING)); // #1 SUCCESS (Reference #1) - FreeStyleProject project = createJob(JOB_NAME, "eclipse8Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse8Warnings.txt"); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( @@ -541,7 +535,7 @@ void shouldCreateUnstableResultWithIgnoredUnstableInBetweenWithReferenceBuild() @Test void shouldCreateSuccessResultWithNotIgnoredUnstableInBetweenWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); enableWarnings(reference, recorder -> { recorder.setIgnoreQualityGate(true); recorder.setQualityGates(List.of( @@ -560,7 +554,7 @@ void shouldCreateSuccessResultWithNotIgnoredUnstableInBetweenWithReferenceBuild( .hasQualityGateStatus(QualityGateStatus.WARNING)).getOwner(); // #1 SUCCESS (Reference #2) - FreeStyleProject project = createJob(JOB_NAME, "eclipse8Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse8Warnings.txt"); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( @@ -575,13 +569,13 @@ void shouldCreateSuccessResultWithNotIgnoredUnstableInBetweenWithReferenceBuild( } /** - * Checks if the reference ignores the result of the last build and therefore returns an unstable in the end. Uses a + * Checks if the reference ignores the result of the last build and therefore returns an unstable build in the end. Uses a * different freestyle project for the reference. */ @Test void shouldCreateUnstableResultWithNotIgnoredUnstableInBetweenWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse6Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse6Warnings.txt"); IssuesRecorder issuesRecorder = enableWarnings(reference, recorder -> recorder.setIgnoreQualityGate(true)); scheduleBuildAndAssertStatus(reference, Result.SUCCESS, analysisResult -> assertThat(analysisResult).hasTotalSize(6) @@ -599,7 +593,7 @@ void shouldCreateUnstableResultWithNotIgnoredUnstableInBetweenWithReferenceBuild .hasQualityGateStatus(QualityGateStatus.WARNING)).getOwner(); // #1 SUCCESS (Reference #2) - FreeStyleProject project = createJob(JOB_NAME, "eclipse8Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse8Warnings.txt"); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( @@ -621,9 +615,8 @@ void shouldCreateUnstableResultWithNotIgnoredUnstableInBetweenWithReferenceBuild @Test void shouldCreateUnstableResultWithOverAllMustBeSuccessWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); enableWarnings(reference, recorder -> { - recorder.setIgnoreFailedBuilds(true); recorder.setEnabledForFailure(true); recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); @@ -643,12 +636,11 @@ void shouldCreateUnstableResultWithOverAllMustBeSuccessWithReferenceBuild() { removeBuilder(reference, failureStep); // #1 SUCCESS (Reference #1) - FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse6Warnings.txt"); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); - recorder.setIgnoreFailedBuilds(true); recorder.setEnabledForFailure(true); }); scheduleBuildAndAssertStatus(project, Result.UNSTABLE, analysisResult -> assertThat(analysisResult) @@ -658,6 +650,49 @@ void shouldCreateUnstableResultWithOverAllMustBeSuccessWithReferenceBuild() { .hasReferenceBuild(Optional.of(expectedReference))); } + /** + * Checks if the plugin ignores failed builds if the reference finder is configured accordingly. + * + * @see #shouldCreateUnstableResultWithOverAllMustBeSuccessWithReferenceBuild + */ + @Test + void shouldUseFailedBuildsIfConfigured() { + // #1 SUCCESS + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); + enableWarnings(reference, recorder -> { + recorder.setEnabledForFailure(true); + recorder.setQualityGates(List.of( + new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); + }); + scheduleBuildAndAssertStatus(reference, Result.SUCCESS, + analysisResult -> assertThat(analysisResult).hasTotalSize(2) + .hasNewSize(0) + .hasQualityGateStatus(QualityGateStatus.PASSED)); + + // #2 FAILURE + cleanAndCopy(reference, "eclipse4Warnings.txt"); + Builder failureStep = addFailureStep(reference); + Run expectedReference = scheduleBuildAndAssertStatus(reference, Result.FAILURE, + analysisResult -> assertThat(analysisResult).hasTotalSize(4) + .hasNewSize(2) + .hasQualityGateStatus(QualityGateStatus.PASSED)).getOwner(); + removeBuilder(reference, failureStep); + + // #1 SUCCESS (Reference #1) + FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt", Result.FAILURE, REFERENCE_JOB_NAME); + + enableWarnings(project, recorder -> { + recorder.setQualityGates(List.of( + new WarningsQualityGate(2, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); + recorder.setEnabledForFailure(true); + }); + scheduleBuildAndAssertStatus(project, Result.UNSTABLE, analysisResult -> assertThat(analysisResult) + .hasTotalSize(6) + .hasNewSize(2) + .hasQualityGateStatus(QualityGateStatus.WARNING) + .hasReferenceBuild(Optional.of(expectedReference))); + } + /** * Checks if the reference only looks at complete success builds instead of just looking at the eclipse result. * Should return a success result. Uses a different freestyle project for the reference. @@ -665,9 +700,8 @@ void shouldCreateUnstableResultWithOverAllMustBeSuccessWithReferenceBuild() { @Test void shouldCreateSuccessResultWithOverAllMustBeSuccessWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse4Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse4Warnings.txt"); IssuesRecorder issuesRecorder = enableWarnings(reference, recorder -> { - recorder.setIgnoreFailedBuilds(true); recorder.setEnabledForFailure(true); }); Run expectedReference = scheduleBuildAndAssertStatus(reference, Result.SUCCESS, @@ -686,12 +720,11 @@ void shouldCreateSuccessResultWithOverAllMustBeSuccessWithReferenceBuild() { .hasQualityGateStatus(QualityGateStatus.PASSED)); // #1 SUCCESS (Reference #1) - FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt"); + FreeStyleProject project = createEmptyReferenceJob(JOB_NAME, "eclipse6Warnings.txt"); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); - recorder.setIgnoreFailedBuilds(true); recorder.setEnabledForFailure(true); }); scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -708,9 +741,8 @@ void shouldCreateSuccessResultWithOverAllMustBeSuccessWithReferenceBuild() { @Test void shouldCreateUnstableResultWithOverAllMustNotBeSuccessWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse4Warnings.txt"); + FreeStyleProject reference = createEmptyReferenceJob(REFERENCE_JOB_NAME, "eclipse4Warnings.txt"); IssuesRecorder issuesRecorder = enableWarnings(reference, recorder -> { - recorder.setIgnoreFailedBuilds(false); recorder.setEnabledForFailure(true); }); scheduleBuildAndAssertStatus(reference, Result.SUCCESS, @@ -730,12 +762,11 @@ void shouldCreateUnstableResultWithOverAllMustNotBeSuccessWithReferenceBuild() { removeBuilder(reference, failureStep); // #1 UNSTABLE (Reference #2) - FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt"); + FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt", Result.FAILURE, REFERENCE_JOB_NAME); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); - recorder.setIgnoreFailedBuilds(false); recorder.setEnabledForFailure(true); }); scheduleBuildAndAssertStatus(project, Result.UNSTABLE, @@ -752,9 +783,8 @@ void shouldCreateUnstableResultWithOverAllMustNotBeSuccessWithReferenceBuild() { @Test void shouldCreateSuccessResultWithOverAllMustNotBeSuccessWithReferenceBuild() { // #1 SUCCESS - FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt"); + FreeStyleProject reference = createJob(REFERENCE_JOB_NAME, "eclipse2Warnings.txt", Result.FAILURE, StringUtils.EMPTY); enableWarnings(reference, recorder -> { - recorder.setIgnoreFailedBuilds(false); recorder.setEnabledForFailure(true); recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); @@ -775,12 +805,11 @@ void shouldCreateSuccessResultWithOverAllMustNotBeSuccessWithReferenceBuild() { removeBuilder(reference, failureStep); // #1 UNSTABLE (Reference #2) - FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt"); + FreeStyleProject project = createJob(JOB_NAME, "eclipse6Warnings.txt", Result.FAILURE, REFERENCE_JOB_NAME); enableWarnings(project, recorder -> { recorder.setQualityGates(List.of( new WarningsQualityGate(3, QualityGateType.NEW, QualityGateCriticality.UNSTABLE))); - recorder.setIgnoreFailedBuilds(false); recorder.setEnabledForFailure(true); }); scheduleBuildAndAssertStatus(project, Result.SUCCESS, @@ -813,13 +842,25 @@ private void cleanAndCopy(final FreeStyleProject project, final String fileName) copyMultipleFilesToWorkspaceWithSuffix(project, fileName); } - private FreeStyleProject createJob(final String jobName, final String fileName) { + private FreeStyleProject createEmptyReferenceJob() { + return createEmptyReferenceJob(Result.UNSTABLE); + } + + private FreeStyleProject createEmptyReferenceJob(final Result requiredResult) { + return createJob(JOB_NAME, "eclipse2Warnings.txt", requiredResult, StringUtils.EMPTY); + } + + private FreeStyleProject createEmptyReferenceJob(final String jobName, final String fileName) { + return createJob(jobName, fileName, Result.UNSTABLE, StringUtils.EMPTY); + } + + private FreeStyleProject createJob(final String jobName, final String fileName, final Result requiredResult, + final String referenceJobName) { FreeStyleProject job = createProject(FreeStyleProject.class, jobName); var referenceRecorder = new SimpleReferenceRecorder(); job.getPublishersList().add(referenceRecorder); - if (!referenceRecorder.equals(REFERENCE_JOB_NAME)) { - referenceRecorder.setReferenceJob(REFERENCE_JOB_NAME); - } + referenceRecorder.setReferenceJob(referenceJobName); + referenceRecorder.setRequiredResult(requiredResult); copyMultipleFilesToWorkspaceWithSuffix(job, fileName); return job; } diff --git a/plugin/src/test/resources/io/jenkins/plugins/analysis/warnings/integrations/job-dsl-warnings-ng.yaml b/plugin/src/test/resources/io/jenkins/plugins/analysis/warnings/integrations/job-dsl-warnings-ng.yaml index a51f35a417..1822cf8170 100644 --- a/plugin/src/test/resources/io/jenkins/plugins/analysis/warnings/integrations/job-dsl-warnings-ng.yaml +++ b/plugin/src/test/resources/io/jenkins/plugins/analysis/warnings/integrations/job-dsl-warnings-ng.yaml @@ -9,7 +9,6 @@ jobs: enabledForFailure(true) quiet(false) healthy(10) - ignoreFailedBuilds(false) ignoreQualityGate(true) skipPublishingChecks(true) id('test-id')