diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java b/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java index 750e7f8a..52d898e1 100644 --- a/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java +++ b/src/main/java/hudson/plugins/parameterizedtrigger/TriggerBuilder.java @@ -148,7 +148,15 @@ public boolean perform(AbstractBuild build, Launcher launcher, try { if (future != null ) { listener.getLogger().println("Waiting for the completion of " + HyperlinkNote.encodeTo('/'+ p.getUrl(), p.getFullDisplayName())); - Run startedRun = future.waitForStart(); + Run startedRun; + try { + startedRun = future.waitForStart(); + } catch (InterruptedException x) { + listener.getLogger().println( "Build aborting: cancelling queued project " + HyperlinkNote.encodeTo('/'+ p.getUrl(), p.getFullDisplayName()) ); + future.cancel(true); + throw x; // rethrow so that the triggering project get flagged as cancelled + } + listener.getLogger().println(HyperlinkNote.encodeTo('/' + startedRun.getUrl(), startedRun.getFullDisplayName()) + " started."); Run completedRun = future.get(); diff --git a/src/test/java/hudson/plugins/parameterizedtrigger/test/TriggerBuilderTest.java b/src/test/java/hudson/plugins/parameterizedtrigger/test/TriggerBuilderTest.java index 8d94a62c..a91779ca 100644 --- a/src/test/java/hudson/plugins/parameterizedtrigger/test/TriggerBuilderTest.java +++ b/src/test/java/hudson/plugins/parameterizedtrigger/test/TriggerBuilderTest.java @@ -52,6 +52,7 @@ import java.util.ArrayList; +import java.util.concurrent.Future; import java.util.Collections; import java.util.List; import java.util.ListIterator; @@ -70,10 +71,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; + public class TriggerBuilderTest { @Rule @@ -224,6 +228,34 @@ public void testNonBlockingTrigger() throws Exception { "Triggering projects: project1, project2, project3"); } + @Test + public void testCancelsDownstreamBuildWhenInterrupted() throws Exception{ + r.jenkins.setNumExecutors(1); // the downstream-project would be in the build queue + + FreeStyleProject triggerProject = r.createFreeStyleProject("upstream-project"); + FreeStyleProject downstreamProject = r.createFreeStyleProject("downstream-project"); + + TriggerBuilder triggerBuilder = new TriggerBuilder(createTriggerConfig("downstream-project")); + + triggerProject.getBuildersList().add(triggerBuilder); + + QueueTaskFuture parentBuild = triggerProject.scheduleBuild2(0); + parentBuild.waitForStart(); + + // Now cancel the trigger project and let it finishes + triggerProject.getLastBuild().getExecutor().interrupt(); + parentBuild.get(); + + assertLines(triggerProject.getLastBuild(), + "Waiting for the completion of downstream-project", + "Build aborting: cancelling queued project downstream-project", + "Build was aborted", + "Finished: ABORTED" + ); + assertNull("No downstream build has been run", downstreamProject.getLastBuild()); + assertEquals("No build left in queue", 0, r.jenkins.getQueue().countBuildableItems()); + } + @Test public void testConsoleOutputWithCounterParameters() throws Exception{ r.createFreeStyleProject("project1");