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  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.assertThrows;
22  
23  import java.io.IOException;
24  import java.nio.file.Files;
25  import java.nio.file.Path;
26  import java.util.concurrent.atomic.AtomicInteger;
27  
28  import org.apache.commons.io.IOUtils;
29  import org.apache.commons.io.file.TempFile;
30  import org.apache.commons.lang3.ArrayFill;
31  import org.junit.jupiter.api.Test;
32  
33  /**
34   * Tests {@link ChunkedOutputStream}.
35   */
36  public class ChunkedOutputStreamTest {
37  
38      private ByteArrayOutputStream newByteArrayOutputStream(final AtomicInteger numWrites) {
39          return new ByteArrayOutputStream() {
40              @Override
41              public void write(final byte[] b, final int off, final int len) {
42                  numWrites.incrementAndGet();
43                  super.write(b, off, len);
44              }
45          };
46      }
47  
48      /**
49       * Tests the default chunk size with a ByteArrayOutputStream.
50       *
51       * @throws IOException
52       */
53      @Test
54      public void testBuildSetByteArrayOutputStream() throws IOException {
55          final AtomicInteger numWrites = new AtomicInteger();
56          try (ByteArrayOutputStream baos = newByteArrayOutputStream(numWrites);
57                  final ChunkedOutputStream chunked = ChunkedOutputStream.builder().setOutputStream(baos).get()) {
58              chunked.write(new byte[IOUtils.DEFAULT_BUFFER_SIZE + 1]);
59              assertEquals(2, numWrites.get());
60          }
61          assertThrows(IllegalStateException.class, () -> ChunkedOutputStream.builder().get());
62      }
63  
64      /**
65       * Tests the default chunk size with a Path.
66       *
67       * @throws IOException
68       */
69      @Test
70      public void testBuildSetPath() throws IOException {
71          try (TempFile tempFile = TempFile.create("test-", ".txt")) {
72              final byte[] fill = ArrayFill.fill(new byte[IOUtils.DEFAULT_BUFFER_SIZE + 1], (byte) 'a');
73              final Path tempPath = tempFile.get();
74              try (ChunkedOutputStream chunked = ChunkedOutputStream.builder().setPath(tempPath).get()) {
75                  chunked.write(fill);
76              }
77              assertArrayEquals(fill, Files.readAllBytes(tempPath));
78          }
79      }
80  
81      @Test
82      public void testDefaultConstructor() throws IOException {
83          final AtomicInteger numWrites = new AtomicInteger();
84          try (ByteArrayOutputStream baos = newByteArrayOutputStream(numWrites);
85                  final ChunkedOutputStream chunked = new ChunkedOutputStream(baos)) {
86              chunked.write(new byte[IOUtils.DEFAULT_BUFFER_SIZE + 1]);
87              assertEquals(2, numWrites.get());
88          }
89      }
90  
91      @Test
92      public void testNegativeChunkSize() throws IOException {
93          assertThrows(IllegalArgumentException.class, () -> new ChunkedOutputStream(new ByteArrayOutputStream(), -1));
94          // Builder resets invalid input to the default.
95          try (ChunkedOutputStream os = ChunkedOutputStream.builder().setOutputStream(new ByteArrayOutputStream()).setBufferSize(-1).get()) {
96              assertEquals(IOUtils.DEFAULT_BUFFER_SIZE, os.getChunkSize());
97          }
98      }
99  
100     @Test
101     public void testWriteFourChunks() throws Exception {
102         final AtomicInteger numWrites = new AtomicInteger();
103         try (ByteArrayOutputStream baos = newByteArrayOutputStream(numWrites);
104                 final ChunkedOutputStream chunked = new ChunkedOutputStream(baos, 10)) {
105             chunked.write("0123456789012345678901234567891".getBytes());
106             assertEquals(4, numWrites.get());
107         }
108     }
109 
110     @Test
111     public void testZeroChunkSize() throws IOException {
112         assertThrows(IllegalArgumentException.class, () -> new ChunkedOutputStream(new ByteArrayOutputStream(), 0));
113         // Builder resets invalid input to the default.
114         try (ChunkedOutputStream os = ChunkedOutputStream.builder().setOutputStream(new ByteArrayOutputStream()).setBufferSize(0).get()) {
115             assertEquals(IOUtils.DEFAULT_BUFFER_SIZE, os.getChunkSize());
116         }
117     }
118 
119 }