-
Notifications
You must be signed in to change notification settings - Fork 189
/
DSLTest.java
234 lines (211 loc) · 10.8 KB
/
DSLTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* The MIT License
*
* Copyright 2014 Jesse Glick.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jenkinsci.plugins.workflow;
import hudson.model.Result;
import javax.inject.Inject;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
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.AbstractStepImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousStepExecution;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestExtension;
import org.kohsuke.stapler.DataBoundConstructor;
/**
* Verifies general DSL functionality.
*/
public class DSLTest {
@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public JenkinsRule r = new JenkinsRule();
@Test public void overrideFunction() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("echo 'this came from a step'"));
r.assertLogContains("this came from a step", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
p.setDefinition(new CpsFlowDefinition("def echo(s) {println s.toUpperCase()}\necho 'this came from my own function'\nsteps.echo 'but this is still from a step'", true));
WorkflowRun b2 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("THIS CAME FROM MY OWN FUNCTION", b2);
r.assertLogContains("but this is still from a step", b2);
}
@Test public void flattenGString() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("def x = 'the message'; echo \"What is ${x}?\""));
r.assertLogContains("What is the message?", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
/**
* Tests the ability to execute meta-step with clean syntax
*/
@Issue("JENKINS-29922")
@Test
public void dollar_class_must_die() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "die1");
p.setDefinition(new CpsFlowDefinition("california ocean:'pacific', mountain:'sierra'"));
r.assertLogContains("California from pacific to sierra", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
/**
* Split arguments between meta step and state
*/
@Issue("JENKINS-29922")
@Test
public void dollar_class_must_die2() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "die2");
p.setDefinition(new CpsFlowDefinition("california ocean:'pacific', mountain:'sierra', moderate:true"));
r.assertLogContains("Introducing california\nCalifornia from pacific to sierra", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
/**
* Split arguments between meta step and state
*/
@Issue("JENKINS-29922")
@Test
public void dollar_class_must_die3() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "die3");
p.setDefinition(new CpsFlowDefinition("nevada()"));
r.assertLogContains("All For Our Country", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
/**
* Split arguments between meta step and state, when argument is colliding
*/
@Issue("JENKINS-29922")
@Test
public void dollar_class_must_die_colliding_argument() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "die5");
p.setDefinition(new CpsFlowDefinition("newYork motto:'Empire', moderate:true"));
WorkflowRun run = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("Introducing newYork\nThe Empire State", run);
r.assertLogNotContains("New York can be moderate in spring or fall", run);
}
/**
* Single argument state
*/
@Issue("JENKINS-29922")
@Test
public void dollar_class_must_die_onearg() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "die4");
p.setDefinition(new CpsFlowDefinition("newYork 'Empire'"));
r.assertLogContains("The Empire State", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
@Issue("JENKINS-29922")
@Test
public void nonexistentFunctions() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("nonexistent()"));
WorkflowRun b = r.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0));
r.assertLogContains("nonexistent", b);
r.assertLogContains("wrapInCurve", b);
r.assertLogContains("polygon", b);
}
@Issue("JENKINS-29922")
@Test public void runMetaBlockStep() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("circle {echo 'interior is a disk'}", true));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("wrapping in a circle", b);
r.assertLogContains("interior is a disk", b);
p.setDefinition(new CpsFlowDefinition("polygon(17) {echo 'constructible with compass and straightedge'}", true));
b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("wrapping in a 17-gon", b);
r.assertLogContains("constructible with compass and straightedge", b);
}
/**
* Tests the ability to execute a step with an unnamed monomorphic describable argument.
*/
@Issue("JENKINS-29711")
@Test
public void monomorphic() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "mon");
p.setDefinition(new CpsFlowDefinition("monomorphStep([firstArg:'one', secondArg:'two'])", true));
r.assertLogContains("First arg: one, second arg: two", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
@Issue("JENKINS-29711")
@Test
public void monomorphicSymbol() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "monSymbol");
p.setDefinition(new CpsFlowDefinition("monomorphWithSymbolStep monomorphSymbol(firstArg: 'one', secondArg: 'two')", true));
r.assertLogContains("First arg: one, second arg: two", r.assertBuildStatusSuccess(p.scheduleBuild2(0)));
}
/**
* Tests the ability to execute a step with an unnamed monomorphic list argument.
*/
@Issue("JENKINS-29711")
@Test
public void monomorphicList() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "monList");
p.setDefinition(new CpsFlowDefinition("monomorphListStep([[firstArg:'one', secondArg:'two'], [firstArg:'three', secondArg:'four']])", true));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("First arg: one, second arg: two", b);
r.assertLogContains("First arg: three, second arg: four", b);
}
@Issue("JENKINS-29711")
@Test
public void monomorphicListWithSymbol() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "monListSymbol");
p.setDefinition(new CpsFlowDefinition("monomorphListSymbolStep([monomorphSymbol(firstArg: 'one', secondArg: 'two'), monomorphSymbol(firstArg: 'three', secondArg: 'four')])", true));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("First arg: one, second arg: two", b);
r.assertLogContains("First arg: three, second arg: four", b);
}
@Issue("JENKINS-38037")
@Test
public void metaStepSyntaxForDataBoundSetters() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "metaStepSyntaxForDataBoundSetters");
p.setDefinition(new CpsFlowDefinition("multiShape(count: 2, name: 'pentagon') { echo 'Multiple shapes' }", true));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("wrapping in a group of 2 instances of pentagon", b);
r.assertLogContains("Multiple shapes", b);
}
@Issue("JENKINS-38169")
@Test
public void namedSoleParamForStep() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "namedSoleParamForStep");
p.setDefinition(new CpsFlowDefinition("echo message:'Hello world'", true));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
r.assertLogContains("Hello world", b);
}
@Test public void contextClassLoader() throws Exception {
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("try {def c = classLoad(getClass().name); error(/did not expect to be able to load ${c} from ${c.classLoader}/)} catch (ClassNotFoundException x) {echo(/good, got ${x}/)}", false));
r.assertBuildStatusSuccess(p.scheduleBuild2(0));
}
public static class CLStep extends AbstractStepImpl {
public final String name;
@DataBoundConstructor public CLStep(String name) {this.name = name;}
public static class Execution extends AbstractSynchronousStepExecution<Class<?>> {
@Inject CLStep step;
protected Class<?> run() throws Exception {
return Thread.currentThread().getContextClassLoader().loadClass(step.name);
}
}
@TestExtension("contextClassLoader") public static class DescriptorImpl extends AbstractStepDescriptorImpl {
public DescriptorImpl() {super(Execution.class);}
@Override public String getFunctionName() {
return "classLoad";
}
}
}
}