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 }