View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Google Inc.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.util;
45  
46  import static org.eclipse.jgit.junit.JGitTestUtil.getName;
47  import static org.junit.Assert.assertArrayEquals;
48  import static org.junit.Assert.assertEquals;
49  import static org.junit.Assert.assertNotNull;
50  import static org.junit.Assert.fail;
51  
52  import java.io.ByteArrayInputStream;
53  import java.io.ByteArrayOutputStream;
54  import java.io.IOException;
55  import java.io.InputStream;
56  
57  import org.eclipse.jgit.junit.TestRng;
58  import org.eclipse.jgit.util.TemporaryBuffer.Block;
59  import org.junit.Test;
60  
61  public class TemporaryBufferTest {
62  	@Test
63  	public void testEmpty() throws IOException {
64  		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
65  		try {
66  			b.close();
67  			assertEquals(0, b.length());
68  			final byte[] r = b.toByteArray();
69  			assertNotNull(r);
70  			assertEquals(0, r.length);
71  		} finally {
72  			b.destroy();
73  		}
74  	}
75  
76  	@Test
77  	public void testOneByte() throws IOException {
78  		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
79  		final byte test = (byte) new TestRng(getName()).nextInt();
80  		try {
81  			b.write(test);
82  			b.close();
83  			assertEquals(1, b.length());
84  			{
85  				final byte[] r = b.toByteArray();
86  				assertNotNull(r);
87  				assertEquals(1, r.length);
88  				assertEquals(test, r[0]);
89  			}
90  			{
91  				final ByteArrayOutputStream o = new ByteArrayOutputStream();
92  				b.writeTo(o, null);
93  				o.close();
94  				final byte[] r = o.toByteArray();
95  				assertEquals(1, r.length);
96  				assertEquals(test, r[0]);
97  			}
98  		} finally {
99  			b.destroy();
100 		}
101 	}
102 
103 	@Test
104 	public void testOneBlock_BulkWrite() throws IOException {
105 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
106 		final byte[] test = new TestRng(getName())
107 				.nextBytes(TemporaryBuffer.Block.SZ);
108 		try {
109 			b.write(test, 0, 2);
110 			b.write(test, 2, 4);
111 			b.write(test, 6, test.length - 6 - 2);
112 			b.write(test, test.length - 2, 2);
113 			b.close();
114 			assertEquals(test.length, b.length());
115 			{
116 				final byte[] r = b.toByteArray();
117 				assertNotNull(r);
118 				assertEquals(test.length, r.length);
119 				assertArrayEquals(test, r);
120 			}
121 			{
122 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
123 				b.writeTo(o, null);
124 				o.close();
125 				final byte[] r = o.toByteArray();
126 				assertEquals(test.length, r.length);
127 				assertArrayEquals(test, r);
128 			}
129 		} finally {
130 			b.destroy();
131 		}
132 	}
133 
134 	@Test
135 	public void testOneBlockAndHalf_BulkWrite() throws IOException {
136 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
137 		final byte[] test = new TestRng(getName())
138 				.nextBytes(TemporaryBuffer.Block.SZ * 3 / 2);
139 		try {
140 			b.write(test, 0, 2);
141 			b.write(test, 2, 4);
142 			b.write(test, 6, test.length - 6 - 2);
143 			b.write(test, test.length - 2, 2);
144 			b.close();
145 			assertEquals(test.length, b.length());
146 			{
147 				final byte[] r = b.toByteArray();
148 				assertNotNull(r);
149 				assertEquals(test.length, r.length);
150 				assertArrayEquals(test, r);
151 			}
152 			{
153 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
154 				b.writeTo(o, null);
155 				o.close();
156 				final byte[] r = o.toByteArray();
157 				assertEquals(test.length, r.length);
158 				assertArrayEquals(test, r);
159 			}
160 		} finally {
161 			b.destroy();
162 		}
163 	}
164 
165 	@Test
166 	public void testOneBlockAndHalf_SingleWrite() throws IOException {
167 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
168 		final byte[] test = new TestRng(getName())
169 				.nextBytes(TemporaryBuffer.Block.SZ * 3 / 2);
170 		try {
171 			for (int i = 0; i < test.length; i++)
172 				b.write(test[i]);
173 			b.close();
174 			assertEquals(test.length, b.length());
175 			{
176 				final byte[] r = b.toByteArray();
177 				assertNotNull(r);
178 				assertEquals(test.length, r.length);
179 				assertArrayEquals(test, r);
180 			}
181 			{
182 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
183 				b.writeTo(o, null);
184 				o.close();
185 				final byte[] r = o.toByteArray();
186 				assertEquals(test.length, r.length);
187 				assertArrayEquals(test, r);
188 			}
189 		} finally {
190 			b.destroy();
191 		}
192 	}
193 
194 	@Test
195 	public void testOneBlockAndHalf_Copy() throws IOException {
196 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
197 		final byte[] test = new TestRng(getName())
198 				.nextBytes(TemporaryBuffer.Block.SZ * 3 / 2);
199 		try {
200 			final ByteArrayInputStream in = new ByteArrayInputStream(test);
201 			b.write(in.read());
202 			b.copy(in);
203 			b.close();
204 			assertEquals(test.length, b.length());
205 			{
206 				final byte[] r = b.toByteArray();
207 				assertNotNull(r);
208 				assertEquals(test.length, r.length);
209 				assertArrayEquals(test, r);
210 			}
211 			{
212 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
213 				b.writeTo(o, null);
214 				o.close();
215 				final byte[] r = o.toByteArray();
216 				assertEquals(test.length, r.length);
217 				assertArrayEquals(test, r);
218 			}
219 		} finally {
220 			b.destroy();
221 		}
222 	}
223 
224 	@Test
225 	public void testLarge_SingleWrite() throws IOException {
226 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
227 		final byte[] test = new TestRng(getName())
228 				.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3);
229 		try {
230 			b.write(test);
231 			b.close();
232 			assertEquals(test.length, b.length());
233 			{
234 				final byte[] r = b.toByteArray();
235 				assertNotNull(r);
236 				assertEquals(test.length, r.length);
237 				assertArrayEquals(test, r);
238 			}
239 			{
240 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
241 				b.writeTo(o, null);
242 				o.close();
243 				final byte[] r = o.toByteArray();
244 				assertEquals(test.length, r.length);
245 				assertArrayEquals(test, r);
246 			}
247 		} finally {
248 			b.destroy();
249 		}
250 	}
251 
252 	@Test
253 	public void testInCoreInputStream() throws IOException {
254 		final int cnt = 256;
255 		final byte[] test = new TestRng(getName()).nextBytes(cnt);
256 		final TemporaryBuffer.Heap b = new TemporaryBuffer.Heap(cnt + 4);
257 		b.write(test);
258 		b.close();
259 
260 		InputStream in = b.openInputStream();
261 		byte[] act = new byte[cnt];
262 		IO.readFully(in, act, 0, cnt);
263 		assertArrayEquals(test, act);
264 	}
265 
266 	@Test
267 	public void testInCoreLimit_SwitchOnAppendByte() throws IOException {
268 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
269 		final byte[] test = new TestRng(getName())
270 				.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT + 1);
271 		try {
272 			b.write(test, 0, test.length - 1);
273 			b.write(test[test.length - 1]);
274 			b.close();
275 			assertEquals(test.length, b.length());
276 			{
277 				final byte[] r = b.toByteArray();
278 				assertNotNull(r);
279 				assertEquals(test.length, r.length);
280 				assertArrayEquals(test, r);
281 			}
282 			{
283 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
284 				b.writeTo(o, null);
285 				o.close();
286 				final byte[] r = o.toByteArray();
287 				assertEquals(test.length, r.length);
288 				assertArrayEquals(test, r);
289 			}
290 		} finally {
291 			b.destroy();
292 		}
293 	}
294 
295 	@Test
296 	public void testInCoreLimit_SwitchBeforeAppendByte() throws IOException {
297 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
298 		final byte[] test = new TestRng(getName())
299 				.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3);
300 		try {
301 			b.write(test, 0, test.length - 1);
302 			b.write(test[test.length - 1]);
303 			b.close();
304 			assertEquals(test.length, b.length());
305 			{
306 				final byte[] r = b.toByteArray();
307 				assertNotNull(r);
308 				assertEquals(test.length, r.length);
309 				assertArrayEquals(test, r);
310 			}
311 			{
312 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
313 				b.writeTo(o, null);
314 				o.close();
315 				final byte[] r = o.toByteArray();
316 				assertEquals(test.length, r.length);
317 				assertArrayEquals(test, r);
318 			}
319 		} finally {
320 			b.destroy();
321 		}
322 	}
323 
324 	@Test
325 	public void testInCoreLimit_SwitchOnCopy() throws IOException {
326 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
327 		final byte[] test = new TestRng(getName())
328 				.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2);
329 		try {
330 			final ByteArrayInputStream in = new ByteArrayInputStream(test,
331 					TemporaryBuffer.DEFAULT_IN_CORE_LIMIT, test.length
332 							- TemporaryBuffer.DEFAULT_IN_CORE_LIMIT);
333 			b.write(test, 0, TemporaryBuffer.DEFAULT_IN_CORE_LIMIT);
334 			b.copy(in);
335 			b.close();
336 			assertEquals(test.length, b.length());
337 			{
338 				final byte[] r = b.toByteArray();
339 				assertNotNull(r);
340 				assertEquals(test.length, r.length);
341 				assertArrayEquals(test, r);
342 			}
343 			{
344 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
345 				b.writeTo(o, null);
346 				o.close();
347 				final byte[] r = o.toByteArray();
348 				assertEquals(test.length, r.length);
349 				assertArrayEquals(test, r);
350 			}
351 		} finally {
352 			b.destroy();
353 		}
354 	}
355 
356 	@Test
357 	public void testDestroyWhileOpen() throws IOException {
358 		@SuppressWarnings("resource" /* java 7 */)
359 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
360 		try {
361 			b.write(new TestRng(getName())
362 					.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2));
363 		} finally {
364 			b.destroy();
365 		}
366 	}
367 
368 	@Test
369 	public void testRandomWrites() throws IOException {
370 		final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
371 		final TestRng rng = new TestRng(getName());
372 		final int max = TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2;
373 		final byte[] expect = new byte[max];
374 		try {
375 			int written = 0;
376 			boolean onebyte = true;
377 			while (written < max) {
378 				if (onebyte) {
379 					final byte v = (byte) rng.nextInt();
380 					b.write(v);
381 					expect[written++] = v;
382 				} else {
383 					final int len = Math
384 							.min(rng.nextInt() & 127, max - written);
385 					final byte[] tmp = rng.nextBytes(len);
386 					b.write(tmp, 0, len);
387 					System.arraycopy(tmp, 0, expect, written, len);
388 					written += len;
389 				}
390 				onebyte = !onebyte;
391 			}
392 			assertEquals(expect.length, written);
393 			b.close();
394 
395 			assertEquals(expect.length, b.length());
396 			{
397 				final byte[] r = b.toByteArray();
398 				assertNotNull(r);
399 				assertEquals(expect.length, r.length);
400 				assertArrayEquals(expect, r);
401 			}
402 			{
403 				final ByteArrayOutputStream o = new ByteArrayOutputStream();
404 				b.writeTo(o, null);
405 				o.close();
406 				final byte[] r = o.toByteArray();
407 				assertEquals(expect.length, r.length);
408 				assertArrayEquals(expect, r);
409 			}
410 		} finally {
411 			b.destroy();
412 		}
413 	}
414 
415 	@Test
416 	public void testHeap() throws IOException {
417 		@SuppressWarnings("resource" /* java 7 */)
418 		final TemporaryBuffer b = new TemporaryBuffer.Heap(2 * 8 * 1024);
419 		final byte[] r = new byte[8 * 1024];
420 		b.write(r);
421 		b.write(r);
422 		try {
423 			b.write(1);
424 			fail("accepted too many bytes of data");
425 		} catch (IOException e) {
426 			assertEquals("In-memory buffer limit exceeded", e.getMessage());
427 		}
428 	}
429 
430 	@Test
431 	public void testHeapWithEstimatedSize() throws IOException {
432 		int sz = 2 * Block.SZ;
433 		try (TemporaryBuffer b = new TemporaryBuffer.Heap(sz / 2, sz)) {
434 			for (int i = 0; i < sz; i++) {
435 				b.write('x');
436 			}
437 			try {
438 				b.write(1);
439 				fail("accepted too many bytes of data");
440 			} catch (IOException e) {
441 				assertEquals("In-memory buffer limit exceeded", e.getMessage());
442 			}
443 
444 			try (InputStream in = b.openInputStream()) {
445 				for (int i = 0; i < sz; i++) {
446 					assertEquals('x', in.read());
447 				}
448 				assertEquals(-1, in.read());
449 			}
450 		}
451 	}
452 }