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

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
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;
25
26 import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
27 import com.gargoylesoftware.htmlunit.WebAssert;
28 import com.gargoylesoftware.htmlunit.html.HtmlPage;
29 import com.gargoylesoftware.htmlunit.TextPage;
30
31 import hudson.util.TextFile;
32 import java.io.IOException;
33 import java.net.HttpURLConnection;
34 import java.util.concurrent.CountDownLatch;
35
36 import jenkins.model.ProjectNamingStrategy;
37
38 import org.jvnet.hudson.test.Bug;
39 import org.jvnet.hudson.test.HudsonTestCase;
40 import org.jvnet.hudson.test.recipes.LocalData;
41
42 /**
43 * @author Kohsuke Kawaguchi
44 */
45 public class JobTest extends HudsonTestCase {
46
47 @SuppressWarnings("unchecked")
48 public void testJobPropertySummaryIsShownInMainPage() throws Exception {
49 AbstractProject project = createFreeStyleProject();
50 project.addProperty(new JobPropertyImpl("NeedleInPage"));
51
52 HtmlPage page = new WebClient().getPage(project);
53 WebAssert.assertTextPresent(page, "NeedleInPage");
54 }
55
56 public void testBuildNumberSynchronization() throws Exception {
57 AbstractProject project = createFreeStyleProject();
58 CountDownLatch startLatch = new CountDownLatch(1);
59 CountDownLatch stopLatch = new CountDownLatch(2);
60 BuildNumberSyncTester test1 = new BuildNumberSyncTester(project, startLatch, stopLatch, true);
61 BuildNumberSyncTester test2 = new BuildNumberSyncTester(project, startLatch, stopLatch, false);
62 new Thread(test1).start();
63 new Thread(test2).start();
64
65 startLatch.countDown();
66 stopLatch.await();
67
68 assertTrue(test1.message, test2.passed);
69 assertTrue(test2.message, test2.passed);
70 }
71
72 public static class BuildNumberSyncTester implements Runnable {
73 private final AbstractProject p;
74 private final CountDownLatch start;
75 private final CountDownLatch stop;
76 private final boolean assign;
77
78 String message;
79 boolean passed;
80
81 BuildNumberSyncTester(AbstractProject p, CountDownLatch l1, CountDownLatch l2, boolean b) {
82 this.p = p;
83 this.start = l1;
84 this.stop = l2;
85 this.assign = b;
86 this.message = null;
87 this.passed = false;
88 }
89
90 public void run() {
91 try {
92 start.await();
93
94 for (int i = 0; i < 100; i++) {
95 int buildNumber = -1, savedBuildNumber = -1;
96 TextFile f;
97
98 synchronized (p) {
99 if (assign) {
100 buildNumber = p.assignBuildNumber();
101 f = p.getNextBuildNumberFile();
102 if (f == null) {
103 this.message = "Could not get build number file";
104 this.passed = false;
105 return;
106 }
107 savedBuildNumber = Integer.parseInt(f.readTrim());
108 if (buildNumber != (savedBuildNumber-1)) {
109 this.message = "Build numbers don't match (" + buildNumber + ", " + (savedBuildNumber-1) + ")";
110 this.passed = false;
111 return;
112 }
113 } else {
114 buildNumber = p.getNextBuildNumber() + 100;
115 p.updateNextBuildNumber(buildNumber);
116 f = p.getNextBuildNumberFile();
117 if (f == null) {
118 this.message = "Could not get build number file";
119 this.passed = false;
120 return;
121 }
122 savedBuildNumber = Integer.parseInt(f.readTrim());
123 if (buildNumber != savedBuildNumber) {
124 this.message = "Build numbers don't match (" + buildNumber + ", " + savedBuildNumber + ")";
125 this.passed = false;
126 return;
127 }
128 }
129 }
130 }
131
132 this.passed = true;
133 }
134 catch (InterruptedException e) {}
135 catch (IOException e) {
136 fail("Failed to assign build number");
137 }
138 finally {
139 stop.countDown();
140 }
141 }
142 }
143
144 @SuppressWarnings("unchecked")
145 public static class JobPropertyImpl extends JobProperty<Job<?,?>> {
146 public static DescriptorImpl DESCRIPTOR = new DescriptorImpl();
147 private final String testString;
148
149 public JobPropertyImpl(String testString) {
150 this.testString = testString;
151 }
152
153 public String getTestString() {
154 return testString;
155 }
156
157 @Override
158 public JobPropertyDescriptor getDescriptor() {
159 return DESCRIPTOR;
160 }
161
162 private static final class DescriptorImpl extends JobPropertyDescriptor {
163 public String getDisplayName() {
164 return "";
165 }
166 }
167 }
168
169 @LocalData
170 public void testReadPermission() throws Exception {
171 WebClient wc = new WebClient();
172 wc.assertFails("job/testJob/", HttpURLConnection.HTTP_NOT_FOUND);
173 wc.assertFails("jobCaseInsensitive/testJob/", HttpURLConnection.HTTP_NOT_FOUND);
174 wc.login("joe"); // Has Item.READ permission
175 // Verify we can access both URLs:
176 wc.goTo("job/testJob/");
177 wc.goTo("jobCaseInsensitive/TESTJOB/");
178 }
179
180 @LocalData
181 public void testConfigDotXmlPermission() throws Exception {
182 jenkins.setCrumbIssuer(null);
183 WebClient wc = new WebClient();
184 boolean saveEnabled = Item.EXTENDED_READ.getEnabled();
185 Item.EXTENDED_READ.setEnabled(true);
186 try {
187 wc.assertFails("job/testJob/config.xml", HttpURLConnection.HTTP_FORBIDDEN);
188 wc.login("alice"); // Has CONFIGURE and EXTENDED_READ permission
189 tryConfigDotXml(wc, 500, "Both perms; should get 500");
190 wc.login("bob"); // Has only CONFIGURE permission (this should imply EXTENDED_READ)
191 tryConfigDotXml(wc, 500, "Config perm should imply EXTENDED_READ");
192 wc.login("charlie"); // Has only EXTENDED_READ permission
193 tryConfigDotXml(wc, 403, "No permission, should get 403");
194 } finally {
195 Item.EXTENDED_READ.setEnabled(saveEnabled);
196 }
197 }
198
199 private static void tryConfigDotXml(WebClient wc, int status, String msg) throws Exception {
200 // Verify we can GET the config.xml:
201 wc.goTo("job/testJob/config.xml", "application/xml");
202 // This page is a simple form to POST to /job/testJob/config.xml
203 // But it posts invalid data so we expect 500 if we have permission, 403 if not
204 HtmlPage page = wc.goTo("userContent/post.html");
205 try {
206 page.getForms().get(0).submit();
207 fail("Expected exception: " + msg);
208 } catch (FailingHttpStatusCodeException expected) {
209 assertEquals(msg, status, expected.getStatusCode());
210 }
211 wc.goTo("logout");
212 }
213
214 @LocalData @Bug(6371)
215 public void testGetArtifactsUpTo() throws Exception {
216 // There was a bug where intermediate directories were counted,
217 // so too few artifacts were returned.
218 Run r = jenkins.getItemByFullName("testJob", Job.class).getLastCompletedBuild();
219 assertEquals(3, r.getArtifacts().size());
220 assertEquals(3, r.getArtifactsUpTo(3).size());
221 assertEquals(2, r.getArtifactsUpTo(2).size());
222 assertEquals(1, r.getArtifactsUpTo(1).size());
223 }
224
225 @Bug(10182)
226 public void testEmptyDescriptionReturnsEmptyPage() throws Exception {
227 // A NPE was thrown if a job had a null (empty) description.
228 WebClient wc = createWebClient();
229 FreeStyleProject project = createFreeStyleProject("project");
230 project.setDescription("description");
231 assertEquals("description", ((TextPage) wc.goTo("job/project/description", "text/plain")).getContent());
232 project.setDescription(null);
233 assertEquals("", ((TextPage) wc.goTo("job/project/description", "text/plain")).getContent());
234 }
235
236 public void testProjectNamingStrategy() throws Exception {
237 jenkins.setProjectNamingStrategy(new ProjectNamingStrategy.PatternProjectNamingStrategy("DUMMY.*", false));
238 final FreeStyleProject p = createFreeStyleProject("DUMMY_project");
239 assertNotNull("no project created", p);
240 try {
241 createFreeStyleProject("project");
242 fail("should not get here, the project name is not allowed, therefore the creation must fail!");
243 } catch (Failure e) {
244 // OK, expected
245 }finally{
246 // set it back to the default naming strategy, otherwise all other tests would fail to create jobs!
247 jenkins.setProjectNamingStrategy(ProjectNamingStrategy.DEFAULT_NAMING_STRATEGY);
248 }
249 createFreeStyleProject("project");
250 }
251 }
252