use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.
the class MockHttpServerFactory method create.
/**
* Creates a {@link HttpServer} that contains a {@link RestLiServer} to be used for testing a set of Rest.li
* resources.
*
* The {@link HttpServer} uses an empty {@link FilterChain} and uses "/" as the context path.
*
* If the server is run in async mode (by calling this function with the last parameter {@code true}), the
* timeout used is {@link #ASYNC_TIMEOUT}.
*
* Both the async and sync servers will use {@link #NUM_THREADS} threads.
*
* @param port the port the server will run on on localhost
* @param config the {@link RestLiConfig} to be used by the {@link RestLiServer}
* @param beans beans you want to inject into your Rest.li resource.
* @param enableAsync true if the server should be async, false otherwise
*/
private static HttpServer create(int port, RestLiConfig config, Map<String, ?> beans, boolean enableAsync) {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(NUM_THREADS);
final ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
EngineBuilder engineBuilder = new EngineBuilder().setTaskExecutor(scheduler).setTimerScheduler(scheduler);
com.linkedin.parseq.AsyncCallableTask.register(engineBuilder, executor);
final Engine engine = engineBuilder.build();
ResourceFactory resourceFactory = createResourceFactory(beans);
TransportDispatcher dispatcher = new DelegatingTransportDispatcher(new RestLiServer(config, resourceFactory, engine));
final FilterChain fc = FilterChains.empty().addLastRest(new SimpleLoggingFilter());
final HttpServer server = new HttpServerFactory(fc).createServer(port, HttpServerFactory.DEFAULT_CONTEXT_PATH, NUM_THREADS, dispatcher, enableAsync ? HttpJettyServer.ServletType.ASYNC_EVENT : HttpJettyServer.ServletType.RAP, enableAsync ? ASYNC_TIMEOUT : -1);
return new HttpServer() {
@Override
public void start() throws IOException {
server.start();
}
@Override
public void stop() throws IOException {
server.stop();
engine.shutdown();
executor.shutdown();
scheduler.shutdown();
}
@Override
public void waitForStop() throws InterruptedException {
server.waitForStop();
}
};
}
use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.
the class TestMIMEInputStream method testSingleOnWritePossibleDataSources.
@Test(dataProvider = "singleOnWritePossibleDataSources")
public void testSingleOnWritePossibleDataSources(final byte[] inputData, final StrictByteArrayInputStream inputStream, final int writesRemainingPerOnWritePossibles, final int expectedTotalWrites) {
// Setup:
final WriteHandle writeHandle = Mockito.mock(WriteHandle.class);
final MultiPartMIMEInputStream multiPartMIMEInputStream = new MultiPartMIMEInputStream.Builder(inputStream, _scheduledExecutorService, Collections.<String, String>emptyMap()).withWriteChunkSize(TEST_CHUNK_SIZE).build();
// Simulate a write handle that offers decreasing writeHandle.remaining()
final Integer[] remainingWriteHandleCount = simulateDecreasingWriteHandleCount(writesRemainingPerOnWritePossibles);
when(writeHandle.remaining()).thenReturn(writesRemainingPerOnWritePossibles, remainingWriteHandleCount);
final ByteArrayOutputStream byteArrayOutputStream = setupMockWriteHandleToOutputStream(writeHandle);
// Setup for done()
final CountDownLatch doneLatch = new CountDownLatch(1);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
doneLatch.countDown();
return null;
}
}).when(writeHandle).done();
// /////////////////////////////////
// Start things off
// Init the data source
multiPartMIMEInputStream.onInit(writeHandle);
multiPartMIMEInputStream.onWritePossible();
// Wait to finish
try {
boolean successful = doneLatch.await(_testTimeout, TimeUnit.MILLISECONDS);
if (!successful) {
Assert.fail("Timeout when waiting for input stream to completely transfer");
}
} catch (Exception exception) {
Assert.fail("Unexpected exception when waiting for input stream to completely transfer");
}
// /////////////////////////////////
// Assert
Assert.assertEquals(byteArrayOutputStream.toByteArray(), inputData, "All data from the input stream should have successfully been transferred");
Assert.assertEquals(inputStream.isClosed(), true);
// Mock verifies:
verify(writeHandle, times(expectedTotalWrites)).write(isA(ByteString.class));
// One extra remaining() call for knowing the stream has ended.
verify(writeHandle, times(expectedTotalWrites + 1)).remaining();
verify(writeHandle, never()).error(isA(Throwable.class));
verify(writeHandle, times(1)).done();
verifyNoMoreInteractions(writeHandle);
}
use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.
the class TestMIMEInputStream method testExceptionDataSources.
@Test(dataProvider = "exceptionDataSources")
public void testExceptionDataSources(final ExceptionThrowingByteArrayInputStream exceptionThrowingByteArrayInputStream, final int expectedTotalWrites, final int expectedWriteHandleRemainingCalls, final byte[] expectedDataWritten) {
// Setup:
final WriteHandle writeHandle = Mockito.mock(WriteHandle.class);
final MultiPartMIMEInputStream multiPartMIMEInputStream = new MultiPartMIMEInputStream.Builder(exceptionThrowingByteArrayInputStream, _scheduledExecutorService, Collections.<String, String>emptyMap()).withWriteChunkSize(TEST_CHUNK_SIZE).build();
// Doesn't matter what we return here as long as its constant and above 0.
when(writeHandle.remaining()).thenReturn(500);
final ByteArrayOutputStream byteArrayOutputStream = setupMockWriteHandleToOutputStream(writeHandle);
// Setup for error()
final CountDownLatch errorLatch = new CountDownLatch(1);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
errorLatch.countDown();
return null;
}
}).when(writeHandle).error(isA(Throwable.class));
// /////////////////////////////////
// Start things off
// Init the data source
multiPartMIMEInputStream.onInit(writeHandle);
multiPartMIMEInputStream.onWritePossible();
// Wait to finish
try {
boolean successful = errorLatch.await(_testTimeout, TimeUnit.MILLISECONDS);
if (!successful) {
Assert.fail("Timeout when waiting for input stream to completely transfer");
}
} catch (Exception exception) {
Assert.fail("Unexpected exception when waiting for input stream to transfer");
}
// /////////////////////////////////
// Assert
Assert.assertEquals(byteArrayOutputStream.toByteArray(), expectedDataWritten, "Partial data should have been transferred in the case of an exception");
Assert.assertEquals(exceptionThrowingByteArrayInputStream.isClosed(), true);
// Mock verifies:
verify(writeHandle, times(expectedTotalWrites)).write(isA(ByteString.class));
verify(writeHandle, times(expectedWriteHandleRemainingCalls)).remaining();
// Since we can't override equals
verify(writeHandle, times(1)).error(isA(IOException.class));
verify(writeHandle, never()).done();
verifyNoMoreInteractions(writeHandle);
}
use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.
the class TestMIMEInputStream method testDifferentDataSourceSizes.
@Test(dataProvider = "differentDataSourceSizes")
public void testDifferentDataSourceSizes(final byte[] inputData, final StrictByteArrayInputStream inputStream, final int writesRemainingPerOnWritePossibles, final int expectedWriteHandleRemaining, final int expectedTotalWrites) {
// Setup:
final WriteHandle writeHandle = Mockito.mock(WriteHandle.class);
final MultiPartMIMEInputStream multiPartMIMEInputStream = new MultiPartMIMEInputStream.Builder(inputStream, _scheduledExecutorService, Collections.<String, String>emptyMap()).withWriteChunkSize(TEST_CHUNK_SIZE).build();
// Simulate a write handle that offers decreasing writeHandle.remaining()
final Integer[] remainingWriteHandleCount = simulateDecreasingWriteHandleCount(writesRemainingPerOnWritePossibles);
when(writeHandle.remaining()).thenReturn(writesRemainingPerOnWritePossibles, remainingWriteHandleCount);
final ByteArrayOutputStream byteArrayOutputStream = setupMockWriteHandleToOutputStream(writeHandle);
// Setup for done()
final CountDownLatch doneLatch = new CountDownLatch(1);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
doneLatch.countDown();
return null;
}
}).when(writeHandle).done();
// /////////////////////////////////
// Start things off
// Init the data source
multiPartMIMEInputStream.onInit(writeHandle);
multiPartMIMEInputStream.onWritePossible();
// Wait to finish
try {
boolean successful = doneLatch.await(_testTimeout, TimeUnit.MILLISECONDS);
if (!successful) {
Assert.fail("Timeout when waiting for input stream to completely transfer");
}
} catch (Exception exception) {
Assert.fail("Unexpected exception when waiting for input stream to completely transfer");
}
// /////////////////////////////////
// Assert
Assert.assertEquals(byteArrayOutputStream.toByteArray(), inputData, "All data from the input stream should have successfully been transferred");
Assert.assertEquals(inputStream.isClosed(), true);
// Mock verifies:
verify(writeHandle, times(expectedTotalWrites)).write(isA(ByteString.class));
verify(writeHandle, times(expectedWriteHandleRemaining)).remaining();
verify(writeHandle, never()).error(isA(Throwable.class));
verify(writeHandle, times(1)).done();
verifyNoMoreInteractions(writeHandle);
}
use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.
the class TestMIMEInputStream method testAbortBeforeWrite.
// /////////////////////////////////////////////////////////////////////////////////////
//
// These tests will verify that aborts work properly and close the input stream regardless of the
// current state.
// This test will simulate an abort before any writes requested.
@Test
public void testAbortBeforeWrite() throws Exception {
final byte[] smallInputData = "b".getBytes();
final StrictByteArrayInputStream inputStream = new StrictByteArrayInputStream(smallInputData);
final StrictByteArrayInputStream spyInputStream = spy(inputStream);
// Setup:
final WriteHandle writeHandle = Mockito.mock(WriteHandle.class);
final MultiPartMIMEInputStream multiPartMIMEInputStream = new MultiPartMIMEInputStream.Builder(spyInputStream, _scheduledExecutorService, Collections.<String, String>emptyMap()).withWriteChunkSize(TEST_CHUNK_SIZE).build();
// Setup for the close on the input stream.
// The close must happen for the test to finish.
final CountDownLatch closeInputStreamLatch = new CountDownLatch(1);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
closeInputStreamLatch.countDown();
return null;
}
}).when(spyInputStream).close();
// /////////////////////////////////
// Start things off
// Init the data source
multiPartMIMEInputStream.onInit(writeHandle);
multiPartMIMEInputStream.onAbort(new IOException());
// Wait to finish
try {
boolean successful = closeInputStreamLatch.await(_testTimeout, TimeUnit.MILLISECONDS);
if (!successful) {
Assert.fail("Timeout when waiting for abort to happen!");
}
} catch (Exception exception) {
Assert.fail("Unexpected exception when waiting for input stream to be closed!");
}
// /////////////////////////////////
// Mock verifies:
verify(spyInputStream, times(1)).close();
verify(spyInputStream, never()).read(isA(byte[].class));
verify(writeHandle, never()).write(isA(ByteString.class));
verify(writeHandle, never()).remaining();
verify(writeHandle, never()).error(isA(Throwable.class));
verify(writeHandle, never()).done();
verifyNoMoreInteractions(writeHandle);
}
Aggregations