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