use of io.pravega.shared.protocol.netty.WireCommands.SegmentRead in project pravega by pravega.
the class AsyncSegmentInputStreamTest method testRetryWithConnectionFailures.
@Test(timeout = 10000)
public void testRetryWithConnectionFailures() throws ConnectionFailedException {
Segment segment = new Segment("scope", "testRetry", 4);
PravegaNodeUri endpoint = new PravegaNodeUri("localhost", SERVICE_PORT);
@Cleanup MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
@Cleanup MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory, true);
ClientConnection c = mock(ClientConnection.class);
connectionFactory.provideConnection(endpoint, c);
MockConnectionFactoryImpl mockedCF = spy(connectionFactory);
Semaphore dataAvailable = new Semaphore(0);
@Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, mockedCF, segment, DelegationTokenProviderFactory.createWithEmptyToken(), dataAvailable);
InOrder inOrder = Mockito.inOrder(c);
// Failed Connection
CompletableFuture<ClientConnection> failedConnection = new CompletableFuture<>();
failedConnection.completeExceptionally(new ConnectionFailedException("Netty error while establishing connection"));
// Successful Connection
CompletableFuture<ClientConnection> successfulConnection = new CompletableFuture<>();
successfulConnection.complete(c);
WireCommands.SegmentRead segmentRead = new WireCommands.SegmentRead(segment.getScopedName(), 1234, false, false, Unpooled.EMPTY_BUFFER, in.getRequestId());
// simulate a establishConnection failure to segment store.
Mockito.doReturn(failedConnection).doCallRealMethod().when(mockedCF).establishConnection(eq(endpoint), any(ReplyProcessor.class));
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
// Simulate a connection failure post establishing connection to SegmentStore.
throw Exceptions.sneakyThrow(new ConnectionFailedException("SendAsync exception since netty channel is null"));
}
}).doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
mockedCF.getProcessor(endpoint).process(segmentRead);
return null;
}
}).when(c).send(any(ReadSegment.class));
assertEquals(0, dataAvailable.availablePermits());
// Read invocation.
CompletableFuture<SegmentRead> readFuture = in.read(1234, 5678);
// Verification.
assertEquals(segmentRead, readFuture.join());
// read completes after 3 retries.
assertTrue(Futures.isSuccessful(readFuture));
assertEquals(1, dataAvailable.availablePermits());
// Verify that the reader attempts to establish connection 3 times ( 2 failures followed by a successful attempt).
verify(mockedCF, times(3)).establishConnection(eq(endpoint), any(ReplyProcessor.class));
// The second time sendAsync is invoked but it fail due to the exception.
inOrder.verify(c).send(eq(new WireCommands.ReadSegment(segment.getScopedName(), 1234, 5678, "", in.getRequestId())));
// Validate that the connection is closed in case of an error.
inOrder.verify(c).close();
// Validate that the read command is send again over the new connection.
inOrder.verify(c).send(eq(new WireCommands.ReadSegment(segment.getScopedName(), 1234, 5678, "", in.getRequestId())));
// No more interactions since the SSS responds and the ReplyProcessor.segmentRead is invoked by netty.
verifyNoMoreInteractions(c);
}
use of io.pravega.shared.protocol.netty.WireCommands.SegmentRead in project pravega by pravega.
the class AsyncSegmentInputStreamTest method testProcessingFailure.
@Test
public void testProcessingFailure() throws ConnectionFailedException {
Segment segment = new Segment("scope", "testRetry", 4);
PravegaNodeUri endpoint = new PravegaNodeUri("localhost", SERVICE_PORT);
@Cleanup MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
@Cleanup MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory, true);
DelegationTokenProvider tokenProvider = mock(DelegationTokenProvider.class);
// return empty token
when(tokenProvider.retrieveToken()).thenReturn(CompletableFuture.completedFuture(""));
Semaphore dataAvailable = new Semaphore(0);
@Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, tokenProvider, dataAvailable);
ClientConnection c = mock(ClientConnection.class);
InOrder inOrder = Mockito.inOrder(c);
connectionFactory.provideConnection(endpoint, c);
WireCommands.SegmentRead segmentRead = new WireCommands.SegmentRead(segment.getScopedName(), 1234, false, false, Unpooled.EMPTY_BUFFER, in.getRequestId());
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
connectionFactory.getProcessor(endpoint).processingFailure(new ConnectionFailedException("Custom error"));
return null;
}
}).doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
connectionFactory.getProcessor(endpoint).process(segmentRead);
return null;
}
}).when(c).send(any(ReadSegment.class));
assertEquals(0, dataAvailable.availablePermits());
CompletableFuture<SegmentRead> readFuture = in.read(1234, 5678);
assertEquals(segmentRead, readFuture.join());
assertTrue(Futures.isSuccessful(readFuture));
assertEquals(1, dataAvailable.availablePermits());
inOrder.verify(c).send(eq(new WireCommands.ReadSegment(segment.getScopedName(), 1234, 5678, "", in.getRequestId())));
inOrder.verify(c).close();
inOrder.verify(c).send(eq(new WireCommands.ReadSegment(segment.getScopedName(), 1234, 5678, "", in.getRequestId())));
verifyNoMoreInteractions(c);
// ensure retrieve Token is invoked for every retry.
verify(tokenProvider, times(2)).retrieveToken();
}
use of io.pravega.shared.protocol.netty.WireCommands.SegmentRead in project pravega by pravega.
the class SegmentInputStreamTest method testRefillSize.
@Test
public void testRefillSize() throws EndOfSegmentException, SegmentTruncatedException {
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
val wireData = createEventFromData(data);
// size of the data with header size.
int wireDataSize = wireData.readableBytes();
int bufferSize = SegmentInputStreamImpl.DEFAULT_BUFFER_SIZE;
AsyncSegmentInputStream mockAsyncInputStream = mock(AsyncSegmentInputStream.class);
when(mockAsyncInputStream.read(0, bufferSize)).thenReturn(completedFuture(new SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice(), requestId)));
int expectedReadSize = bufferSize - wireDataSize;
when(mockAsyncInputStream.read(wireDataSize, expectedReadSize)).thenReturn(completedFuture(new SegmentRead(segment.getScopedName(), wireDataSize, false, false, wireData.slice(), requestId)));
// Verify that it requests enough data to fill the buffer.
@Cleanup EventSegmentReaderImpl stream1 = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0);
ByteBuffer read = stream1.read();
assertEquals(ByteBuffer.wrap(data), read);
verify(mockAsyncInputStream, times(1)).read(0L, bufferSize);
verify(mockAsyncInputStream, times(1)).read(wireDataSize, expectedReadSize);
when(mockAsyncInputStream.read(0, wireDataSize)).thenReturn(completedFuture(new SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice(), requestId)));
// Verify it won't read beyond it's limit.
@Cleanup EventSegmentReaderImpl stream2 = SegmentInputStreamFactoryImpl.getEventSegmentReader(mockAsyncInputStream, 0, wireDataSize, bufferSize);
read = stream2.read();
assertEquals(ByteBuffer.wrap(data), read);
verify(mockAsyncInputStream, times(1)).read(0L, wireDataSize);
// Verify it works with a small buffer.
when(mockAsyncInputStream.read(0, 100)).thenReturn(completedFuture(new SegmentRead(segment.getScopedName(), 0, false, false, wireData.slice(), requestId)));
@Cleanup 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);
}
use of io.pravega.shared.protocol.netty.WireCommands.SegmentRead in project pravega by pravega.
the class ReadTest method testReceivingReadCall.
@Test(timeout = 10000)
public void testReceivingReadCall() throws Exception {
String segmentName = "testReceivingReadCall";
int entries = 10;
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
StreamSegmentStore segmentStore = SERVICE_BUILDER.createStreamSegmentService();
// fill segment store with 10 entries; the total data size is 100 bytes.
fillStoreForSegment(segmentName, data, entries, segmentStore);
@Cleanup EmbeddedChannel channel = AppendTest.createChannel(segmentStore);
ByteBuf actual = Unpooled.buffer(entries * data.length);
while (actual.writerIndex() < actual.capacity()) {
SegmentRead result = (SegmentRead) AppendTest.sendRequest(channel, new ReadSegment(segmentName, actual.writerIndex(), 10000, "", 1L));
assertEquals(segmentName, result.getSegment());
assertEquals(result.getOffset(), actual.writerIndex());
assertFalse(result.isEndOfSegment());
actual.writeBytes(result.getData());
// release the ByteBuf and ensure it is deallocated.
assertTrue(result.getData().release());
if (actual.writerIndex() < actual.capacity()) {
// Prevent entering a tight loop by giving the store a bit of time to process al the appends internally
// before trying again.
Thread.sleep(10);
} else {
// Verify the last read result has the the atTail flag set to true.
assertTrue(result.isAtTail());
// mark the channel as finished
assertFalse(channel.finish());
}
}
ByteBuf expected = Unpooled.buffer(entries * data.length);
for (int i = 0; i < entries; i++) {
expected.writeBytes(data);
}
expected.writerIndex(expected.capacity()).resetReaderIndex();
actual.writerIndex(actual.capacity()).resetReaderIndex();
assertEquals(expected, actual);
// Release the ByteBuf and ensure it is deallocated.
assertTrue(actual.release());
assertTrue(expected.release());
}
use of io.pravega.shared.protocol.netty.WireCommands.SegmentRead in project pravega by pravega.
the class AsyncSegmentInputStreamTest method testCloseAbortsRead.
@Test(timeout = 10000)
public void testCloseAbortsRead() throws InterruptedException, ExecutionException {
Segment segment = new Segment("scope", "testRetry", 4);
PravegaNodeUri endpoint = new PravegaNodeUri("localhost", SERVICE_PORT);
@Cleanup MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
@Cleanup MockController controller = new MockController(endpoint.getEndpoint(), endpoint.getPort(), connectionFactory, true);
Semaphore dataAvailable = new Semaphore(0);
@Cleanup AsyncSegmentInputStreamImpl in = new AsyncSegmentInputStreamImpl(controller, connectionFactory, segment, DelegationTokenProviderFactory.createWithEmptyToken(), dataAvailable);
ClientConnection c = mock(ClientConnection.class);
connectionFactory.provideConnection(endpoint, c);
// Make sure connection is established.
in.getConnection().get();
CompletableFuture<SegmentRead> read = in.read(1234, 5678);
assertFalse(read.isDone());
in.close();
assertThrows(ConnectionClosedException.class, () -> Futures.getThrowingException(read));
verify(c).close();
assertEquals(0, dataAvailable.availablePermits());
}
Aggregations