File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\test\src\test\java\hudson\model\labels\LabelExpressionTest.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2010, InfraDNA, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.model.labels;
25
26 import antlr.ANTLRException;
27 import hudson.Launcher;
28 import hudson.model.AbstractBuild;
29 import hudson.model.AbstractProject;
30 import hudson.model.BuildListener;
31 import hudson.model.FreeStyleBuild;
32 import hudson.model.FreeStyleProject;
33 import hudson.model.Label;
34 import hudson.model.Node.Mode;
35 import hudson.slaves.DumbSlave;
36 import hudson.slaves.RetentionStrategy;
37 import org.jvnet.hudson.test.Bug;
38 import org.jvnet.hudson.test.HudsonTestCase;
39 import org.jvnet.hudson.test.SequenceLock;
40 import org.jvnet.hudson.test.TestBuilder;
41
42 import java.io.IOException;
43 import java.lang.reflect.Field;
44 import java.util.Collections;
45 import java.util.concurrent.Callable;
46 import java.util.concurrent.Future;
47
48 /**
49 * @author Kohsuke Kawaguchi
50 */
51 public class LabelExpressionTest extends HudsonTestCase {
52 /**
53 * Verifies the queueing behavior in the presence of the expression.
54 */
55 public void testQueueBehavior() throws Exception {
56 DumbSlave w32 = createSlave("win 32bit",null);
57 DumbSlave w64 = createSlave("win 64bit",null);
58 createSlave("linux 32bit",null);
59
60 final SequenceLock seq = new SequenceLock();
61
62 FreeStyleProject p1 = createFreeStyleProject();
63 p1.getBuildersList().add(new TestBuilder() {
64 public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
65 seq.phase(0); // first, make sure the w32 slave is occupied
66 seq.phase(2);
67 seq.done();
68 return true;
69 }
70 });
71 p1.setAssignedLabel(jenkins.getLabel("win && 32bit"));
72
73 FreeStyleProject p2 = createFreeStyleProject();
74 p2.setAssignedLabel(jenkins.getLabel("win && 32bit"));
75
76 FreeStyleProject p3 = createFreeStyleProject();
77 p3.setAssignedLabel(jenkins.getLabel("win"));
78
79 Future<FreeStyleBuild> f1 = p1.scheduleBuild2(0);
80
81 seq.phase(1); // we schedule p2 build after w32 slave is occupied
82 Future<FreeStyleBuild> f2 = p2.scheduleBuild2(0);
83
84 Thread.sleep(1000); // time window to ensure queue has tried to assign f2 build
85
86 // p3 is tied to 'win', so even though p1 is busy, this should still go ahead and complete
87 FreeStyleBuild b3 = assertBuildStatusSuccess(p3.scheduleBuild2(0));
88 assertSame(w64,b3.getBuiltOn());
89
90 seq.phase(3); // once we confirm that p3 build is over, we let p1 proceed
91
92 // p1 should have been built on w32
93 FreeStyleBuild b1 = assertBuildStatusSuccess(f1);
94 assertSame(w32,b1.getBuiltOn());
95
96 // and so is p2
97 FreeStyleBuild b2 = assertBuildStatusSuccess(f2);
98 assertSame(w32,b2.getBuiltOn());
99 }
100
101 /**
102 * Push the build around to different nodes via the assignment
103 * to make sure it gets where we need it to.
104 */
105 public void testQueueBehavior2() throws Exception {
106 DumbSlave s = createSlave("win",null);
107
108 FreeStyleProject p = createFreeStyleProject();
109
110 p.setAssignedLabel(jenkins.getLabel("!win"));
111 FreeStyleBuild b = assertBuildStatusSuccess(p.scheduleBuild2(0));
112 assertSame(jenkins,b.getBuiltOn());
113
114 p.setAssignedLabel(jenkins.getLabel("win"));
115 b = assertBuildStatusSuccess(p.scheduleBuild2(0));
116 assertSame(s,b.getBuiltOn());
117
118 p.setAssignedLabel(jenkins.getLabel("!win"));
119 b = assertBuildStatusSuccess(p.scheduleBuild2(0));
120 assertSame(jenkins,b.getBuiltOn());
121 }
122
123 /**
124 * Make sure we can reset the label of an existing slave.
125 */
126 public void testSetLabelString() throws Exception {
127 DumbSlave s = createSlave("foo","",null);
128
129 assertSame(s.getLabelString(), "");
130
131 s.setLabelString("bar");
132
133 assertSame(s.getLabelString(), "bar");
134
135 }
136
137 /**
138 * Tests the expression parser.
139 */
140 public void testParser() throws Exception {
141 parseAndVerify("foo", "foo");
142 parseAndVerify("32bit.dot", "32bit.dot");
143 parseAndVerify("foo||bar", "foo || bar");
144
145 // user-given parenthesis is preserved
146 parseAndVerify("foo||bar&&zot", "foo||bar&&zot");
147 parseAndVerify("foo||(bar&&zot)", "foo||(bar&&zot)");
148
149 parseAndVerify("(foo||bar)&&zot", "(foo||bar)&&zot");
150 parseAndVerify("foo->bar", "foo ->\tbar");
151 parseAndVerify("!foo<->bar", "!foo <-> bar");
152 }
153
154 @Bug(8537)
155 public void testParser2() throws Exception {
156 parseAndVerify("aaa&&bbb&&ccc","aaa&&bbb&&ccc");
157 }
158
159 private void parseAndVerify(String expected, String expr) throws ANTLRException {
160 assertEquals(expected, LabelExpression.parseExpression(expr).getName());
161 }
162
163 public void testParserError() throws Exception {
164 parseShouldFail("foo bar");
165 parseShouldFail("foo (bar)");
166 }
167
168 public void testLaxParsing() {
169 // this should parse as an atom
170 LabelAtom l = (LabelAtom) jenkins.getLabel("lucene.zones.apache.org (Solaris 10)");
171 assertEquals(l.getName(),"lucene.zones.apache.org (Solaris 10)");
172 assertEquals(l.getExpression(),"\"lucene.zones.apache.org (Solaris 10)\"");
173 }
174
175 public void testDataCompatibilityWithHostNameWithWhitespace() throws Exception {
176 DumbSlave slave = new DumbSlave("abc def (xyz) : test", "dummy",
177 createTmpDir().getPath(), "1", Mode.NORMAL, "", createComputerLauncher(null), RetentionStrategy.NOOP, Collections.EMPTY_LIST);
178 jenkins.addNode(slave);
179
180
181 FreeStyleProject p = createFreeStyleProject();
182 p.setAssignedLabel(jenkins.getLabel("abc def"));
183 assertEquals("abc def",p.getAssignedLabel().getName());
184 assertEquals("\"abc def\"",p.getAssignedLabel().getExpression());
185
186 // expression should be persisted, not the name
187 Field f = AbstractProject.class.getDeclaredField("assignedNode");
188 f.setAccessible(true);
189 assertEquals("\"abc def\"",f.get(p));
190
191 // but if the name is set, we'd still like to parse it
192 f.set(p,"a:b c");
193 assertEquals("a:b c",p.getAssignedLabel().getName());
194 }
195
196 public void testQuote() {
197 Label l = jenkins.getLabel("\"abc\\\\\\\"def\"");
198 assertEquals("abc\\\"def",l.getName());
199 }
200
201 /**
202 * The name should have parenthesis at the right place to preserve the tree structure.
203 */
204 public void testComposite() {
205 LabelAtom x = jenkins.getLabelAtom("x");
206 assertEquals("!!x",x.not().not().getName());
207 assertEquals("(x||x)&&x",x.or(x).and(x).getName());
208 assertEquals("x&&x||x",x.and(x).or(x).getName());
209 }
210
211 public void testDash() {
212 jenkins.getLabelAtom("solaris-x86");
213 }
214
215 private void parseShouldFail(String expr) {
216 try {
217 LabelExpression.parseExpression(expr);
218 fail(expr + " should fail to parse");
219 } catch (ANTLRException e) {
220 // expected
221 }
222 }
223
224 public void testFormValidation() throws Exception {
225 executeOnServer(new Callable<Object>() {
226 public Object call() throws Exception {
227 Label l = jenkins.getLabel("foo");
228 DumbSlave s = createSlave(l);
229 String msg = FreeStyleProject.DESCRIPTOR.doCheckAssignedLabelString("goo").renderHtml();
230 assertTrue(msg.contains("foo"));
231 assertTrue(msg.contains("goo"));
232
233 msg = FreeStyleProject.DESCRIPTOR.doCheckAssignedLabelString("master && goo").renderHtml();
234 assertTrue(msg.contains("foo"));
235 assertTrue(msg.contains("goo"));
236 return null;
237 }
238 });
239 }
240 }
241