/** * Copyright © 2013, Adam Retter All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * Redistributions in binary * form must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials provided * with the distribution. * Neither the name of the <organization> nor the names * of its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.exist.util.io; import org.junit.runners.Parameterized.Parameters; import java.util.Collection; import java.util.Arrays; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Random; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertArrayEquals; /** * Test cases for CachingFilterInputStream * * @version 1.0 * * @author Adam Retter <adam.retter@googlemail.com> */ @RunWith(value = Parameterized.class) public class CachingFilterInputStreamTest_NonMarkableByteArrayInputStream { @Parameters public static Collection data() throws IOException { Object[][] data = new Object[][]{ {MemoryFilterInputStreamCache.class}, {MemoryMappedFileFilterInputStreamCache.class}, {FileFilterInputStreamCache.class} }; return Arrays.asList(data); } private final static int _4KB = 4 * 1024; private final static int _6KB = 6 * 1024; private final static int _12KB = 12 * 1024; private final static int _32KB = 32 * 1024; private final static int _64KB = 64 * 1024; private final Class<FilterInputStreamCache> cacheClass; public CachingFilterInputStreamTest_NonMarkableByteArrayInputStream(final Class<FilterInputStreamCache> cacheClass) { this.cacheClass = cacheClass; } private FilterInputStreamCache getNewCache(InputStream is) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { Constructor ctor = cacheClass.getDeclaredConstructor(InputStream.class); ctor.setAccessible(true); return (FilterInputStreamCache) ctor.newInstance(is); } @Test public void readByte() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read the first 3 bytes assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); assertEquals(testData[2], cfis.read()); //mark position cfis.mark(Integer.MAX_VALUE); //read the next 3 bytes assertEquals(testData[3], cfis.read()); assertEquals(testData[4], cfis.read()); assertEquals(testData[5], cfis.read()); //reset position to the mark cfis.reset(); //attempt to reread the last 3 bytes from the mark (from the cache) assertEquals(testData[3], cfis.read()); assertEquals(testData[4], cfis.read()); assertEquals(testData[5], cfis.read()); //read the next 2 bytes past the reset mark (past the cache, e.g. from src) assertEquals(testData[6], cfis.read()); assertEquals(testData[7], cfis.read()); //reset position to the mark cfis.reset(); //attempt to read the last 5 bytes (from the cache) assertEquals(testData[3], cfis.read()); assertEquals(testData[4], cfis.read()); assertEquals(testData[5], cfis.read()); assertEquals(testData[6], cfis.read()); assertEquals(testData[7], cfis.read()); //mark position cfis.mark(-1); //read the next 2 bytes past the reset mark (past the cache, e.g. from src) assertEquals(testData[8], cfis.read()); assertEquals(testData[9], cfis.read()); //reset position to the mark cfis.reset(); //attempt to reread the last 2 bytes from the mark (from the cache) assertEquals(testData[8], cfis.read()); assertEquals(testData[9], cfis.read()); } @Test(expected = IOException.class) public void readByte_onClosedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); assertEquals(testData[0], cfis.read()); cfis.close(); //should cause IOException cfis.read(); } @Test public void readByte_pastEndOfStream_fromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "he"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); cfis.mark(Integer.MAX_VALUE); assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); cfis.reset(); assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); //read byte past end of cache final int b = cfis.read(); assertEquals(-1, b); } @Test public void readByte_pastEndOfStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read all the bytes upto end of stream int b = -1; int testDataOffset = 0; while ((b = cfis.read()) > -1) { assertEquals(testData[testDataOffset++], b); } //read byte past end of stream b = cfis.read(); assertEquals(-1, b); } @Test public void readByte_allFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "hello"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark the position cfis.mark(Integer.MAX_VALUE); //read the data assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); assertEquals(testData[2], cfis.read()); assertEquals(testData[3], cfis.read()); assertEquals(testData[4], cfis.read()); //reset position to the mark cfis.reset(); //attempt to reread the data (from the cache) assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); assertEquals(testData[2], cfis.read()); assertEquals(testData[3], cfis.read()); assertEquals(testData[4], cfis.read()); } @Test public void readBytes() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read the first 3 bytes byte result[] = new byte[3]; int read = cfis.read(result); assertEquals(3, read); assertArrayEquals(subArray(testData, 3), result); //mark position cfis.mark(Integer.MAX_VALUE); //read the next 3 bytes result = new byte[3]; read = cfis.read(result); assertEquals(3, read); assertArrayEquals(subArray(testData, 3, 3), result); //reset position to the mark cfis.reset(); //attempt to reread the last 3 bytes from the mark (from the cache) result = new byte[3]; read = cfis.read(result); assertEquals(3, read); assertArrayEquals(subArray(testData, 3, 3), result); //read the next 2 bytes past the reset mark (past the cache, e.g. from src) result = new byte[2]; read = cfis.read(result); assertEquals(2, read); assertArrayEquals(subArray(testData, 6, 2), result); //reset position to the mark cfis.reset(); //attempt to read the last 5 bytes (from the cache) result = new byte[5]; read = cfis.read(result); assertEquals(5, read); assertArrayEquals(subArray(testData, 3, 5), result); //mark position cfis.mark(-1); //read the next 2 bytes past the reset mark (past the cache, e.g. from src) result = new byte[2]; read = cfis.read(result); assertEquals(2, read); assertArrayEquals(subArray(testData, 8, 2), result); //reset position to the mark cfis.reset(); //attempt to reread the last 2 bytes from the mark (from the cache) result = new byte[2]; read = cfis.read(result); assertEquals(2, read); assertArrayEquals(subArray(testData, 8, 2), result); } @Test(expected = IOException.class) public void readBytes_onClosedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); final byte result[] = new byte[2]; cfis.read(result); assertArrayEquals(subArray(testData, 2), result); cfis.close(); //should cause IOException cfis.read(result); } @Test public void readBytes_pastEndOfStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); final byte result[] = new byte[testData.length]; int read = cfis.read(result); assertEquals(testData.length, read); assertArrayEquals(testData, result); final byte endOfStreamResult[] = new byte[testData.length]; read = cfis.read(endOfStreamResult); assertEquals(-1, read); assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, endOfStreamResult); } @Test public void readBytes_pastEndOfStream_fromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); cfis.mark(Integer.MAX_VALUE); //read first two bytes from stream final byte result[] = new byte[2]; int read = cfis.read(result); assertEquals(2, read); assertArrayEquals(subArray(testData, 2), result); cfis.reset(); //read all bytes from cache and src, +1 past end of stream final byte endOfStreamResult[] = new byte[testData.length + 1]; read = cfis.read(endOfStreamResult); final byte expectedResult[] = new byte[testData.length + 1]; System.arraycopy(testData, 0, expectedResult, 0, testData.length); assertEquals(testData.length, read); assertArrayEquals(expectedResult, endOfStreamResult); //2nd attempt to read past end of stream read = cfis.read(result); assertEquals(-1, read); read = cfis.read(result); assertEquals(-1, read); } @Test public void readBytes_allFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "hello"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark the position cfis.mark(Integer.MAX_VALUE); //read the data byte result[] = new byte[testData.length]; int read = cfis.read(result); assertEquals(testData.length, read); assertArrayEquals(testData, result); //reset position to the mark cfis.reset(); //attempt to reread the data (from the cache) result = new byte[testData.length]; read = cfis.read(result); assertEquals(testData.length, read); assertArrayEquals(testData, result); } @Test public void readBytes_partFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark the position cfis.mark(Integer.MAX_VALUE); //read the first 5 byts data byte result[] = new byte[5]; int read = cfis.read(result); assertEquals(5, read); assertArrayEquals(subArray(testData, 5), result); //reset position to the mark cfis.reset(); //attempt to read all the data (first 5 bytes will be from the cache) result = new byte[testData.length]; read = cfis.read(result); assertEquals(testData.length, read); assertArrayEquals(testData, result); } @Test public void readBytes_withZeroOffset_allFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "hello"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark the position cfis.mark(Integer.MAX_VALUE); //read the data byte result[] = new byte[testData.length]; int read = cfis.read(result, 0, testData.length); assertEquals(testData.length, read); assertArrayEquals(testData, result); //reset position to the mark cfis.reset(); //attempt to reread the data (from the cache) result = new byte[testData.length]; read = cfis.read(result, 0, testData.length); assertEquals(testData.length, read); assertArrayEquals(testData, result); } @Test public void readBytes_withZeroOffset_partFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark the position cfis.mark(Integer.MAX_VALUE); //read the first 5 byts data byte result[] = new byte[5]; int read = cfis.read(result, 0, result.length); assertEquals(5, read); assertArrayEquals(subArray(testData, 5), result); //reset position to the mark cfis.reset(); //attempt to read all the data (first 5 bytes will be from the cache) result = new byte[testData.length]; read = cfis.read(result, 0, result.length); assertEquals(testData.length, read); assertArrayEquals(testData, result); } @Test public void readBytes_withOffsetAndLength_allFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark the position cfis.mark(Integer.MAX_VALUE); //read the data byte result[] = new byte[4]; int read = cfis.read(result, 1, 3); assertEquals(3, read); byte expected[] = new byte[4]; expected[0] = 0; System.arraycopy(testData, 0, expected, 1, 3); assertArrayEquals(expected, result); //reset position to the mark cfis.reset(); //attempt to reread the data (from the cache) result = new byte[4]; read = cfis.read(result, 2, 2); expected = new byte[4]; expected[0] = 0; expected[1] = 0; System.arraycopy(testData, 0, expected, 2, 2); assertEquals(2, read); assertArrayEquals(expected, result); } @Test public void skip() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read the first 3 bytes assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); assertEquals(testData[2], cfis.read()); //skip 3 bytes cfis.skip(3); //read bytes 5 to 7 inclusive assertEquals(testData[6], cfis.read()); assertEquals(testData[7], cfis.read()); assertEquals(testData[8], cfis.read()); } @Test public void skip_partFromCache() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read the first 2 bytes assertEquals(testData[0], cfis.read()); assertEquals(testData[1], cfis.read()); //skip 2 bytes cfis.skip(2); cfis.mark(Integer.MAX_VALUE); //read byte 5 assertEquals(testData[4], cfis.read()); //skip 2 bytes cfis.skip(2); //read bytes 6 to 7 inclusive assertEquals(testData[7], cfis.read()); assertEquals(testData[8], cfis.read()); cfis.reset(); //reread bytes 5 to 7 inclusive assertEquals(testData[4], cfis.read()); assertEquals(testData[5], cfis.read()); assertEquals(testData[6], cfis.read()); assertEquals(testData[7], cfis.read()); assertEquals(testData[8], cfis.read()); //read final byte (outside cache) assertEquals(testData[9], cfis.read()); } @Test(expected = IOException.class) public void skip_onClosedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); cfis.close(); //should cause IOException cfis.skip(1); } @Test public void skip_negativeBytes() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //should cause IOException final long skipped = cfis.skip(-1); assertEquals(0, skipped); } @Test public void available_onClosedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); cfis.close(); assertEquals(0, cfis.available()); } @Test public void available_onEmptyStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final InputStream is = new ByteArrayInputStream(new byte[]{}); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); cfis.close(); assertEquals(0, cfis.available()); } @Test public void available_onUnCachedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); assertEquals(testData.length, cfis.available()); } @Test public void available_onPartiallyReadStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read first 2 bytes cfis.read(); cfis.read(); assertEquals(testData.length - 2, cfis.available()); } @Test public void available_onPartiallyCachedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark for later reset cfis.mark(Integer.MAX_VALUE); //read first 2 bytes cfis.read(); cfis.read(); //return to the start of the stream cfis.reset(); assertEquals(testData.length, cfis.available()); } @Test public void available_onOffsetPartiallyCachedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read first 2 bytes cfis.read(); cfis.read(); //mark for later reset cfis.mark(Integer.MAX_VALUE); //read next 2 bytes cfis.read(); cfis.read(); //return to the start of the stream cfis.reset(); assertEquals(testData.length - 2, cfis.available()); } @Test public void available_onCachedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //mark for later reset cfis.mark(Integer.MAX_VALUE); for (int i = 0; i < testData.length; i++) { cfis.read(); } //return to the start of the stream cfis.reset(); assertEquals(testData.length, cfis.available()); } @Test public void available_onOffsetCachedStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final String testString = "helloWorld"; final byte testData[] = testString.getBytes(); final InputStream is = new ByteArrayInputStream(testData); final CachingFilterInputStream cfis = new CachingFilterInputStream(getNewCache(is)); //read first 2 bytes cfis.read(); cfis.read(); //mark for later reset cfis.mark(Integer.MAX_VALUE); for (int i = 0; i < testData.length - 2; i++) { cfis.read(); } //return to the start of the stream cfis.reset(); assertEquals(testData.length - 2, cfis.available()); } @Test public void constructed_from_CachingFilterInputStream() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final byte[] testData = generateRandomData(_12KB); final InputStream is = new ByteArrayInputStream(testData); //first CachingFilterInputStream final CachingFilterInputStream cfis1 = new CachingFilterInputStream(getNewCache(is)); //second CachingFilterInputStream wraps first CachingFilterInputStream final CachingFilterInputStream cfis2 = new CachingFilterInputStream(cfis1); assertArrayEquals(testData, consumeInputStream(cfis2)); } @Test public void constructed_from_CachingFilterInputStream_consumed() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final byte[] testData = generateRandomData(_12KB); final InputStream is = new NonMarkableByteArrayInputStream(testData); //first CachingFilterInputStream final CachingFilterInputStream cfis1 = new CachingFilterInputStream(getNewCache(is)); assertArrayEquals(testData, consumeInputStream(cfis1)); //second CachingFilterInputStream wraps first CachingFilterInputStream final CachingFilterInputStream cfis2 = new CachingFilterInputStream(cfis1); assertArrayEquals(testData, consumeInputStream(cfis2)); } @Test public void constructed_from_CachingFilterInputStream_partiallyConsumed() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final byte[] testData = generateRandomData(_12KB); final InputStream is = new NonMarkableByteArrayInputStream(testData); //first CachingFilterInputStream final CachingFilterInputStream cfis1 = new CachingFilterInputStream(getNewCache(is)); //read first 6KB final byte firstPart[] = new byte[_6KB]; cfis1.read(firstPart); assertArrayEquals(subArray(testData, _6KB), firstPart); //ensure first 6KB was read! //second CachingFilterInputStream wraps first CachingFilterInputStream final CachingFilterInputStream cfis2 = new CachingFilterInputStream(cfis1); assertArrayEquals(testData, consumeInputStream(cfis2)); } /** * When given an underlying InputSource and caching it twice with the same * cache we should be able to read the input twice assuming that the input * that we are interested in has not been read before a mark() */ @Test public void interleavedSourceReads() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final byte[] testData = generateRandomData(_64KB); final InputStream is = new NonMarkableByteArrayInputStream(testData); final FilterInputStreamCache cache1 = getNewCache(is); final CachingFilterInputStream cfis1 = new CachingFilterInputStream(cache1); cfis1.mark(Integer.MAX_VALUE); final CachingFilterInputStream cfis2 = new CachingFilterInputStream(cache1); final byte result1[] = new byte[_12KB]; cfis1.read(result1); assertArrayEquals(subArray(testData, _12KB), result1); final byte result2[] = new byte[_12KB]; cfis2.read(result2); assertArrayEquals(subArray(testData, _12KB), result2); } @Test public void sharedCacheWritesInOrder() throws IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { final byte[] testData = generateRandomData(_64KB); final InputStream is = new NonMarkableByteArrayInputStream(testData); //first CachingFilterInputStream final CachingFilterInputStream cfis1 = new CachingFilterInputStream(getNewCache(is)); //read first 6KB final byte cfis1Part1[] = new byte[_6KB]; cfis1.read(cfis1Part1); assertArrayEquals(subArray(testData, _6KB), cfis1Part1); //ensure first 6KB was read! //second CachingFilterInputStream wraps first CachingFilterInputStream final CachingFilterInputStream cfis2 = new CachingFilterInputStream(cfis1); //read first 32KB from second InputStream final byte cfis2Part1[] = new byte[_32KB]; cfis2.read(cfis2Part1); assertArrayEquals(subArray(testData, _32KB), cfis2Part1); //ensure next 32KB was read! //interleave by reading another 6KB from first InputStream final byte cfis1Part2[] = new byte[_6KB]; cfis1.read(cfis1Part2); assertArrayEquals(subArray(testData, _6KB, _6KB), cfis1Part2); //ensure first 6KB was read! } private byte[] consumeInputStream(final CachingFilterInputStream is) throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { int read = -1; final byte buf[] = new byte[_4KB]; while ((read = is.read(buf)) > -1) { baos.write(buf, 0, read); } return baos.toByteArray(); } finally { baos.close(); } } private byte[] generateRandomData(final int bytes) { final byte[] data = new byte[bytes]; new Random().nextBytes(data); return data; } private byte[] subArray(final byte data[], final int len) { final byte newData[] = new byte[len]; System.arraycopy(data, 0, newData, 0, len); return newData; } private byte[] subArray(final byte data[], final int offset, final int len) { final byte newData[] = new byte[len]; System.arraycopy(data, offset, newData, 0, len); return newData; } }