Skip to content

Commit 51869f7

Browse files
authored
Merge pull request #306 from gbhat618/support-step-display-function-name-and-exception-verification
Expose StepDescriptor in DefaultStepContext.get
2 parents 2a79d8a + 27eef34 commit 51869f7

3 files changed

Lines changed: 103 additions & 1 deletion

File tree

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@
8080
<scope>import</scope>
8181
<type>pom</type>
8282
</dependency>
83+
<!-- TODO remove this after bom is updated; currently required for code merged in
84+
https://github.com/jenkinsci/workflow-step-api-plugin/pull/204 -->
85+
<dependency>
86+
<groupId>org.jenkins-ci.plugins.workflow</groupId>
87+
<artifactId>workflow-step-api</artifactId>
88+
<version>700.v6e45cb_a_5a_a_21</version>
89+
</dependency>
8390
</dependencies>
8491
</dependencyManagement>
8592
<dependencies>

src/main/java/org/jenkinsci/plugins/workflow/support/DefaultStepContext.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
import org.jenkinsci.plugins.workflow.flow.FlowExecution;
5050
import org.jenkinsci.plugins.workflow.flow.GraphListener;
5151
import org.jenkinsci.plugins.workflow.graph.FlowNode;
52+
import org.jenkinsci.plugins.workflow.graph.StepNode;
5253
import org.jenkinsci.plugins.workflow.log.TaskListenerDecorator;
5354
import org.jenkinsci.plugins.workflow.steps.EnvironmentExpander;
5455
import org.jenkinsci.plugins.workflow.steps.StepContext;
56+
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
5557
import org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction;
5658
import org.jenkinsci.plugins.workflow.support.actions.LogStorageAction;
5759

@@ -70,7 +72,7 @@ public abstract class DefaultStepContext extends StepContext {
7072
/**
7173
* Uses {@link #doGet} but automatically translates certain kinds of objects into others.
7274
* <p>Note that some basic types are handled directly by {@link #get} and cannot be overridden,
73-
* such as {@link Run}, {@link Job}, {@link FlowExecution}, and {@link FlowNode}.
75+
* such as {@link Run}, {@link Job}, {@link FlowExecution}, {@link FlowNode} and {@link StepDescriptor}.
7476
* <p>{@inheritDoc}
7577
*/
7678
@Override public final <T> T get(Class<T> key) throws IOException, InterruptedException {
@@ -83,6 +85,11 @@ public abstract class DefaultStepContext extends StepContext {
8385
value = castOrNull(key, getExecution());
8486
} else if (FlowNode.class.isAssignableFrom(key)) {
8587
value = castOrNull(key, getNode());
88+
} else if (StepDescriptor.class.isAssignableFrom(key)) {
89+
var stepNode = castOrNull(StepNode.class, getNode());
90+
if (stepNode != null) {
91+
value = castOrNull(key, stepNode.getDescriptor());
92+
}
8693
}
8794
if (value != null) {
8895
return value;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package org.jenkinsci.plugins.workflow.test.steps;
2+
3+
import java.util.Set;
4+
5+
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
6+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
7+
import org.jenkinsci.plugins.workflow.steps.Step;
8+
import org.jenkinsci.plugins.workflow.steps.StepContext;
9+
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
10+
import org.jenkinsci.plugins.workflow.steps.StepExecution;
11+
import org.jenkinsci.plugins.workflow.steps.StepExecutions;
12+
import org.junit.ClassRule;
13+
import org.junit.Rule;
14+
import org.junit.Test;
15+
import org.jvnet.hudson.test.BuildWatcher;
16+
import org.jvnet.hudson.test.JenkinsSessionRule;
17+
import org.jvnet.hudson.test.TestExtension;
18+
import org.kohsuke.stapler.DataBoundConstructor;
19+
20+
import hudson.model.TaskListener;
21+
22+
import static org.hamcrest.MatcherAssert.assertThat;
23+
import static org.hamcrest.Matchers.allOf;
24+
import static org.hamcrest.Matchers.containsString;
25+
26+
public class SynchronousResumeNotSupportedExceptionTest {
27+
28+
@ClassRule
29+
public static BuildWatcher bw = new BuildWatcher();
30+
31+
@Rule
32+
public JenkinsSessionRule rjr = new JenkinsSessionRule();
33+
34+
@Test
35+
public void test_SynchronousResumeNotSupportedException_ShouldShowFailedStep_AndSuggestRetry() throws Throwable {
36+
rjr.then(j -> {
37+
WorkflowJob p = j.createProject(WorkflowJob.class, "p");
38+
p.setDefinition(new CpsFlowDefinition("simulatedSleep 20", true));
39+
var run = p.scheduleBuild2(0).waitForStart();
40+
j.waitForMessage("Going to sleep for", run);
41+
});
42+
rjr.then(j -> {
43+
var b = j.jenkins.getItemByFullName("p", WorkflowJob.class).getBuildByNumber(1);
44+
j.waitForCompletion(b);
45+
assertThat(b.getLog(), allOf(
46+
containsString("nonresumable"),
47+
containsString("retry"),
48+
containsString("simulatedSleep"),
49+
containsString("retries")));
50+
});
51+
}
52+
53+
@SuppressWarnings("unused")
54+
public static class SimulatedSleepStep extends Step {
55+
56+
private final int sleepSeconds;
57+
58+
@DataBoundConstructor
59+
public SimulatedSleepStep(int sleepSeconds) {
60+
this.sleepSeconds = sleepSeconds;
61+
}
62+
63+
@Override
64+
public StepExecution start(StepContext context) throws Exception {
65+
return StepExecutions.synchronousNonBlockingVoid(context, c -> {
66+
var buildLogger = context.get(TaskListener.class).getLogger();
67+
buildLogger.println("Simulated sleep step started");
68+
buildLogger.println("Going to sleep for " + sleepSeconds + " seconds");
69+
Thread.sleep(sleepSeconds * 1000L);
70+
buildLogger.println("Simulated sleep step completed");
71+
});
72+
}
73+
74+
@TestExtension
75+
public static final class DescriptorImpl extends StepDescriptor {
76+
77+
@Override
78+
public Set<? extends Class<?>> getRequiredContext() {
79+
return Set.of(TaskListener.class);
80+
}
81+
82+
@Override
83+
public String getFunctionName() {
84+
return "simulatedSleep";
85+
}
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)