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

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, 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.util;
25
26 import com.google.common.collect.ImmutableList;
27 import com.google.common.collect.ImmutableMap;
28 import hudson.XmlFile;
29 import hudson.matrix.MatrixRun;
30 import hudson.model.Result;
31 import hudson.model.Run;
32 import java.io.File;
33 import java.io.InputStream;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.logging.Level;
38 import java.util.logging.Logger;
39 import jenkins.model.CauseOfInterruption;
40 import jenkins.model.InterruptedBuildAction;
41 import junit.framework.TestCase;
42 import org.apache.commons.io.FileUtils;
43 import org.jvnet.hudson.test.Bug;
44
45 /**
46 * Tests for XML serialization of java objects.
47 * @author Kohsuke Kawaguchi, Mike Dillon, Alan Harder, Richard Mortimer
48 */
49 public class XStream2Test extends TestCase {
50
51 public static final class Foo {
52 Result r1,r2;
53 }
54
55 public void testMarshalValue() {
56 Foo f = new Foo();
57 f.r1 = f.r2 = Result.FAILURE;
58 String xml = Run.XSTREAM.toXML(f);
59 // we should find two "FAILURE"s as they should be written out twice
60 assertEquals(xml, 3, xml.split("FAILURE").length);
61 }
62
63 private static class Bar {
64 String s;
65 }
66
67 /**
68 * Test ability to read old XML from Hudson 1.105 or older.
69 */
70 public void testXStream11Compatibility() {
71 Bar b = (Bar)new XStream2().fromXML(
72 "<hudson.util.XStream2Test-Bar><s>foo</s></hudson.util.XStream2Test-Bar>");
73 assertEquals("foo", b.s);
74 }
75
76 public static final class __Foo_Bar$Class {
77 String under_1 = "1", under__2 = "2",
78 _leadUnder1 = "L1", __leadUnder2 = "L2",
79 $dollar = "D1", dollar$2 = "D2";
80 }
81
82 /**
83 * Test marshal/unmarshal round trip for class/field names with _ and $ characters.
84 * (HUDSON-5768)
85 */
86 public void testXmlRoundTrip() {
87 XStream2 xs = new XStream2();
88 __Foo_Bar$Class b = new __Foo_Bar$Class();
89
90 String xml = xs.toXML(b);
91 __Foo_Bar$Class b2 = (__Foo_Bar$Class)xs.fromXML(xml);
92
93 assertEquals(xml, b.under_1, b2.under_1);
94 assertEquals(xml, b.under__2, b2.under__2);
95 assertEquals(xml, b._leadUnder1, b2._leadUnder1);
96 assertEquals(xml, b.__leadUnder2, b2.__leadUnder2);
97 assertEquals(xml, b.$dollar, b2.$dollar);
98 assertEquals(xml, b.dollar$2, b2.dollar$2);
99 }
100
101 private static class Baz {
102 private Exception myFailure;
103 }
104
105 /**
106 * Verify RobustReflectionConverter can handle missing fields in a class extending
107 * Throwable/Exception (default ThrowableConverter registered by XStream calls
108 * ReflectionConverter directly, rather than our RobustReflectionConverter replacement).
109 * (HUDSON-5769)
110 */
111 public void testUnmarshalThrowableMissingField() {
112 Level oldLevel = disableLogging();
113
114 Baz baz = new Baz();
115 baz.myFailure = new Exception("foo");
116
117 XStream2 xs = new XStream2();
118 String xml = xs.toXML(baz);
119 baz = (Baz)xs.fromXML(xml);
120 assertEquals("foo", baz.myFailure.getMessage());
121
122 baz = (Baz)xs.fromXML("<hudson.util.XStream2Test_-Baz><myFailure>"
123 + "<missingField>true</missingField>"
124 + "<detailMessage>hoho</detailMessage>"
125 + "<stackTrace><trace>"
126 + "hudson.util.XStream2Test.testUnmarshalThrowableMissingField(XStream2Test.java:97)"
127 + "</trace></stackTrace>"
128 + "</myFailure></hudson.util.XStream2Test_-Baz>");
129 // Object should load, despite "missingField" in XML above
130 assertEquals("hoho", baz.myFailure.getMessage());
131
132 enableLogging(oldLevel);
133 }
134
135 private Level disableLogging() {
136 Level oldLevel = Logger.getLogger(RobustReflectionConverter.class.getName()).getLevel();
137 Logger.getLogger(RobustReflectionConverter.class.getName()).setLevel(Level.OFF);
138 return oldLevel;
139 }
140
141 private void enableLogging(Level oldLevel) {
142 Logger.getLogger(RobustReflectionConverter.class.getName()).setLevel(oldLevel);
143 }
144
145 private static class ImmutableMapHolder {
146 ImmutableMap<?,?> m;
147 }
148
149 private static class MapHolder {
150 Map<?,?> m;
151 }
152
153 public void testImmutableMap() {
154 XStream2 xs = new XStream2();
155
156 roundtripImmutableMap(xs, ImmutableMap.of());
157 roundtripImmutableMap(xs, ImmutableMap.of("abc", "xyz"));
158 roundtripImmutableMap(xs, ImmutableMap.of("abc", "xyz", "def","ghi"));
159
160 roundtripImmutableMapAsPlainMap(xs, ImmutableMap.of());
161 roundtripImmutableMapAsPlainMap(xs, ImmutableMap.of("abc", "xyz"));
162 roundtripImmutableMapAsPlainMap(xs, ImmutableMap.of("abc", "xyz", "def","ghi"));
163 }
164
165 /**
166 * Since the field type is {@link ImmutableMap}, XML shouldn't contain a reference to the type name.
167 */
168 private void roundtripImmutableMap(XStream2 xs, ImmutableMap<?,?> m) {
169 ImmutableMapHolder a = new ImmutableMapHolder();
170 a.m = m;
171 String xml = xs.toXML(a);
172 //System.out.println(xml);
173 assertFalse("shouldn't contain the class name",xml.contains("google"));
174 assertFalse("shouldn't contain the class name",xml.contains("class"));
175 a = (ImmutableMapHolder)xs.fromXML(xml);
176
177 assertSame(m.getClass(),a.m.getClass()); // should get back the exact same type, not just a random map
178 assertEquals(m,a.m);
179 }
180
181 private void roundtripImmutableMapAsPlainMap(XStream2 xs, ImmutableMap<?,?> m) {
182 MapHolder a = new MapHolder();
183 a.m = m;
184 String xml = xs.toXML(a);
185 //System.out.println(xml);
186 assertTrue("XML should mention the class name",xml.contains('\"'+ImmutableMap.class.getName()+'\"'));
187 a = (MapHolder)xs.fromXML(xml);
188
189 assertSame(m.getClass(),a.m.getClass()); // should get back the exact same type, not just a random map
190 assertEquals(m,a.m);
191 }
192
193 private static class ImmutableListHolder {
194 ImmutableList<?> l;
195 }
196
197 private static class ListHolder {
198 List<?> l;
199 }
200
201 public void testImmutableList() {
202 XStream2 xs = new XStream2();
203
204 roundtripImmutableList(xs, ImmutableList.of());
205 roundtripImmutableList(xs, ImmutableList.of("abc"));
206 roundtripImmutableList(xs, ImmutableList.of("abc", "def"));
207
208 roundtripImmutableListAsPlainList(xs, ImmutableList.of());
209 roundtripImmutableListAsPlainList(xs, ImmutableList.of("abc"));
210 roundtripImmutableListAsPlainList(xs, ImmutableList.of("abc", "def"));
211 }
212
213 /**
214 * Since the field type is {@link ImmutableList}, XML shouldn't contain a reference to the type name.
215 */
216 private void roundtripImmutableList(XStream2 xs, ImmutableList<?> l) {
217 ImmutableListHolder a = new ImmutableListHolder();
218 a.l = l;
219 String xml = xs.toXML(a);
220 //System.out.println(xml);
221 assertFalse("shouldn't contain the class name",xml.contains("google"));
222 assertFalse("shouldn't contain the class name",xml.contains("class"));
223 a = (ImmutableListHolder)xs.fromXML(xml);
224
225 assertSame(l.getClass(),a.l.getClass()); // should get back the exact same type, not just a random list
226 assertEquals(l,a.l);
227 }
228
229 private void roundtripImmutableListAsPlainList(XStream2 xs, ImmutableList<?> l) {
230 ListHolder a = new ListHolder();
231 a.l = l;
232 String xml = xs.toXML(a);
233 //System.out.println(xml);
234 assertTrue("XML should mention the class name",xml.contains('\"'+ImmutableList.class.getName()+'\"'));
235 a = (ListHolder)xs.fromXML(xml);
236
237 assertSame(l.getClass(),a.l.getClass()); // should get back the exact same type, not just a random list
238 assertEquals(l,a.l);
239 }
240
241 @Bug(8006) // Previously a null entry in an array caused NPE
242 public void testEmptyStack() {
243 assertEquals("<object-array><null/><null/></object-array>",
244 Run.XSTREAM.toXML(new Object[2]).replaceAll("[ \n\r\t]+", ""));
245 }
246
247 @Bug(9843)
248 public void testCompatibilityAlias() {
249 XStream2 xs = new XStream2();
250 xs.addCompatibilityAlias("legacy.Point",Point.class);
251 Point pt = (Point)xs.fromXML("<legacy.Point><x>1</x><y>2</y></legacy.Point>");
252 assertEquals(1,pt.x);
253 assertEquals(2,pt.y);
254 String xml = xs.toXML(pt);
255 //System.out.println(xml);
256 assertFalse("Shouldn't use the alias when writing back",xml.contains("legacy"));
257 }
258
259 public static class Point {
260 public int x,y;
261 }
262
263 /**
264 * Unmarshall a matrix build.xml result.
265 */
266 @Bug(10903)
267 public void testUnMarshalRunMatrix() {
268 InputStream is = XStream2Test.class.getResourceAsStream("runMatrix.xml");
269 MatrixRun result = (MatrixRun) Run.XSTREAM.fromXML(is);
270 assertNotNull(result);
271 assertNotNull(result.getPersistentActions());
272 assertEquals(2, result.getPersistentActions().size());
273 InterruptedBuildAction action = (InterruptedBuildAction) result.getPersistentActions().get(1);
274 assertNotNull(action.getCauses());
275 assertEquals(1, action.getCauses().size());
276 CauseOfInterruption.UserInterruption cause =
277 (CauseOfInterruption.UserInterruption) action.getCauses().get(0);
278 assertNotNull(cause);
279 }
280
281 public static class Foo2 {
282 ConcurrentHashMap<String,String> m = new ConcurrentHashMap<String,String>();
283 }
284
285 /**
286 * Tests that ConcurrentHashMap is serialized into a more compact format,
287 * but still can deserialize to older, verbose format.
288 */
289 public void testConcurrentHashMapSerialization() throws Exception {
290 Foo2 foo = new Foo2();
291 foo.m.put("abc","def");
292 foo.m.put("ghi","jkl");
293 File v = File.createTempFile("hashmap", "xml");
294 try {
295 new XmlFile(v).write(foo);
296
297 // should serialize like map
298 String xml = FileUtils.readFileToString(v);
299 assertFalse(xml.contains("java.util.concurrent"));
300 //System.out.println(xml);
301 Foo2 deserialized = (Foo2) new XStream2().fromXML(xml);
302 assertEquals(2,deserialized.m.size());
303 assertEquals("def", deserialized.m.get("abc"));
304 assertEquals("jkl", deserialized.m.get("ghi"));
305 } finally {
306 v.delete();
307 }
308
309 // should be able to read in old data just fine
310 Foo2 map = (Foo2) new XStream2().fromXML(getClass().getResourceAsStream("old-concurrentHashMap.xml"));
311 assertEquals(1,map.m.size());
312 assertEquals("def",map.m.get("abc"));
313 }
314
315 public void testTrimVersion() throws Exception {
316 assertEquals("3.2", XStream2.trimVersion("3.2"));
317 assertEquals("3.2.1", XStream2.trimVersion("3.2.1"));
318 assertEquals("3.2-SNAPSHOT", XStream2.trimVersion("3.2-SNAPSHOT (private-09/23/2012 12:26-jhacker)"));
319 }
320
321 }
322