Skip to content

Commit

Permalink
[FIXED JENKINS-25550] Hard kill.
Browse files Browse the repository at this point in the history
Originally-Committed-As: 60a0db70e7747d212632854deca1efb5e081cd8b
  • Loading branch information
jglick committed Jun 17, 2015
1 parent 0440887 commit 0e97bc5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
Expand Up @@ -25,12 +25,14 @@
package org.jenkinsci.plugins.workflow;

import hudson.model.BallColor;
import hudson.model.Executor;
import hudson.model.Item;
import hudson.model.ParametersAction;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Result;
import hudson.model.StringParameterDefinition;
import hudson.model.StringParameterValue;
import hudson.model.TaskListener;
import hudson.model.User;
import hudson.model.queue.QueueTaskFuture;
import hudson.security.ACL;
Expand All @@ -45,18 +47,26 @@
import org.jenkinsci.plugins.workflow.cps.CpsFlowExecution;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestExtension;
import org.jvnet.hudson.test.recipes.LocalData;
import org.kohsuke.stapler.DataBoundConstructor;

public class WorkflowRunTest {

@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public JenkinsRule r = new JenkinsRule();

WorkflowJob p;
Expand Down Expand Up @@ -201,4 +211,48 @@ public void contextInjectionOfSubParameters() throws Exception {
r.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
}

@Issue("JENKINS-25550")
@Test public void hardKill() throws Exception {
p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("zombie()"));
WorkflowRun b = p.scheduleBuild2(0).waitForStart();
JenkinsRuleExt.waitForMessage("undead", b);
Executor ex = b.getExecutor();
assertNotNull(ex);
ex.interrupt();
JenkinsRuleExt.waitForMessage("bwahaha org.jenkinsci.plugins.workflow.steps.FlowInterruptedException #1", b);
ex.interrupt();
JenkinsRuleExt.waitForMessage("bwahaha org.jenkinsci.plugins.workflow.steps.FlowInterruptedException #2", b);
ex.interrupt();
JenkinsRuleExt.waitForMessage("Hard kill!", b);
JenkinsRuleExt.waitForCompletion(b);
r.assertBuildStatus(Result.ABORTED, b);
}
public static class Zombie extends AbstractStepImpl {
@DataBoundConstructor public Zombie() {}
public static class Execution extends AbstractStepExecutionImpl {
@StepContextParameter private transient TaskListener listener;
int count;
@Override public boolean start() throws Exception {
listener.getLogger().println("undead");
return false;
}
@Override public void stop(Throwable cause) throws Exception {
listener.getLogger().println("bwahaha " + cause + " #" + ++count);
}

}
@TestExtension("hardKill") public static class DescriptorImpl extends AbstractStepDescriptorImpl {
public DescriptorImpl() {
super(Execution.class);
}
@Override public String getFunctionName() {
return "zombie";
}
@Override public String getDisplayName() {
return "zombie";
}
}
}

}
Expand Up @@ -68,6 +68,7 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -202,10 +203,16 @@ public WorkflowRun(WorkflowJob job, File dir) throws IOException {

private AsynchronousExecution sleep() {
final AsynchronousExecution asynchronousExecution = new AsynchronousExecution() {
AtomicInteger interruptionCount = new AtomicInteger();
@Override public void interrupt(boolean forShutdown) {
if (forShutdown) {
return;
}
if (interruptionCount.incrementAndGet() == 3) {
listener.getLogger().println("Hard kill!");
finish(Result.ABORTED);
return;
}
try {
execution.interrupt(Result.ABORTED);
} catch (Exception x) {
Expand Down Expand Up @@ -503,7 +510,7 @@ public boolean hasntStartedYet() {

@Exported
@Override protected boolean isInProgress() {
return execution != null && !execution.isComplete();
return execution != null && !execution.isComplete() && (completed == null || !completed.get());
}

@Override public boolean isLogUpdated() {
Expand Down

0 comments on commit 0e97bc5

Please sign in to comment.