package io.airlift.http.client; import com.google.common.collect.ImmutableList; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import static java.lang.Math.min; import static java.lang.System.arraycopy; import static org.testng.Assert.assertEquals; public class TestGatheringByteArrayInputStream { @Test public void testNormal() { byte[] lastStringArray = "client".getBytes(); byte[] lastArray = Arrays.copyOf(lastStringArray, lastStringArray.length + 32); arraycopy(lastStringArray, 0, lastArray, 0, lastStringArray.length); List<byte[]> buffers = ImmutableList.of( "hello ".getBytes(), "this ".getBytes(), "is ".getBytes(), "http ".getBytes(), lastArray); byte[] expectedAll = "hello this is http client".getBytes(); byte[] expectedPartial = "hello this".getBytes(); try (GatheringByteArrayInputStream in = new GatheringByteArrayInputStream(buffers, expectedAll.length)) { byte[] buffer = new byte[expectedAll.length + 32]; // read the first part assertEquals(in.read(buffer, 0, expectedPartial.length), expectedPartial.length); // verify the first part assertByteArrayEquals(buffer, 0, expectedPartial, 0, expectedPartial.length); // read the remaining part assertEquals(in.read(buffer, expectedPartial.length, buffer.length - expectedPartial.length), expectedAll.length - expectedPartial.length); // verify the whole string assertByteArrayEquals(buffer, 0, expectedAll, 0, expectedAll.length); // make sure there is no more data assertEquals(-1, in.read(buffer, 0, expectedAll.length)); } } @Test public void testSingleByteRead() { byte[] expected = "This is a test for single byte read".getBytes(); List<byte[]> buffers = ImmutableList.of( "This ".getBytes(), "is ".getBytes(), "a test ".getBytes(), "for".getBytes(), " single byte read".getBytes()); byte[] resultBuffer = new byte[expected.length]; try (GatheringByteArrayInputStream in = new GatheringByteArrayInputStream(buffers, expected.length)) { for (int i = 0; i < expected.length; i++) { resultBuffer[i] = (byte) in.read(); } assertByteArrayEquals(resultBuffer, 0, expected, 0, expected.length); assertEquals(in.read(), -1); } } @Test public void testNegativeSingleByteRead() { byte[] expected = new byte[1]; expected[0] = -100; try (GatheringByteArrayInputStream in = new GatheringByteArrayInputStream(ImmutableList.of(expected), expected.length)) { assertEquals(in.read(), expected[0] & 0x000000ff); assertEquals(in.read(), -1); } } @Test public void testSkip() { byte[] allDataBytes = "Hello, this is http client package, and I am just a test for GatheringByteArrayInputStream".getBytes(); int length = allDataBytes.length; try (GatheringByteArrayInputStream in = new GatheringByteArrayInputStream( ImmutableList.of( Arrays.copyOfRange(allDataBytes, 0, length / 3), Arrays.copyOfRange(allDataBytes, length / 3, length / 3 + length / 2), Arrays.copyOfRange(allDataBytes, length / 3 + length / 2, length)), length)) { int skipped = length / 2; int firstPartLength = length / 4; int restPartLength = length - firstPartLength - skipped; byte[] actual = new byte[length - skipped + 10]; // read the first part assertEquals(in.read(actual, 0, firstPartLength), firstPartLength); assertByteArrayEquals(actual, 0, allDataBytes, 0, firstPartLength); // skip some bytes assertEquals(in.skip(skipped), skipped); // read the rest part assertEquals(in.read(actual, firstPartLength, restPartLength + 10), restPartLength); assertByteArrayEquals(actual, firstPartLength, allDataBytes, firstPartLength + skipped, restPartLength); assertEquals(in.skip(10), 0); assertEquals(in.read(), -1); } } @Test public void testLargeData() { int length = 123456789; Random random = new Random(0); byte[] expected = new byte[length]; // randomly generate the bytes random.nextBytes(expected); List<byte[]> buffers = new ArrayList<>(); int copyBytes = 0; while (copyBytes < length) { int currentLength = min(length - copyBytes, random.nextInt(1 << 20) + 64); buffers.add(Arrays.copyOfRange(expected, copyBytes, copyBytes + currentLength)); copyBytes += currentLength; } try (GatheringByteArrayInputStream in = new GatheringByteArrayInputStream(buffers, length)) { byte[] actual = new byte[length]; copyBytes = 0; while (copyBytes < length) { int currentLength = min(length - copyBytes, random.nextInt(1 << 20) + 64); assertEquals(in.read(actual, copyBytes, currentLength), currentLength); assertByteArrayEquals(actual, copyBytes, expected, copyBytes, currentLength); copyBytes += currentLength; } assertEquals(in.skip(100), 0); assertEquals(in.read(), -1); } } private static void assertByteArrayEquals( byte[] actual, int actualStart, byte[] expected, int expectedStart, int length) { for (int i = 0; i < length; i++) { assertEquals(actual[i + actualStart], expected[i + expectedStart]); } } }