Skip to content

Commit

Permalink
Merge pull request #925 from jglick/capturedBodies
Browse files Browse the repository at this point in the history
Clear `CpsBodyExecution.thread`
  • Loading branch information
jglick authored Aug 26, 2024
2 parents 3519a32 + 48ab09b commit 7935cbe
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ public Next receive(Object o) {
sc.onFailure(t);
}
}
synchronized (CpsBodyExecution.this) {
thread = null;
}
return Next.terminate(null);
}

Expand All @@ -377,6 +380,9 @@ public Next receive(Object o) {
sc.onFailure(e);
}
}
synchronized (CpsBodyExecution.this) {
thread = null;
}
return Next.terminate(null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ private void checkAllDone(boolean stepFailed) {
} else {
handler.context.onSuccess(success);
}
// TODO should this also bodies.clear()?

Check warning on line 179 in plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: should this also bodies.clear()?
}

private static final long serialVersionUID = 1L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import groovy.lang.Closure;
import hudson.model.Result;
import hudson.slaves.DumbSlave;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.jenkinsci.plugins.workflow.actions.ErrorAction;
import org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode;
Expand All @@ -31,22 +34,23 @@
import org.junit.Test;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.RestartableJenkinsRule;
import org.jvnet.hudson.test.TestExtension;
import org.kohsuke.stapler.DataBoundConstructor;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.iterableWithSize;
import static org.hamcrest.Matchers.not;
import org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner;
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.jvnet.hudson.test.JenkinsSessionRule;

public class CpsBodyExecutionTest {

@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public RestartableJenkinsRule rr = new RestartableJenkinsRule();
@Rule public JenkinsSessionRule rr = new JenkinsSessionRule();

/**
* When the body of a step is synchronous and explodes, the failure should be recorded and the pipeline job
Expand All @@ -60,7 +64,7 @@ public class CpsBodyExecutionTest {
* never arrives.
*/
@Test
public void synchronousExceptionInBody() throws Exception {
public void synchronousExceptionInBody() throws Throwable {
rr.then(jenkins -> {
WorkflowJob p = jenkins.createProject(WorkflowJob.class);
p.setDefinition(new CpsFlowDefinition("synchronousExceptionInBody()",true));
Expand Down Expand Up @@ -138,7 +142,7 @@ public boolean start() throws Exception {
}

@Issue("JENKINS-34637")
@Test public void currentExecutions() throws Exception {
@Test public void currentExecutions() throws Throwable {
rr.then(jenkins -> {
WorkflowJob p = jenkins.createProject(WorkflowJob.class);
p.setDefinition(new CpsFlowDefinition("parallel main: {retainsBody {parallel a: {retainsBody {semaphore 'a'}}, b: {retainsBody {semaphore 'b'}}}}, aside: {semaphore 'c'}", true));
Expand Down Expand Up @@ -200,7 +204,7 @@ public static class Execution extends AbstractStepExecutionImpl {
}

@Issue({"JENKINS-53709", "JENKINS-41791"})
@Test public void popContextVarsOnBodyCompletion() {
@Test public void popContextVarsOnBodyCompletion() throws Throwable {
rr.then(r -> {
DumbSlave s = r.createOnlineSlave();
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "demo");
Expand All @@ -226,7 +230,7 @@ public static class Execution extends AbstractStepExecutionImpl {
}

@Issue("JENKINS-63164")
@Test public void closureCapturesCpsBodyExecution() {
@Test public void closureCapturesCpsBodyExecution() throws Throwable {
rr.then(r -> {
DumbSlave s = r.createOnlineSlave();
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "demo");
Expand All @@ -253,4 +257,28 @@ public static class Execution extends AbstractStepExecutionImpl {
});
}

@Test public void capturedBodies() throws Throwable {
var semaphores = List.of("y1", "y2");
AtomicReference<Path> buildXml = new AtomicReference<>();
rr.then(r -> {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("parallel x1: {}, x2: {g = {x -> x + 1}; echo(/${g(1)}/)}; parallel y1: {semaphore 'y1'}, y2: {semaphore 'y2'}", true));
WorkflowRun b = p.scheduleBuild2(0).waitForStart();
for (var semaphore : semaphores) {
SemaphoreStep.waitForStart(semaphore + "/1", b);
}
buildXml.set(b.getRootDir().toPath().resolve("build.xml"));
});
Files.copy(buildXml.get(), System.out);
rr.then(r -> {
WorkflowJob p = r.jenkins.getItemByFullName("p", WorkflowJob.class);
WorkflowRun b = p.getLastBuild();
for (var semaphore : semaphores) {
SemaphoreStep.success(semaphore + "/1", null);
}
r.assertBuildStatusSuccess(r.waitForCompletion(b));
new DepthFirstScanner().allNodes(b.getExecution()).stream().sorted(Comparator.comparing(n -> Integer.valueOf(n.getId()))).forEach(n -> System.out.println(n.getId() + " " + n.getDisplayName()));
});
}

}

0 comments on commit 7935cbe

Please sign in to comment.