Skip to content

Commit

Permalink
JENKINS-23786: Allow batch files to set an exit code for unstable builds
Browse files Browse the repository at this point in the history
  • Loading branch information
ringerc authored and stochmim committed Sep 22, 2016
1 parent e773eb4 commit 4b067fd
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 12 deletions.
21 changes: 19 additions & 2 deletions core/src/main/java/hudson/tasks/BatchFile.java
Expand Up @@ -40,10 +40,17 @@
*/
public class BatchFile extends CommandInterpreter {
@DataBoundConstructor
public BatchFile(String command) {
public BatchFile(String command, Integer unstableReturn) {
super(LineEndingConversion.convertEOL(command, LineEndingConversion.EOLType.Windows));
this.unstableReturn = unstableReturn;
}

public BatchFile(String command) {
this(command, null);
}

private final Integer unstableReturn;

public String[] buildCommandLine(FilePath script) {
return new String[] {"cmd","/c","call",script.getRemote()};
}
Expand All @@ -56,6 +63,10 @@ protected String getFileExtension() {
return ".bat";
}

public final Integer getUnstableReturn() {
return unstableReturn;
}

private Object readResolve() throws ObjectStreamException {
return new BatchFile(command);
}
Expand All @@ -73,7 +84,13 @@ public String getDisplayName() {

@Override
public Builder newInstance(StaplerRequest req, JSONObject data) {
return new BatchFile(data.getString("command"));
final String unstableReturnStr = data.getString("unstableReturn");
Integer unstableReturn = null;
if (unstableReturnStr != null && ! unstableReturnStr.isEmpty()) {
/* Already validated by f.number in the form */
unstableReturn = (Integer)Integer.parseInt(unstableReturnStr, 10);
}
return new BatchFile(data.getString("command"), unstableReturn);
}

public boolean isApplicable(Class<? extends AbstractProject> jobType) {
Expand Down
8 changes: 7 additions & 1 deletion core/src/main/resources/hudson/tasks/BatchFile/config.jelly
Expand Up @@ -25,7 +25,13 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry title="${%Command}"
description="${%description(rootURL)}">
description="${%command_description(rootURL)}">
<f:textarea name="command" value="${instance.command}" class="fixed-width" />
</f:entry>
<f:advanced>
<f:entry title="errorlevel to set build unstable"
description="${%unstableReturn_description(rootURL)}">
<f:number clazz="positive-number" name="unstableReturn" value="${instance.unstableReturn}" min="1" max="255" step="1" />
</f:entry>
</f:advanced>
</j:jelly>
Expand Up @@ -20,4 +20,5 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

description=See <a href="{0}/env-vars.html" target=_new>the list of available environment variables</a>
command_description=See <a href="{0}/env-vars.html" target=_new>the list of available environment variables</a>
unstableReturn_description=If set, the batch errorlevel result that will be interpreted as an unstable build result.
91 changes: 83 additions & 8 deletions test/src/test/java/hudson/tasks/BatchFileTest.java
@@ -1,16 +1,25 @@
package hudson.tasks;

import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.asssertNull;
import static org.junit.Assume.assumeTrue;

import hudson.Functions;
import hudson.Launcher.ProcStarter;
import hudson.Proc;
import hudson.model.Result;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import org.apache.commons.io.FileUtils;
import org.jvnet.hudson.test.FakeLauncher;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.PretendSlave;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;

/**
* Tests for the BatchFile tasks class.
*
* @author David Ruhmann
*/
public class BatchFileTest {
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;

@Rule
public JenkinsRule rule = new JenkinsRule();
Expand All @@ -27,4 +36,70 @@ public void validateBatchFileContents() throws Exception {
BatchFile obj = new BatchFile("echo A\necho B\recho C");
rule.assertStringContains(obj.getContents(), "echo A\r\necho B\r\necho C\r\nexit %ERRORLEVEL%");
}

/* A FakeLauncher that just returns the specified error code */
private class ReturnCodeFakeLauncher implements FakeLauncher {
final int code;

ReturnCodeFakeLauncher(int code)
{
super();
this.code = code;
}

@Override
public Proc onLaunch(ProcStarter p) throws IOException {
return new FinishedProc(this.code);
}
}

@Issue("JENKINS-23786")
public void testUnstableReturn() throws Exception {
if(!Functions.isWindows())
return;

PretendSlave returns2 = createPretendSlave(new ReturnCodeFakeLauncher(2));
PretendSlave returns1 = createPretendSlave(new ReturnCodeFakeLauncher(1));
PretendSlave returns0 = createPretendSlave(new ReturnCodeFakeLauncher(0));

FreeStyleProject p;
FreeStyleBuild b;

/* Unstable=2, error codes 0/1/2 */
p = createFreeStyleProject();
p.getBuildersList().add(new BatchFile("", 2));
p.setAssignedNode(returns2);
b = assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());

p = createFreeStyleProject();
p.getBuildersList().add(new BatchFile("", 2));
p.setAssignedNode(returns1);
b = assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());

p = createFreeStyleProject();
p.getBuildersList().add(new BatchFile("", 2));
p.setAssignedNode(returns0);
b = assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());

/* unstable=null, error codes 0/1/2 */
p = createFreeStyleProject();
p.getBuildersList().add(new BatchFile("", null));
p.setAssignedNode(returns2);
b = assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());

p = createFreeStyleProject();
p.getBuildersList().add(new BatchFile("", null));
p.setAssignedNode(returns1);
b = assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get());

p = createFreeStyleProject();
p.getBuildersList().add(new BatchFile("", null));
p.setAssignedNode(returns0);
b = assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get());

/* Creating unstable=0 produces unstable=null */
assertNull( new BatchFile("",0).getUnstableReturn() );

}

}

0 comments on commit 4b067fd

Please sign in to comment.