1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.ObjectInputStream;
24  import java.io.ObjectOutputStream;
25  import java.io.OutputStream;
26  import java.io.Serializable;
27  import java.lang.reflect.Constructor;
28  import java.lang.reflect.Modifier;
29  import java.util.HashMap;
30  
31  import junit.framework.Test;
32  import junit.framework.TestCase;
33  import junit.framework.TestSuite;
34  import junit.textui.TestRunner;
35  
36  /**
37   * Unit tests {@link org.apache.commons.lang.SerializationUtils}.
38   *
39   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
40   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
41   * @version $Id: SerializationUtilsTest.java 437554 2006-08-28 06:21:41Z bayard $
42   */
43  public class SerializationUtilsTest extends TestCase {
44  
45    static final String CLASS_NOT_FOUND_MESSAGE = "ClassNotFoundSerializationTest.readObject fake exception";
46      protected static final String SERIALIZE_IO_EXCEPTION_MESSAGE = "Anonymous OutputStream I/O exception";
47    
48      private String iString;
49      private Integer iInteger;
50      private HashMap iMap;
51  
52      public SerializationUtilsTest(String name) {
53          super(name);
54      }
55  
56      public static void main(String[] args) {
57          TestRunner.run(suite());
58      }
59  
60      public static Test suite() {
61          TestSuite suite = new TestSuite(SerializationUtilsTest.class);
62          suite.setName("SerializationUtils Tests");
63          return suite;
64      }
65  
66      protected void setUp() throws Exception {
67          super.setUp();
68  
69          iString = "foo";
70          iInteger = new Integer(7);
71          iMap = new HashMap();
72          iMap.put("FOO", iString);
73          iMap.put("BAR", iInteger);
74      }
75  
76      protected void tearDown() throws Exception {
77          super.tearDown();
78      }
79  
80      //-----------------------------------------------------------------------
81      public void testConstructor() {
82          assertNotNull(new SerializationUtils());
83          Constructor[] cons = SerializationUtils.class.getDeclaredConstructors();
84          assertEquals(1, cons.length);
85          assertEquals(true, Modifier.isPublic(cons[0].getModifiers()));
86          assertEquals(true, Modifier.isPublic(SerializationUtils.class.getModifiers()));
87          assertEquals(false, Modifier.isFinal(SerializationUtils.class.getModifiers()));
88      }
89      
90      public void testException() {
91          SerializationException serEx;
92          Exception ex = new Exception();
93          
94          serEx = new SerializationException();
95          assertSame(null, serEx.getMessage());
96          assertSame(null, serEx.getCause());
97          
98          serEx = new SerializationException("Message");
99          assertSame("Message", serEx.getMessage());
100         assertSame(null, serEx.getCause());
101         
102         serEx = new SerializationException(ex);
103         assertEquals("java.lang.Exception", serEx.getMessage());
104         assertSame(ex, serEx.getCause());
105         
106         serEx = new SerializationException("Message", ex);
107         assertSame("Message", serEx.getMessage());
108         assertSame(ex, serEx.getCause());
109     }
110     
111     //-----------------------------------------------------------------------
112     public void testSerializeStream() throws Exception {
113         ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
114         SerializationUtils.serialize(iMap, streamTest);
115 
116         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
117         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
118         oos.writeObject(iMap);
119         oos.flush();
120         oos.close();
121 
122         byte[] testBytes = streamTest.toByteArray();
123         byte[] realBytes = streamReal.toByteArray();
124         assertEquals(testBytes.length, realBytes.length);
125         for (int i = 0; i < realBytes.length; i++) {
126             assertEquals(realBytes[i], testBytes[i]);
127         }
128     }
129 
130     public void testSerializeStreamUnserializable() throws Exception {
131         ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
132         try {
133             iMap.put(new Object(), new Object());
134             SerializationUtils.serialize(iMap, streamTest);
135         } catch (SerializationException ex) {
136             return;
137         }
138         fail();
139     }
140 
141     public void testSerializeStreamNullObj() throws Exception {
142         ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
143         SerializationUtils.serialize(null, streamTest);
144 
145         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
146         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
147         oos.writeObject(null);
148         oos.flush();
149         oos.close();
150 
151         byte[] testBytes = streamTest.toByteArray();
152         byte[] realBytes = streamReal.toByteArray();
153         assertEquals(testBytes.length, realBytes.length);
154         for (int i = 0; i < realBytes.length; i++) {
155             assertEquals(realBytes[i], testBytes[i]);
156         }
157     }
158 
159     public void testSerializeStreamObjNull() throws Exception {
160         ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
161         try {
162             SerializationUtils.serialize(iMap, null);
163         } catch (IllegalArgumentException ex) {
164             return;
165         }
166         fail();
167     }
168 
169     public void testSerializeStreamNullNull() throws Exception {
170         ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
171         try {
172             SerializationUtils.serialize(null, null);
173         } catch (IllegalArgumentException ex) {
174             return;
175         }
176         fail();
177     }
178     
179     public void testSerializeIOException() throws Exception {
180         // forces an IOException when the ObjectOutputStream is created, to test not closing the stream
181         // in the finally block
182         OutputStream streamTest = new OutputStream() {
183             public void write(int arg0) throws IOException {
184                 throw new IOException(SERIALIZE_IO_EXCEPTION_MESSAGE);
185             }
186         };
187         try {
188             SerializationUtils.serialize(iMap, streamTest);
189         }
190         catch(SerializationException e) {
191             assertEquals("java.io.IOException: " + SERIALIZE_IO_EXCEPTION_MESSAGE, e.getMessage());
192         }
193     }
194 
195     //-----------------------------------------------------------------------
196 
197     public void testDeserializeStream() throws Exception {
198         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
199         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
200         oos.writeObject(iMap);
201         oos.flush();
202         oos.close();
203 
204         ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
205         Object test = SerializationUtils.deserialize(inTest);
206         assertNotNull(test);
207         assertTrue(test instanceof HashMap);
208         assertTrue(test != iMap);
209         HashMap testMap = (HashMap) test;
210         assertEquals(iString, testMap.get("FOO"));
211         assertTrue(iString != testMap.get("FOO"));
212         assertEquals(iInteger, testMap.get("BAR"));
213         assertTrue(iInteger != testMap.get("BAR"));
214         assertEquals(iMap, testMap);
215     }
216 
217     public void testDeserializeStreamOfNull() throws Exception {
218         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
219         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
220         oos.writeObject(null);
221         oos.flush();
222         oos.close();
223 
224         ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
225         Object test = SerializationUtils.deserialize(inTest);
226         assertNull(test);
227     }
228 
229     public void testDeserializeStreamNull() throws Exception {
230         try {
231             SerializationUtils.deserialize((InputStream) null);
232         } catch (IllegalArgumentException ex) {
233             return;
234         }
235         fail();
236     }
237 
238     public void testDeserializeStreamBadStream() throws Exception {
239         try {
240             SerializationUtils.deserialize(new ByteArrayInputStream(new byte[0]));
241         } catch (SerializationException ex) {
242             return;
243         }
244         fail();
245     }
246 
247     public void testDeserializeStreamClassNotFound() throws Exception {
248         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
249         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
250         oos.writeObject(new ClassNotFoundSerializationTest());
251         oos.flush();
252         oos.close();
253 
254         ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
255         try {
256             Object test = SerializationUtils.deserialize(inTest);
257         } catch(SerializationException se) {
258             assertEquals("java.lang.ClassNotFoundException: " + CLASS_NOT_FOUND_MESSAGE, se.getMessage());
259         }
260     }
261     
262     //-----------------------------------------------------------------------
263 
264     public void testSerializeBytes() throws Exception {
265         byte[] testBytes = SerializationUtils.serialize(iMap);
266 
267         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
268         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
269         oos.writeObject(iMap);
270         oos.flush();
271         oos.close();
272 
273         byte[] realBytes = streamReal.toByteArray();
274         assertEquals(testBytes.length, realBytes.length);
275         for (int i = 0; i < realBytes.length; i++) {
276             assertEquals(realBytes[i], testBytes[i]);
277         }
278     }
279 
280     public void testSerializeBytesUnserializable() throws Exception {
281         try {
282             iMap.put(new Object(), new Object());
283             SerializationUtils.serialize(iMap);
284         } catch (SerializationException ex) {
285             return;
286         }
287         fail();
288     }
289 
290     public void testSerializeBytesNull() throws Exception {
291         byte[] testBytes = SerializationUtils.serialize(null);
292 
293         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
294         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
295         oos.writeObject(null);
296         oos.flush();
297         oos.close();
298 
299         byte[] realBytes = streamReal.toByteArray();
300         assertEquals(testBytes.length, realBytes.length);
301         for (int i = 0; i < realBytes.length; i++) {
302             assertEquals(realBytes[i], testBytes[i]);
303         }
304     }
305 
306     //-----------------------------------------------------------------------
307 
308     public void testDeserializeBytes() throws Exception {
309         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
310         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
311         oos.writeObject(iMap);
312         oos.flush();
313         oos.close();
314 
315         Object test = SerializationUtils.deserialize(streamReal.toByteArray());
316         assertNotNull(test);
317         assertTrue(test instanceof HashMap);
318         assertTrue(test != iMap);
319         HashMap testMap = (HashMap) test;
320         assertEquals(iString, testMap.get("FOO"));
321         assertTrue(iString != testMap.get("FOO"));
322         assertEquals(iInteger, testMap.get("BAR"));
323         assertTrue(iInteger != testMap.get("BAR"));
324         assertEquals(iMap, testMap);
325     }
326 
327     public void testDeserializeBytesOfNull() throws Exception {
328         ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
329         ObjectOutputStream oos = new ObjectOutputStream(streamReal);
330         oos.writeObject(null);
331         oos.flush();
332         oos.close();
333 
334         Object test = SerializationUtils.deserialize(streamReal.toByteArray());
335         assertNull(test);
336     }
337 
338     public void testDeserializeBytesNull() throws Exception {
339         try {
340             SerializationUtils.deserialize((byte[]) null);
341         } catch (IllegalArgumentException ex) {
342             return;
343         }
344         fail();
345     }
346 
347     public void testDeserializeBytesBadStream() throws Exception {
348         try {
349             SerializationUtils.deserialize(new byte[0]);
350         } catch (SerializationException ex) {
351             return;
352         }
353         fail();
354     }
355 
356     //-----------------------------------------------------------------------
357 
358     public void testClone() throws Exception {
359         Object test = SerializationUtils.clone(iMap);
360         assertNotNull(test);
361         assertTrue(test instanceof HashMap);
362         assertTrue(test != iMap);
363         HashMap testMap = (HashMap) test;
364         assertEquals(iString, testMap.get("FOO"));
365         assertTrue(iString != testMap.get("FOO"));
366         assertEquals(iInteger, testMap.get("BAR"));
367         assertTrue(iInteger != testMap.get("BAR"));
368         assertEquals(iMap, testMap);
369     }
370 
371     public void testCloneNull() throws Exception {
372         Object test = SerializationUtils.clone(null);
373         assertNull(test);
374     }
375 
376     public void testCloneUnserializable() throws Exception {
377         try {
378             iMap.put(new Object(), new Object());
379             SerializationUtils.clone(iMap);
380         } catch (SerializationException ex) {
381             return;
382         }
383         fail();
384     }
385 
386 }
387 
388 class ClassNotFoundSerializationTest implements Serializable
389 {
390 
391     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException    {
392         throw new ClassNotFoundException(SerializationUtilsTest.CLASS_NOT_FOUND_MESSAGE);
393     }
394 }