1 /* 2 * Copyright 2008-2012 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.util.test.io; 17 18 import java.io.ByteArrayInputStream; 19 import java.io.ByteArrayOutputStream; 20 import java.io.IOException; 21 import java.io.ObjectInputStream; 22 import java.io.ObjectOutputStream; 23 24 import org.apache.commons.io.IOUtils; 25 import static org.junit.Assert.fail; 26 27 /** 28 * Provides utility functions to help on tests dealing with serialization. 29 * <p> 30 * The example shows the typical usage of {@link #runSerialization(Object)}: 31 * </p> {@example "Example Usage Error" final MyClass uut = new MyClass(); ... 32 * SerialTestUtils.runSerialization(uut); 33 * assertTrue("Serialization successful.", true);} 34 * <p> 35 * If the serialization is not successful, an exception is thrown. If you do not 36 * want an error to be reported by JUnit you have catch the exception and fail. 37 * </p> {@example "Example Usage Failure" final MyClass uut = new MyClass(); ... 38 * SerialTestUtils.runSerializationQuietly(uut); 39 * assertTrue("Serialization successful.", true);} 40 * 41 * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a> 42 * @version $Revision:591 $ 43 */ 44 public final class SerialTestUtils 45 { 46 // ********************************* Fields ********************************* 47 48 // --- constants ------------------------------------------------------------ 49 50 // --- members -------------------------------------------------------------- 51 52 // ****************************** Initializer ******************************* 53 54 // ****************************** Constructors ****************************** 55 56 /** 57 * Utility class. 58 */ 59 private SerialTestUtils() 60 { 61 } 62 63 // ****************************** Inner Classes ***************************** 64 65 // ********************************* Methods ******************************** 66 67 // --- init ----------------------------------------------------------------- 68 69 // --- get&set -------------------------------------------------------------- 70 71 // --- business ------------------------------------------------------------- 72 73 /** 74 * Runs the serialization test and signals a fail to the JUnit runtime. 75 * 76 * @param <T> the type of the instance to read and write. 77 * @param uut the unit under test to serialize and deserialized. 78 * @return the serialized and deserialized object. Allows the client to check 79 * the internals if required. 80 */ 81 public static <T> T runSerializationQuietly(final T uut) 82 { 83 try 84 { 85 return runSerialization(uut); 86 } 87 catch (final IOException e) 88 { 89 fail("Serialization failed."); 90 } 91 catch (final ClassNotFoundException e) 92 { 93 fail("Serialization failed since class cannot be found: " 94 + e.getMessage()); 95 } 96 return null; // never happens. 97 } 98 99 /** 100 * Test the serialization and deserialization of the unit under test. 101 * 102 * @param <T> the type of the instance to read and write. 103 * @param uut the unit under test to serialize and deserialized. 104 * @return the serialized and deserialized object. Allows the client to check 105 * the internals if required. 106 * @throws IOException if the object cannot be serialized or deserialized. 107 * @throws ClassNotFoundException if the class for the deserialized object 108 * cannot be found. 109 */ 110 public static <T> T runSerialization(final T uut) throws IOException, 111 ClassNotFoundException 112 { 113 final byte[] data = writeObject(uut); 114 115 // The following specifies the type T because of a bug in the javac 116 // (including version 1.6.0_12) that prevents proper type inference. 117 // * http://forums.sun.com/thread.jspa?messageID=4196171 118 // * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954 119 return SerialTestUtils.<T> readObject(data); 120 } 121 122 /** 123 * Reads the object from the given byte array. 124 * 125 * @param <T> the type of the instance to read. 126 * @param data the serialized object to deserialize. 127 * @return the deserialized object. 128 * @throws IOException if the object cannot be deserialized. 129 * @throws ClassNotFoundException if the class for the deserialized object 130 * cannot be found. 131 */ 132 @SuppressWarnings("unchecked") 133 public static <T> T readObject(final byte[] data) throws IOException, 134 ClassNotFoundException 135 { 136 final ByteArrayInputStream in = new ByteArrayInputStream(data); 137 ObjectInputStream ois = null; // NOPMD resource release pattern 138 try 139 { 140 ois = new ObjectInputStream(in); 141 final T result = (T) ois.readObject(); 142 return result; 143 } 144 finally 145 { 146 IOUtils.closeQuietly(ois); 147 } 148 } 149 150 /** 151 * Writes the given object to an byte array. 152 * 153 * @param <T> the type of the instance to write. 154 * @param uut the unit under test to serialize. 155 * @param bufferSize the size of the in-memory buffer to write to. 156 * @return the serialized object in a byte array. 157 * @throws IOException if the object cannot be serialized. 158 */ 159 public static <T> byte[] writeObject(final T uut, final int bufferSize) 160 throws IOException 161 { 162 final ByteArrayOutputStream out = new ByteArrayOutputStream(bufferSize); 163 ObjectOutputStream oos = null; // NOPMD resource release pattern 164 try 165 { 166 oos = new ObjectOutputStream(out); 167 oos.writeObject(uut); 168 } 169 finally 170 { 171 IOUtils.closeQuietly(oos); 172 } 173 return out.toByteArray(); 174 } 175 176 /** 177 * Writes the given object to an byte array. The size of the in-memory buffer 178 * is set to 1024 bytes. 179 * 180 * @param <T> the type of the instance to write. 181 * @param uut the unit under test to serialize. 182 * @return the serialized object in a byte array. 183 * @throws IOException if the object cannot be serialized. 184 */ 185 public static <T> byte[] writeObject(final T uut) throws IOException 186 { 187 // The following specifies the type T because of a bug in the javac 188 // (including version 1.6.0_12) that prevents proper type inference. 189 // * http://forums.sun.com/thread.jspa?messageID=4196171 190 // * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954 191 return SerialTestUtils.<T> writeObject(uut, 1024); 192 } 193 194 // --- object basics -------------------------------------------------------- 195 196 }