    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
    18  package org.apache.log4j.util;
    19
    20  import junit.framework.TestCase;
    21
    22  import java.io.ByteArrayInputStream;
    23  import java.io.ByteArrayOutputStream;
    24  import java.io.File;
    25  import java.io.FileInputStream;
    26  import java.io.FileOutputStream;
    27  import java.io.IOException;
    28  import java.io.ObjectInputStream;
    29  import java.io.ObjectOutputStream;
    30
    31
    32  /**
    33   * Utiities for serialization tests.
    34   *
    35   * @author Curt Arnold
    36   */
    37  public class SerializationTestHelper {
    38    /**
    39     * Private constructor.
    40     */
    41    private SerializationTestHelper() {
    42    }
    43
    44    /**
    45     * Creates a clone by serializing object and
    46     * deserializing byte stream.
    47     * @param obj object to serialize and deserialize.
    48     * @return clone
    49     * @throws IOException on IO error.
    50     * @throws ClassNotFoundException if class not found.
    51     */
    52    public static Object serializeClone(final Object obj)
    53      throws IOException, ClassNotFoundException {
    54      ByteArrayOutputStream memOut = new ByteArrayOutputStream();
    55      ObjectOutputStream objOut = new ObjectOutputStream(memOut);
    56      objOut.writeObject(obj);
    57      objOut.close();
    58
    59      ByteArrayInputStream src = new ByteArrayInputStream(memOut.toByteArray());
    60      ObjectInputStream objIs = new ObjectInputStream(src);
    61
    62      return objIs.readObject();
    63    }
    64
    65    /**
    66     * Deserializes a specified file.
    67     * @param witness serialization file, may not be null.
    68     * @return deserialized object.
    69     * @throws Exception thrown on IO or deserialization exception.
    70     */
    71    public static Object deserializeStream(final String witness)
    72      throws Exception {
    73      FileInputStream fileIs = new FileInputStream(witness);
    74      ObjectInputStream objIs = new ObjectInputStream(fileIs);
    75
    76      return objIs.readObject();
    77    }
    78
    79    /**
    80     * Checks the serialization of an object against an file
    81     * containing the expected serialization.
    82     *
    83     * @param witness name of file containing expected serialization.
    84     * @param obj object to be serialized.
    85     * @param skip positions in serialized stream that should not be compared.
    86     * @param endCompare position to stop comparison.
    87     * @throws Exception thrown on IO or serialization exception.
    88     */
    89    public static void assertSerializationEquals(
    90      final String witness, final Object obj, final int[] skip,
    91      final int endCompare) throws Exception {
    92      ByteArrayOutputStream memOut = new ByteArrayOutputStream();
    93      ObjectOutputStream objOut = new ObjectOutputStream(memOut);
    94      objOut.writeObject(obj);
    95      objOut.close();
    96
    97      assertStreamEquals(witness, memOut.toByteArray(), skip, endCompare);
    98    }
    99
    100   /**
    101    * Asserts the serialized form of an object.
    102    * @param witness file name of expected serialization.
    103    * @param actual byte array of actual serialization.
    104    * @param skip positions to skip comparison.
    105    * @param endCompare position to stop comparison.
    106    * @throws IOException thrown on IO or serialization exception.
    107    */
    108   public static void assertStreamEquals(
    109     final String witness, final byte[] actual, final int[] skip,
    110     final int endCompare) throws IOException {
    111     File witnessFile = new File(witness);
    112
    113     if (witnessFile.exists()) {
    114       int skipIndex = 0;
    115       byte[] expected = new byte[actual.length];
    116       FileInputStream is = new FileInputStream(witnessFile);
    117       int bytesRead = is.read(expected);
    118       is.close();
    119
    120       if(bytesRead < endCompare) {
    121           TestCase.assertEquals(bytesRead, actual.length);
    122       }
    123
    124       int endScan = actual.length;
    125
    126       if (endScan > endCompare) {
    127         endScan = endCompare;
    128       }
    129
    130       for (int i = 0; i < endScan; i++) {
    131         if ((skipIndex < skip.length) && (skip[skipIndex] == i)) {
    132           skipIndex++;
    133         } else {
    134           if (expected[i] != actual[i]) {
    135             TestCase.assertEquals(
    136               "Difference at offset " + i, expected[i], actual[i]);
    137           }
    138         }
    139       }
    140     } else {
    141       //
    142       //  if the file doesn't exist then
    143       //      assume that we are setting up and need to write it
    144       FileOutputStream os = new FileOutputStream(witnessFile);
    145       os.write(actual);
    146       os.close();
    147       TestCase.fail("Writing witness file " + witness);
    148     }
    149   }
    150 }