diff options
Diffstat (limited to 'src/test/java/org/apache/commons/lang3/SerializationUtilsTest.java')
-rw-r--r-- | src/test/java/org/apache/commons/lang3/SerializationUtilsTest.java | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/src/test/java/org/apache/commons/lang3/SerializationUtilsTest.java b/src/test/java/org/apache/commons/lang3/SerializationUtilsTest.java new file mode 100644 index 000000000..f31610343 --- /dev/null +++ b/src/test/java/org/apache/commons/lang3/SerializationUtilsTest.java @@ -0,0 +1,368 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.lang3; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.HashMap; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Unit tests {@link org.apache.commons.lang3.SerializationUtils}. + */ +public class SerializationUtilsTest extends AbstractLangTest { + + static final String CLASS_NOT_FOUND_MESSAGE = "ClassNotFoundSerialization.readObject fake exception"; + protected static final String SERIALIZE_IO_EXCEPTION_MESSAGE = "Anonymous OutputStream I/O exception"; + + private String iString; + private Integer iInteger; + private HashMap<Object, Object> iMap; + + @BeforeEach + public void setUp() { + iString = "foo"; + iInteger = Integer.valueOf(7); + iMap = new HashMap<>(); + iMap.put("FOO", iString); + iMap.put("BAR", iInteger); + } + + + @Test + public void testConstructor() { + assertNotNull(new SerializationUtils()); + final Constructor<?>[] cons = SerializationUtils.class.getDeclaredConstructors(); + assertEquals(1, cons.length); + assertTrue(Modifier.isPublic(cons[0].getModifiers())); + assertTrue(Modifier.isPublic(SerializationUtils.class.getModifiers())); + assertFalse(Modifier.isFinal(SerializationUtils.class.getModifiers())); + } + + @Test + public void testException() { + SerializationException serEx; + final Exception ex = new Exception(); + + serEx = new SerializationException(); + assertSame(null, serEx.getMessage()); + assertSame(null, serEx.getCause()); + + serEx = new SerializationException("Message"); + assertSame("Message", serEx.getMessage()); + assertSame(null, serEx.getCause()); + + serEx = new SerializationException(ex); + assertEquals("java.lang.Exception", serEx.getMessage()); + assertSame(ex, serEx.getCause()); + + serEx = new SerializationException("Message", ex); + assertSame("Message", serEx.getMessage()); + assertSame(ex, serEx.getCause()); + } + + + @Test + public void testSerializeStream() throws Exception { + final ByteArrayOutputStream streamTest = new ByteArrayOutputStream(); + SerializationUtils.serialize(iMap, streamTest); + + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(iMap); + oos.flush(); + } + + final byte[] testBytes = streamTest.toByteArray(); + final byte[] realBytes = streamReal.toByteArray(); + assertEquals(testBytes.length, realBytes.length); + assertArrayEquals(realBytes, testBytes); + } + + @Test + public void testSerializeStreamUnserializable() { + final ByteArrayOutputStream streamTest = new ByteArrayOutputStream(); + iMap.put(new Object(), new Object()); + assertThrows(SerializationException.class, () -> SerializationUtils.serialize(iMap, streamTest)); + } + + @Test + public void testSerializeStreamNullObj() throws Exception { + final ByteArrayOutputStream streamTest = new ByteArrayOutputStream(); + SerializationUtils.serialize(null, streamTest); + + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(null); + oos.flush(); + } + + final byte[] testBytes = streamTest.toByteArray(); + final byte[] realBytes = streamReal.toByteArray(); + assertEquals(testBytes.length, realBytes.length); + assertArrayEquals(realBytes, testBytes); + } + + @Test + public void testSerializeStreamObjNull() { + assertThrows(NullPointerException.class, () -> SerializationUtils.serialize(iMap, null)); + } + + @Test + public void testSerializeStreamNullNull() { + assertThrows(NullPointerException.class, () -> SerializationUtils.serialize(null, null)); + } + + @Test + public void testSerializeIOException() { + // forces an IOException when the ObjectOutputStream is created, to test not closing the stream + // in the finally block + final OutputStream streamTest = new OutputStream() { + @Override + public void write(final int arg0) throws IOException { + throw new IOException(SERIALIZE_IO_EXCEPTION_MESSAGE); + } + }; + final SerializationException e = + assertThrows(SerializationException.class, () -> SerializationUtils.serialize(iMap, streamTest)); + assertEquals("java.io.IOException: " + SERIALIZE_IO_EXCEPTION_MESSAGE, e.getMessage()); + } + + + @Test + public void testDeserializeStream() throws Exception { + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(iMap); + oos.flush(); + } + + final ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray()); + final Object test = SerializationUtils.deserialize(inTest); + assertNotNull(test); + assertTrue(test instanceof HashMap<?, ?>); + assertNotSame(test, iMap); + final HashMap<?, ?> testMap = (HashMap<?, ?>) test; + assertEquals(iString, testMap.get("FOO")); + assertNotSame(iString, testMap.get("FOO")); + assertEquals(iInteger, testMap.get("BAR")); + assertNotSame(iInteger, testMap.get("BAR")); + assertEquals(iMap, testMap); + } + + @Test + public void testDeserializeClassCastException() { + final String value = "Hello"; + final byte[] serialized = SerializationUtils.serialize(value); + assertEquals(value, SerializationUtils.deserialize(serialized)); + assertThrows(ClassCastException.class, () -> { + // Causes ClassCastException in call site, not in SerializationUtils.deserialize + @SuppressWarnings("unused") // needed to cause Exception + final Integer i = SerializationUtils.deserialize(serialized); + }); + } + + @Test + public void testDeserializeStreamOfNull() throws Exception { + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(null); + oos.flush(); + } + + final ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray()); + final Object test = SerializationUtils.deserialize(inTest); + assertNull(test); + } + + @Test + public void testDeserializeStreamNull() { + assertThrows(NullPointerException.class, () -> SerializationUtils.deserialize((InputStream) null)); + } + + @Test + public void testDeserializeStreamBadStream() { + assertThrows(SerializationException.class, + () -> SerializationUtils.deserialize(new ByteArrayInputStream(new byte[0]))); + } + + @Test + public void testDeserializeStreamClassNotFound() throws Exception { + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(new ClassNotFoundSerialization()); + oos.flush(); + } + + final ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray()); + final SerializationException se = assertThrows(SerializationException.class, () -> SerializationUtils.deserialize(inTest)); + assertEquals("java.lang.ClassNotFoundException: " + CLASS_NOT_FOUND_MESSAGE, se.getMessage()); + } + + @Test + public void testRoundtrip() { + final HashMap<Object, Object> newMap = SerializationUtils.roundtrip(iMap); + assertEquals(iMap, newMap); + } + + @Test + public void testSerializeBytes() throws Exception { + final byte[] testBytes = SerializationUtils.serialize(iMap); + + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(iMap); + oos.flush(); + } + + final byte[] realBytes = streamReal.toByteArray(); + assertEquals(testBytes.length, realBytes.length); + assertArrayEquals(realBytes, testBytes); + } + + @Test + public void testSerializeBytesUnserializable() { + iMap.put(new Object(), new Object()); + assertThrows(SerializationException.class, () -> SerializationUtils.serialize(iMap)); + } + + @Test + public void testSerializeBytesNull() throws Exception { + final byte[] testBytes = SerializationUtils.serialize(null); + + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(null); + oos.flush(); + } + + final byte[] realBytes = streamReal.toByteArray(); + assertEquals(testBytes.length, realBytes.length); + assertArrayEquals(realBytes, testBytes); + } + + + @Test + public void testDeserializeBytes() throws Exception { + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(iMap); + oos.flush(); + } + + final Object test = SerializationUtils.deserialize(streamReal.toByteArray()); + assertNotNull(test); + assertTrue(test instanceof HashMap<?, ?>); + assertNotSame(test, iMap); + final HashMap<?, ?> testMap = (HashMap<?, ?>) test; + assertEquals(iString, testMap.get("FOO")); + assertNotSame(iString, testMap.get("FOO")); + assertEquals(iInteger, testMap.get("BAR")); + assertNotSame(iInteger, testMap.get("BAR")); + assertEquals(iMap, testMap); + } + + @Test + public void testDeserializeBytesOfNull() throws Exception { + final ByteArrayOutputStream streamReal = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) { + oos.writeObject(null); + oos.flush(); + } + + final Object test = SerializationUtils.deserialize(streamReal.toByteArray()); + assertNull(test); + } + + @Test + public void testDeserializeBytesNull() { + assertThrows(NullPointerException.class, () -> SerializationUtils.deserialize((byte[]) null)); + } + + @Test + public void testDeserializeBytesBadStream() { + assertThrows(SerializationException.class, () -> SerializationUtils.deserialize(new byte[0])); + } + + + @Test + public void testClone() { + final Object test = SerializationUtils.clone(iMap); + assertNotNull(test); + assertTrue(test instanceof HashMap<?, ?>); + assertNotSame(test, iMap); + final HashMap<?, ?> testMap = (HashMap<?, ?>) test; + assertEquals(iString, testMap.get("FOO")); + assertNotSame(iString, testMap.get("FOO")); + assertEquals(iInteger, testMap.get("BAR")); + assertNotSame(iInteger, testMap.get("BAR")); + assertEquals(iMap, testMap); + } + + @Test + public void testCloneNull() { + final Object test = SerializationUtils.clone(null); + assertNull(test); + } + + @Test + public void testCloneUnserializable() { + iMap.put(new Object(), new Object()); + assertThrows(SerializationException.class, () -> SerializationUtils.clone(iMap)); + } + + @Test + public void testPrimitiveTypeClassSerialization() { + final Class<?>[] primitiveTypes = { byte.class, short.class, int.class, long.class, float.class, double.class, + boolean.class, char.class, void.class }; + + for (final Class<?> primitiveType : primitiveTypes) { + final Class<?> clone = SerializationUtils.clone(primitiveType); + assertEquals(primitiveType, clone); + } + } + +} + +class ClassNotFoundSerialization implements Serializable { + + private static final long serialVersionUID = 1L; + + private void readObject(final ObjectInputStream in) throws ClassNotFoundException { + throw new ClassNotFoundException(SerializationUtilsTest.CLASS_NOT_FOUND_MESSAGE); + } +} |