1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.assertNotEquals;
21 import static org.junit.jupiter.api.Assertions.assertNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.IOException;
27
28 import org.apache.commons.io.IOUtils;
29 import org.apache.commons.io.input.ObservableInputStream.Observer;
30 import org.apache.commons.io.output.NullOutputStream;
31 import org.junit.jupiter.api.Test;
32
33
34
35
36 public class ObservableInputStreamTest {
37
38 private static final class DataViewObserver extends MethodCountObserver {
39 private byte[] buffer;
40 private int lastValue = -1;
41 private int length = -1;
42 private int offset = -1;
43
44 @Override
45 public void data(final byte[] buffer, final int offset, final int length) throws IOException {
46 this.buffer = buffer;
47 this.offset = offset;
48 this.length = length;
49 }
50
51 @Override
52 public void data(final int value) throws IOException {
53 super.data(value);
54 lastValue = value;
55 }
56 }
57
58 private static final class LengthObserver extends Observer {
59 private long total;
60
61 @Override
62 public void data(final byte[] buffer, final int offset, final int length) throws IOException {
63 this.total += length;
64 }
65
66 @Override
67 public void data(final int value) throws IOException {
68 total++;
69 }
70
71 public long getTotal() {
72 return total;
73 }
74 }
75
76 private static class MethodCountObserver extends Observer {
77 private long closedCount;
78 private long dataBufferCount;
79 private long dataCount;
80 private long errorCount;
81 private long finishedCount;
82
83 @Override
84 public void closed() throws IOException {
85 closedCount++;
86 }
87
88 @Override
89 public void data(final byte[] buffer, final int offset, final int length) throws IOException {
90 dataBufferCount++;
91 }
92
93 @Override
94 public void data(final int value) throws IOException {
95 dataCount++;
96 }
97
98 @Override
99 public void error(final IOException exception) throws IOException {
100 errorCount++;
101 }
102
103 @Override
104 public void finished() throws IOException {
105 finishedCount++;
106 }
107
108 public long getClosedCount() {
109 return closedCount;
110 }
111
112 public long getDataBufferCount() {
113 return dataBufferCount;
114 }
115
116 public long getDataCount() {
117 return dataCount;
118 }
119
120 public long getErrorCount() {
121 return errorCount;
122 }
123
124 public long getFinishedCount() {
125 return finishedCount;
126 }
127
128 }
129
130 @Test
131 public void testBrokenInputStreamRead() throws IOException {
132 try (ObservableInputStream ois = new ObservableInputStream(BrokenInputStream.INSTANCE)) {
133 assertThrows(IOException.class, ois::read);
134 }
135 }
136
137 @Test
138 public void testBrokenInputStreamReadBuffer() throws IOException {
139 try (ObservableInputStream ois = new ObservableInputStream(BrokenInputStream.INSTANCE)) {
140 assertThrows(IOException.class, () -> ois.read(new byte[1]));
141 }
142 }
143
144 @Test
145 public void testBrokenInputStreamReadSubBuffer() throws IOException {
146 try (ObservableInputStream ois = new ObservableInputStream(BrokenInputStream.INSTANCE)) {
147 assertThrows(IOException.class, () -> ois.read(new byte[2], 0, 1));
148 }
149 }
150
151
152
153
154 @Test
155 public void testDataByteCalled_add() throws Exception {
156 final byte[] buffer = MessageDigestInputStreamTest.generateRandomByteStream(IOUtils.DEFAULT_BUFFER_SIZE);
157 final DataViewObserver lko = new DataViewObserver();
158 try (ObservableInputStream ois = new ObservableInputStream(new ByteArrayInputStream(buffer))) {
159 assertEquals(-1, lko.lastValue);
160 ois.read();
161 assertEquals(-1, lko.lastValue);
162 assertEquals(0, lko.getFinishedCount());
163 assertEquals(0, lko.getClosedCount());
164 ois.add(lko);
165 for (int i = 1; i < buffer.length; i++) {
166 final int result = ois.read();
167 assertEquals((byte) result, buffer[i]);
168 assertEquals(result, lko.lastValue);
169 assertEquals(0, lko.getFinishedCount());
170 assertEquals(0, lko.getClosedCount());
171 }
172 final int result = ois.read();
173 assertEquals(-1, result);
174 assertEquals(1, lko.getFinishedCount());
175 assertEquals(0, lko.getClosedCount());
176 ois.close();
177 assertEquals(1, lko.getFinishedCount());
178 assertEquals(1, lko.getClosedCount());
179 }
180 }
181
182
183
184
185 @Test
186 public void testDataByteCalled_ctor() throws Exception {
187 final byte[] buffer = MessageDigestInputStreamTest.generateRandomByteStream(IOUtils.DEFAULT_BUFFER_SIZE);
188 final DataViewObserver lko = new DataViewObserver();
189 try (ObservableInputStream ois = new ObservableInputStream(new ByteArrayInputStream(buffer), lko)) {
190 assertEquals(-1, lko.lastValue);
191 ois.read();
192 assertNotEquals(-1, lko.lastValue);
193 assertEquals(0, lko.getFinishedCount());
194 assertEquals(0, lko.getClosedCount());
195 for (int i = 1; i < buffer.length; i++) {
196 final int result = ois.read();
197 assertEquals((byte) result, buffer[i]);
198 assertEquals(result, lko.lastValue);
199 assertEquals(0, lko.getFinishedCount());
200 assertEquals(0, lko.getClosedCount());
201 }
202 final int result = ois.read();
203 assertEquals(-1, result);
204 assertEquals(1, lko.getFinishedCount());
205 assertEquals(0, lko.getClosedCount());
206 ois.close();
207 assertEquals(1, lko.getFinishedCount());
208 assertEquals(1, lko.getClosedCount());
209 }
210 }
211
212
213
214
215 @Test
216 public void testDataBytesCalled() throws Exception {
217 final byte[] buffer = MessageDigestInputStreamTest.generateRandomByteStream(IOUtils.DEFAULT_BUFFER_SIZE);
218 try (ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
219 final ObservableInputStream ois = new ObservableInputStream(bais)) {
220 final DataViewObserver observer = new DataViewObserver();
221 final byte[] readBuffer = new byte[23];
222 assertNull(observer.buffer);
223 ois.read(readBuffer);
224 assertNull(observer.buffer);
225 ois.add(observer);
226 for (;;) {
227 if (bais.available() >= 2048) {
228 final int result = ois.read(readBuffer);
229 if (result == -1) {
230 ois.close();
231 break;
232 }
233 assertEquals(readBuffer, observer.buffer);
234 assertEquals(0, observer.offset);
235 assertEquals(readBuffer.length, observer.length);
236 } else {
237 final int res = Math.min(11, bais.available());
238 final int result = ois.read(readBuffer, 1, 11);
239 if (result == -1) {
240 ois.close();
241 break;
242 }
243 assertEquals(readBuffer, observer.buffer);
244 assertEquals(1, observer.offset);
245 assertEquals(res, observer.length);
246 }
247 }
248 }
249 }
250
251 @Test
252 public void testGetObservers0() throws IOException {
253 try (ObservableInputStream ois = new ObservableInputStream(NullInputStream.INSTANCE)) {
254 assertTrue(ois.getObservers().isEmpty());
255 }
256 }
257
258 @Test
259 public void testGetObservers1() throws IOException {
260 final DataViewObserver observer0 = new DataViewObserver();
261 try (ObservableInputStream ois = new ObservableInputStream(NullInputStream.INSTANCE, observer0)) {
262 assertEquals(observer0, ois.getObservers().get(0));
263 }
264 }
265
266 @Test
267 public void testGetObserversOrder() throws IOException {
268 final DataViewObserver observer0 = new DataViewObserver();
269 final DataViewObserver observer1 = new DataViewObserver();
270 try (ObservableInputStream ois = new ObservableInputStream(NullInputStream.INSTANCE, observer0, observer1)) {
271 assertEquals(observer0, ois.getObservers().get(0));
272 assertEquals(observer1, ois.getObservers().get(1));
273 }
274 }
275
276 private void testNotificationCallbacks(final int bufferSize) throws IOException {
277 final byte[] buffer = IOUtils.byteArray();
278 final LengthObserver lengthObserver = new LengthObserver();
279 final MethodCountObserver methodCountObserver = new MethodCountObserver();
280 try (ObservableInputStream ois = new ObservableInputStream(new ByteArrayInputStream(buffer),
281 lengthObserver, methodCountObserver)) {
282 assertEquals(IOUtils.DEFAULT_BUFFER_SIZE,
283 IOUtils.copy(ois, NullOutputStream.INSTANCE, bufferSize));
284 }
285 assertEquals(IOUtils.DEFAULT_BUFFER_SIZE, lengthObserver.getTotal());
286 assertEquals(1, methodCountObserver.getClosedCount());
287 assertEquals(1, methodCountObserver.getFinishedCount());
288 assertEquals(0, methodCountObserver.getErrorCount());
289 assertEquals(0, methodCountObserver.getDataCount());
290 assertEquals(buffer.length / bufferSize, methodCountObserver.getDataBufferCount());
291 }
292
293 @Test
294 public void testNotificationCallbacksBufferSize1() throws Exception {
295 testNotificationCallbacks(1);
296 }
297
298 @Test
299 public void testNotificationCallbacksBufferSize2() throws Exception {
300 testNotificationCallbacks(2);
301 }
302
303 @Test
304 public void testNotificationCallbacksBufferSizeDefault() throws Exception {
305 testNotificationCallbacks(IOUtils.DEFAULT_BUFFER_SIZE);
306 }
307 }