1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.io.output;
18
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.util.stream.IntStream;
33
34 import org.apache.commons.io.IOUtils;
35 import org.apache.commons.io.file.AbstractTempDirTest;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.io.TempDir;
38 import org.junit.jupiter.params.ParameterizedTest;
39 import org.junit.jupiter.params.provider.MethodSource;
40
41
42
43
44 public class DeferredFileOutputStreamTest extends AbstractTempDirTest {
45
46 public static IntStream data() {
47 return IntStream.of(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096);
48 }
49
50
51
52
53 private final String testString = "0123456789";
54
55
56
57
58 private final byte[] testBytes = testString.getBytes();
59
60
61
62
63
64 @ParameterizedTest(name = "initialBufferSize = {0}")
65 @MethodSource("data")
66 public void testAboveThreshold(final int initialBufferSize) throws IOException {
67 final File testFile = Files.createTempFile(tempDirPath, "testAboveThreshold", "dat").toFile();
68 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
69 .setThreshold(testBytes.length - 5)
70 .setBufferSize(initialBufferSize)
71 .setOutputFile(testFile)
72 .get()) {
73 dfos.write(testBytes, 0, testBytes.length);
74 dfos.close();
75 assertFalse(dfos.isInMemory());
76 assertNull(dfos.getData());
77 assertEquals(testFile.length(), dfos.getByteCount());
78 verifyResultFile(testFile);
79 }
80 }
81
82
83
84
85
86
87 @ParameterizedTest(name = "initialBufferSize = {0}")
88 @MethodSource("data")
89 public void testAboveThresholdGetInputStream(final int initialBufferSize, final @TempDir Path tempDir) throws IOException {
90 final File testFile = Files.createTempFile(tempDirPath, "testAboveThreshold", "dat").toFile();
91 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
92 .setThreshold(testBytes.length - 5)
93 .setBufferSize(initialBufferSize)
94 .setOutputFile(testFile)
95 .get()) {
96 dfos.write(testBytes, 0, testBytes.length);
97 dfos.close();
98 assertFalse(dfos.isInMemory());
99 assertEquals(testFile.length(), dfos.getByteCount());
100 try (InputStream is = dfos.toInputStream()) {
101 assertArrayEquals(testBytes, IOUtils.toByteArray(is));
102 }
103 verifyResultFile(testFile);
104 }
105 }
106
107
108
109
110
111 @ParameterizedTest(name = "initialBufferSize = {0}")
112 @MethodSource("data")
113 public void testAtThreshold(final int initialBufferSize) throws IOException {
114 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
115
116 .setThreshold(testBytes.length)
117 .setBufferSize(initialBufferSize)
118 .get()) {
119
120 dfos.write(testBytes, 0, testBytes.length);
121 dfos.close();
122 assertTrue(dfos.isInMemory());
123 assertEquals(testBytes.length, dfos.getByteCount());
124 final byte[] resultBytes = dfos.getData();
125 assertEquals(testBytes.length, resultBytes.length);
126 assertArrayEquals(resultBytes, testBytes);
127 }
128 }
129
130
131
132
133
134 @ParameterizedTest(name = "initialBufferSize = {0}")
135 @MethodSource("data")
136 public void testBelowThreshold(final int initialBufferSize) throws IOException {
137 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
138
139 .setThreshold(testBytes.length + 42)
140 .setBufferSize(initialBufferSize)
141 .get()) {
142
143 dfos.write(testBytes, 0, testBytes.length);
144 dfos.close();
145 assertTrue(dfos.isInMemory());
146 assertEquals(testBytes.length, dfos.getByteCount());
147 final byte[] resultBytes = dfos.getData();
148 assertEquals(testBytes.length, resultBytes.length);
149 assertArrayEquals(resultBytes, testBytes);
150 }
151 }
152
153
154
155
156
157 @ParameterizedTest(name = "initialBufferSize = {0}")
158 @MethodSource("data")
159 public void testBelowThresholdGetInputStream(final int initialBufferSize) throws IOException {
160
161 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
162 .setThreshold(testBytes.length + 42)
163 .setBufferSize(initialBufferSize)
164 .get()) {
165
166 dfos.write(testBytes, 0, testBytes.length);
167 dfos.close();
168 assertTrue(dfos.isInMemory());
169 assertEquals(testBytes.length, dfos.getByteCount());
170 try (InputStream is = dfos.toInputStream()) {
171 assertArrayEquals(testBytes, IOUtils.toByteArray(is));
172 }
173 }
174 }
175
176
177
178
179 @ParameterizedTest(name = "initialBufferSize = {0}")
180 @MethodSource("data")
181 public void testTempFileAboveThreshold(final int initialBufferSize) throws IOException {
182 final String prefix = "commons-io-test";
183 final String suffix = ".out";
184
185 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
186 .setThreshold(testBytes.length - 5)
187 .setBufferSize(initialBufferSize)
188 .setPrefix(prefix)
189 .setSuffix(suffix)
190 .setDirectory(tempDirFile)
191 .setDirectory(tempDirPath.toFile())
192 .get()) {
193
194 assertNull(dfos.getFile(), "Check File is null-A");
195 assertNull(dfos.getPath(), "Check Path is null-A");
196 dfos.write(testBytes, 0, testBytes.length);
197 dfos.close();
198 assertFalse(dfos.isInMemory());
199 assertEquals(testBytes.length, dfos.getByteCount());
200 assertNull(dfos.getData());
201 assertNotNull(dfos.getFile(), "Check file not null");
202 assertTrue(dfos.getFile().exists(), "Check file exists");
203 assertTrue(dfos.getFile().getName().startsWith(prefix), "Check prefix");
204 assertTrue(dfos.getFile().getName().endsWith(suffix), "Check suffix");
205 assertEquals(tempDirPath, dfos.getPath().getParent(), "Check dir");
206 verifyResultFile(dfos.getFile());
207 }
208 }
209
210
211
212
213
214 @ParameterizedTest(name = "initialBufferSize = {0}")
215 @MethodSource("data")
216 public void testTempFileAboveThresholdPrefixOnly(final int initialBufferSize) throws IOException {
217 final String prefix = "commons-io-test";
218 final String suffix = null;
219 try (final DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
220
221 .setThreshold(testBytes.length - 5)
222 .setBufferSize(initialBufferSize)
223 .setPrefix(prefix)
224 .setSuffix(suffix)
225 .setDirectory((Path) null)
226 .get()) {
227
228 try {
229 assertNull(dfos.getFile(), "Check File is null-A");
230 assertNull(dfos.getPath(), "Check Path is null-A");
231 dfos.write(testBytes, 0, testBytes.length);
232 dfos.close();
233 assertFalse(dfos.isInMemory());
234 assertNull(dfos.getData());
235 assertEquals(testBytes.length, dfos.getByteCount());
236 assertNotNull(dfos.getFile(), "Check file not null");
237 assertTrue(dfos.getFile().exists(), "Check file exists");
238 assertTrue(dfos.getFile().getName().startsWith(prefix), "Check prefix");
239 assertTrue(dfos.getFile().getName().endsWith(".tmp"), "Check suffix");
240 verifyResultFile(dfos.getFile());
241 } finally {
242
243 dfos.getFile().delete();
244 }
245 }
246 }
247
248
249
250
251
252 @ParameterizedTest(name = "initialBufferSize = {0}")
253 @MethodSource("data")
254 public void testTempFileBelowThreshold(final int initialBufferSize) throws IOException {
255 final String prefix = "commons-io-test";
256 final String suffix = ".out";
257 try (final DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length + 42, initialBufferSize, prefix, suffix, tempDirFile)) {
258 assertNull(dfos.getFile(), "Check File is null-A");
259 assertNull(dfos.getPath(), "Check Path is null-A");
260 dfos.write(testBytes, 0, testBytes.length);
261 dfos.close();
262 assertTrue(dfos.isInMemory());
263 assertEquals(testBytes.length, dfos.getByteCount());
264 assertNull(dfos.getFile(), "Check file is null-B");
265 }
266 }
267
268
269
270
271
272
273 @Test
274 public void testTempFileError() throws Exception {
275 final String prefix = null;
276 final String suffix = ".out";
277 assertThrows(NullPointerException.class, () -> new DeferredFileOutputStream(testBytes.length - 5, prefix, suffix, tempDirFile));
278 }
279
280
281
282
283
284 @ParameterizedTest(name = "initialBufferSize = {0}")
285 @MethodSource("data")
286 public void testThresholdNegative(final int initialBufferSize) throws IOException {
287 final File testFile = Files.createTempFile(tempDirPath, "testThresholdNegative", "dat").toFile();
288 try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
289 .setThreshold(-1)
290 .setBufferSize(initialBufferSize)
291 .setOutputFile(testFile)
292 .get()) {
293 dfos.write(testBytes, 0, testBytes.length);
294 dfos.close();
295 assertFalse(dfos.isInMemory());
296 assertNull(dfos.getData());
297 assertEquals(testFile.length(), dfos.getByteCount());
298 verifyResultFile(testFile);
299 }
300 }
301
302
303
304
305
306
307 @ParameterizedTest(name = "initialBufferSize = {0}")
308 @MethodSource("data")
309 public void testThresholdReached(final int initialBufferSize) throws IOException {
310 final File testFile = Files.createTempFile(tempDirPath, "testThresholdReached", "dat").toFile();
311 try (final DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
312
313 .setThreshold(testBytes.length /2)
314 .setBufferSize(initialBufferSize)
315 .setOutputFile(testFile)
316 .get()) {
317
318 final int chunkSize = testBytes.length / 3;
319 dfos.write(testBytes, 0, chunkSize);
320 dfos.write(testBytes, chunkSize, chunkSize);
321 dfos.write(testBytes, chunkSize * 2, testBytes.length - chunkSize * 2);
322 dfos.close();
323 assertFalse(dfos.isInMemory());
324 assertNull(dfos.getData());
325 assertEquals(testBytes.length, dfos.getByteCount());
326 verifyResultFile(testFile);
327 }
328 }
329
330
331
332
333 @ParameterizedTest(name = "initialBufferSize = {0}")
334 @MethodSource("data")
335 public void testWriteToLarge(final int initialBufferSize) throws IOException {
336 final File testFile = Files.createTempFile(tempDirPath, "testWriteToFile", "dat").toFile();
337 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(initialBufferSize);
338 DeferredFileOutputStream dfos = DeferredFileOutputStream.builder().setThreshold(testBytes.length / 2).setOutputFile(testFile).get()) {
339 dfos.write(testBytes);
340
341 assertTrue(testFile.exists());
342 assertFalse(dfos.isInMemory());
343 assertEquals(testBytes.length, dfos.getByteCount());
344
345 assertThrows(IOException.class, () -> dfos.writeTo(baos));
346
347 dfos.close();
348 dfos.writeTo(baos);
349 final byte[] copiedBytes = baos.toByteArray();
350 assertArrayEquals(testBytes, copiedBytes);
351 verifyResultFile(testFile);
352 }
353 }
354
355
356
357
358 @ParameterizedTest(name = "initialBufferSize = {0}")
359 @MethodSource("data")
360 public void testWriteToLargeCtor(final int initialBufferSize) throws IOException {
361 final File testFile = Files.createTempFile(tempDirPath, "testWriteToFile", "dat").toFile();
362 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(initialBufferSize);
363 DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length / 2, testFile)) {
364 dfos.write(testBytes);
365
366 assertTrue(testFile.exists());
367 assertFalse(dfos.isInMemory());
368
369 assertThrows(IOException.class, () -> dfos.writeTo(baos));
370 assertEquals(testBytes.length, dfos.getByteCount());
371
372 dfos.close();
373 dfos.writeTo(baos);
374 final byte[] copiedBytes = baos.toByteArray();
375 assertArrayEquals(testBytes, copiedBytes);
376 verifyResultFile(testFile);
377 }
378 }
379
380
381
382
383
384 @ParameterizedTest(name = "initialBufferSize = {0}")
385 @MethodSource("data")
386 public void testWriteToSmall(final int initialBufferSize) throws IOException {
387 final File testFile = Files.createTempFile(tempDirPath, "testWriteToMem", "dat").toFile();
388 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(initialBufferSize);
389 final DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length * 2, initialBufferSize, testFile)) {
390 dfos.write(testBytes);
391
392 assertTrue(dfos.isInMemory());
393
394 assertThrows(IOException.class, () -> dfos.writeTo(baos));
395 assertEquals(testBytes.length, dfos.getByteCount());
396
397 dfos.close();
398 dfos.writeTo(baos);
399 final byte[] copiedBytes = baos.toByteArray();
400 assertArrayEquals(testBytes, copiedBytes);
401 }
402 }
403
404
405
406
407
408
409 private void verifyResultFile(final File testFile) throws IOException {
410 try (final InputStream fis = Files.newInputStream(testFile.toPath())) {
411 assertEquals(testBytes.length, fis.available());
412
413 final byte[] resultBytes = new byte[testBytes.length];
414 assertEquals(testBytes.length, fis.read(resultBytes));
415
416 assertArrayEquals(resultBytes, testBytes);
417 assertEquals(-1, fis.read(resultBytes));
418 }
419 }
420 }