Skip to content
Permalink
Browse files
[FIXED JENKINS-25975] Finally able to delete WatchYourStep; using Sem…
…aphoreStep instead.

Originally-Committed-As: d3ba64ddd6eaaacad401624d5b17809ebbec9b30
  • Loading branch information
jglick committed May 29, 2015
1 parent 9922b51 commit 78b05a55574421d0d9383eab50f926d3954c7dd6
@@ -26,13 +26,11 @@

import hudson.model.queue.QueueTaskFuture;
import hudson.slaves.DumbSlave;
import javax.inject.Inject;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
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.test.steps.WatchYourStep;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
@@ -49,10 +47,6 @@ public abstract class SingleJobTestBase extends Assert {
@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public RestartableJenkinsRule story = new RestartableJenkinsRule();

@Deprecated
@Inject
WatchYourStep.DescriptorImpl watchDescriptor;

// currently executing workflow and its build
public WorkflowJob p;
public WorkflowRun b;
@@ -27,11 +27,7 @@
import com.google.common.base.Function;
import hudson.model.Computer;
import hudson.model.Node;
import hudson.model.ParametersAction;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Queue;
import hudson.model.StringParameterDefinition;
import hudson.model.StringParameterValue;
import hudson.model.TaskListener;
import hudson.model.User;
import hudson.model.labels.LabelAtom;
@@ -58,7 +54,6 @@
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import jenkins.security.QueueItemAuthenticatorConfiguration;
import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.util.JavaEnvUtils;
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
import org.jenkinsci.plugins.workflow.actions.WorkspaceAction;
@@ -103,9 +98,9 @@ public class WorkflowTest extends SingleJobTestBase {
@Override
public void evaluate() throws Throwable {
p = jenkins().createProject(WorkflowJob.class, "demo");
p.setDefinition(new CpsFlowDefinition("watch(new File('" + jenkins().getRootDir() + "/touch'))"));
p.setDefinition(new CpsFlowDefinition("semaphore 'wait'"));
startBuilding();
waitForWorkflowToSuspend();
SemaphoreStep.waitForStart("wait/1", b);
assertTrue(b.isBuilding());
assertFalse(jenkins().toComputer().isIdle());
}
@@ -119,8 +114,7 @@ public void evaluate() throws Throwable {
Thread.sleep(100);
}
assertFalse(jenkins().toComputer().isIdle());
FileUtils.write(new File(jenkins().getRootDir(), "touch"), "I'm here");
watchDescriptor.watchUpdate();
SemaphoreStep.success("wait/1", null);
story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
}
});
@@ -158,7 +152,7 @@ public void evaluate() throws Throwable {
@Override public void evaluate() throws Throwable {
rebuildContext(story.j);
assertThatWorkflowIsSuspended();
SemaphoreStep.success("wait/1", story);
SemaphoreStep.success("wait/1", null);
story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
}
});
@@ -180,37 +174,22 @@ public void evaluate() throws Throwable {
p = jenkins().createProject(WorkflowJob.class, "demo");
p.setDefinition(new CpsFlowDefinition(
"node('" + s.getNodeName() + "') {\n" +
// TODO this has been observed to print the basename command, but not echo the result; why?
" sh('echo before=`basename $PWD`')\n" +
" sh('echo ONSLAVE=$ONSLAVE')\n" +

// we'll suspend the execution here
" watch(new File('" + jenkins().getRootDir() + "/touch'))\n" +

" semaphore 'wait'\n" +
" sh('echo after=$PWD')\n" +
"}"));

startBuilding();

// wait until the execution gets to the watch task
while (watchDescriptor.getActiveWatches().isEmpty()) {
assertTrue(b.isBuilding());
waitForWorkflowToSuspend();
}
SemaphoreStep.waitForStart("wait/1", b);
}
});
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
rebuildContext(story.j);
assertThatWorkflowIsSuspended();

FileUtils.write(new File(jenkins().getRootDir(), "touch"), "I'm here");

while (!e.isComplete()) {
e.waitForSuspension();
}

assertBuildCompletedSuccessfully(); // TODO sometimes fails even though Allocate node : End has been printed
SemaphoreStep.success("wait/1", null);
story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));

story.j.assertLogContains("before=demo", b);
story.j.assertLogContains("ONSLAVE=true", b);
@@ -233,20 +212,18 @@ public void evaluate() throws Throwable {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
p = jenkins().createProject(WorkflowJob.class, "demo");
String script = "node {watch(new File('" + jenkins().getRootDir() + "/touch'))}";
String script = "node {semaphore 'wait'}";
p.setDefinition(new CpsFlowDefinition(script));
startBuilding();
waitForWorkflowToSuspend();
// intentionally not waiting for watch step to begin
// intentionally not waiting for semaphore step to begin
}
});
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
rebuildContext(story.j);
FileUtils.write(new File(jenkins().getRootDir(), "touch"), "");
watchDescriptor.watchUpdate();
waitForWorkflowToComplete();
assertBuildCompletedSuccessfully();
SemaphoreStep.success("wait/1", null);
story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
}
});
}
@@ -406,30 +383,23 @@ private void startJnlpProc() throws Exception {
String slaveRoot = story.j.createTmpDir().getPath();
jenkins().addNode(new DumbSlave("slave", "dummy", slaveRoot, "2", Node.Mode.NORMAL, "", story.j.createComputerLauncher(null), RetentionStrategy.NOOP, Collections.<NodeProperty<?>>emptyList()));
p = jenkins().createProject(WorkflowJob.class, "demo");
p.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("FLAG", null)));
p.setDefinition(new CpsFlowDefinition(
"node('slave') {\n" + // this locks the WS
" sh('echo default=`basename $PWD`')\n" +
" ws {\n" + // and this locks a second one
" sh('echo before=`basename $PWD`')\n" +
" watch(new File('" + jenkins().getRootDir() + "', FLAG))\n" +
" semaphore 'wait'\n" +
" sh('echo after=`basename $PWD`')\n" +
" }\n" +
"}"
));
p.save();
WorkflowRun b1 = p.scheduleBuild2(0, new ParametersAction(new StringParameterValue("FLAG", "one"))).waitForStart();
CpsFlowExecution e1 = (CpsFlowExecution) b1.getExecutionPromise().get();
while (watchDescriptor.getActiveWatches().isEmpty()) {
assertTrue(b1.isBuilding());
waitForWorkflowToSuspend(e1);
}
WorkflowRun b2 = p.scheduleBuild2(0, new ParametersAction(new StringParameterValue("FLAG", "two"))).waitForStart();
CpsFlowExecution e2 = (CpsFlowExecution) b2.getExecutionPromise().get();
while (watchDescriptor.getActiveWatches().size() == 1) {
assertTrue(b2.isBuilding());
waitForWorkflowToSuspend(e2);
}
WorkflowRun b1 = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.waitForStart("wait/1", b1);
assertTrue(b1.isBuilding());
WorkflowRun b2 = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.waitForStart("wait/2", b2);
assertTrue(b2.isBuilding());
}
});
story.addStep(new Statement() {
@@ -441,20 +411,20 @@ private void startJnlpProc() throws Exception {
WorkflowRun b2 = p.getBuildByNumber(2);
CpsFlowExecution e2 = (CpsFlowExecution) b2.getExecution();
assertThatWorkflowIsSuspended(b2, e2);
FileUtils.write(new File(jenkins().getRootDir(), "one"), "here");
FileUtils.write(new File(jenkins().getRootDir(), "two"), "here");
SemaphoreStep.success("wait/1", null);
SemaphoreStep.success("wait/2", null);
story.j.waitUntilNoActivity();
assertBuildCompletedSuccessfully(b1);
assertBuildCompletedSuccessfully(b2);
// TODO sometimes basename is run but echo is not, or output lost; once got ‘InvalidClassException: cannot bind non-proxy descriptor to a proxy class’ inside BourneShellScript.doLaunch
// TODO once got ‘InvalidClassException: cannot bind non-proxy descriptor to a proxy class’ inside BourneShellScript.doLaunch
story.j.assertLogContains("default=demo", b1);
story.j.assertLogContains("before=demo@2", b1);
story.j.assertLogContains("after=demo@2", b1);
story.j.assertLogContains("default=demo@3", b2);
story.j.assertLogContains("before=demo@4", b2);
story.j.assertLogContains("after=demo@4", b2);
FileUtils.write(new File(jenkins().getRootDir(), "three"), "here");
WorkflowRun b3 = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0, new ParametersAction(new StringParameterValue("FLAG", "three"))));
SemaphoreStep.success("wait/3", null);
WorkflowRun b3 = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
story.j.assertLogContains("default=demo", b3);
story.j.assertLogContains("before=demo@2", b3);
story.j.assertLogContains("after=demo@2", b3);
@@ -472,21 +442,15 @@ private void startJnlpProc() throws Exception {
p.setDefinition(new CpsFlowDefinition(
"int count=0;\n" +
"retry(3) {\n" +
// we'll suspend the execution here
" watch(new File('" + jenkins().getRootDir() + "/touch'))\n" +

" semaphore 'wait'\n" +
" if (count++ < 2) {\n" + // forcing retry
" error 'died'\n" +
" }\n" +
"}"));

startBuilding();

// wait until the execution gets to the watch task
while (watchDescriptor.getActiveWatches().isEmpty()) {
assertTrue(b.isBuilding());
waitForWorkflowToSuspend();
}
SemaphoreStep.waitForStart("wait/1", b);
assertTrue(b.isBuilding());
}
});
story.addStep(new Statement() {
@@ -495,15 +459,12 @@ private void startJnlpProc() throws Exception {
assertThatWorkflowIsSuspended();

// resume execution and cause the retry to invoke the body again
FileUtils.write(new File(jenkins().getRootDir(), "touch"), "I'm here");

while (!e.isComplete()) {
e.waitForSuspension();
}
SemaphoreStep.success("wait/1", null);
SemaphoreStep.success("wait/2", null);
SemaphoreStep.success("wait/3", null);

story.j.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
assertTrue(e.programPromise.get().closures.isEmpty());

assertBuildCompletedSuccessfully();
}
});
}

0 comments on commit 78b05a5

Please sign in to comment.