Fixing isDone in SimpleChannelPromiseAggregator
Motivation: The isDone method is currently broken in the aggregator because the doneAllocatingPromises accidentally calls the overridden version of setSuccess, rather than calling the base class version. This causes the base class's version to never be called since allowNotificationEvent will evaluate to false. This means that setSuccess0 will never be set, resulting in isDone always returning false. Modifications: Changed setSuccess() to call the base class when appropriate, regardless of the result of allowNotificationEvent. Result: isDone now behaves properly for the promise aggregator.
This commit is contained in:
parent
a3cea186ce
commit
60a94f0c5f
@ -225,7 +225,7 @@ public final class Http2CodecUtil {
|
|||||||
doneAllocating = true;
|
doneAllocating = true;
|
||||||
if (successfulCount == expectedCount) {
|
if (successfulCount == expectedCount) {
|
||||||
promise.setSuccess();
|
promise.setSuccess();
|
||||||
return super.setSuccess();
|
return super.setSuccess(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@ -233,7 +233,7 @@ public final class Http2CodecUtil {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryFailure(Throwable cause) {
|
public boolean tryFailure(Throwable cause) {
|
||||||
if (allowNotificationEvent()) {
|
if (awaitingPromises()) {
|
||||||
++failureCount;
|
++failureCount;
|
||||||
if (failureCount == 1) {
|
if (failureCount == 1) {
|
||||||
promise.tryFailure(cause);
|
promise.tryFailure(cause);
|
||||||
@ -254,7 +254,7 @@ public final class Http2CodecUtil {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ChannelPromise setFailure(Throwable cause) {
|
public ChannelPromise setFailure(Throwable cause) {
|
||||||
if (allowNotificationEvent()) {
|
if (awaitingPromises()) {
|
||||||
++failureCount;
|
++failureCount;
|
||||||
if (failureCount == 1) {
|
if (failureCount == 1) {
|
||||||
promise.setFailure(cause);
|
promise.setFailure(cause);
|
||||||
@ -264,13 +264,13 @@ public final class Http2CodecUtil {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean allowNotificationEvent() {
|
private boolean awaitingPromises() {
|
||||||
return successfulCount + failureCount < expectedCount;
|
return successfulCount + failureCount < expectedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelPromise setSuccess(Void result) {
|
public ChannelPromise setSuccess(Void result) {
|
||||||
if (allowNotificationEvent()) {
|
if (awaitingPromises()) {
|
||||||
++successfulCount;
|
++successfulCount;
|
||||||
if (successfulCount == expectedCount && doneAllocating) {
|
if (successfulCount == expectedCount && doneAllocating) {
|
||||||
promise.setSuccess(result);
|
promise.setSuccess(result);
|
||||||
@ -282,7 +282,7 @@ public final class Http2CodecUtil {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trySuccess(Void result) {
|
public boolean trySuccess(Void result) {
|
||||||
if (allowNotificationEvent()) {
|
if (awaitingPromises()) {
|
||||||
++successfulCount;
|
++successfulCount;
|
||||||
if (successfulCount == expectedCount && doneAllocating) {
|
if (successfulCount == expectedCount && doneAllocating) {
|
||||||
promise.trySuccess(result);
|
promise.trySuccess(result);
|
||||||
|
@ -18,27 +18,24 @@ package io.netty.handler.codec.http2;
|
|||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_UNSIGNED_INT;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_UNSIGNED_INT;
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.as;
|
import static io.netty.handler.codec.http2.Http2TestUtil.as;
|
||||||
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.DefaultChannelPromise;
|
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
|
import org.junit.After;
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@ -54,8 +51,8 @@ public class DefaultHttp2FrameIOTest {
|
|||||||
private DefaultHttp2FrameReader reader;
|
private DefaultHttp2FrameReader reader;
|
||||||
private DefaultHttp2FrameWriter writer;
|
private DefaultHttp2FrameWriter writer;
|
||||||
private ByteBufAllocator alloc;
|
private ByteBufAllocator alloc;
|
||||||
private CountDownLatch latch;
|
|
||||||
private ByteBuf buffer;
|
private ByteBuf buffer;
|
||||||
|
private ByteBuf data;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ChannelHandlerContext ctx;
|
private ChannelHandlerContext ctx;
|
||||||
@ -66,6 +63,9 @@ public class DefaultHttp2FrameIOTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private ChannelPromise promise;
|
private ChannelPromise promise;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ChannelPromise aggregatePromise;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Channel channel;
|
private Channel channel;
|
||||||
|
|
||||||
@ -78,26 +78,23 @@ public class DefaultHttp2FrameIOTest {
|
|||||||
|
|
||||||
alloc = UnpooledByteBufAllocator.DEFAULT;
|
alloc = UnpooledByteBufAllocator.DEFAULT;
|
||||||
buffer = alloc.buffer();
|
buffer = alloc.buffer();
|
||||||
latch = new CountDownLatch(1);
|
data = dummyData();
|
||||||
|
|
||||||
when(executor.inEventLoop()).thenReturn(true);
|
when(executor.inEventLoop()).thenReturn(true);
|
||||||
when(ctx.alloc()).thenReturn(alloc);
|
when(ctx.alloc()).thenReturn(alloc);
|
||||||
when(ctx.channel()).thenReturn(channel);
|
when(ctx.channel()).thenReturn(channel);
|
||||||
when(ctx.executor()).thenReturn(executor);
|
when(ctx.executor()).thenReturn(executor);
|
||||||
doAnswer(new Answer<ChannelPromise>() {
|
when(ctx.newPromise()).thenReturn(promise);
|
||||||
|
when(promise.isDone()).thenReturn(true);
|
||||||
|
when(promise.isSuccess()).thenReturn(true);
|
||||||
|
doAnswer(new Answer<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public ChannelPromise answer(InvocationOnMock invocation) throws Throwable {
|
public Void answer(InvocationOnMock in) throws Throwable {
|
||||||
return new DefaultChannelPromise(channel, executor);
|
ChannelFutureListener l = (ChannelFutureListener) in.getArguments()[0];
|
||||||
|
l.operationComplete(promise);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}).when(ctx).newPromise();
|
}).when(promise).addListener(any(ChannelFutureListener.class));
|
||||||
|
|
||||||
doAnswer(new Answer<ChannelPromise>() {
|
|
||||||
@Override
|
|
||||||
public ChannelPromise answer(InvocationOnMock in) throws Throwable {
|
|
||||||
latch.countDown();
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
}).when(promise).setSuccess();
|
|
||||||
|
|
||||||
doAnswer(new Answer<ChannelFuture>() {
|
doAnswer(new Answer<ChannelFuture>() {
|
||||||
@Override
|
@Override
|
||||||
@ -121,97 +118,53 @@ public class DefaultHttp2FrameIOTest {
|
|||||||
writer = new DefaultHttp2FrameWriter();
|
writer = new DefaultHttp2FrameWriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
buffer.release();
|
||||||
|
data.release();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptyDataShouldRoundtrip() throws Exception {
|
public void emptyDataShouldRoundtrip() throws Exception {
|
||||||
final ByteBuf data = Unpooled.EMPTY_BUFFER;
|
final ByteBuf data = Unpooled.EMPTY_BUFFER;
|
||||||
writer.writeData(ctx, 1000, data, 0, false, promise);
|
writer.writeData(ctx, 1000, data, 0, false, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = null;
|
|
||||||
try {
|
|
||||||
frame = captureWrite();
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onDataRead(eq(ctx), eq(1000), eq(data), eq(0), eq(false));
|
verify(listener).onDataRead(eq(ctx), eq(1000), eq(data), eq(0), eq(false));
|
||||||
} finally {
|
|
||||||
if (frame != null) {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
data.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dataShouldRoundtrip() throws Exception {
|
public void dataShouldRoundtrip() throws Exception {
|
||||||
final ByteBuf data = dummyData();
|
|
||||||
writer.writeData(ctx, 1000, data.retain().duplicate(), 0, false, promise);
|
writer.writeData(ctx, 1000, data.retain().duplicate(), 0, false, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = null;
|
|
||||||
try {
|
|
||||||
frame = captureWrite();
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onDataRead(eq(ctx), eq(1000), eq(data), eq(0), eq(false));
|
verify(listener).onDataRead(eq(ctx), eq(1000), eq(data), eq(0), eq(false));
|
||||||
} finally {
|
|
||||||
if (frame != null) {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
data.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dataWithPaddingShouldRoundtrip() throws Exception {
|
public void dataWithPaddingShouldRoundtrip() throws Exception {
|
||||||
final ByteBuf data = dummyData();
|
|
||||||
writer.writeData(ctx, 1, data.retain().duplicate(), 0xFF, true, promise);
|
writer.writeData(ctx, 1, data.retain().duplicate(), 0xFF, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = null;
|
|
||||||
try {
|
|
||||||
frame = captureWrite();
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onDataRead(eq(ctx), eq(1), eq(data), eq(0xFF), eq(true));
|
verify(listener).onDataRead(eq(ctx), eq(1), eq(data), eq(0xFF), eq(true));
|
||||||
} finally {
|
|
||||||
if (frame != null) {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
data.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void priorityShouldRoundtrip() throws Exception {
|
public void priorityShouldRoundtrip() throws Exception {
|
||||||
writer.writePriority(ctx, 1, 2, (short) 255, true, promise);
|
writer.writePriority(ctx, 1, 2, (short) 255, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPriorityRead(eq(ctx), eq(1), eq(2), eq((short) 255), eq(true));
|
verify(listener).onPriorityRead(eq(ctx), eq(1), eq(2), eq((short) 255), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rstStreamShouldRoundtrip() throws Exception {
|
public void rstStreamShouldRoundtrip() throws Exception {
|
||||||
writer.writeRstStream(ctx, 1, MAX_UNSIGNED_INT, promise);
|
writer.writeRstStream(ctx, 1, MAX_UNSIGNED_INT, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onRstStreamRead(eq(ctx), eq(1), eq(MAX_UNSIGNED_INT));
|
verify(listener).onRstStreamRead(eq(ctx), eq(1), eq(MAX_UNSIGNED_INT));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptySettingsShouldRoundtrip() throws Exception {
|
public void emptySettingsShouldRoundtrip() throws Exception {
|
||||||
writer.writeSettings(ctx, new Http2Settings(), promise);
|
writer.writeSettings(ctx, new Http2Settings(), promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onSettingsRead(eq(ctx), eq(new Http2Settings()));
|
verify(listener).onSettingsRead(eq(ctx), eq(new Http2Settings()));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -223,294 +176,159 @@ public class DefaultHttp2FrameIOTest {
|
|||||||
settings.maxConcurrentStreams(456);
|
settings.maxConcurrentStreams(456);
|
||||||
|
|
||||||
writer.writeSettings(ctx, settings, promise);
|
writer.writeSettings(ctx, settings, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onSettingsRead(eq(ctx), eq(settings));
|
verify(listener).onSettingsRead(eq(ctx), eq(settings));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void settingsAckShouldRoundtrip() throws Exception {
|
public void settingsAckShouldRoundtrip() throws Exception {
|
||||||
writer.writeSettingsAck(ctx, promise);
|
writer.writeSettingsAck(ctx, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onSettingsAckRead(eq(ctx));
|
verify(listener).onSettingsAckRead(eq(ctx));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pingShouldRoundtrip() throws Exception {
|
public void pingShouldRoundtrip() throws Exception {
|
||||||
ByteBuf data = dummyData();
|
|
||||||
writer.writePing(ctx, false, data.retain().duplicate(), promise);
|
writer.writePing(ctx, false, data.retain().duplicate(), promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = null;
|
|
||||||
try {
|
|
||||||
frame = captureWrite();
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPingRead(eq(ctx), eq(data));
|
verify(listener).onPingRead(eq(ctx), eq(data));
|
||||||
} finally {
|
|
||||||
if (frame != null) {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
data.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pingAckShouldRoundtrip() throws Exception {
|
public void pingAckShouldRoundtrip() throws Exception {
|
||||||
ByteBuf data = dummyData();
|
|
||||||
writer.writePing(ctx, true, data.retain().duplicate(), promise);
|
writer.writePing(ctx, true, data.retain().duplicate(), promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = null;
|
|
||||||
try {
|
|
||||||
frame = captureWrite();
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPingAckRead(eq(ctx), eq(data));
|
verify(listener).onPingAckRead(eq(ctx), eq(data));
|
||||||
} finally {
|
|
||||||
if (frame != null) {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
data.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void goAwayShouldRoundtrip() throws Exception {
|
public void goAwayShouldRoundtrip() throws Exception {
|
||||||
ByteBuf data = dummyData();
|
|
||||||
writer.writeGoAway(ctx, 1, MAX_UNSIGNED_INT, data.retain().duplicate(), promise);
|
writer.writeGoAway(ctx, 1, MAX_UNSIGNED_INT, data.retain().duplicate(), promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = null;
|
|
||||||
try {
|
|
||||||
frame = captureWrite();
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onGoAwayRead(eq(ctx), eq(1), eq(MAX_UNSIGNED_INT), eq(data));
|
verify(listener).onGoAwayRead(eq(ctx), eq(1), eq(MAX_UNSIGNED_INT), eq(data));
|
||||||
} finally {
|
|
||||||
if (frame != null) {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
data.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void windowUpdateShouldRoundtrip() throws Exception {
|
public void windowUpdateShouldRoundtrip() throws Exception {
|
||||||
writer.writeWindowUpdate(ctx, 1, Integer.MAX_VALUE, promise);
|
writer.writeWindowUpdate(ctx, 1, Integer.MAX_VALUE, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onWindowUpdateRead(eq(ctx), eq(1), eq(Integer.MAX_VALUE));
|
verify(listener).onWindowUpdateRead(eq(ctx), eq(1), eq(Integer.MAX_VALUE));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptyHeadersShouldRoundtrip() throws Exception {
|
public void emptyHeadersShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = EmptyHttp2Headers.INSTANCE;
|
Http2Headers headers = EmptyHttp2Headers.INSTANCE;
|
||||||
writer.writeHeaders(ctx, 1, headers, 0, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 0, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0), eq(true));
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptyHeadersWithPaddingShouldRoundtrip() throws Exception {
|
public void emptyHeadersWithPaddingShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = EmptyHttp2Headers.INSTANCE;
|
Http2Headers headers = EmptyHttp2Headers.INSTANCE;
|
||||||
writer.writeHeaders(ctx, 1, headers, 0xFF, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 0xFF, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0xFF), eq(true));
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0xFF), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void binaryHeadersWithoutPriorityShouldRoundtrip() throws Exception {
|
public void binaryHeadersWithoutPriorityShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyBinaryHeaders();
|
Http2Headers headers = dummyBinaryHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 0, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 0, true, promise);
|
||||||
ByteBuf frame = captureWrite();
|
reader.readFrame(ctx, buffer, listener);
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0), eq(true));
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headersWithoutPriorityShouldRoundtrip() throws Exception {
|
public void headersWithoutPriorityShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyHeaders();
|
Http2Headers headers = dummyHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 0, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 0, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0), eq(true));
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headersWithPaddingWithoutPriorityShouldRoundtrip() throws Exception {
|
public void headersWithPaddingWithoutPriorityShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyHeaders();
|
Http2Headers headers = dummyHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 0xFF, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 0xFF, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0xFF), eq(true));
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(0xFF), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headersWithPriorityShouldRoundtrip() throws Exception {
|
public void headersWithPriorityShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyHeaders();
|
Http2Headers headers = dummyHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0), eq(true));
|
.onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void headersWithPaddingWithPriorityShouldRoundtrip() throws Exception {
|
public void headersWithPaddingWithPriorityShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyHeaders();
|
Http2Headers headers = dummyHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0xFF, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0xFF, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0xFF),
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0xFF),
|
||||||
eq(true));
|
eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void continuedHeadersShouldRoundtrip() throws Exception {
|
public void continuedHeadersShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = largeHeaders();
|
Http2Headers headers = largeHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0), eq(true));
|
.onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0), eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void continuedHeadersWithPaddingShouldRoundtrip() throws Exception {
|
public void continuedHeadersWithPaddingShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = largeHeaders();
|
Http2Headers headers = largeHeaders();
|
||||||
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0xFF, true, promise);
|
writer.writeHeaders(ctx, 1, headers, 2, (short) 3, true, 0xFF, true, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0xFF),
|
verify(listener).onHeadersRead(eq(ctx), eq(1), eq(headers), eq(2), eq((short) 3), eq(true), eq(0xFF),
|
||||||
eq(true));
|
eq(true));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptypushPromiseShouldRoundtrip() throws Exception {
|
public void emptypushPromiseShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = EmptyHttp2Headers.INSTANCE;
|
Http2Headers headers = EmptyHttp2Headers.INSTANCE;
|
||||||
writer.writePushPromise(ctx, 1, 2, headers, 0, promise);
|
writer.writePushPromise(ctx, 1, 2, headers, 0, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0));
|
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pushPromiseShouldRoundtrip() throws Exception {
|
public void pushPromiseShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyHeaders();
|
Http2Headers headers = dummyHeaders();
|
||||||
writer.writePushPromise(ctx, 1, 2, headers, 0, promise);
|
writer.writePushPromise(ctx, 1, 2, headers, 0, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0));
|
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pushPromiseWithPaddingShouldRoundtrip() throws Exception {
|
public void pushPromiseWithPaddingShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = dummyHeaders();
|
Http2Headers headers = dummyHeaders();
|
||||||
writer.writePushPromise(ctx, 1, 2, headers, 0xFF, promise);
|
writer.writePushPromise(ctx, 1, 2, headers, 0xFF, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0xFF));
|
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0xFF));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void continuedPushPromiseShouldRoundtrip() throws Exception {
|
public void continuedPushPromiseShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = largeHeaders();
|
Http2Headers headers = largeHeaders();
|
||||||
writer.writePushPromise(ctx, 1, 2, headers, 0, promise);
|
writer.writePushPromise(ctx, 1, 2, headers, 0, promise);
|
||||||
ByteBuf frame = captureWrite();
|
reader.readFrame(ctx, buffer, listener);
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0));
|
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0));
|
||||||
frame.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void continuedPushPromiseWithPaddingShouldRoundtrip() throws Exception {
|
public void continuedPushPromiseWithPaddingShouldRoundtrip() throws Exception {
|
||||||
Http2Headers headers = largeHeaders();
|
Http2Headers headers = largeHeaders();
|
||||||
writer.writePushPromise(ctx, 1, 2, headers, 0xFF, promise);
|
writer.writePushPromise(ctx, 1, 2, headers, 0xFF, promise);
|
||||||
|
reader.readFrame(ctx, buffer, listener);
|
||||||
ByteBuf frame = captureWrite();
|
|
||||||
try {
|
|
||||||
reader.readFrame(ctx, frame, listener);
|
|
||||||
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0xFF));
|
verify(listener).onPushPromiseRead(eq(ctx), eq(1), eq(2), eq(headers), eq(0xFF));
|
||||||
} finally {
|
|
||||||
frame.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ByteBuf captureWrite() throws InterruptedException {
|
|
||||||
assertTrue(latch.await(2, TimeUnit.SECONDS));
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBuf dummyData() {
|
private ByteBuf dummyData() {
|
||||||
|
Loading…
Reference in New Issue
Block a user