diff options
Diffstat (limited to 'jdisc_core/src/test/java/com/yahoo/jdisc/core/ContainerShutdownTestCase.java')
-rw-r--r-- | jdisc_core/src/test/java/com/yahoo/jdisc/core/ContainerShutdownTestCase.java | 848 |
1 files changed, 848 insertions, 0 deletions
diff --git a/jdisc_core/src/test/java/com/yahoo/jdisc/core/ContainerShutdownTestCase.java b/jdisc_core/src/test/java/com/yahoo/jdisc/core/ContainerShutdownTestCase.java new file mode 100644 index 00000000000..488628867b4 --- /dev/null +++ b/jdisc_core/src/test/java/com/yahoo/jdisc/core/ContainerShutdownTestCase.java @@ -0,0 +1,848 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.core; + +import com.yahoo.jdisc.Container; +import com.yahoo.jdisc.Request; +import com.yahoo.jdisc.Response; +import com.yahoo.jdisc.application.ContainerBuilder; +import com.yahoo.jdisc.handler.AbstractRequestHandler; +import com.yahoo.jdisc.handler.CompletionHandler; +import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.RequestHandler; +import com.yahoo.jdisc.handler.ResponseHandler; +import com.yahoo.jdisc.test.TestDriver; +import org.junit.Test; + +import java.net.URI; +import java.nio.ByteBuffer; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a> + */ +public class ContainerShutdownTestCase { + + @Test + public void requireThatContainerBlocksTermination() { + Context ctx = Context.newInstance(); + Container container = ctx.driver.newReference(URI.create("http://host/path")); + assertFalse(ctx.shutdown()); + container.release(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatNewRequestBlocksTermination() { + Context ctx = Context.newPendingRequest(MyRequestHandler.newInstance()); + assertFalse(ctx.shutdown()); + ctx.request.release(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatOpenRequestBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + ctx.request.release(); + requestHandler.respond().close(null); + assertFalse(ctx.shutdown()); + requestContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponsePendingBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newEagerCompletion()).close(null); + ctx.request.release(); + assertFalse(ctx.shutdown()); + requestHandler.respond().close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatOpenResponseBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newEagerCompletion()).close(null); + ctx.request.release(); + ContentChannel responseContent = requestHandler.respond(); + assertFalse(ctx.shutdown()); + responseContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestExceptionDoesNotBlockTermination() { + Context ctx = Context.newPendingRequest(MyRequestHandler.newRequestException()); + try { + ctx.request.connect(MyResponseHandler.newEagerCompletion()); + fail(); + } catch (MyException e) { + // ignore + } + ctx.request.release(); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestExceptionWithEagerHandleResponseBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newRequestExceptionWithEagerHandleResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + try { + ctx.request.connect(MyResponseHandler.newEagerCompletion()); + fail(); + } catch (MyException e) { + // ignore + } + ctx.request.release(); + assertFalse(ctx.shutdown()); + requestHandler.responseContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestExceptionWithEagerCloseResponseDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newRequestExceptionWithEagerCloseResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + try { + ctx.request.connect(MyResponseHandler.newEagerCompletion()); + fail(); + } catch (MyException e) { + // ignore + } + ctx.request.release(); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatNullRequestContentBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newNullContent(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newEagerCompletion()).close(null); + ctx.request.release(); + assertFalse(ctx.shutdown()); + requestHandler.respond(); + requestHandler.responseContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatNullRequestContentWithEagerHandleResponseBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newNullContentWithEagerHandleResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newEagerCompletion()).close(null); + ctx.request.release(); + assertFalse(ctx.shutdown()); + requestHandler.responseContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatNullRequestContentWithEagerCloseResponseBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newNulContentWithEagerCloseResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + ctx.request.release(); + assertFalse(ctx.shutdown()); + requestContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentWriteFailedDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerFail(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + requestContent.write(ByteBuffer.allocate(69), null); + requestContent.close(null); + ctx.request.release(); + requestHandler.respond().close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentWriteExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newContentWriteExceptionWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + try { + requestContent.write(ByteBuffer.allocate(69), null); + fail(); + } catch (MyException e) { + // ignore + } + requestContent.close(null); + ctx.request.release(); + requestHandler.respond().close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentWriteExceptionDoesNotForceTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newContentWriteExceptionWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + try { + requestContent.write(ByteBuffer.allocate(69), null); + fail(); + } catch (MyException e) { + // ignore + } + ctx.request.release(); + requestHandler.respond().close(null); + assertFalse(ctx.shutdown()); + requestContent.close(null); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentWriteExceptionWithCompletionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newContentWriteExceptionWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + try { + requestContent.write(ByteBuffer.allocate(69), MyCompletion.newInstance()); + fail(); + } catch (MyException e) { + // ignore + } + requestContent.close(null); + ctx.request.release(); + requestHandler.respond().close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentCloseFailedDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerFail(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + requestContent.close(null); + ctx.request.release(); + requestHandler.respond().close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentCloseExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newContentCloseException(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + try { + requestContent.close(null); + fail(); + } catch (MyException e) { + // ignore + } + ctx.request.release(); + requestHandler.respond().close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestContentCloseExceptionWithCompletionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newContentCloseException(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + try { + requestContent.close(MyCompletion.newInstance()); + fail(); + } catch (MyException e) { + // ignore + } + ctx.request.release(); + requestHandler.respond().close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestWriteCompletionBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCloseResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + ctx.request.release(); + requestContent.write(null, MyCompletion.newInstance()); + requestContent.close(null); + requestHandler.requestContent.closeCompletion.completed(); + assertFalse(ctx.shutdown()); + requestHandler.requestContent.writeCompletion.completed(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestWriteCompletionExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCloseResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + ctx.request.release(); + requestContent.write(null, MyCompletion.newException()); + requestContent.close(null); + requestHandler.requestContent.closeCompletion.completed(); + assertFalse(ctx.shutdown()); + try { + requestHandler.requestContent.writeCompletion.completed(); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestCloseCompletionBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCloseResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + ctx.request.release(); + requestContent.close(MyCompletion.newInstance()); + assertFalse(ctx.shutdown()); + requestHandler.requestContent.closeCompletion.completed(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatRequestCloseCompletionExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCloseResponse(); + Context ctx = Context.newPendingRequest(requestHandler); + ContentChannel requestContent = ctx.request.connect(MyResponseHandler.newEagerCompletion()); + ctx.request.release(); + requestContent.close(MyCompletion.newException()); + assertFalse(ctx.shutdown()); + try { + requestHandler.requestContent.closeCompletion.completed(); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatNullResponseContentBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerRespondWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newNullContent(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + + assertFalse(ctx.shutdown()); + requestHandler.responseContent.close(MyCompletion.newInstance()); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newResponseException()).close(null); + ctx.request.release(); + try { + requestHandler.respond(); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentWriteFailedDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newEagerFail(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + requestHandler.respond(); + requestHandler.responseContent.write(ByteBuffer.allocate(69), null); + requestHandler.responseContent.close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentCloseFailedDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newEagerFail(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + requestHandler.respond(); + requestHandler.responseContent.close(null); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentWriteExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newContentWriteException(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + requestHandler.respond(); + try { + requestHandler.responseContent.write(ByteBuffer.allocate(69), null); + fail(); + } catch (MyException e) { + // ignore + } + requestHandler.responseContent.close(null); + responseHandler.content.closeCompletion.completed(); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentWriteExceptionDoesNotForceTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newContentWriteException(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + requestHandler.respond(); + try { + requestHandler.responseContent.write(ByteBuffer.allocate(69), null); + fail(); + } catch (MyException e) { + // ignore + } + assertFalse(ctx.shutdown()); + requestHandler.responseContent.close(null); + responseHandler.content.closeCompletion.completed(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentWriteExceptionWithCompletionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newContentWriteException(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + requestHandler.respond(); + try { + requestHandler.responseContent.write(ByteBuffer.allocate(69), MyCompletion.newInstance()); + fail(); + } catch (MyException e) { + // ignore + } + requestHandler.responseContent.close(null); + responseHandler.content.closeCompletion.completed(); + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentCloseExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newContentCloseException()).close(null); + ctx.request.release(); + try { + requestHandler.respond().close(null); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseContentCloseExceptionWithCompletionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + ctx.request.connect(MyResponseHandler.newContentCloseException()).close(null); + ctx.request.release(); + try { + requestHandler.respond().close(MyCompletion.newInstance()); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.shutdown()); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseWriteCompletionBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerRespondWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newInstance(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + + requestHandler.responseContent.write(null, MyCompletion.newInstance()); + requestHandler.responseContent.close(null); + responseHandler.content.closeCompletion.completed(); + assertFalse(ctx.shutdown()); + responseHandler.content.writeCompletion.completed(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseWriteCompletionExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerRespondWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newInstance(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + + requestHandler.responseContent.write(null, MyCompletion.newException()); + requestHandler.responseContent.close(null); + responseHandler.content.closeCompletion.completed(); + assertFalse(ctx.shutdown()); + try { + responseHandler.content.writeCompletion.completed(); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseCloseCompletionBlocksTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerRespondWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newInstance(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + + requestHandler.responseContent.close(MyCompletion.newInstance()); + assertFalse(ctx.shutdown()); + responseHandler.content.closeCompletion.completed(); + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + @Test + public void requireThatResponseCloseCompletionExceptionDoesNotBlockTermination() { + MyRequestHandler requestHandler = MyRequestHandler.newEagerRespondWithEagerCompletion(); + Context ctx = Context.newPendingRequest(requestHandler); + MyResponseHandler responseHandler = MyResponseHandler.newInstance(); + ctx.request.connect(responseHandler).close(null); + ctx.request.release(); + + requestHandler.responseContent.close(MyCompletion.newException()); + assertFalse(ctx.shutdown()); + try { + responseHandler.content.closeCompletion.completed(); + fail(); + } catch (MyException e) { + // ignore + } + assertTrue(ctx.terminated); + assertTrue(ctx.driver.close()); + } + + private static class Context { + + final TestDriver driver; + final Request request; + boolean terminated = false; + + Context(TestDriver driver, Request request) { + this.driver = driver; + this.request = request; + } + + boolean shutdown() { + driver.activateContainer(null).notifyTermination(new Runnable() { + + @Override + public void run() { + terminated = true; + } + }); + return terminated; + } + + static Context newInstance() { + TestDriver driver = TestDriver.newSimpleApplicationInstanceWithoutOsgi(); + driver.activateContainer(driver.newContainerBuilder()); + return new Context(driver, null); + } + + static Context newPendingRequest(RequestHandler requestHandler) { + TestDriver driver = TestDriver.newSimpleApplicationInstanceWithoutOsgi(); + ContainerBuilder builder = driver.newContainerBuilder(); + builder.serverBindings().bind("http://host/path", requestHandler); + driver.activateContainer(builder); + return new Context(driver, new Request(driver, URI.create("http://host/path"))); + } + } + + private static class MyCompletion implements CompletionHandler { + + final boolean throwException; + + MyCompletion(boolean throwException) { + this.throwException = throwException; + } + + @Override + public void completed() { + if (throwException) { + throw new MyException(); + } + } + + @Override + public void failed(Throwable t) { + if (throwException) { + throw new MyException(); + } + } + + static MyCompletion newInstance() { + return new MyCompletion(false); + } + + static MyCompletion newException() { + return new MyCompletion(true); + } + } + + private static class MyContent implements ContentChannel { + + final boolean eagerCompletion; + final boolean eagerFail; + final boolean writeException; + final boolean closeException; + CompletionHandler writeCompletion = null; + CompletionHandler closeCompletion = null; + + MyContent(boolean eagerCompletion, boolean eagerFail, boolean writeException, boolean closeException) { + this.eagerCompletion = eagerCompletion; + this.eagerFail = eagerFail; + this.writeException = writeException; + this.closeException = closeException; + } + + @Override + public void write(ByteBuffer buf, CompletionHandler handler) { + writeCompletion = handler; + if (eagerCompletion) { + writeCompletion.completed(); + } else if (eagerFail) { + writeCompletion.failed(new MyException()); + } + if (writeException) { + throw new MyException(); + } + } + + @Override + public void close(CompletionHandler handler) { + closeCompletion = handler; + if (eagerCompletion) { + closeCompletion.completed(); + } else if (eagerFail) { + closeCompletion.failed(new MyException()); + } + if (closeException) { + throw new MyException(); + } + } + + static MyContent newInstance() { + return new MyContent(false, false, false, false); + } + + static MyContent newEagerCompletion() { + return new MyContent(true, false, false, false); + } + + static MyContent newEagerFail() { + return new MyContent(false, true, false, false); + } + + static MyContent newWriteException() { + return new MyContent(false, false, true, false); + } + + static MyContent newWriteExceptionWithEagerCompletion() { + return new MyContent(true, false, true, false); + } + + static MyContent newCloseException() { + return new MyContent(false, false, false, true); + } + } + + private static class MyRequestHandler extends AbstractRequestHandler { + + final MyContent requestContent; + final boolean eagerRespond; + final boolean closeResponse; + final boolean throwException; + ContentChannel responseContent = null; + ResponseHandler handler = null; + + MyRequestHandler(MyContent requestContent, boolean eagerRespond, boolean closeResponse, + boolean throwException) + { + this.requestContent = requestContent; + this.eagerRespond = eagerRespond; + this.closeResponse = closeResponse; + this.throwException = throwException; + } + + @Override + public ContentChannel handleRequest(Request request, ResponseHandler handler) { + this.handler = handler; + if (eagerRespond) { + respond(); + } + if (throwException) { + throw new MyException(); + } + return requestContent; + } + + ContentChannel respond() { + responseContent = handler.handleResponse(new Response(Response.Status.OK)); + if (responseContent != null && closeResponse) { + responseContent.close(null); + } + return responseContent; + } + + static MyRequestHandler newInstance() { + return new MyRequestHandler(MyContent.newInstance(), false, false, false); + } + + static MyRequestHandler newEagerCompletion() { + return new MyRequestHandler(MyContent.newEagerCompletion(), false, false, false); + } + + static MyRequestHandler newEagerFail() { + return new MyRequestHandler(MyContent.newEagerFail(), false, false, false); + } + + static RequestHandler newRequestException() { + return new MyRequestHandler(null, false, false, true); + } + + static MyRequestHandler newNullContent() { + return new MyRequestHandler(null, false, false, false); + } + + static MyRequestHandler newNullContentWithEagerHandleResponse() { + return new MyRequestHandler(null, true, false, false); + } + + static MyRequestHandler newNulContentWithEagerCloseResponse() { + return new MyRequestHandler(null, true, true, false); + } + + static MyRequestHandler newRequestExceptionWithEagerHandleResponse() { + return new MyRequestHandler(null, true, false, true); + } + + static MyRequestHandler newRequestExceptionWithEagerCloseResponse() { + return new MyRequestHandler(null, true, true, true); + } + + static MyRequestHandler newContentWriteExceptionWithEagerCompletion() { + return new MyRequestHandler(MyContent.newWriteExceptionWithEagerCompletion(), true, true, false); + } + + static MyRequestHandler newContentCloseException() { + return new MyRequestHandler(MyContent.newCloseException(), true, true, false); + } + + static MyRequestHandler newEagerRespondWithEagerCompletion() { + return new MyRequestHandler(MyContent.newEagerCompletion(), true, false, false); + } + + static MyRequestHandler newEagerCloseResponse() { + return new MyRequestHandler(MyContent.newInstance(), true, true, false); + } + } + + private static class MyResponseHandler implements ResponseHandler { + + final MyContent content; + final boolean throwException; + + MyResponseHandler(MyContent content, boolean throwException) { + this.content = content; + this.throwException = throwException; + } + + @Override + public ContentChannel handleResponse(Response response) { + if (throwException) { + throw new MyException(); + } + return content; + } + + static MyResponseHandler newInstance() { + return new MyResponseHandler(MyContent.newInstance(), false); + } + + static MyResponseHandler newEagerCompletion() { + return new MyResponseHandler(MyContent.newEagerCompletion(), false); + } + + static MyResponseHandler newEagerFail() { + return new MyResponseHandler(MyContent.newEagerFail(), false); + } + + static MyResponseHandler newNullContent() { + return new MyResponseHandler(null, false); + } + + static MyResponseHandler newResponseException() { + return new MyResponseHandler(null, true); + } + + static MyResponseHandler newContentWriteException() { + return new MyResponseHandler(MyContent.newWriteException(), false); + } + + static MyResponseHandler newContentCloseException() { + return new MyResponseHandler(MyContent.newCloseException(), false); + } + } + + private static final class MyException extends RuntimeException { + + } +} |