#7281 add more tests and fix shortcomings
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
parent
ec9846c116
commit
1682265a00
|
@ -352,13 +352,26 @@ class AsyncContentProducer implements ContentProducer
|
|||
_transformedContent = _rawContent;
|
||||
}
|
||||
|
||||
if (_transformedContent != null && _transformedContent.isEmpty())
|
||||
if (_transformedContent != null)
|
||||
{
|
||||
if (_transformedContent != _rawContent)
|
||||
_transformedContent.succeeded();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("nulling depleted transformed content {}", this);
|
||||
_transformedContent = null;
|
||||
if (_transformedContent.isSpecial())
|
||||
{
|
||||
if (_transformedContent != _rawContent)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("making special transformed content the new raw content {}", this);
|
||||
_rawContent.succeeded();
|
||||
_rawContent = _transformedContent;
|
||||
}
|
||||
}
|
||||
else if (_transformedContent.isEmpty())
|
||||
{
|
||||
if (_transformedContent != _rawContent)
|
||||
_transformedContent.succeeded();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("nulling depleted transformed content {}", this);
|
||||
_transformedContent = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (_transformedContent == null)
|
||||
|
@ -366,7 +379,7 @@ class AsyncContentProducer implements ContentProducer
|
|||
if (_rawContent.isSpecial())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("using special raw content as transformed content {}", this);
|
||||
LOG.debug("checking if special raw content should be refreshed {}", this);
|
||||
|
||||
// In case the _rawContent was set by consumeAll(), check the httpChannel
|
||||
// to see if it has a more precise error. Otherwise, the exact same
|
||||
|
@ -382,7 +395,6 @@ class AsyncContentProducer implements ContentProducer
|
|||
LOG.debug("refreshed raw content: {} {}", _rawContent, this);
|
||||
}
|
||||
|
||||
_transformedContent = _rawContent;
|
||||
break;
|
||||
}
|
||||
else if (_rawContent.isEmpty())
|
||||
|
@ -433,7 +445,7 @@ class AsyncContentProducer implements ContentProducer
|
|||
Response response = _httpChannel.getResponse();
|
||||
if (response.isCommitted())
|
||||
_httpChannel.abort(failure);
|
||||
return null;
|
||||
return _transformedContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.eclipse.jetty.io.ArrayByteBufferPool;
|
||||
|
@ -188,6 +189,96 @@ public class AsyncContentProducerTest
|
|||
assertThat(interceptor.contents.get(3).getError().getMessage(), is("testAsyncContentProducerErrorContentIsPassedToInterceptor error"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncContentProducerInterceptorGeneratesError()
|
||||
{
|
||||
AtomicInteger contentSucceededCount = new AtomicInteger();
|
||||
ContentProducer contentProducer = new AsyncContentProducer(new StaticContentHttpChannel(new HttpInput.Content(ByteBuffer.allocate(1))
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
contentSucceededCount.incrementAndGet();
|
||||
}
|
||||
}));
|
||||
try (AutoLock lock = contentProducer.lock())
|
||||
{
|
||||
contentProducer.setInterceptor(content -> new HttpInput.ErrorContent(new Throwable("testAsyncContentProducerInterceptorGeneratesError interceptor error")));
|
||||
|
||||
assertThat(contentProducer.isReady(), is(true));
|
||||
|
||||
HttpInput.Content content1 = contentProducer.nextContent();
|
||||
assertThat(content1.isSpecial(), is(true));
|
||||
assertThat(content1.getError().getMessage(), is("testAsyncContentProducerInterceptorGeneratesError interceptor error"));
|
||||
|
||||
HttpInput.Content content2 = contentProducer.nextContent();
|
||||
assertThat(content2.isSpecial(), is(true));
|
||||
assertThat(content2.getError().getMessage(), is("testAsyncContentProducerInterceptorGeneratesError interceptor error"));
|
||||
}
|
||||
assertThat(contentSucceededCount.get(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncContentProducerInterceptorGeneratesEof()
|
||||
{
|
||||
AtomicInteger contentSucceededCount = new AtomicInteger();
|
||||
ContentProducer contentProducer = new AsyncContentProducer(new StaticContentHttpChannel(new HttpInput.Content(ByteBuffer.allocate(1))
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
contentSucceededCount.incrementAndGet();
|
||||
}
|
||||
}));
|
||||
try (AutoLock lock = contentProducer.lock())
|
||||
{
|
||||
contentProducer.setInterceptor(content -> new HttpInput.EofContent());
|
||||
|
||||
assertThat(contentProducer.isReady(), is(true));
|
||||
|
||||
HttpInput.Content content1 = contentProducer.nextContent();
|
||||
assertThat(content1.isSpecial(), is(true));
|
||||
assertThat(content1.isEof(), is(true));
|
||||
|
||||
HttpInput.Content content2 = contentProducer.nextContent();
|
||||
assertThat(content2.isSpecial(), is(true));
|
||||
assertThat(content2.isEof(), is(true));
|
||||
}
|
||||
assertThat(contentSucceededCount.get(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncContentProducerInterceptorThrows()
|
||||
{
|
||||
AtomicInteger contentFailedCount = new AtomicInteger();
|
||||
ContentProducer contentProducer = new AsyncContentProducer(new StaticContentHttpChannel(new HttpInput.Content(ByteBuffer.allocate(1))
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
contentFailedCount.incrementAndGet();
|
||||
}
|
||||
}));
|
||||
try (AutoLock lock = contentProducer.lock())
|
||||
{
|
||||
contentProducer.setInterceptor(content ->
|
||||
{
|
||||
throw new RuntimeException("testAsyncContentProducerInterceptorThrows error");
|
||||
});
|
||||
|
||||
assertThat(contentProducer.isReady(), is(true));
|
||||
|
||||
HttpInput.Content content1 = contentProducer.nextContent();
|
||||
assertThat(content1.isSpecial(), is(true));
|
||||
assertThat(content1.getError().getCause().getMessage(), is("testAsyncContentProducerInterceptorThrows error"));
|
||||
|
||||
HttpInput.Content content2 = contentProducer.nextContent();
|
||||
assertThat(content2.isSpecial(), is(true));
|
||||
assertThat(content1.getError().getCause().getMessage(), is("testAsyncContentProducerInterceptorThrows error"));
|
||||
}
|
||||
assertThat(contentFailedCount.get(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncContentProducerGzipInterceptor() throws Exception
|
||||
{
|
||||
|
@ -361,6 +452,47 @@ public class AsyncContentProducerTest
|
|||
}
|
||||
}
|
||||
|
||||
private static class StaticContentHttpChannel extends HttpChannel
|
||||
{
|
||||
private final HttpInput.Content content;
|
||||
|
||||
public StaticContentHttpChannel(HttpInput.Content content)
|
||||
{
|
||||
super(new MockConnector(), new HttpConfiguration(), null, null);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needContent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpInput.Content produceContent()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean failAllContent(Throwable failure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean failed(Throwable failure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean eof()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrayDelayedHttpChannel extends HttpChannel
|
||||
{
|
||||
private final ByteBuffer[] byteBuffers;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.eclipse.jetty.io.ArrayByteBufferPool;
|
||||
|
@ -118,6 +119,90 @@ public class BlockingContentProducerTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingContentProducerInterceptorGeneratesError()
|
||||
{
|
||||
AtomicInteger contentSucceededCount = new AtomicInteger();
|
||||
ContentProducer contentProducer = new BlockingContentProducer(new AsyncContentProducer(new StaticContentHttpChannel(new HttpInput.Content(ByteBuffer.allocate(1))
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
contentSucceededCount.incrementAndGet();
|
||||
}
|
||||
})));
|
||||
try (AutoLock lock = contentProducer.lock())
|
||||
{
|
||||
contentProducer.setInterceptor(content -> new HttpInput.ErrorContent(new Throwable("testBlockingContentProducerInterceptorGeneratesError interceptor error")));
|
||||
|
||||
HttpInput.Content content1 = contentProducer.nextContent();
|
||||
assertThat(content1.isSpecial(), Matchers.is(true));
|
||||
assertThat(content1.getError().getMessage(), Matchers.is("testBlockingContentProducerInterceptorGeneratesError interceptor error"));
|
||||
|
||||
HttpInput.Content content2 = contentProducer.nextContent();
|
||||
assertThat(content2.isSpecial(), Matchers.is(true));
|
||||
assertThat(content2.getError().getMessage(), Matchers.is("testBlockingContentProducerInterceptorGeneratesError interceptor error"));
|
||||
}
|
||||
assertThat(contentSucceededCount.get(), Matchers.is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingContentProducerInterceptorGeneratesEof()
|
||||
{
|
||||
AtomicInteger contentSucceededCount = new AtomicInteger();
|
||||
ContentProducer contentProducer = new BlockingContentProducer(new AsyncContentProducer(new StaticContentHttpChannel(new HttpInput.Content(ByteBuffer.allocate(1))
|
||||
{
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
contentSucceededCount.incrementAndGet();
|
||||
}
|
||||
})));
|
||||
try (AutoLock lock = contentProducer.lock())
|
||||
{
|
||||
contentProducer.setInterceptor(content -> new HttpInput.EofContent());
|
||||
|
||||
HttpInput.Content content1 = contentProducer.nextContent();
|
||||
assertThat(content1.isSpecial(), Matchers.is(true));
|
||||
assertThat(content1.isEof(), Matchers.is(true));
|
||||
|
||||
HttpInput.Content content2 = contentProducer.nextContent();
|
||||
assertThat(content2.isSpecial(), Matchers.is(true));
|
||||
assertThat(content2.isEof(), Matchers.is(true));
|
||||
}
|
||||
assertThat(contentSucceededCount.get(), Matchers.is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingContentProducerInterceptorThrows()
|
||||
{
|
||||
AtomicInteger contentFailedCount = new AtomicInteger();
|
||||
ContentProducer contentProducer = new BlockingContentProducer(new AsyncContentProducer(new StaticContentHttpChannel(new HttpInput.Content(ByteBuffer.allocate(1))
|
||||
{
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
contentFailedCount.incrementAndGet();
|
||||
}
|
||||
})));
|
||||
try (AutoLock lock = contentProducer.lock())
|
||||
{
|
||||
contentProducer.setInterceptor(content ->
|
||||
{
|
||||
throw new RuntimeException("testBlockingContentProducerInterceptorThrows error");
|
||||
});
|
||||
|
||||
HttpInput.Content content1 = contentProducer.nextContent();
|
||||
assertThat(content1.isSpecial(), Matchers.is(true));
|
||||
assertThat(content1.getError().getCause().getMessage(), Matchers.is("testBlockingContentProducerInterceptorThrows error"));
|
||||
|
||||
HttpInput.Content content2 = contentProducer.nextContent();
|
||||
assertThat(content2.isSpecial(), Matchers.is(true));
|
||||
assertThat(content1.getError().getCause().getMessage(), Matchers.is("testBlockingContentProducerInterceptorThrows error"));
|
||||
}
|
||||
assertThat(contentFailedCount.get(), Matchers.is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingContentProducerEofContentIsPassedToInterceptor() throws Exception
|
||||
{
|
||||
|
@ -371,6 +456,47 @@ public class BlockingContentProducerTest
|
|||
}
|
||||
}
|
||||
|
||||
private static class StaticContentHttpChannel extends HttpChannel
|
||||
{
|
||||
private final HttpInput.Content content;
|
||||
|
||||
public StaticContentHttpChannel(HttpInput.Content content)
|
||||
{
|
||||
super(new MockConnector(), new HttpConfiguration(), null, null);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needContent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpInput.Content produceContent()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean failAllContent(Throwable failure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean failed(Throwable failure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean eof()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrayDelayedHttpChannel extends HttpChannel
|
||||
{
|
||||
private final ByteBuffer[] byteBuffers;
|
||||
|
|
Loading…
Reference in New Issue