    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.fileupload;
    18
    19  import java.io.IOException;
    20  import java.io.OutputStream;
    21  import java.io.ByteArrayInputStream;
    22  import java.io.ByteArrayOutputStream;
    23  import java.io.ObjectInputStream;
    24  import java.io.ObjectOutputStream;
    25
    26  import junit.framework.TestCase;
    27  import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    28
    29
    30  /**
    31   * Serialization Unit tests for
    32   *  {@link org.apache.commons.fileupload.disk.DiskFileItem}.
    33   */
    34  public class DiskFileItemSerializeTest extends TestCase
    35   {
    36
    37      /**
    38       * Content type for regular form items.
    39       */
    40      private static final String textContentType = "text/plain";
    41
    42      /**
    43       * Content type for file uploads.
    44       */
    45      private static final String fileContentType = "application/octet-stream";
    46
    47      /**
    48       * Very low threshold for testing memory versus disk options.
    49       */
    50      private static final int threshold = 16;
    51
    52      /**
    53       * Standard JUnit test case constructor.
    54       *
    55       * @param name The name of the test case.
    56       */
    57      public DiskFileItemSerializeTest(String name)
    58      {
    59          super(name);
    60      }
    61
    62      /**
    63       * Test creation of a field for which the amount of data falls below the
    64       * configured threshold.
    65       */
    66      public void testBelowThreshold()
    67      {
    68
    69          // Create the FileItem
    70          byte[] testFieldValueBytes = createContentBytes(threshold - 1);
    71          FileItem item = createFileItem(testFieldValueBytes);
    72
    73          // Check state is as expected
    74          assertTrue("Initial: in memory", item.isInMemory());
    75          assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    76          compareBytes("Initial", item.get(), testFieldValueBytes);
    77
    78          // Serialize & Deserialize
    79          try
    80          {
    81              FileItem newItem = (FileItem)serializeDeserialize(item);
    82
    83              // Test deserialized content is as expected
    84              assertTrue("Check in memory", newItem.isInMemory());
    85              compareBytes("Check", testFieldValueBytes, newItem.get());
    86
    87              // Compare FileItem's (except byte[])
    88              compareFileItems(item, newItem);
    89
    90          }
    91          catch(Exception e)
    92          {
    93              fail("Error Serializing/Deserializing: " + e);
    94          }
    95
    96
    97      }
    98
    99      /**
    100      * Test creation of a field for which the amount of data equals the
    101      * configured threshold.
    102      */
    103     public void testThreshold() {
    104         // Create the FileItem
    105         byte[] testFieldValueBytes = createContentBytes(threshold);
    106         FileItem item = createFileItem(testFieldValueBytes);
    107
    108         // Check state is as expected
    109         assertTrue("Initial: in memory", item.isInMemory());
    110         assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    111         compareBytes("Initial", item.get(), testFieldValueBytes);
    112
    113
    114         // Serialize & Deserialize
    115         try
    116         {
    117             FileItem newItem = (FileItem)serializeDeserialize(item);
    118
    119             // Test deserialized content is as expected
    120             assertTrue("Check in memory", newItem.isInMemory());
    121             compareBytes("Check", testFieldValueBytes, newItem.get());
    122
    123             // Compare FileItem's (except byte[])
    124             compareFileItems(item, newItem);
    125
    126         }
    127         catch(Exception e)
    128         {
    129             fail("Error Serializing/Deserializing: " + e);
    130         }
    131     }
    132
    133     /**
    134      * Test creation of a field for which the amount of data falls above the
    135      * configured threshold.
    136      */
    137     public void testAboveThreshold() {
    138
    139         // Create the FileItem
    140         byte[] testFieldValueBytes = createContentBytes(threshold + 1);
    141         FileItem item = createFileItem(testFieldValueBytes);
    142
    143         // Check state is as expected
    144         assertFalse("Initial: in memory", item.isInMemory());
    145         assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    146         compareBytes("Initial", item.get(), testFieldValueBytes);
    147
    148         // Serialize & Deserialize
    149         try
    150         {
    151             FileItem newItem = (FileItem)serializeDeserialize(item);
    152
    153             // Test deserialized content is as expected
    154             assertFalse("Check in memory", newItem.isInMemory());
    155             compareBytes("Check", testFieldValueBytes, newItem.get());
    156
    157             // Compare FileItem's (except byte[])
    158             compareFileItems(item, newItem);
    159
    160         }
    161         catch(Exception e)
    162         {
    163             fail("Error Serializing/Deserializing: " + e);
    164         }
    165     }
    166
    167     /**
    168      * Compare FileItem's (except the byte[] content)
    169      */
    170     private void compareFileItems(FileItem origItem, FileItem newItem) {
    171         assertTrue("Compare: is in Memory",   origItem.isInMemory()   == newItem.isInMemory());
    172         assertTrue("Compare: is Form Field",  origItem.isFormField()  == newItem.isFormField());
    173         assertEquals("Compare: Field Name",   origItem.getFieldName(),   newItem.getFieldName());
    174         assertEquals("Compare: Content Type", origItem.getContentType(), newItem.getContentType());
    175         assertEquals("Compare: File Name",    origItem.getName(),        newItem.getName());
    176     }
    177
    178     /**
    179      * Compare content bytes.
    180      */
    181     private void compareBytes(String text, byte[] origBytes, byte[] newBytes) {
    182         if (origBytes == null) {
    183             fail(text + " origBytes are null");
    184         }
    185         if (newBytes == null) {
    186             fail(text + " newBytes are null");
    187         }
    188         assertEquals(text + " byte[] length", origBytes.length, newBytes.length);
    189         for (int i = 0; i < origBytes.length; i++) {
    190             assertEquals(text + " byte[" + i + "]", origBytes[i], newBytes[i]);
    191         }
    192     }
    193
    194     /**
    195      * Create content bytes of a specified size.
    196      */
    197     private byte[] createContentBytes(int size) {
    198         StringBuffer buffer = new StringBuffer(size);
    199         byte count = 0;
    200         for (int i = 0; i < size; i++) {
    201             buffer.append(count+"");
    202             count++;
    203             if (count > 9) {
    204                 count = 0;
    205             }
    206         }
    207         return buffer.toString().getBytes();
    208     }
    209
    210     /**
    211      * Create a FileItem with the specfied content bytes.
    212      */
    213     private FileItem createFileItem(byte[] contentBytes) {
    214         FileItemFactory factory = new DiskFileItemFactory(threshold, null);
    215         String textFieldName = "textField";
    216
    217         FileItem item = factory.createItem(
    218                 textFieldName,
    219                 textContentType,
    220                 true,
    221                 "My File Name"
    222         );
    223         try
    224         {
    225             OutputStream os = item.getOutputStream();
    226             os.write(contentBytes);
    227             os.close();
    228         }
    229         catch(IOException e)
    230         {
    231             fail("Unexpected IOException" + e);
    232         }
    233
    234         return item;
    235
    236     }
    237
    238     /**
    239      * Do serialization and deserialization.
    240      */
    241     private Object serializeDeserialize(Object target) {
    242
    243         // Serialize the test object
    244         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    245         try {
    246             ObjectOutputStream oos = new ObjectOutputStream(baos);
    247             oos.writeObject(target);
    248             oos.flush();
    249             oos.close();
    250         } catch (Exception e) {
    251             fail("Exception during serialization: " + e);
    252         }
    253
    254         // Deserialize the test object
    255         Object result = null;
    256         try {
    257             ByteArrayInputStream bais =
    258                 new ByteArrayInputStream(baos.toByteArray());
    259             ObjectInputStream ois = new ObjectInputStream(bais);
    260             result = ois.readObject();
    261             bais.close();
    262         } catch (Exception e) {
    263             fail("Exception during deserialization: " + e);
    264         }
    265         return result;
    266
    267     }
    268
    269 }