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    *      https://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.input;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  
26  import org.apache.commons.io.IOUtils;
27  import org.junit.jupiter.api.Test;
28  import org.junit.jupiter.params.ParameterizedTest;
29  import org.junit.jupiter.params.provider.MethodSource;
30  
31  /**
32   * Tests {@link CountingInputStream}.
33   */
34  class CountingInputStreamTest {
35  
36      @SuppressWarnings("resource")
37      @ParameterizedTest
38      @MethodSource(AbstractInputStreamTest.ARRAY_LENGTHS_NAME)
39      void testAvailableAfterClose(final int len) throws Exception {
40          final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[len]);
41          final InputStream shadow;
42          try (InputStream in = CloseShieldInputStream.wrap(bais)) {
43              assertEquals(len, in.available());
44              shadow = in;
45          }
46          assertEquals(0, shadow.available());
47      }
48  
49      @ParameterizedTest
50      @MethodSource(AbstractInputStreamTest.ARRAY_LENGTHS_NAME)
51      void testAvailableAfterOpen(final int len) throws Exception {
52          final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[len]);
53          try (InputStream in = CloseShieldInputStream.wrap(bais)) {
54              assertEquals(len, in.available());
55          }
56      }
57  
58      @SuppressWarnings({ "resource", "deprecation" })
59      @Test
60      void testCloseHandleIOException() throws IOException {
61          ProxyInputStreamTest.testCloseHandleIOException(new CountingInputStream(new BrokenInputStream((Throwable) new IOException())));
62      }
63  
64      @Test
65      void testCounting() throws Exception {
66          final String text = "A piece of text";
67          try (CountingInputStream cis = new CountingInputStream(CharSequenceInputStream.builder().setCharSequence(text).get())) {
68  
69              // have to declare this larger as we're going to read
70              // off the end of the stream and input stream seems
71              // to do bounds checking
72              final byte[] result = new byte[21];
73  
74              final byte[] ba = new byte[5];
75              int found = cis.read(ba);
76              System.arraycopy(ba, 0, result, 0, 5);
77              assertEquals(found, cis.getCount());
78  
79              final int value = cis.read();
80              found++;
81              result[5] = (byte) value;
82              assertEquals(found, cis.getCount());
83  
84              found += cis.read(result, 6, 5);
85              assertEquals(found, cis.getCount());
86  
87              found += cis.read(result, 11, 10); // off the end
88              assertEquals(found, cis.getCount());
89  
90              // trim to get rid of the 6 empty values
91              final String textResult = new String(result).trim();
92              assertEquals(textResult, text);
93          }
94      }
95  
96      @Test
97      void testEOF1() throws Exception {
98          final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[2]);
99          try (CountingInputStream cis = new CountingInputStream(bais)) {
100 
101             int found = cis.read();
102             assertEquals(0, found);
103             assertEquals(1, cis.getCount());
104             found = cis.read();
105             assertEquals(0, found);
106             assertEquals(2, cis.getCount());
107             found = cis.read();
108             assertEquals(-1, found);
109             assertEquals(2, cis.getCount());
110         }
111     }
112 
113     @Test
114     void testEOF2() throws Exception {
115         final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[2]);
116         try (CountingInputStream cis = new CountingInputStream(bais)) {
117 
118             final byte[] result = new byte[10];
119 
120             final int found = cis.read(result);
121             assertEquals(2, found);
122             assertEquals(2, cis.getCount());
123         }
124     }
125 
126     @Test
127     void testEOF3() throws Exception {
128         final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[2]);
129         try (CountingInputStream cis = new CountingInputStream(bais)) {
130 
131             final byte[] result = new byte[10];
132 
133             final int found = cis.read(result, 0, 5);
134             assertEquals(2, found);
135             assertEquals(2, cis.getCount());
136         }
137     }
138 
139     /*
140      * Test for files > 2GB in size - see issue IO-84
141      */
142     @Test
143     void testLargeFiles_IO84() throws Exception {
144         final long size = (long) Integer.MAX_VALUE + (long) 1;
145         final NullInputStream mock = new NullInputStream(size);
146         final CountingInputStream cis = new CountingInputStream(mock);
147 
148         // Test integer methods
149         IOUtils.consume(cis);
150         assertThrows(ArithmeticException.class, () -> cis.getCount());
151         assertThrows(ArithmeticException.class, () -> cis.resetCount());
152 
153         mock.init();
154 
155         // Test long methods
156         IOUtils.consume(cis);
157         assertEquals(size, cis.getByteCount(), "getByteCount()");
158         assertEquals(size, cis.resetByteCount(), "resetByteCount()");
159     }
160 
161     @SuppressWarnings("resource")
162     @ParameterizedTest
163     @MethodSource(AbstractInputStreamTest.ARRAY_LENGTHS_NAME)
164     void testReadAfterClose(final int len) throws Exception {
165         final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[len]);
166         final InputStream shadow;
167         try (InputStream in = CloseShieldInputStream.wrap(bais)) {
168             assertEquals(len, in.available());
169             shadow = in;
170         }
171         assertEquals(IOUtils.EOF, shadow.read());
172     }
173 
174     @Test
175     void testResetting() throws Exception {
176         final String text = "A piece of text";
177         final byte[] bytes = text.getBytes();
178         final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
179         try (CountingInputStream cis = new CountingInputStream(bais)) {
180 
181             final byte[] result = new byte[bytes.length];
182 
183             int found = cis.read(result, 0, 5);
184             assertEquals(found, cis.getCount());
185 
186             final int count = cis.resetCount();
187             found = cis.read(result, 6, 5);
188             assertEquals(found, count);
189         }
190     }
191 
192     @Test
193     void testSkipping() throws IOException {
194         final String text = "Hello World!";
195         try (CountingInputStream cis = new CountingInputStream(CharSequenceInputStream.builder().setCharSequence(text).get())) {
196 
197             assertEquals(6, cis.skip(6));
198             assertEquals(6, cis.getCount());
199             final byte[] result = new byte[6];
200             assertEquals(result.length, cis.read(result));
201 
202             assertEquals("World!", new String(result));
203             assertEquals(12, cis.getCount());
204         }
205     }
206 
207     @Test
208     void testZeroLength1() throws Exception {
209         final ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.EMPTY_BYTE_ARRAY);
210         try (CountingInputStream cis = new CountingInputStream(bais)) {
211 
212             final int found = cis.read();
213             assertEquals(-1, found);
214             assertEquals(0, cis.getCount());
215         }
216     }
217 
218     @Test
219     void testZeroLength2() throws Exception {
220         final ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.EMPTY_BYTE_ARRAY);
221         try (CountingInputStream cis = new CountingInputStream(bais)) {
222 
223             final byte[] result = new byte[10];
224 
225             final int found = cis.read(result);
226             assertEquals(-1, found);
227             assertEquals(0, cis.getCount());
228         }
229     }
230 
231     @Test
232     void testZeroLength3() throws Exception {
233         final ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.EMPTY_BYTE_ARRAY);
234         try (CountingInputStream cis = new CountingInputStream(bais)) {
235 
236             final byte[] result = new byte[10];
237 
238             final int found = cis.read(result, 0, 5);
239             assertEquals(-1, found);
240             assertEquals(0, cis.getCount());
241         }
242     }
243 
244 }