View Javadoc

    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 static org.junit.Assert.assertEquals;
    20  import static org.junit.Assert.assertFalse;
    21  import static org.junit.Assert.assertNotNull;
    22  import static org.junit.Assert.assertTrue;
    23  import static org.junit.Assert.fail;
    24
    25  import java.io.ByteArrayInputStream;
    26  import java.io.ByteArrayOutputStream;
    27  import java.io.File;
    28  import java.io.IOException;
    29  import java.io.ObjectInputStream;
    30  import java.io.ObjectOutputStream;
    31  import java.io.OutputStream;
    32
    33  import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    34  import org.apache.commons.io.FileUtils;
    35  import org.junit.After;
    36  import org.junit.Before;
    37  import org.junit.Test;
    38
    39  /**
    40   * Serialization Unit tests for
    41   *  {@link org.apache.commons.fileupload.disk.DiskFileItem}.
    42   */
    43  public class DiskFileItemSerializeTest {
    44
    45      // Use a private repo to catch any files left over by tests
    46      private static final File REPO = new File(System.getProperty("java.io.tmpdir"), "diskfileitemrepo");
    47
    48      @Before
    49      public void setUp() throws Exception {
    50          if (REPO.exists()) {
    51              FileUtils.deleteDirectory(REPO);
    52          }
    53          FileUtils.forceMkdir(REPO);
    54      }
    55
    56      @After
    57      public void tearDown() throws IOException {
    58          for(File file : FileUtils.listFiles(REPO, null, true)) {
    59              System.out.println("Found leftover file " + file);
    60          }
    61          FileUtils.deleteDirectory(REPO);
    62      }
    63
    64      /**
    65       * Content type for regular form items.
    66       */
    67      private static final String textContentType = "text/plain";
    68
    69      /**
    70       * Very low threshold for testing memory versus disk options.
    71       */
    72      private static final int threshold = 16;
    73
    74      /**
    75       * Helper method to test creation of a field when a repository is used.
    76       */
    77      public void testInMemoryObject(byte[] testFieldValueBytes, File repository) {
    78          FileItem item = createFileItem(testFieldValueBytes, repository);
    79
    80          // Check state is as expected
    81          assertTrue("Initial: in memory", item.isInMemory());
    82          assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    83          compareBytes("Initial", item.get(), testFieldValueBytes);
    84          item.delete();
    85      }
    86
    87      /**
    88       * Helper method to test creation of a field.
    89       */
    90      private void testInMemoryObject(byte[] testFieldValueBytes) {
    91          testInMemoryObject(testFieldValueBytes, REPO);
    92      }
    93
    94      /**
    95       * Test creation of a field for which the amount of data falls below the
    96       * configured threshold.
    97       */
    98      @Test
    99      public void testBelowThreshold() {
    100         // Create the FileItem
    101         byte[] testFieldValueBytes = createContentBytes(threshold - 1);
    102         testInMemoryObject(testFieldValueBytes);
    103     }
    104
    105     /**
    106      * Test creation of a field for which the amount of data equals the
    107      * configured threshold.
    108      */
    109     @Test
    110     public void testThreshold() {
    111         // Create the FileItem
    112         byte[] testFieldValueBytes = createContentBytes(threshold);
    113         testInMemoryObject(testFieldValueBytes);
    114     }
    115
    116     /**
    117      * Test creation of a field for which the amount of data falls above the
    118      * configured threshold.
    119      */
    120     @Test
    121     public void testAboveThreshold() {
    122         // Create the FileItem
    123         byte[] testFieldValueBytes = createContentBytes(threshold + 1);
    124         FileItem item = createFileItem(testFieldValueBytes);
    125
    126         // Check state is as expected
    127         assertFalse("Initial: in memory", item.isInMemory());
    128         assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    129         compareBytes("Initial", item.get(), testFieldValueBytes);
    130
    131         item.delete();
    132     }
    133
    134     /**
    135      * Test serialization and deserialization when repository is not null.
    136      */
    137     @Test
    138     public void testValidRepository() {
    139         // Create the FileItem
    140         byte[] testFieldValueBytes = createContentBytes(threshold);
    141         testInMemoryObject(testFieldValueBytes, REPO);
    142     }
    143
    144     /**
    145      * Test deserialization fails when repository is not valid.
    146      */
    147     @Test(expected=IOException.class)
    148     public void testInvalidRepository() throws Exception {
    149         // Create the FileItem
    150         byte[] testFieldValueBytes = createContentBytes(threshold);
    151         File repository = new File(System.getProperty("java.io.tmpdir"), "file");
    152         FileItem item = createFileItem(testFieldValueBytes, repository);
    153         deserialize(serialize(item));
    154     }
    155
    156     /**
    157      * Test deserialization fails when repository contains a null character.
    158      */
    159     @Test(expected=IOException.class)
    160     public void testInvalidRepositoryWithNullChar() throws Exception {
    161         // Create the FileItem
    162         byte[] testFieldValueBytes = createContentBytes(threshold);
    163         File repository = new File(System.getProperty("java.io.tmpdir"), "\0");
    164         FileItem item = createFileItem(testFieldValueBytes, repository);
    165         deserialize(serialize(item));
    166     }
    167
    168     /**
    169      * Compare content bytes.
    170      */
    171     private void compareBytes(String text, byte[] origBytes, byte[] newBytes) {
    172         assertNotNull("origBytes must not be null", origBytes);
    173         assertNotNull("newBytes must not be null", newBytes);
    174         assertEquals(text + " byte[] length", origBytes.length, newBytes.length);
    175         for (int i = 0; i < origBytes.length; i++) {
    176             assertEquals(text + " byte[" + i + "]", origBytes[i], newBytes[i]);
    177         }
    178     }
    179
    180     /**
    181      * Create content bytes of a specified size.
    182      */
    183     private byte[] createContentBytes(int size) {
    184         StringBuilder buffer = new StringBuilder(size);
    185         byte count = 0;
    186         for (int i = 0; i < size; i++) {
    187             buffer.append(count+"");
    188             count++;
    189             if (count > 9) {
    190                 count = 0;
    191             }
    192         }
    193         return buffer.toString().getBytes();
    194     }
    195
    196     /**
    197      * Create a FileItem with the specfied content bytes and repository.
    198      */
    199     private FileItem createFileItem(byte[] contentBytes, File repository) {
    200         FileItemFactory factory = new DiskFileItemFactory(threshold, repository);
    201         String textFieldName = "textField";
    202
    203         FileItem item = factory.createItem(
    204                 textFieldName,
    205                 textContentType,
    206                 true,
    207                 "My File Name"
    208         );
    209         try {
    210             OutputStream os = item.getOutputStream();
    211             os.write(contentBytes);
    212             os.close();
    213         } catch(IOException e) {
    214             fail("Unexpected IOException" + e);
    215         }
    216
    217         return item;
    218
    219     }
    220
    221     /**
    222      * Create a FileItem with the specfied content bytes.
    223      */
    224     private FileItem createFileItem(byte[] contentBytes) {
    225         return createFileItem(contentBytes, REPO);
    226     }
    227
    228     /**
    229      * Do serialization
    230      */
    231     private ByteArrayOutputStream serialize(Object target) throws Exception {
    232         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    233         ObjectOutputStream oos = new ObjectOutputStream(baos);
    234         oos.writeObject(target);
    235         oos.flush();
    236         oos.close();
    237         return baos;
    238     }
    239
    240     /**
    241      * Do deserialization
    242      */
    243     private Object deserialize(ByteArrayOutputStream baos) throws Exception {
    244         Object result = null;
    245         ByteArrayInputStream bais =
    246                 new ByteArrayInputStream(baos.toByteArray());
    247         ObjectInputStream ois = new ObjectInputStream(bais);
    248         result = ois.readObject();
    249         bais.close();
    250
    251         return result;
    252     }
    253 }