View Javadoc
1   /*
2    * Copyright (C) 2009, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.util.io;
12  
13  import static org.junit.Assert.assertEquals;
14  import static org.junit.Assert.assertFalse;
15  import static org.junit.Assert.assertTrue;
16  import static org.junit.Assert.fail;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.Arrays;
22  
23  import org.junit.Test;
24  
25  public class UnionInputStreamTest {
26  	@Test
27  	public void testEmptyStream() throws IOException {
28  		try (UnionInputStream u = new UnionInputStream()) {
29  			assertTrue(u.isEmpty());
30  			assertEquals(-1, u.read());
31  			assertEquals(-1, u.read(new byte[1], 0, 1));
32  			assertEquals(0, u.available());
33  			assertEquals(0, u.skip(1));
34  		}
35  	}
36  
37  	@Test
38  	public void testReadSingleBytes() throws IOException {
39  		try (UnionInputStream u = new UnionInputStream()) {
40  			assertTrue(u.isEmpty());
41  			u.add(new ByteArrayInputStream(new byte[] { 1, 0, 2 }));
42  			u.add(new ByteArrayInputStream(new byte[] { 3 }));
43  			u.add(new ByteArrayInputStream(new byte[] { 4, 5 }));
44  
45  			assertFalse(u.isEmpty());
46  			assertEquals(3, u.available());
47  			assertEquals(1, u.read());
48  			assertEquals(0, u.read());
49  			assertEquals(2, u.read());
50  			assertEquals(0, u.available());
51  
52  			assertEquals(3, u.read());
53  			assertEquals(0, u.available());
54  
55  			assertEquals(4, u.read());
56  			assertEquals(1, u.available());
57  			assertEquals(5, u.read());
58  			assertEquals(0, u.available());
59  			assertEquals(-1, u.read());
60  
61  			assertTrue(u.isEmpty());
62  			u.add(new ByteArrayInputStream(new byte[] { (byte) 255 }));
63  			assertEquals(255, u.read());
64  			assertEquals(-1, u.read());
65  			assertTrue(u.isEmpty());
66  		}
67  	}
68  
69  	@Test
70  	public void testReadByteBlocks() throws IOException {
71  		try (UnionInputStream u = new UnionInputStream()) {
72  			u.add(new ByteArrayInputStream(new byte[] { 1, 0, 2 }));
73  			u.add(new ByteArrayInputStream(new byte[] { 3 }));
74  			u.add(new ByteArrayInputStream(new byte[] { 4, 5 }));
75  
76  			final byte[] r = new byte[5];
77  			assertEquals(3, u.read(r, 0, 5));
78  			assertTrue(Arrays.equals(new byte[] { 1, 0, 2, }, slice(r, 3)));
79  			assertEquals(1, u.read(r, 0, 5));
80  			assertEquals(3, r[0]);
81  			assertEquals(2, u.read(r, 0, 5));
82  			assertTrue(Arrays.equals(new byte[] { 4, 5, }, slice(r, 2)));
83  			assertEquals(-1, u.read(r, 0, 5));
84  		}
85  	}
86  
87  	private static byte[] slice(byte[] in, int len) {
88  		byte[] r = new byte[len];
89  		System.arraycopy(in, 0, r, 0, len);
90  		return r;
91  	}
92  
93  	@Test
94  	public void testArrayConstructor() throws IOException {
95  		try (UnionInputStream u = new UnionInputStream(
96  				new ByteArrayInputStream(new byte[] { 1, 0, 2 }),
97  				new ByteArrayInputStream(new byte[] { 3 }),
98  				new ByteArrayInputStream(new byte[] { 4, 5 }))) {
99  			final byte[] r = new byte[5];
100 			assertEquals(3, u.read(r, 0, 5));
101 			assertTrue(Arrays.equals(new byte[] { 1, 0, 2, }, slice(r, 3)));
102 			assertEquals(1, u.read(r, 0, 5));
103 			assertEquals(3, r[0]);
104 			assertEquals(2, u.read(r, 0, 5));
105 			assertTrue(Arrays.equals(new byte[] { 4, 5, }, slice(r, 2)));
106 			assertEquals(-1, u.read(r, 0, 5));
107 		}
108 	}
109 
110 	@Test
111 	public void testMarkSupported() throws IOException {
112 		try (UnionInputStream u = new UnionInputStream()) {
113 			assertFalse(u.markSupported());
114 			u.add(new ByteArrayInputStream(new byte[] { 1, 0, 2 }));
115 			assertFalse(u.markSupported());
116 		}
117 	}
118 
119 	@Test
120 	public void testSkip() throws IOException {
121 		try (UnionInputStream u = new UnionInputStream()) {
122 			u.add(new ByteArrayInputStream(new byte[] { 1, 0, 2 }));
123 			u.add(new ByteArrayInputStream(new byte[] { 3 }));
124 			u.add(new ByteArrayInputStream(new byte[] { 4, 5 }));
125 			assertEquals(0, u.skip(0));
126 			assertEquals(3, u.skip(3));
127 			assertEquals(3, u.read());
128 			assertEquals(2, u.skip(5));
129 			assertEquals(0, u.skip(5));
130 			assertEquals(-1, u.read());
131 
132 			u.add(new ByteArrayInputStream(new byte[] { 20, 30 }) {
133 				@Override
134 				@SuppressWarnings("UnsynchronizedOverridesSynchronized")
135 				// This is only used in tests and is thread-safe
136 				public long skip(long n) {
137 					return 0;
138 				}
139 			});
140 			assertEquals(2, u.skip(8));
141 			assertEquals(-1, u.read());
142 		}
143 	}
144 
145 	@Test
146 	public void testAutoCloseDuringRead() throws IOException {
147 		try (UnionInputStream u = new UnionInputStream()) {
148 			final boolean closed[] = new boolean[2];
149 			u.add(new ByteArrayInputStream(new byte[] { 1 }) {
150 				@Override
151 				public void close() {
152 					closed[0] = true;
153 				}
154 			});
155 			u.add(new ByteArrayInputStream(new byte[] { 2 }) {
156 				@Override
157 				public void close() {
158 					closed[1] = true;
159 				}
160 			});
161 
162 			assertFalse(closed[0]);
163 			assertFalse(closed[1]);
164 
165 			assertEquals(1, u.read());
166 			assertFalse(closed[0]);
167 			assertFalse(closed[1]);
168 
169 			assertEquals(2, u.read());
170 			assertTrue(closed[0]);
171 			assertFalse(closed[1]);
172 
173 			assertEquals(-1, u.read());
174 			assertTrue(closed[0]);
175 			assertTrue(closed[1]);
176 		}
177 	}
178 
179 	@Test
180 	public void testCloseDuringClose() throws IOException {
181 		final boolean closed[] = new boolean[2];
182 		try (UnionInputStream u = new UnionInputStream()) {
183 			u.add(new ByteArrayInputStream(new byte[] { 1 }) {
184 				@Override
185 				public void close() {
186 					closed[0] = true;
187 				}
188 			});
189 			u.add(new ByteArrayInputStream(new byte[] { 2 }) {
190 				@Override
191 				public void close() {
192 					closed[1] = true;
193 				}
194 			});
195 
196 			assertFalse(closed[0]);
197 			assertFalse(closed[1]);
198 		}
199 
200 		assertTrue(closed[0]);
201 		assertTrue(closed[1]);
202 	}
203 
204 	@Test
205 	public void testExceptionDuringClose() {
206 		@SuppressWarnings("resource") // We are testing the close() method
207 		final UnionInputStream u = new UnionInputStream();
208 		u.add(new ByteArrayInputStream(new byte[] { 1 }) {
209 			@Override
210 			public void close() throws IOException {
211 				throw new IOException("I AM A TEST");
212 			}
213 		});
214 		try {
215 			u.close();
216 			fail("close ignored inner stream exception");
217 		} catch (IOException e) {
218 			assertEquals("I AM A TEST", e.getMessage());
219 		}
220 	}
221 
222 	@Test
223 	public void testNonBlockingPartialRead() throws Exception {
224 		InputStream errorReadStream = new InputStream() {
225 			@Override
226 			public int read() throws IOException {
227 				throw new IOException("Expected");
228 			}
229 
230 			@Override
231 			public int read(byte b[], int off, int len) throws IOException {
232 				throw new IOException("Expected");
233 			}
234 		};
235 		try (UnionInputStream u = new UnionInputStream(
236 				new ByteArrayInputStream(new byte[] { 1, 2, 3 }),
237 				errorReadStream)) {
238 			byte buf[] = new byte[10];
239 			assertEquals(3, u.read(buf, 0, 10));
240 			assertTrue(Arrays.equals(new byte[] { 1, 2, 3 }, slice(buf, 3)));
241 			try {
242 				u.read(buf, 0, 1);
243 				fail("Expected exception from errorReadStream");
244 			} catch (IOException e) {
245 				assertEquals("Expected", e.getMessage());
246 			}
247 		}
248 	}
249 }