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 }