diff --git a/pom.xml b/pom.xml index 7da70f18..3f3be8d5 100644 --- a/pom.xml +++ b/pom.xml @@ -52,8 +52,8 @@ parameterized-trigger 2.25 - - + + org.jenkins-ci.plugins junit diff --git a/src/main/java/com/tikal/jenkins/plugins/multijob/MultiJobBuilder.java b/src/main/java/com/tikal/jenkins/plugins/multijob/MultiJobBuilder.java index 9e4aa1a2..c2659b73 100644 --- a/src/main/java/com/tikal/jenkins/plugins/multijob/MultiJobBuilder.java +++ b/src/main/java/com/tikal/jenkins/plugins/multijob/MultiJobBuilder.java @@ -410,7 +410,14 @@ else if(!jobStatus.isBuildable() && !phaseConfig.isApplyConditionOnlyIfNoSCMChan } } else { AbstractBuild jobBuild = subTask.subJob.getBuildByNumber(subBuild.getBuildNumber()); - updateSubBuild(multiJobBuild, thisProject, jobBuild, subBuild.getResult()); + Result resultToUse; + if (!subTask.phaseConfig.isPretendSuccess()) { + resultToUse = subBuild.getResult(); + } else { + listener.getLogger().println("Going to pretend success (instead of " + subBuild.getResult() +") for the subBuild.result of " + subTask.subJob.getDisplayName()); + resultToUse = Result.SUCCESS; + } + updateSubBuild(multiJobBuild, thisProject, jobBuild, resultToUse); } } @@ -422,8 +429,16 @@ else if(!jobStatus.isBuildable() && !phaseConfig.isApplyConditionOnlyIfNoSCMChan if (subTask != null) { resultCounter++; if (subTask.result != null) { - jobResults.add(subTask.result); - phaseCounters.process(subTask.result); + //Possibly change the result to success if the pretendSuccess config was set + Result resultToUse; + if (!subTask.phaseConfig.isPretendSuccess()) { + resultToUse = subTask.result; + } else { + listener.getLogger().println("Going to pretend success (instead of " + subTask.result +") for the subTask.result of " + subTask.subJob.getDisplayName()); + resultToUse = Result.SUCCESS; + } + jobResults.add(resultToUse); + phaseCounters.process(resultToUse); checkPhaseTermination(subTask, subTasks, listener); } } @@ -531,31 +546,39 @@ public Object call() { result = jobBuild.getResult(); reportFinish(listener, jobBuild, result); + Result resultToUse; + if (!subTask.phaseConfig.isPretendSuccess()) { + resultToUse = result; + } else { + listener.getLogger().println("Going to pretend success (instead of " + result +") for the result of " + subTask.subJob.getDisplayName()); + resultToUse = Result.SUCCESS; + } + if (result.isWorseOrEqualTo(Result.UNSTABLE) && result.isCompleteBuild() && subTask.phaseConfig.getEnableRetryStrategy()) { if (isKnownRandomFailure(jobBuild)) { if (retry <= maxRetries) { listener.getLogger().println("Known failure detected, retrying this build. Try " + retry + " of " + maxRetries + "."); - updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, result, true); + updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, resultToUse, true); subTask.generateFuture(); } else { listener.getLogger().println("Known failure detected, max retries (" + maxRetries + ") exceeded."); - updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, result); + updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, resultToUse); } } else { listener.getLogger().println("Failed the build, the failure doesn't match the rules."); - updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, result); + updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, resultToUse); finish = true; } } else { - updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, result); + updateSubBuild(subTask.multiJobBuild, multiJobProject, jobBuild, resultToUse); finish = true; } ChangeLogSet changeLogSet = jobBuild.getChangeSet(); subTask.multiJobBuild.addChangeLogSet(changeLogSet); addBuildEnvironmentVariables(subTask.multiJobBuild, jobBuild, listener); - subTask.result = result; + subTask.result = resultToUse; } } @@ -710,6 +733,10 @@ private boolean isKnownRandomFailure(AbstractBuild build) throws InterruptedExce protected boolean checkPhaseTermination(SubTask subTask, List subTasks, final BuildListener listener) { try { + if (subTask.phaseConfig.isPretendSuccess()) { + listener.getLogger().println("Pretend success is enabled for" + subTask.subJob.getDisplayName() + "; not going to terminate phase"); + return false; + } KillPhaseOnJobResultCondition killCondition = subTask.phaseConfig.getKillPhaseOnJobResultCondition(); if (killCondition.equals(KillPhaseOnJobResultCondition.NEVER) && subTask.result != Result.ABORTED) { return false; diff --git a/src/main/java/com/tikal/jenkins/plugins/multijob/PhaseJobsConfig.java b/src/main/java/com/tikal/jenkins/plugins/multijob/PhaseJobsConfig.java index fe47f13c..63c88dbd 100644 --- a/src/main/java/com/tikal/jenkins/plugins/multijob/PhaseJobsConfig.java +++ b/src/main/java/com/tikal/jenkins/plugins/multijob/PhaseJobsConfig.java @@ -50,6 +50,7 @@ public class PhaseJobsConfig implements Describable { private boolean aggregatedTestResults; private boolean exposedSCM; private boolean disableJob; + private boolean pretendSuccess; private String parsingRulesPath; private int maxRetries; private boolean enableRetryStrategy; @@ -133,6 +134,14 @@ public void setDisableJob(boolean disableJob) { this.disableJob = disableJob; } + public boolean isPretendSuccess() { + return pretendSuccess; + } + + public void setPretendSuccess(boolean pretendSuccess) { + this.pretendSuccess = pretendSuccess; + } + public KillPhaseOnJobResultCondition getKillPhaseOnJobResultCondition() { return killPhaseOnJobResultCondition; } @@ -193,12 +202,12 @@ public String getDisplayName() { public PhaseJobsConfig(String jobName, String jobProperties, boolean currParams, List configs, KillPhaseOnJobResultCondition killPhaseOnJobResultCondition, - boolean disableJob, boolean enableRetryStrategy, + boolean disableJob, boolean pretendSuccess, boolean enableRetryStrategy, String parsingRulesPath, int maxRetries, boolean enableCondition, boolean abortAllJob, String condition, boolean buildOnlyIfSCMChanges, boolean applyConditionOnlyIfNoSCMChanges) { this(jobName, jobProperties, currParams, configs, killPhaseOnJobResultCondition, - disableJob, enableRetryStrategy, parsingRulesPath, maxRetries, enableCondition, + disableJob, pretendSuccess, enableRetryStrategy, parsingRulesPath, maxRetries, enableCondition, abortAllJob, condition, buildOnlyIfSCMChanges, applyConditionOnlyIfNoSCMChanges, false); } @@ -206,7 +215,7 @@ public PhaseJobsConfig(String jobName, String jobProperties, public PhaseJobsConfig(String jobName, String jobProperties, boolean currParams, List configs, KillPhaseOnJobResultCondition killPhaseOnJobResultCondition, - boolean disableJob, boolean enableRetryStrategy, + boolean disableJob, boolean pretendSuccess, boolean enableRetryStrategy, String parsingRulesPath, int maxRetries, boolean enableCondition, boolean abortAllJob, String condition, boolean buildOnlyIfSCMChanges, boolean applyConditionOnlyIfNoSCMChanges, boolean aggregatedTestResults) { @@ -215,6 +224,7 @@ public PhaseJobsConfig(String jobName, String jobProperties, this.currParams = currParams; this.killPhaseOnJobResultCondition = killPhaseOnJobResultCondition; this.disableJob = disableJob; + this.pretendSuccess = pretendSuccess; this.configs = Util.fixNull(configs); this.enableRetryStrategy = enableRetryStrategy; this.maxRetries = maxRetries; diff --git a/src/main/resources/com/tikal/jenkins/plugins/multijob/MultiJobBuilder/config.jelly b/src/main/resources/com/tikal/jenkins/plugins/multijob/MultiJobBuilder/config.jelly index 8432b365..1d408933 100644 --- a/src/main/resources/com/tikal/jenkins/plugins/multijob/MultiJobBuilder/config.jelly +++ b/src/main/resources/com/tikal/jenkins/plugins/multijob/MultiJobBuilder/config.jelly @@ -24,6 +24,9 @@ + + + diff --git a/src/main/webapp/help-pretendSuccess.html b/src/main/webapp/help-pretendSuccess.html new file mode 100644 index 00000000..8877884e --- /dev/null +++ b/src/main/webapp/help-pretendSuccess.html @@ -0,0 +1,4 @@ +
+ Ignore the result of this job and pretend that sucess was returned.
+ Great for adding out a new phase job in production without having it break functionality +
\ No newline at end of file diff --git a/src/test/java/com/tikal/jenkins/plugins/multijob/test/ConditionalPhaseTest.java b/src/test/java/com/tikal/jenkins/plugins/multijob/test/ConditionalPhaseTest.java index 940f1d4e..67589ee8 100644 --- a/src/test/java/com/tikal/jenkins/plugins/multijob/test/ConditionalPhaseTest.java +++ b/src/test/java/com/tikal/jenkins/plugins/multijob/test/ConditionalPhaseTest.java @@ -54,14 +54,14 @@ public void run(JenkinsRule j) throws Throwable { final MultiJobProject multi = j.jenkins.createProject(MultiJobProject.class, "MultiTop"); // create 'FirstPhase' containing job 'free' - PhaseJobsConfig firstPhase = new PhaseJobsConfig("free", null, true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig firstPhase = new PhaseJobsConfig("free", null, true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List configTopList = new ArrayList(); configTopList.add(firstPhase); MultiJobBuilder firstPhaseBuilder = new MultiJobBuilder("FirstPhase", configTopList, ContinuationCondition.SUCCESSFUL, MultiJobBuilder.ExecutionType.PARALLEL); // create 'SecondPhase' containing job 'free2' - PhaseJobsConfig secondPhase = new PhaseJobsConfig("free2", null, true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig secondPhase = new PhaseJobsConfig("free2", null, true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List configTopList2 = new ArrayList(); configTopList.add(secondPhase); MultiJobBuilder secondPhaseBuilder = new MultiJobBuilder("SecondPhase", configTopList2, ContinuationCondition.SUCCESSFUL, MultiJobBuilder.ExecutionType.PARALLEL); diff --git a/src/test/java/com/tikal/jenkins/plugins/multijob/test/PhaseJobsConfigTest.java b/src/test/java/com/tikal/jenkins/plugins/multijob/test/PhaseJobsConfigTest.java index 8ed48638..ee298713 100644 --- a/src/test/java/com/tikal/jenkins/plugins/multijob/test/PhaseJobsConfigTest.java +++ b/src/test/java/com/tikal/jenkins/plugins/multijob/test/PhaseJobsConfigTest.java @@ -81,7 +81,7 @@ public void testNoParameters() throws Exception { AbstractProject projectB = createTriggeredProject(null); MultiJobBuild mjb =createTriggeringBuild(null); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "" , true, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "" , true, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, true); // check single ParametersAction created @@ -93,7 +93,7 @@ public void testDefaultParameters() throws Exception { AbstractProject projectB = createTriggeredProject(DEFAULT_KEY_VALUES); MultiJobBuild mjb = createTriggeringBuild(null); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, true); // check single ParametersAction created @@ -113,7 +113,7 @@ public void testCurrentDefaultParameters() throws Exception { AbstractProject projectB = createTriggeredProject(DEFAULT_KEY_VALUES); MultiJobBuild mjb = createTriggeringBuild(createParametersAction(CURRENT_KEY_VALUES)); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "" , false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "" , false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, true); @@ -136,7 +136,7 @@ public void testCurrentOverridesDefaultParameters() throws Exception { AbstractProject projectB = createTriggeredProject(DEFAULT_KEY_VALUES); MultiJobBuild mjb = createTriggeringBuild(createParametersAction(OVERRIDES_KEY_VALUES)); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, true); @@ -158,7 +158,7 @@ public void testCurrentIgnoredDefaultParameters() throws Exception { AbstractProject projectB = createTriggeredProject(DEFAULT_KEY_VALUES); MultiJobBuild mjb = createTriggeringBuild(createParametersAction(OVERRIDES_KEY_VALUES)); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, null, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, false); // check single ParametersAction created @@ -181,7 +181,7 @@ public void testConfigsDefaultParameters() throws Exception { configs.add(new TestParametersConfig()); configs.add(new TestParametersConfig(OVERRIDES_KEY_VALUES)); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, configs, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, configs, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, true); @@ -210,7 +210,7 @@ public void testCurrentConfigsDefaultParameters() throws Exception { configs.add(new TestParametersConfig()); configs.add(new TestParametersConfig(CONFIG_OVERRIDES_KEY_VALUES)); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, configs, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, configs, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, true); @@ -239,7 +239,7 @@ public void testNotCurrentConfigsDefaultParameters() throws Exception { configs.add(new TestParametersConfig()); configs.add(new TestParametersConfig(CONFIG_OVERRIDES_KEY_VALUES)); - PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, configs, KillPhaseOnJobResultCondition.NEVER, false, false, "", 0, false, false, "",false, false); + PhaseJobsConfig pjc = new PhaseJobsConfig("dummy", "", true, configs, KillPhaseOnJobResultCondition.NEVER, false, false, false, "", 0, false, false, "",false, false); List actions = pjc.getActions(mjb, TaskListener.NULL, projectB, false);