@VisibleForTesting static EventSegmentReaderImpl getEventSegmentReader(AsyncSegmentInputStream async, long startOffset) { return new EventSegmentReaderImpl(new SegmentInputStreamImpl(async, startOffset)); }
/** * @see EventSegmentReader#read() */ @Override @Synchronized public ByteBuffer read(long timeout) throws EndOfSegmentException, SegmentTruncatedException { long originalOffset = in.getOffset(); long traceId = LoggerHelpers.traceEnter(log, "read", getSegmentId(), originalOffset, timeout); boolean success = false; try { ByteBuffer result = readEvent(timeout); success = true; return result; } finally { LoggerHelpers.traceLeave(log, "read", traceId, getSegmentId(), originalOffset, timeout, success); if (!success) { in.setOffset(originalOffset); } } }
@Test(expected = EndOfSegmentException.class) public void testReadWithEndOffset() throws Exception { byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); int wireDataSize = wireData.remaining(); //size of the data with header size. AsyncSegmentInputStream mockAsyncInputStream = mock(AsyncSegmentInputStream.class); when(mockAsyncInputStream.read(0, wireDataSize)) .thenReturn(CompletableFuture.completedFuture(new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice()))); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0, wireDataSize, SegmentInputStreamImpl.DEFAULT_BUFFER_SIZE); ByteBuffer read = stream.read(); assertEquals(ByteBuffer.wrap(data), read); //verify we are reading the data. verify(mockAsyncInputStream, times(1)).read(0L, wireDataSize); //ensure there is one invocation. stream.read(); // this should throw EndOfSegmentExceptiono as we have reached the endOffset }
@Test public void testIsSegmentReady() throws EndOfSegmentException, SegmentTruncatedException { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int numEntries = SegmentInputStreamImpl.DEFAULT_BUFFER_SIZE / data.length; ByteBuffer wireData = ByteBuffer.allocate((data.length + WireCommands.TYPE_PLUS_LENGTH_SIZE) * numEntries); for (int i = 0; i < numEntries; i++) { wireData.putInt(WireCommandType.EVENT.getCode()); wireData.putInt(data.length); wireData.put(data); } wireData.flip(); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 3); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); assertFalse(stream.isSegmentReady()); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, true, false, wireData.slice())); for (int i = 0; i < numEntries; i++) { assertTrue(stream.isSegmentReady()); assertEquals(ByteBuffer.wrap(data), stream.read()); } assertFalse(stream.isSegmentReady()); assertBlocks(() -> stream.read(), () -> { fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), wireData.capacity(), false, false, createEventFromData(data))); }); assertFalse(stream.isSegmentReady()); }
@Test(timeout = 5000) public void testClose() { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 2); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, wireData.remaining()))); EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); stream.close(); AssertExtensions.assertThrows(ObjectClosedException.class, () -> stream.read()); }
@Test public void testSetOffset() throws EndOfSegmentException, SegmentTruncatedException { byte[] data1 = new byte[]{0, 1, 2, 3, 4, 5}; byte[] data2 = new byte[]{6, 7, 8, 9}; ByteBuffer wireData1 = createEventFromData(data1); ByteBuffer wireData2 = createEventFromData(data2); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 5); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData1, 0, wireData1.remaining()))); ByteBuffer read = stream.read(); assertEquals(ByteBuffer.wrap(data1), read); fakeNetwork.complete(2, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData1, 0, wireData1.remaining()))); fakeNetwork.complete(3, new WireCommands.SegmentRead(segment.getScopedName(), wireData1.remaining(), false, false, ByteBufferUtils.slice(wireData2, 0, wireData2.remaining()))); stream.setOffset(0); read = stream.read(); assertEquals(ByteBuffer.wrap(data1), read); read = stream.read(); assertEquals(ByteBuffer.wrap(data2), read); }
@Cleanup EventSegmentReaderImpl stream1 = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); assertFalse(stream1.isSegmentReady()); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, true, ByteBufferUtils.slice(wireData, 0, 0))); assertTrue(stream1.isSegmentReady()); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream1.read()); assertFalse(stream2.isSegmentReady()); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, true, wireData.slice())); assertTrue(stream2.isSegmentReady()); assertEquals(ByteBuffer.wrap(data), stream2.read()); assertTrue(stream2.isSegmentReady()); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream2.read()); assertFalse(stream3.isSegmentReady()); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice())); fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), wireData.remaining(), false, true, ByteBufferUtils.slice(wireData, 0, 0))); assertTrue(stream3.isSegmentReady()); assertEquals(ByteBuffer.wrap(data), stream3.read()); assertTrue(stream3.isSegmentReady()); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream3.read()); assertFalse(stream4.isSegmentReady()); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 0))); fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, true, wireData.slice())); assertEquals(ByteBuffer.wrap(data), stream4.read()); assertTrue(stream4.isSegmentReady()); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream4.read());
@Test public void testReadWithEndOffsetWithDataGreaterThanBuffer() throws Exception { byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); int wireDataSize = wireData.remaining(); //size of the data with header size. int bufferSize = wireDataSize / 2; //buffer is half the data length AsyncSegmentInputStream mockAsyncInputStream = mock(AsyncSegmentInputStream.class); when(mockAsyncInputStream.read(0, bufferSize)) .thenReturn(CompletableFuture.completedFuture(new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, bufferSize)))); when(mockAsyncInputStream.read(bufferSize, wireDataSize - bufferSize)) .thenReturn(CompletableFuture.completedFuture(new WireCommands.SegmentRead(segment.getScopedName(), bufferSize, false, false, ByteBufferUtils.slice(wireData, bufferSize, wireDataSize - bufferSize)))); //Create a SegmentInputStream where the Buffer can hold only part of the data. @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0, wireDataSize, bufferSize); ByteBuffer read = stream.read(); assertEquals(ByteBuffer.wrap(data), read); //verify we are reading the data. verify(mockAsyncInputStream, times(1)).read(0L, bufferSize); verify(mockAsyncInputStream, times(1)).read(bufferSize, wireDataSize - bufferSize); }
@VisibleForTesting static EventSegmentReaderImpl getEventSegmentReader(AsyncSegmentInputStream async, long startOffset, long endOffset, int bufferSize) { return new EventSegmentReaderImpl(new SegmentInputStreamImpl(async, startOffset, endOffset, bufferSize)); }
@Test(timeout = 10000) public void testTimeout() throws EndOfSegmentException, SegmentTruncatedException { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 7); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); assertBlocks(() -> stream.read(), () -> fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice()))); ByteBuffer read = stream.read(10); assertNull(read); fakeNetwork.completeExceptionally(1, new ConnectionFailedException()); AssertExtensions.assertThrows(ConnectionFailedException.class, () -> stream.read()); stream.read(10); assertNull(read); read = stream.read(10); assertNull(read); }
@Test public void testReadWithEndOffsetWithSmallerReads() throws Exception { byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); int wireDataSize = wireData.remaining(); //size of the data with header size. AsyncSegmentInputStream mockAsyncInputStream = mock(AsyncSegmentInputStream.class); when(mockAsyncInputStream.read(0, wireDataSize)) .thenReturn(CompletableFuture.completedFuture(new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2)))); when(mockAsyncInputStream.read(2, 16)) .thenReturn(CompletableFuture.completedFuture(new WireCommands.SegmentRead(segment.getScopedName(), 2, false, false, ByteBufferUtils.slice(wireData, 2, wireDataSize - 2)))); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0, wireDataSize, SegmentInputStreamImpl.DEFAULT_BUFFER_SIZE); ByteBuffer read = stream.read(); assertEquals(ByteBuffer.wrap(data), read); //verify we are reading the data. verify(mockAsyncInputStream, times(1)).read(0L, wireDataSize); verify(mockAsyncInputStream, times(1)).read(2L, wireDataSize - 2); }
EventSegmentReaderImpl stream1 = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0); ByteBuffer read = stream1.read(); assertEquals(ByteBuffer.wrap(data), read); verify(mockAsyncInputStream, times(1)).read(0L, bufferSize); EventSegmentReaderImpl stream2 = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0, wireDataSize, bufferSize); read = stream2.read(); assertEquals(ByteBuffer.wrap(data), read); verify(mockAsyncInputStream, times(1)).read(0L, wireDataSize); EventSegmentReaderImpl stream3 = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0, Long.MAX_VALUE, 100); read = stream3.read(); assertEquals(ByteBuffer.wrap(data), read); verify(mockAsyncInputStream, times(1)).read(0L, 100);
@Test public void testLongerThanRequestedRead() throws EndOfSegmentException, SegmentTruncatedException { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int numEntries = SegmentInputStreamImpl.DEFAULT_BUFFER_SIZE / data.length; ByteBuffer wireData = ByteBuffer.allocate((data.length + WireCommands.TYPE_PLUS_LENGTH_SIZE) * numEntries); for (int i = 0; i < numEntries; i++) { wireData.putInt(WireCommandType.EVENT.getCode()); wireData.putInt(data.length); wireData.put(data); } wireData.flip(); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 3); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice())); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); for (int i = 0; i < numEntries; i++) { assertEquals(ByteBuffer.wrap(data), stream.read()); } ByteBuffer read = assertBlocks(() -> stream.read(), () -> { fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), wireData.capacity(), false, false, createEventFromData(data))); }); assertEquals(ByteBuffer.wrap(data), read); }
@Test public void testStreamTruncatedWithPartialEvent() throws EndOfSegmentException { ByteBuffer trailingData = ByteBuffer.wrap(new byte[] {0, 1}); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 1); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, true, trailingData.slice())); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream.read()); }
@Test public void testRead() { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 3); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); ByteBuffer read = assertBlocks(() -> stream.read(), () -> fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice()))); assertEquals(ByteBuffer.wrap(data), read); read = assertBlocks(() -> stream .read(), () -> fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), wireData.capacity(), false, false, wireData.slice()))); assertEquals(ByteBuffer.wrap(data), read); }
@Test public void testBlockingEndOfSegment() { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 2); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); assertBlocks(() -> { assertEquals(ByteBuffer.wrap(data), stream.read()); }, () -> { fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 0))); fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, true, wireData.slice())); }); }
@Test public void testStreamTruncated() throws EndOfSegmentException { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 6); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2))); fakeNetwork.completeExceptionally(1, new SegmentTruncatedException()); fakeNetwork.complete(2, new WireCommands.SegmentRead(segment.getScopedName(), 2, false, false, ByteBufferUtils.slice(wireData, 2, 7))); fakeNetwork.complete(3, new WireCommands.SegmentRead(segment.getScopedName(), 9, false, false, ByteBufferUtils.slice(wireData, 9, 2))); fakeNetwork.complete(4, new WireCommands.SegmentRead(segment.getScopedName(), 11, false, false, ByteBufferUtils.slice(wireData, 11, wireData.capacity() - 11))); AssertExtensions.assertThrows(SegmentTruncatedException.class, () -> stream.read()); AssertExtensions.assertThrows(SegmentTruncatedException.class, () -> stream.read()); }
@Test public void testSmallerThanNeededRead() throws EndOfSegmentException, SegmentTruncatedException { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 5); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2))); fakeNetwork.complete(1, new WireCommands.SegmentRead(segment.getScopedName(), 2, false, false, ByteBufferUtils.slice(wireData, 2, 7))); fakeNetwork.complete(2, new WireCommands.SegmentRead(segment.getScopedName(), 9, false, false, ByteBufferUtils.slice(wireData, 9, 2))); fakeNetwork.complete(3, new WireCommands.SegmentRead(segment.getScopedName(), 11, false, false, ByteBufferUtils.slice(wireData, 11, wireData.capacity() - 11))); ByteBuffer read = stream.read(); assertEquals(ByteBuffer.wrap(data), read); }
@Test public void testExceptionRecovery() throws EndOfSegmentException, SegmentTruncatedException { byte[] data = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ByteBuffer wireData = createEventFromData(data); TestAsyncSegmentInputStream fakeNetwork = new TestAsyncSegmentInputStream(segment, 7); @Cleanup EventSegmentReaderImpl stream = SegmentInputStreamFactoryImpl.getEventSegmentReader(fakeNetwork, 0); fakeNetwork.complete(0, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2))); fakeNetwork.completeExceptionally(1, new ConnectionFailedException()); fakeNetwork.complete(2, new WireCommands.SegmentRead(segment.getScopedName(), 0, false, false, ByteBufferUtils.slice(wireData, 0, 2))); fakeNetwork.complete(3, new WireCommands.SegmentRead(segment.getScopedName(), 2, false, false, ByteBufferUtils.slice(wireData, 2, 7))); fakeNetwork.complete(4, new WireCommands.SegmentRead(segment.getScopedName(), 9, false, false, ByteBufferUtils.slice(wireData, 9, 2))); fakeNetwork.complete(5, new WireCommands.SegmentRead(segment.getScopedName(), 11, false, false, ByteBufferUtils.slice(wireData, 11, wireData.capacity() - 11))); AssertExtensions.assertThrows(ConnectionFailedException.class, () -> stream.read()); ByteBuffer read = stream.read(); assertEquals(ByteBuffer.wrap(data), read); }
assertEquals(stream4, o.nextSegment(segments)); assertEquals(stream5, o.nextSegment(segments)); assertNotNull(stream2.read()); assertEquals(stream3, o.nextSegment(segments)); assertEquals(stream4, o.nextSegment(segments)); assertEquals(stream5, o.nextSegment(segments)); assertNotNull(stream3.read()); assertEquals(stream3, o.nextSegment(segments)); assertEquals(stream4, o.nextSegment(segments)); assertEquals(stream5, o.nextSegment(segments)); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream3.read()); AssertExtensions.assertThrows(EndOfSegmentException.class, () -> stream4.read()); AssertExtensions.assertThrows(SegmentTruncatedException.class, () -> stream5.read()); assertEquals(stream3, o.nextSegment(segments)); assertEquals(stream4, o.nextSegment(segments));