Skip to content

Commit

Permalink
[FIXED JENKINS-25295] Do not fail when no Nunit test reports found
Browse files Browse the repository at this point in the history
  • Loading branch information
kinow committed Nov 6, 2014
1 parent 55844d4 commit e6e5f01
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
.classpath
.settings
.project
work/
target/
30 changes: 21 additions & 9 deletions src/main/java/hudson/plugins/nunit/NUnitArchiver.java
@@ -1,5 +1,11 @@
package hudson.plugins.nunit;

import hudson.FilePath;
import hudson.Util;
import hudson.model.BuildListener;
import hudson.remoting.VirtualChannel;
import hudson.util.IOException2;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
Expand All @@ -12,12 +18,6 @@
import org.apache.tools.ant.types.FileSet;
import org.xml.sax.SAXException;

import hudson.FilePath;
import hudson.Util;
import hudson.model.BuildListener;
import hudson.remoting.VirtualChannel;
import hudson.util.IOException2;

/**
* Class responsible for transforming NUnit to JUnit files and then run them all through the JUnit result archiver.
*
Expand All @@ -34,11 +34,19 @@ public class NUnitArchiver implements FilePath.FileCallable<Boolean>, Serializab
private final String testResultsPattern;

private TestReportTransformer unitReportTransformer;

private final Boolean failIfNoResults;

@Deprecated
public NUnitArchiver(BuildListener listener, String testResults, TestReportTransformer unitReportTransformer) throws TransformerException {
this(listener, testResults, unitReportTransformer, true);
}

public NUnitArchiver(BuildListener listener, String testResults, TestReportTransformer unitReportTransformer, Boolean failIfNoResults) throws TransformerException {
this.listener = listener;
this.testResultsPattern = testResults;
this.unitReportTransformer = unitReportTransformer;
this.failIfNoResults = failIfNoResults;
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -66,7 +74,7 @@ public Boolean invoke(File ws, VirtualChannel channel) throws IOException {
fileStream.close();
}
}
} else {
} else if(this.failIfNoResults) {
retValue = Boolean.FALSE;
}

Expand All @@ -85,8 +93,12 @@ private String[] findNUnitReports(File parentPath) {

String[] nunitFiles = ds.getIncludedFiles();
if (nunitFiles.length == 0) {
// no test result. Most likely a configuration error or fatal problem
listener.fatalError("No NUnit test report files were found. Configuration error?");
if (this.failIfNoResults) {
// no test result. Most likely a configuration error or fatal problem
listener.fatalError("No NUnit test report files were found. Configuration error?");
} else {
listener.getLogger().println("No NUnit test report files were found.");
}
}
return nunitFiles;
}
Expand Down
59 changes: 45 additions & 14 deletions src/main/java/hudson/plugins/nunit/NUnitPublisher.java
Expand Up @@ -2,15 +2,14 @@

import hudson.AbortException;
import hudson.Extension;
import hudson.FilePath.FileCallable;
import hudson.Launcher;
import hudson.Util;
import hudson.FilePath.FileCallable;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.Result;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.remoting.VirtualChannel;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
Expand All @@ -26,11 +25,10 @@

import javax.xml.transform.TransformerException;

import net.sf.json.JSONObject;
import org.apache.commons.lang.BooleanUtils;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
* Class that records NUnit test reports into Jenkins.
Expand All @@ -50,15 +48,38 @@ public class NUnitPublisher extends Recorder implements Serializable {
private boolean debug = false;
private boolean keepJUnitReports = false;
private boolean skipJUnitArchiver = false;

/**
* <p>Flag that when set, <strong>marks the build as failed if there are
* no test results</strong>.</p>
*
* <p>Defaults to <code>true</code>.</p>
*/
private final boolean failIfNoResults;

@DataBoundConstructor
@Deprecated
public NUnitPublisher(String testResultsPattern, boolean debug, boolean keepJUnitReports, boolean skipJUnitArchiver) {
this(testResultsPattern, debug, keepJUnitReports, skipJUnitArchiver, Boolean.TRUE);
}

@DataBoundConstructor
public NUnitPublisher(String testResultsPattern, boolean debug, boolean keepJUnitReports, boolean skipJUnitArchiver, Boolean failIfNoResults) {
this.testResultsPattern = testResultsPattern;
this.debug = debug;
if (this.debug) {
this.keepJUnitReports = keepJUnitReports;
this.skipJUnitArchiver = skipJUnitArchiver;
}
this.failIfNoResults = BooleanUtils.toBooleanDefaultIfNull(failIfNoResults, Boolean.TRUE);
}

public Object readResolve() {
return new NUnitPublisher(
testResultsPattern,
debug,
keepJUnitReports,
skipJUnitArchiver,
BooleanUtils.toBooleanDefaultIfNull(failIfNoResults, Boolean.TRUE));
}

public String getTestResultsPattern() {
Expand All @@ -67,7 +88,7 @@ public String getTestResultsPattern() {
public void setTestResultsPattern(String pattern){
this.testResultsPattern = pattern;
}

public void setDebug(boolean b){
this.debug = b;
}
Expand All @@ -88,6 +109,10 @@ public void setSkipJunitArchiver(boolean b){
public boolean getSkipJunitArchiver() {
return skipJUnitArchiver;
}

public boolean getFailIfNoResults() {
return failIfNoResults;
}

@Override
public Action getProjectAction(AbstractProject<?,?> project) {
Expand All @@ -112,7 +137,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen
boolean result = true;
try {
listener.getLogger().println("Recording NUnit tests results");
NUnitArchiver transformer = new NUnitArchiver(listener, testResultsPattern, new NUnitReportTransformer());
NUnitArchiver transformer = new NUnitArchiver(listener, testResultsPattern, new NUnitReportTransformer(), failIfNoResults);
result = build.getWorkspace().act(transformer);

if (result) {
Expand Down Expand Up @@ -166,7 +191,7 @@ private boolean recordTestResult(String junitFilePattern, AbstractBuild<?, ?> bu
action = existingAction;
action.setResult(result, listener);
}
if(result.getPassCount()==0 && result.getFailCount()==0 && result.getSkipCount()==0){
if(this.failIfNoResults && result.getPassCount()==0 && result.getFailCount()==0 && result.getSkipCount()==0){
throw new AbortException("None of the test reports contained any result");
}
} catch (AbortException e) {
Expand Down Expand Up @@ -203,14 +228,20 @@ private boolean recordTestResult(String junitFilePattern, AbstractBuild<?, ?> bu
private TestResult getTestResult(final String junitFilePattern, AbstractBuild<?, ?> build,
final TestResult existingTestResults, final long buildTime) throws IOException, InterruptedException {
TestResult result = build.getWorkspace().act(new FileCallable<TestResult>() {
public TestResult invoke(File ws, VirtualChannel channel) throws IOException {
private static final long serialVersionUID = -8917897415838795523L;

public TestResult invoke(File ws, VirtualChannel channel) throws IOException {
FileSet fs = Util.createFileSet(ws,junitFilePattern);
DirectoryScanner ds = fs.getDirectoryScanner();

String[] files = ds.getIncludedFiles();
if(files.length==0) {
// no test result. Most likely a configuration error or fatal problem
throw new AbortException("No test report files were found. Configuration error?");
if (NUnitPublisher.this.failIfNoResults) {
// no test result. Most likely a configuration error or fatal problem
throw new AbortException("No test report files were found. Configuration error?");
} else {
return new TestResult();
}
}
if (existingTestResults == null) {
return new TestResult(buildTime, ds, true);
Expand Down Expand Up @@ -245,7 +276,7 @@ public String getHelpFile() {
}

@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
public boolean isApplicable(@SuppressWarnings("rawtypes") Class<? extends AbstractProject> jobType) {
return true;
}
}
Expand Down
Expand Up @@ -9,6 +9,11 @@
Basedir of the fileset is &lt;a href='ws/'>the workspace root&lt;/a>.
">
<f:textbox value="${instance.testResultsPattern}" />
<f:advanced>
<f:entry title="Fail the build if no test results are present" field="failIfNoResults">
<f:checkbox value="${instance.failIfNoResults}" checked="${instance.failIfNoResults}" default="true" />
</f:entry>
</f:advanced>
</f:entry>
<j:if test="${instance.debug}">
<f:entry title="Debug" field="debug">
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/hudson/plugins/nunit/NUnitArchiverTest.java
Expand Up @@ -77,7 +77,7 @@ public void testRemovalOfJunitFiles() throws Exception {

@Test
public void testTransformOfTwoReports() throws Exception {
nunitArchiver = new NUnitArchiver(buildListener, "*.xml", transformer);
nunitArchiver = new NUnitArchiver(buildListener, "*.xml", transformer, true);
workspace.createTextTempFile("nunit-report", ".xml", "content");
workspace.createTextTempFile("nunit-report", ".xml", "content");

Expand Down Expand Up @@ -152,7 +152,7 @@ public void testNoNUnitReports() throws Exception {
one(buildListener).fatalError(with(any(String.class)));
}
});
nunitArchiver = new NUnitArchiver(buildListener, "*.xml", transformer);
nunitArchiver = new NUnitArchiver(buildListener, "*.xml", transformer, true);
Boolean result = nunitArchiver.invoke(parentFile, virtualChannel);
assertFalse("The archiver did not return false when it could not find any files", result);
}
Expand Down
34 changes: 22 additions & 12 deletions src/test/java/hudson/plugins/nunit/NUnitPublisherTest.java
Expand Up @@ -8,6 +8,7 @@
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;

import static org.junit.Assert.*;

import org.junit.Before;
Expand All @@ -30,39 +31,39 @@ public void setUp() throws Exception {

@Test
public void testGetTestResultsPattern() {
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, false, false);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, false, false, true);
assertEquals("The test results pattern is incorrect", publisher.getTestResultsPattern(), "**/*.xml");
}

@Test
public void testGetDebug() {
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, false, false);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, false, false, true);
assertTrue("Debug is incorrect", publisher.getDebug());
publisher = new NUnitPublisher("**/*.xml", false, false, false);
publisher = new NUnitPublisher("**/*.xml", false, false, false, true);
assertFalse("Debug is incorrect", publisher.getDebug());
}

@Test
public void testDisabledDebug() {
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, true, true);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, true, true, true);
assertFalse("Debug is incorrect", publisher.getDebug());
assertFalse("KeepJunitReports() is incorrect", publisher.getKeepJunitReports());
assertFalse("SkipJunitArchiver() is incorrect", publisher.getSkipJunitArchiver());
}

@Test
public void testGetKeepJunitReports() {
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, true, false);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, true, false, true);
assertTrue("KeepJunitReports() is incorrect", publisher.getKeepJunitReports());
publisher = new NUnitPublisher("**/*.xml", true, false, false);
publisher = new NUnitPublisher("**/*.xml", true, false, false, true);
assertFalse("KeepJunitReports() is incorrect", publisher.getKeepJunitReports());
}

@Test
public void testGetSkipJunitArchiver() {
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, false, true);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", true, false, true, true);
assertTrue("SkipJunitArchiver() is incorrect", publisher.getSkipJunitArchiver());
publisher = new NUnitPublisher("**/*.xml", true, false, false);
publisher = new NUnitPublisher("**/*.xml", true, false, false, true);
assertFalse("SkipJunitArchiver() is incorrect", publisher.getSkipJunitArchiver());
}

Expand All @@ -73,8 +74,9 @@ public void testGetProjectActionProjectReusing() {
one(project).getAction(with(equal(TestResultProjectAction.class))); will(returnValue(new TestResultProjectAction(project)));
}
});
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, false, true);
Action projectAction = publisher.getProjectAction((AbstractProject)project);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, false, true, true);
@SuppressWarnings("rawtypes")
Action projectAction = publisher.getProjectAction((AbstractProject)project);
assertNotNull("The action was null", projectAction);
}

Expand All @@ -85,9 +87,17 @@ public void testGetProjectActionProject() {
one(project).getAction(with(equal(TestResultProjectAction.class))); will(returnValue(null));
}
});
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, false, true);
Action projectAction = publisher.getProjectAction((AbstractProject)project);
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, false, true, true);
@SuppressWarnings("rawtypes")
Action projectAction = publisher.getProjectAction((AbstractProject)project);
assertNotNull("The action was null", projectAction);
assertEquals("The action type is incorrect", TestResultProjectAction.class, projectAction.getClass());
}

public void testGetFailBuildIfNoResults() {
NUnitPublisher publisher = new NUnitPublisher("**/*.xml", false, true, true, true);
assertTrue("Fail if no results is incorrect", publisher.getFailIfNoResults());
publisher = new NUnitPublisher("**/*.xml", false, true, true, false);
assertFalse("Fail if no results is incorrect", publisher.getFailIfNoResults());
}
}

0 comments on commit e6e5f01

Please sign in to comment.