    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.fileupload;
    018
    019    import java.io.IOException;
    020    import java.io.OutputStream;
    021    import java.io.ByteArrayInputStream;
    022    import java.io.ByteArrayOutputStream;
    023    import java.io.ObjectInputStream;
    024    import java.io.ObjectOutputStream;
    025
    026    import junit.framework.TestCase;
    027    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    028
    029
    030    /**
    031     * Serialization Unit tests for
    032     *  {@link org.apache.commons.fileupload.disk.DiskFileItem}.
    033     */
    034    public class DiskFileItemSerializeTest extends TestCase
    035     {
    036
    037        /**
    038         * Content type for regular form items.
    039         */
    040        private static final String textContentType = "text/plain";
    041
    042        /**
    043         * Content type for file uploads.
    044         */
    045        private static final String fileContentType = "application/octet-stream";
    046
    047        /**
    048         * Very low threshold for testing memory versus disk options.
    049         */
    050        private static final int threshold = 16;
    051
    052        /**
    053         * Standard JUnit test case constructor.
    054         *
    055         * @param name The name of the test case.
    056         */
    057        public DiskFileItemSerializeTest(String name)
    058        {
    059            super(name);
    060        }
    061
    062        /**
    063         * Test creation of a field for which the amount of data falls below the
    064         * configured threshold.
    065         */
    066        public void testBelowThreshold()
    067        {
    068
    069            // Create the FileItem
    070            byte[] testFieldValueBytes = createContentBytes(threshold - 1);
    071            FileItem item = createFileItem(testFieldValueBytes);
    072
    073            // Check state is as expected
    074            assertTrue("Initial: in memory", item.isInMemory());
    075            assertEquals("Initial: size", item.getSize(), testFieldValueBytes.length);
    076            compareBytes("Initial", item.get(), testFieldValueBytes);
    077
    078            // Serialize & Deserialize
    079            try
    080            {
    081                FileItem newItem = (FileItem)serializeDeserialize(item);
    082
    083                // Test deserialized content is as expected
    084                assertTrue("Check in memory", newItem.isInMemory());
    085                compareBytes("Check", testFieldValueBytes, newItem.get());
    086
    087                // Compare FileItem's (except byte[])
    088                compareFileItems(item, newItem);
    089
    090            }
    091            catch(Exception e)
    092            {
    093                fail("Error Serializing/Deserializing: " + e);
    094            }
    095
    096
    097        }
    098
    099        /**
    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    }