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

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
5 * Daniel Dyer, Erik Ramfelt, Richard Bair, id:cactusman
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25 package hudson;
26
27 import java.util.Map;
28 import java.util.HashMap;
29 import java.util.Locale;
30 import java.io.ByteArrayOutputStream;
31 import java.io.File;
32 import java.io.IOException;
33
34 import static org.junit.Assert.*;
35 import org.junit.Assume;
36 import org.junit.Test;
37 import org.jvnet.hudson.test.Bug;
38
39 import hudson.util.StreamTaskListener;
40
41 /**
42 * @author Kohsuke Kawaguchi
43 */
44 public class UtilTest {
45 @Test
46 public void testReplaceMacro() {
47 Map<String,String> m = new HashMap<String,String>();
48 m.put("A","a");
49 m.put("AA","aa");
50 m.put("B","B");
51 m.put("DOLLAR", "$");
52 m.put("ENCLOSED", "a${A}");
53
54 // longest match
55 assertEquals("aa",Util.replaceMacro("$AA",m));
56
57 // invalid keys are ignored
58 assertEquals("$AAB",Util.replaceMacro("$AAB",m));
59
60 assertEquals("aaB",Util.replaceMacro("${AA}B",m));
61 assertEquals("${AAB}",Util.replaceMacro("${AAB}",m));
62
63 // $ escaping
64 assertEquals("asd$${AA}dd", Util.replaceMacro("asd$$$${AA}dd",m));
65 assertEquals("$", Util.replaceMacro("$$",m));
66 assertEquals("$$", Util.replaceMacro("$$$$",m));
67
68 // test that more complex scenarios work
69 assertEquals("/a/B/aa", Util.replaceMacro("/$A/$B/$AA",m));
70 assertEquals("a-aa", Util.replaceMacro("$A-$AA",m));
71 assertEquals("/a/foo/can/B/you-believe_aa~it?", Util.replaceMacro("/$A/foo/can/$B/you-believe_$AA~it?",m));
72 assertEquals("$$aa$Ba${A}$it", Util.replaceMacro("$$$DOLLAR${AA}$$B${ENCLOSED}$it",m));
73 }
74
75 @Test
76 public void testTimeSpanString() {
77 // Check that amounts less than 365 days are not rounded up to a whole year.
78 // In the previous implementation there were 360 days in a year.
79 // We're still working on the assumption that a month is 30 days, so there will
80 // be 5 days at the end of the year that will be "12 months" but not "1 year".
81 // First check 359 days.
82 assertEquals(Messages.Util_month(11), Util.getTimeSpanString(31017600000L));
83 // And 362 days.
84 assertEquals(Messages.Util_month(12), Util.getTimeSpanString(31276800000L));
85
86 // 11.25 years - Check that if the first unit has 2 or more digits, a second unit isn't used.
87 assertEquals(Messages.Util_year(11), Util.getTimeSpanString(354780000000L));
88 // 9.25 years - Check that if the first unit has only 1 digit, a second unit is used.
89 assertEquals(Messages.Util_year(9)+ " " + Messages.Util_month(3), Util.getTimeSpanString(291708000000L));
90 // 67 seconds
91 assertEquals(Messages.Util_minute(1) + " " + Messages.Util_second(7), Util.getTimeSpanString(67000L));
92 // 17 seconds - Check that times less than a minute only use seconds.
93 assertEquals(Messages.Util_second(17), Util.getTimeSpanString(17000L));
94 // 1712ms -> 1.7sec
95 assertEquals(Messages.Util_second(1.7), Util.getTimeSpanString(1712L));
96 // 171ms -> 0.17sec
97 assertEquals(Messages.Util_second(0.17), Util.getTimeSpanString(171L));
98 // 101ms -> 0.10sec
99 assertEquals(Messages.Util_second(0.1), Util.getTimeSpanString(101L));
100 // 17ms
101 assertEquals(Messages.Util_millisecond(17), Util.getTimeSpanString(17L));
102 // 1ms
103 assertEquals(Messages.Util_millisecond(1), Util.getTimeSpanString(1L));
104 // Test HUDSON-2843 (locale with comma as fraction separator got exception for <10 sec)
105 Locale saveLocale = Locale.getDefault();
106 Locale.setDefault(Locale.GERMANY);
107 try {
108 // Just verifying no exception is thrown:
109 assertNotNull("German locale", Util.getTimeSpanString(1234));
110 assertNotNull("German locale <1 sec", Util.getTimeSpanString(123));
111 }
112 finally { Locale.setDefault(saveLocale); }
113 }
114
115
116 /**
117 * Test that Strings that contain spaces are correctly URL encoded.
118 */
119 @Test
120 public void testEncodeSpaces() {
121 final String urlWithSpaces = "http://hudson/job/Hudson Job";
122 String encoded = Util.encode(urlWithSpaces);
123 assertEquals(encoded, "http://hudson/job/Hudson%20Job");
124 }
125
126 /**
127 * Test that Strings that contain ampersand are correctly URL encoded.
128 */
129 @Test
130 public void testEncodeAmpersand() {
131 final String urlWithAmpersand = "http://hudson/job/Hudson-job/label1&&label2";
132 String encoded = Util.encode(urlWithAmpersand);
133 assertEquals(encoded, "http://hudson/job/Hudson-job/label1%26%26label2");
134 }
135
136 /**
137 * Test the rawEncode() method.
138 */
139 @Test
140 public void testRawEncode() {
141 String[] data = { // Alternating raw,encoded
142 "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz",
143 "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
144 "01234567890!@$*()-_=+',.", "01234567890!@$*()-_=+',.",
145 " \"#%/:;<>?", "%20%22%23%25%2F%3A%3B%3C%3E%3F",
146 "[\\]^`{|}~", "%5B%5C%5D%5E%60%7B%7C%7D%7E",
147 "d\u00E9velopp\u00E9s", "d%C3%A9velopp%C3%A9s",
148 };
149 for (int i = 0; i < data.length; i += 2) {
150 assertEquals("test " + i, data[i + 1], Util.rawEncode(data[i]));
151 }
152 }
153
154 /**
155 * Test the tryParseNumber() method.
156 */
157 @Test
158 public void testTryParseNumber() {
159 assertEquals("Successful parse did not return the parsed value", 20, Util.tryParseNumber("20", 10).intValue());
160 assertEquals("Failed parse did not return the default value", 10, Util.tryParseNumber("ss", 10).intValue());
161 assertEquals("Parsing empty string did not return the default value", 10, Util.tryParseNumber("", 10).intValue());
162 assertEquals("Parsing null string did not return the default value", 10, Util.tryParseNumber(null, 10).intValue());
163 }
164
165 @Test
166 public void testSymlink() throws Exception {
167 Assume.assumeTrue(!Functions.isWindows());
168
169 ByteArrayOutputStream baos = new ByteArrayOutputStream();
170 StreamTaskListener l = new StreamTaskListener(baos);
171 File d = Util.createTempDir();
172 try {
173 new FilePath(new File(d, "a")).touch(0);
174 assertNull(Util.resolveSymlink(new File(d, "a")));
175 Util.createSymlink(d,"a","x", l);
176 assertEquals("a",Util.resolveSymlink(new File(d,"x")));
177
178 // test a long name
179 StringBuilder buf = new StringBuilder(768);
180 for( int i=0; i<768; i++)
181 buf.append((char)('0'+(i%10)));
182 Util.createSymlink(d,buf.toString(),"x", l);
183
184 String log = baos.toString();
185 if (log.length() > 0)
186 System.err.println("log output: " + log);
187
188 assertEquals(buf.toString(),Util.resolveSymlink(new File(d,"x")));
189
190
191 // test linking from another directory
192 File anotherDir = new File(d,"anotherDir");
193 assertTrue("Couldn't create "+anotherDir,anotherDir.mkdir());
194
195 Util.createSymlink(d,"a","anotherDir/link",l);
196 assertEquals("a",Util.resolveSymlink(new File(d,"anotherDir/link")));
197
198 // JENKINS-12331: either a bug in createSymlink or this isn't supposed to work:
199 //assertTrue(Util.isSymlink(new File(d,"anotherDir/link")));
200 } finally {
201 Util.deleteRecursive(d);
202 }
203 }
204
205 @Test
206 public void testIsSymlink() throws IOException, InterruptedException {
207 Assume.assumeTrue(!Functions.isWindows());
208
209 ByteArrayOutputStream baos = new ByteArrayOutputStream();
210 StreamTaskListener l = new StreamTaskListener(baos);
211 File d = Util.createTempDir();
212 try {
213 new FilePath(new File(d, "original")).touch(0);
214 assertFalse(Util.isSymlink(new File(d, "original")));
215 Util.createSymlink(d,"original","link", l);
216
217 assertTrue(Util.isSymlink(new File(d, "link")));
218
219 // test linking to another directory
220 File dir = new File(d,"dir");
221 assertTrue("Couldn't create "+dir,dir.mkdir());
222 assertFalse(Util.isSymlink(new File(d,"dir")));
223
224 File anotherDir = new File(d,"anotherDir");
225 assertTrue("Couldn't create "+anotherDir,anotherDir.mkdir());
226
227 Util.createSymlink(d,"dir","anotherDir/symlinkDir",l);
228 // JENKINS-12331: either a bug in createSymlink or this isn't supposed to work:
229 // assertTrue(Util.isSymlink(new File(d,"anotherDir/symlinkDir")));
230 } finally {
231 Util.deleteRecursive(d);
232 }
233 }
234
235 @Test
236 public void testHtmlEscape() {
237 assertEquals("<br>", Util.escape("\n"));
238 assertEquals("&lt;a>", Util.escape("<a>"));
239 assertEquals("&#039;&quot;", Util.escape("'\""));
240 assertEquals("&nbsp; ", Util.escape(" "));
241 }
242
243 /**
244 * Compute 'known-correct' digests and see if I still get them when computed concurrently
245 * to another digest.
246 */
247 @Bug(10346)
248 @Test
249 public void testDigestThreadSafety() throws InterruptedException {
250 String a = "abcdefgh";
251 String b = "123456789";
252
253 String digestA = Util.getDigestOf(a);
254 String digestB = Util.getDigestOf(b);
255
256 DigesterThread t1 = new DigesterThread(a, digestA);
257 DigesterThread t2 = new DigesterThread(b, digestB);
258
259 t1.start();
260 t2.start();
261
262 t1.join();
263 t2.join();
264
265 if (t1.error != null) {
266 fail(t1.error);
267 }
268 if (t2.error != null) {
269 fail(t2.error);
270 }
271 }
272
273 private static class DigesterThread extends Thread {
274 private String string;
275 private String expectedDigest;
276
277 private String error;
278
279 public DigesterThread(String string, String expectedDigest) {
280 this.string = string;
281 this.expectedDigest = expectedDigest;
282 }
283
284 public void run() {
285 for (int i=0; i < 1000; i++) {
286 String digest = Util.getDigestOf(this.string);
287 if (!this.expectedDigest.equals(digest)) {
288 this.error = "Expected " + this.expectedDigest + ", but got " + digest;
289 break;
290 }
291 }
292 }
293 }
294
295 public void testIsAbsoluteUri() {
296 assertTrue(Util.isAbsoluteUri("http://foobar/"));
297 assertTrue(Util.isAbsoluteUri("mailto:kk@kohsuke.org"));
298 assertTrue(Util.isAbsoluteUri("d123://test/"));
299 assertFalse(Util.isAbsoluteUri("foo/bar/abc:def"));
300 assertFalse(Util.isAbsoluteUri("foo?abc:def"));
301 assertFalse(Util.isAbsoluteUri("foo#abc:def"));
302 assertFalse(Util.isAbsoluteUri("foo/bar"));
303 }
304 }
305