Skip to content

Commit

Permalink
Merge pull request #61 from thomaste/cancelation_correction
Browse files Browse the repository at this point in the history
[JENKINS-30102] Cancel the correct queued build
  • Loading branch information
dnozay committed Sep 16, 2015
2 parents e835b49 + 9711dc2 commit ad7f8de
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/main/groovy/com/cloudbees/plugins/flow/JobInvocation.groovy
Expand Up @@ -110,7 +110,15 @@ public class JobInvocation {
/* package */ boolean abort() {
def aborted = false
if (!started) {
aborted = future.cancel(false)
// Need to search the queue for the correct job and cancel it in
// the queue.
def queue = Jenkins.instance.queue
for (queueItem in queue.items) {
if (future == queueItem.getFuture()) {
aborted = queue.cancel(queueItem)
break;
}
}
}
else if (!completed) {
// as the task has already started we want to be kinder in recording the cause.
Expand Down
62 changes: 62 additions & 0 deletions src/test/groovy/com/cloudbees/plugins/flow/AbortTest.groovy
Expand Up @@ -25,6 +25,10 @@ package com.cloudbees.plugins.flow

import hudson.model.Job
import hudson.model.Result
import jenkins.model.Jenkins
import hudson.model.Cause.UserIdCause;
import hudson.model.ParametersAction;
import hudson.model.StringParameterValue;

/**
* Tests that when a flow is aborted is it reported correctly.
Expand Down Expand Up @@ -150,4 +154,62 @@ class AbortTest extends DSLTestCase {
assertBuildStatus(Result.ABORTED, flow)
}

/**
* Tests that when a Flow is aborted it correctly aborts jobs that it queued.
*/
public void testThatAbortAbortsQueuedJobs() {
File f1 = new File("target/${getName()}_job1.lock")
f1.createNewFile()

Job job1 = createBlockingJob("job1", f1)

BuildFlow flow = new BuildFlow(Jenkins.instance, getName())
flow.concurrentBuild = true;
flow.onCreatedFromScratch()
flow.dsl = """ build("job1", param1: build.number) """

// Start an initially blocked job to to create a queue.
def sfr1 = job1.scheduleBuild2(0,new UserIdCause(), new ParametersAction(new StringParameterValue("param1", "first")));
def fr1 = sfr1.waitForStart()

println("Starting build flows...")
// Start three concurrent flows queueing up a job1,
// wait for the job1 to queue up before starting the next
// flow to ensure a consistent queue.
def queue = Jenkins.instance.queue;
def flows = []
for (i in 1..3) {
def scheduled = flow.scheduleBuild2(0)
def future = scheduled.waitForStart()
while (queue.getItems(job1).size() < i ) {
Thread.sleep(10L);
}
flows.add([flow:scheduled, future: future])
}

// abort the second flow
println("aborting flow #2...")
flows[1].future.oneOffExecutor.interrupt(Result.ABORTED)
println("aborting request sent...")
// wait for the flow to finish executing.
assertBuildStatus(Result.ABORTED, flows[1].flow.get())

// Release the blocked job
System.out.println("releasing jobs")
f1.delete()

waitUntilNoActivityUpTo(25000)

assertRan(job1, 3, Result.SUCCESS)

// Needs to assert that only the aborted build, (param1:2), is missing
// since no records exist when queued builds are cancelled.
assertHasParameter(job1.builds[2], 'param1', 'first')
assertHasParameter(job1.builds[1], 'param1', '1')
assertHasParameter(job1.builds[0], 'param1', '3')

// Assert that non aborted flows succeeded.
assertBuildStatusSuccess(flows[0].flow.get())
assertBuildStatusSuccess(flows[2].flow.get())
}
}

0 comments on commit ad7f8de

Please sign in to comment.