diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index e22e32c6ac526b4f0192ec0f2c13cd74899fe75e..98ac7033d320e1b0d0ca7dd5bc107e88f2b20007 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -715,6 +715,8 @@ public abstract class AbstractBuild
,R extends Abs * * @param phase * true for the post build processing, and false for the final "run after finished" execution. + * + * @return false if any build step failed */ protected final boolean performAllBuildSteps(BuildListener listener, Iterable extends BuildStep> buildSteps, boolean phase) throws InterruptedException, IOException { boolean r = true; @@ -728,19 +730,28 @@ public abstract class AbstractBuild
,R extends Abs } } catch (Exception e) { reportError(bs, e, listener, phase); + r = false; } catch (LinkageError e) { reportError(bs, e, listener, phase); + r = false; } } return r; } private void reportError(BuildStep bs, Throwable e, BuildListener listener, boolean phase) { - String msg = "Publisher " + bs.getClass().getName() + " aborted due to exception"; - if (!(e instanceof AbortException)){ + final String publisher = ((Publisher) bs).getDescriptor().getDisplayName(); + + if (e instanceof AbortException) { + LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {AbstractBuild.this, publisher}); + listener.error("Publisher '" + publisher + "' failed: "); + listener.error(e.getMessage()); + } else { + String msg = "Publisher '" + publisher + "' aborted due to exception: "; e.printStackTrace(listener.error(msg)); LOGGER.log(WARNING, msg, e); } + if (phase) { setResult(Result.FAILURE); } diff --git a/test/src/test/java/hudson/model/FreestyleJobPublisherTest.java b/test/src/test/java/hudson/model/FreestyleJobPublisherTest.java index ee1105d38809129928c4decd4031f173e45b2db6..feebd9cf3cfee01574c1e71ae9caba2f170d04e5 100644 --- a/test/src/test/java/hudson/model/FreestyleJobPublisherTest.java +++ b/test/src/test/java/hudson/model/FreestyleJobPublisherTest.java @@ -19,10 +19,12 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Freestyle publishers statuses tests + * * @author Kanstantsin Shautsou */ public class FreestyleJobPublisherTest { @@ -30,7 +32,7 @@ public class FreestyleJobPublisherTest { public JenkinsRule j = new JenkinsRule(); /** - * Execute even one of publishers return false. Shows JENKINS-26964 bug. + * Execute all publishers even one of publishers return false. */ @Issue("JENKINS-26964") @Test @@ -39,51 +41,66 @@ public class FreestyleJobPublisherTest { p.getPublishersList().add(new TrueFalsePublisher(true)); // noop p.getPublishersList().add(new TrueFalsePublisher(false)); // FAIL build with false - p.getPublishersList().add(new ResultWriterPublisher("result.txt")); //catch result to file - p.getPublishersList().add(new ArtifactArchiver("result.txt", "", false)); + p.getPublishersList().add(new ResultWriterPublisher("result.txt")); // catch result to file + final ArtifactArchiver artifactArchiver = new ArtifactArchiver("result.txt"); + artifactArchiver.setOnlyIfSuccessful(false); + p.getPublishersList().add(artifactArchiver); // transfer file to build dir FreeStyleBuild b = p.scheduleBuild2(0).get(); assertEquals("Build must fail, because we used FalsePublisher", b.getResult(), Result.FAILURE); File file = new File(b.getArtifactsDir(), "result.txt"); - assertTrue("ArtifactArchiver is executed even prior publisher fails.", file.exists()); - assertTrue("Second publisher must see FAILURE status", FileUtils.readFileToString(file).equals(Result.FAILURE.toString())); + assertTrue("ArtifactArchiver is executed even prior publisher fails", file.exists()); + assertTrue("Publisher, after publisher with return false status, must see FAILURE status", + FileUtils.readFileToString(file).equals(Result.FAILURE.toString())); } /** * Execute all publishers even one of them throws AbortException. */ + @Issue("JENKINS-26964") @Test - public void testFreestyleWithExceptionPublisher() throws IOException, ExecutionException, InterruptedException { + public void testFreestyleWithExceptionPublisher() throws Exception { FreeStyleProject p = j.createFreeStyleProject(); p.getPublishersList().add(new TrueFalsePublisher(true)); // noop p.getPublishersList().add(new AbortExceptionPublisher()); // FAIL build with AbortException - p.getPublishersList().add(new ResultWriterPublisher("result.txt")); //catch result to file - p.getPublishersList().add(new ArtifactArchiver("result.txt", "", false)); + p.getPublishersList().add(new ResultWriterPublisher("result.txt")); // catch result to file + final ArtifactArchiver artifactArchiver = new ArtifactArchiver("result.txt"); + artifactArchiver.setOnlyIfSuccessful(false); + p.getPublishersList().add(artifactArchiver); // transfer file to build dir FreeStyleBuild b = p.scheduleBuild2(0).get(); - assertEquals("Build must fail, because we used FalsePublisher", b.getResult(), Result.FAILURE); + + assertEquals("Build must fail, because we used AbortExceptionPublisher", b.getResult(), Result.FAILURE); + j.assertLogNotContains("\tat", b); // log must not contain stacktrace File file = new File(b.getArtifactsDir(), "result.txt"); - assertTrue("ArtifactArchiver is executed even prior publisher fails.", file.exists()); - assertTrue("Second publisher must see FAILURE status", FileUtils.readFileToString(file).equals(Result.FAILURE.toString())); + assertTrue("ArtifactArchiver is executed even prior publisher fails", file.exists()); + assertTrue("Second publisher must see FAILURE status", + FileUtils.readFileToString(file).equals(Result.FAILURE.toString())); } /** * Execute all publishers even one of them throws any Exceptions. */ + @Issue("JENKINS-26964") @Test - public void testFreestyleWithIOExceptionPublisher() throws IOException, ExecutionException, InterruptedException { + public void testFreestyleWithIOExceptionPublisher() throws Exception { FreeStyleProject p = j.createFreeStyleProject(); p.getPublishersList().add(new TrueFalsePublisher(true)); // noop p.getPublishersList().add(new IOExceptionPublisher()); // fail with IOException p.getPublishersList().add(new ResultWriterPublisher("result.txt")); //catch result to file - p.getPublishersList().add(new ArtifactArchiver("result.txt", "", false)); + final ArtifactArchiver artifactArchiver = new ArtifactArchiver("result.txt"); + artifactArchiver.setOnlyIfSuccessful(false); + p.getPublishersList().add(artifactArchiver); // transfer file to build dir FreeStyleBuild b = p.scheduleBuild2(0).get(); + assertEquals("Build must fail, because we used FalsePublisher", b.getResult(), Result.FAILURE); + j.assertLogContains("\tat hudson.model.utils.IOExceptionPublisher", b); // log must contain stacktrace File file = new File(b.getArtifactsDir(), "result.txt"); - assertTrue("ArtifactArchiver is executed even prior publisher fails.", file.exists()); - assertTrue("Second publisher must see FAILURE status", FileUtils.readFileToString(file).equals(Result.FAILURE.toString())); + assertTrue("ArtifactArchiver is executed even prior publisher fails", file.exists()); + assertTrue("Third publisher must see FAILURE status", + FileUtils.readFileToString(file).equals(Result.FAILURE.toString())); } } diff --git a/test/src/test/java/hudson/model/utils/AbortExceptionPublisher.java b/test/src/test/java/hudson/model/utils/AbortExceptionPublisher.java index a3af0af7c2814ea37211994959014078577e354e..f634a07a1fe3255ff8a9e6bd18bc6771a52056ac 100644 --- a/test/src/test/java/hudson/model/utils/AbortExceptionPublisher.java +++ b/test/src/test/java/hudson/model/utils/AbortExceptionPublisher.java @@ -19,7 +19,7 @@ import java.io.IOException; public class AbortExceptionPublisher extends Recorder { @Override public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - throw new AbortException("Throwed AbortException from publisher!"); + throw new AbortException("Threw AbortException from publisher!"); } @Override