Migrate codec-http2 to junit5 (#11422)

Motivation:

We should update to use junit5 in all modules.

Modifications:

Adjust codec-http2 tests to use junit5

Result:

Part of https://github.com/netty/netty/issues/10757
This commit is contained in:
Norman Maurer 2021-06-30 10:32:01 +02:00 committed by GitHub
parent d8ad931488
commit 8c73dbe9bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1448 additions and 876 deletions

View File

@ -36,17 +36,17 @@ import io.netty.handler.codec.http2.CleartextHttp2ServerUpgradeHandler.PriorKnow
import io.netty.handler.codec.http2.Http2Stream.State; import io.netty.handler.codec.http2.Http2Stream.State;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -92,7 +92,7 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
}); });
} }
@After @AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
channel.finishAndReleaseAll(); channel.finishAndReleaseAll();
} }

View File

@ -35,9 +35,9 @@ import io.netty.util.AsciiString;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil; import io.netty.util.NetUtil;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -53,8 +53,8 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel; import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -88,7 +88,7 @@ public class DataCompressionHttp2Test {
private Http2ConnectionHandler clientHandler; private Http2ConnectionHandler clientHandler;
private ByteArrayOutputStream serverOut; private ByteArrayOutputStream serverOut;
@Before @BeforeEach
public void setup() throws InterruptedException, Http2Exception { public void setup() throws InterruptedException, Http2Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
doAnswer(new Answer<Void>() { doAnswer(new Answer<Void>() {
@ -113,12 +113,12 @@ public class DataCompressionHttp2Test {
anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean()); anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
} }
@After @AfterEach
public void cleanup() throws IOException { public void cleanup() throws IOException {
serverOut.close(); serverOut.close();
} }
@After @AfterEach
public void teardown() throws InterruptedException { public void teardown() throws InterruptedException {
if (clientChannel != null) { if (clientChannel != null) {
clientChannel.close().sync(); clientChannel.close().sync();

View File

@ -14,21 +14,30 @@
*/ */
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class DecoratingHttp2ConnectionEncoderTest { public class DecoratingHttp2ConnectionEncoderTest {
@Test(expected = IllegalStateException.class) @Test
public void testConsumeReceivedSettingsThrows() { public void testConsumeReceivedSettingsThrows() {
Http2ConnectionEncoder encoder = mock(Http2ConnectionEncoder.class); Http2ConnectionEncoder encoder = mock(Http2ConnectionEncoder.class);
DecoratingHttp2ConnectionEncoder decoratingHttp2ConnectionEncoder = final DecoratingHttp2ConnectionEncoder decoratingHttp2ConnectionEncoder =
new DecoratingHttp2ConnectionEncoder(encoder); new DecoratingHttp2ConnectionEncoder(encoder);
assertThrows(IllegalStateException.class, new Executable() {
@Override
public void execute() {
decoratingHttp2ConnectionEncoder.consumeReceivedSettings(Http2Settings.defaultSettings()); decoratingHttp2ConnectionEncoder.consumeReceivedSettings(Http2Settings.defaultSettings());
} }
});
}
@Test @Test
public void testConsumeReceivedSettingsDelegate() { public void testConsumeReceivedSettingsDelegate() {

View File

@ -24,8 +24,9 @@ import io.netty.channel.DefaultChannelPromise;
import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpResponseStatus;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import org.mockito.Mock; import org.mockito.Mock;
@ -51,9 +52,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -127,7 +128,7 @@ public class DefaultHttp2ConnectionDecoderTest {
@Mock @Mock
private Http2LifecycleManager lifecycleManager; private Http2LifecycleManager lifecycleManager;
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -273,16 +274,19 @@ public class DefaultHttp2ConnectionDecoderTest {
} }
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void dataReadForUnknownStreamShouldApplyFlowControlAndFail() throws Exception { public void dataReadForUnknownStreamShouldApplyFlowControlAndFail() throws Exception {
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(true); when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(true);
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
final ByteBuf data = dummyData(); final ByteBuf data = dummyData();
int padding = 10; final int padding = 10;
int processedBytes = data.readableBytes() + padding; int processedBytes = data.readableBytes() + padding;
try { assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onDataRead(ctx, STREAM_ID, data, padding, true); decode().onDataRead(ctx, STREAM_ID, data, padding, true);
} finally { }
});
try { try {
verify(localFlow) verify(localFlow)
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true)); .receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
@ -294,21 +298,25 @@ public class DefaultHttp2ConnectionDecoderTest {
data.release(); data.release();
} }
} }
}
@Test(expected = Http2Exception.class) @Test
public void dataReadForUnknownStreamThatCouldntExistFail() throws Exception { public void dataReadForUnknownStreamThatCouldntExistFail() throws Exception {
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false); when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
final ByteBuf data = dummyData(); final ByteBuf data = dummyData();
int padding = 10; final int padding = 10;
int processedBytes = data.readableBytes() + padding; int processedBytes = data.readableBytes() + padding;
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
try { try {
decode().onDataRead(ctx, STREAM_ID, data, padding, true); decode().onDataRead(ctx, STREAM_ID, data, padding, true);
} catch (Http2Exception ex) { } catch (Http2Exception ex) {
assertThat(ex, not(instanceOf(Http2Exception.StreamException.class))); assertThat(ex, not(instanceOf(Http2Exception.StreamException.class)));
throw ex; throw ex;
} finally { }
}
});
try { try {
verify(localFlow) verify(localFlow)
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true)); .receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
@ -320,19 +328,20 @@ public class DefaultHttp2ConnectionDecoderTest {
data.release(); data.release();
} }
} }
}
@Test @Test
public void dataReadForUnknownStreamShouldApplyFlowControl() throws Exception { public void dataReadForUnknownStreamShouldApplyFlowControl() throws Exception {
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
final ByteBuf data = dummyData(); final ByteBuf data = dummyData();
int padding = 10; final int padding = 10;
int processedBytes = data.readableBytes() + padding; int processedBytes = data.readableBytes() + padding;
try { try {
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onDataRead(ctx, STREAM_ID, data, padding, true); decode().onDataRead(ctx, STREAM_ID, data, padding, true);
fail(); }
} catch (Http2Exception e) { });
verify(localFlow) verify(localFlow)
.receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true)); .receiveFlowControlledFrame(eq((Http2Stream) null), eq(data), eq(padding), eq(true));
verify(localFlow).consumeBytes(eq((Http2Stream) null), eq(processedBytes)); verify(localFlow).consumeBytes(eq((Http2Stream) null), eq(processedBytes));
@ -341,7 +350,6 @@ public class DefaultHttp2ConnectionDecoderTest {
// Verify that the event was absorbed and not propagated to the observer. // Verify that the event was absorbed and not propagated to the observer.
verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean()); verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
}
} finally { } finally {
data.release(); data.release();
} }
@ -366,16 +374,18 @@ public class DefaultHttp2ConnectionDecoderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void dataReadForStreamInInvalidStateShouldThrow() throws Exception { public void dataReadForStreamInInvalidStateShouldThrow() throws Exception {
// Throw an exception when checking stream state. // Throw an exception when checking stream state.
when(stream.state()).thenReturn(Http2Stream.State.CLOSED); when(stream.state()).thenReturn(Http2Stream.State.CLOSED);
final ByteBuf data = dummyData(); final ByteBuf data = dummyData();
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onDataRead(ctx, STREAM_ID, data, 10, true); decode().onDataRead(ctx, STREAM_ID, data, 10, true);
} finally {
data.release();
} }
});
data.release();
} }
@Test @Test
@ -467,9 +477,12 @@ public class DefaultHttp2ConnectionDecoderTest {
} }
}).when(listener).onDataRead(eq(ctx), eq(STREAM_ID), any(ByteBuf.class), eq(10), eq(true)); }).when(listener).onDataRead(eq(ctx), eq(STREAM_ID), any(ByteBuf.class), eq(10), eq(true));
try { try {
assertThrows(RuntimeException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onDataRead(ctx, STREAM_ID, data, padding, true); decode().onDataRead(ctx, STREAM_ID, data, padding, true);
fail("Expected exception"); }
} catch (RuntimeException cause) { });
verify(localFlow) verify(localFlow)
.receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true)); .receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true));
verify(listener).onDataRead(eq(ctx), eq(STREAM_ID), eq(data), eq(padding), eq(true)); verify(listener).onDataRead(eq(ctx), eq(STREAM_ID), eq(data), eq(padding), eq(true));
@ -479,11 +492,15 @@ public class DefaultHttp2ConnectionDecoderTest {
} }
} }
@Test(expected = Http2Exception.class)
public void headersReadForUnknownStreamShouldThrow() throws Exception { public void headersReadForUnknownStreamShouldThrow() throws Exception {
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
} }
});
}
@Test @Test
public void headersReadForStreamThatAlreadySentResetShouldBeIgnored() throws Exception { public void headersReadForStreamThatAlreadySentResetShouldBeIgnored() throws Exception {
@ -541,29 +558,39 @@ public class DefaultHttp2ConnectionDecoderTest {
eq(DEFAULT_PRIORITY_WEIGHT), eq(false), eq(0), eq(false)); eq(DEFAULT_PRIORITY_WEIGHT), eq(false), eq(0), eq(false));
} }
@Test(expected = Http2Exception.class) @Test
public void trailersDoNotEndStreamThrows() throws Exception { public void trailersDoNotEndStreamThrows() throws Exception {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
// Trailers must end the stream! // Trailers must end the stream!
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void tooManyHeadersEOSThrows() throws Exception { public void tooManyHeadersEOSThrows() throws Exception {
tooManyHeaderThrows(true); tooManyHeaderThrows(true);
} }
@Test(expected = Http2Exception.class) @Test
public void tooManyHeadersNoEOSThrows() throws Exception { public void tooManyHeadersNoEOSThrows() throws Exception {
tooManyHeaderThrows(false); tooManyHeaderThrows(false);
} }
private void tooManyHeaderThrows(boolean eos) throws Exception { private void tooManyHeaderThrows(final boolean eos) throws Exception {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, true); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, true);
// We already received the trailers! // We already received the trailers!
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
} }
});
}
private static Http2Headers informationalHeaders() { private static Http2Headers informationalHeaders() {
Http2Headers headers = new DefaultHttp2Headers(); Http2Headers headers = new DefaultHttp2Headers();
@ -581,22 +608,32 @@ public class DefaultHttp2ConnectionDecoderTest {
infoHeadersAndTrailersAllowed(true, 10); infoHeadersAndTrailersAllowed(true, 10);
} }
@Test(expected = Http2Exception.class) @Test
public void infoHeadersAndTrailersNoEOSThrows() throws Exception { public void infoHeadersAndTrailersNoEOSThrows() throws Exception {
infoHeadersAndTrailersAllowed(false, 1); infoHeadersAndTrailersAllowed(false, 1);
} }
@Test(expected = Http2Exception.class) @Test
public void multipleInfoHeadersAndTrailersNoEOSThrows() throws Exception { public void multipleInfoHeadersAndTrailersNoEOSThrows() throws Exception {
infoHeadersAndTrailersAllowed(false, 10); infoHeadersAndTrailersAllowed(false, 10);
} }
private void infoHeadersAndTrailersAllowed(boolean eos, int infoHeaderCount) throws Exception { private void infoHeadersAndTrailersAllowed(final boolean eos, int infoHeaderCount)
throws Exception {
for (int i = 0; i < infoHeaderCount; ++i) { for (int i = 0; i < infoHeaderCount; ++i) {
decode().onHeadersRead(ctx, STREAM_ID, informationalHeaders(), 0, false); decode().onHeadersRead(ctx, STREAM_ID, informationalHeaders(), 0, false);
} }
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, false);
if (eos) {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos); decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
} else {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, EmptyHttp2Headers.INSTANCE, 0, eos);
}
});
}
} }
@Test() @Test()
@ -636,11 +673,16 @@ public class DefaultHttp2ConnectionDecoderTest {
verify(listener).onPushPromiseRead(eq(ctx), anyInt(), anyInt(), any(Http2Headers.class), anyInt()); verify(listener).onPushPromiseRead(eq(ctx), anyInt(), anyInt(), any(Http2Headers.class), anyInt());
} }
@Test(expected = Http2Exception.class) @Test
public void pushPromiseReadForUnknownStreamShouldThrow() throws Exception { public void pushPromiseReadForUnknownStreamShouldThrow() throws Exception {
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onPushPromiseRead(ctx, STREAM_ID, PUSH_STREAM_ID, EmptyHttp2Headers.INSTANCE, 0); decode().onPushPromiseRead(ctx, STREAM_ID, PUSH_STREAM_ID, EmptyHttp2Headers.INSTANCE, 0);
} }
});
}
@Test @Test
public void pushPromiseReadShouldSucceed() throws Exception { public void pushPromiseReadShouldSucceed() throws Exception {
@ -693,12 +735,17 @@ public class DefaultHttp2ConnectionDecoderTest {
verify(listener).onWindowUpdateRead(eq(ctx), anyInt(), anyInt()); verify(listener).onWindowUpdateRead(eq(ctx), anyInt(), anyInt());
} }
@Test(expected = Http2Exception.class) @Test
public void windowUpdateReadForUnknownStreamShouldThrow() throws Exception { public void windowUpdateReadForUnknownStreamShouldThrow() throws Exception {
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false); when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onWindowUpdateRead(ctx, STREAM_ID, 10); decode().onWindowUpdateRead(ctx, STREAM_ID, 10);
} }
});
}
@Test @Test
public void windowUpdateReadForUnknownStreamShouldBeIgnored() throws Exception { public void windowUpdateReadForUnknownStreamShouldBeIgnored() throws Exception {
@ -723,12 +770,17 @@ public class DefaultHttp2ConnectionDecoderTest {
verify(listener).onRstStreamRead(eq(ctx), anyInt(), anyLong()); verify(listener).onRstStreamRead(eq(ctx), anyInt(), anyLong());
} }
@Test(expected = Http2Exception.class) @Test
public void rstStreamReadForUnknownStreamShouldThrow() throws Exception { public void rstStreamReadForUnknownStreamShouldThrow() throws Exception {
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false); when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);
when(connection.stream(STREAM_ID)).thenReturn(null); when(connection.stream(STREAM_ID)).thenReturn(null);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code()); decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
} }
});
}
@Test @Test
public void rstStreamReadForUnknownStreamShouldBeIgnored() throws Exception { public void rstStreamReadForUnknownStreamShouldBeIgnored() throws Exception {
@ -745,11 +797,15 @@ public class DefaultHttp2ConnectionDecoderTest {
verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code())); verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()));
} }
@Test(expected = Http2Exception.class) @Test
public void rstStreamOnIdleStreamShouldThrow() throws Exception { public void rstStreamOnIdleStreamShouldThrow() throws Exception {
when(stream.state()).thenReturn(IDLE); when(stream.state()).thenReturn(IDLE);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code()); decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
verify(lifecycleManager).closeStream(eq(stream), eq(future)); }
});
verify(listener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong()); verify(listener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
} }
@ -792,31 +848,46 @@ public class DefaultHttp2ConnectionDecoderTest {
verify(listener).onGoAwayRead(eq(ctx), eq(1), eq(2L), eq(EMPTY_BUFFER)); verify(listener).onGoAwayRead(eq(ctx), eq(1), eq(2L), eq(EMPTY_BUFFER));
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void dataContentLengthMissmatch() throws Exception { public void dataContentLengthMissmatch() throws Exception {
dataContentLengthInvalid(false); dataContentLengthInvalid(false);
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void dataContentLengthInvalid() throws Exception { public void dataContentLengthInvalid() throws Exception {
dataContentLengthInvalid(true); dataContentLengthInvalid(true);
} }
private void dataContentLengthInvalid(boolean negative) throws Exception { private void dataContentLengthInvalid(boolean negative) throws Exception {
final ByteBuf data = dummyData(); final ByteBuf data = dummyData();
int padding = 10; final int padding = 10;
int processedBytes = data.readableBytes() + padding; int processedBytes = data.readableBytes() + padding;
mockFlowControl(processedBytes); mockFlowControl(processedBytes);
try { try {
if (negative) {
assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers() decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
.setLong(HttpHeaderNames.CONTENT_LENGTH, negative ? -1L : 1L), padding, false); .setLong(HttpHeaderNames.CONTENT_LENGTH, -1L), padding, false);
}
});
} else {
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
.setLong(HttpHeaderNames.CONTENT_LENGTH, 1L), padding, false);
assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onDataRead(ctx, STREAM_ID, data, padding, true); decode().onDataRead(ctx, STREAM_ID, data, padding, true);
}
});
verify(localFlow).receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true)); verify(localFlow).receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true));
verify(localFlow).consumeBytes(eq(stream), eq(processedBytes)); verify(localFlow).consumeBytes(eq(stream), eq(processedBytes));
verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(), verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(),
any(Http2Headers.class), eq(0), eq(DEFAULT_PRIORITY_WEIGHT), eq(false), any(Http2Headers.class), eq(0), eq(DEFAULT_PRIORITY_WEIGHT), eq(false),
eq(padding), eq(false)); eq(padding), eq(false));
}
// Verify that the event was absorbed and not propagated to the observer. // Verify that the event was absorbed and not propagated to the observer.
verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean()); verify(listener, never()).onDataRead(eq(ctx), anyInt(), any(ByteBuf.class), anyInt(), anyBoolean());
} finally { } finally {
@ -824,42 +895,53 @@ public class DefaultHttp2ConnectionDecoderTest {
} }
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void headersContentLengthPositiveSign() throws Exception { public void headersContentLengthPositiveSign() throws Exception {
headersContentLengthSign("+1"); headersContentLengthSign("+1");
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void headersContentLengthNegativeSign() throws Exception { public void headersContentLengthNegativeSign() throws Exception {
headersContentLengthSign("-1"); headersContentLengthSign("-1");
} }
private void headersContentLengthSign(String length) throws Exception { private void headersContentLengthSign(final String length) throws Exception {
int padding = 10; final int padding = 10;
when(connection.isServer()).thenReturn(true); when(connection.isServer()).thenReturn(true);
assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers() decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
.set(HttpHeaderNames.CONTENT_LENGTH, length), padding, false); .set(HttpHeaderNames.CONTENT_LENGTH, length), padding, false);
}
});
// Verify that the event was absorbed and not propagated to the observer. // Verify that the event was absorbed and not propagated to the observer.
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(), verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean()); any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void headersContentLengthMissmatch() throws Exception { public void headersContentLengthMissmatch() throws Exception {
headersContentLength(false); headersContentLength(false);
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void headersContentLengthInvalid() throws Exception { public void headersContentLengthInvalid() throws Exception {
headersContentLength(true); headersContentLength(true);
} }
private void headersContentLength(boolean negative) throws Exception { private void headersContentLength(final boolean negative) throws Exception {
int padding = 10; final int padding = 10;
when(connection.isServer()).thenReturn(true); when(connection.isServer()).thenReturn(true);
assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers() decode().onHeadersRead(ctx, STREAM_ID, new DefaultHttp2Headers()
.setLong(HttpHeaderNames.CONTENT_LENGTH, negative ? -1L : 1L), padding, true); .setLong(HttpHeaderNames.CONTENT_LENGTH, negative ? -1L : 1L), padding, true);
}
});
// Verify that the event was absorbed and not propagated to the observer. // Verify that the event was absorbed and not propagated to the observer.
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(), verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
@ -871,15 +953,15 @@ public class DefaultHttp2ConnectionDecoderTest {
multipleHeadersContentLength(true); multipleHeadersContentLength(true);
} }
@Test(expected = Http2Exception.StreamException.class) @Test
public void multipleHeadersContentLengthDifferent() throws Exception { public void multipleHeadersContentLengthDifferent() throws Exception {
multipleHeadersContentLength(false); multipleHeadersContentLength(false);
} }
private void multipleHeadersContentLength(boolean same) throws Exception { private void multipleHeadersContentLength(boolean same) throws Exception {
int padding = 10; final int padding = 10;
when(connection.isServer()).thenReturn(true); when(connection.isServer()).thenReturn(true);
Http2Headers headers = new DefaultHttp2Headers(); final Http2Headers headers = new DefaultHttp2Headers();
if (same) { if (same) {
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0); headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0); headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
@ -888,13 +970,19 @@ public class DefaultHttp2ConnectionDecoderTest {
headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 1); headers.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
} }
decode().onHeadersRead(ctx, STREAM_ID, headers, padding, true);
if (same) { if (same) {
decode().onHeadersRead(ctx, STREAM_ID, headers, padding, true);
verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(), verify(listener, times(1)).onHeadersRead(eq(ctx), anyInt(),
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean()); any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());
assertEquals(1, headers.getAll(HttpHeaderNames.CONTENT_LENGTH).size()); assertEquals(1, headers.getAll(HttpHeaderNames.CONTENT_LENGTH).size());
} else { } else {
assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
decode().onHeadersRead(ctx, STREAM_ID, headers, padding, true);
}
});
// Verify that the event was absorbed and not propagated to the observer. // Verify that the event was absorbed and not propagated to the observer.
verify(listener, never()).onHeadersRead(eq(ctx), anyInt(), verify(listener, never()).onHeadersRead(eq(ctx), anyInt(),
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean()); any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), anyBoolean());

View File

@ -31,8 +31,8 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http2.Http2RemoteFlowController.FlowControlled; import io.netty.handler.codec.http2.Http2RemoteFlowController.FlowControlled;
import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.ImmediateEventExecutor;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.InOrder; import org.mockito.InOrder;
import org.mockito.Mock; import org.mockito.Mock;
@ -53,12 +53,12 @@ import static io.netty.handler.codec.http2.Http2TestUtil.newVoidPromise;
import static io.netty.util.CharsetUtil.UTF_8; import static io.netty.util.CharsetUtil.UTF_8;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -116,7 +116,7 @@ public class DefaultHttp2ConnectionEncoderTest {
private List<Integer> writtenPadding; private List<Integer> writtenPadding;
private boolean streamClosed; private boolean streamClosed;
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);

View File

@ -23,12 +23,11 @@ import io.netty.handler.codec.http2.Http2Stream.State;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener; import io.netty.util.concurrent.FutureListener;
import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.Promise;
import org.junit.AfterClass; import org.junit.jupiter.api.AfterAll;
import org.junit.Before; import org.junit.jupiter.api.BeforeAll;
import org.junit.BeforeClass; import org.junit.jupiter.api.BeforeEach;
import org.junit.Rule; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.function.Executable;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@ -39,11 +38,12 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static java.lang.Integer.MAX_VALUE; import static java.lang.Integer.MAX_VALUE;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.anyLong;
@ -56,8 +56,6 @@ import static org.mockito.Mockito.verify;
* Tests for {@link DefaultHttp2Connection}. * Tests for {@link DefaultHttp2Connection}.
*/ */
public class DefaultHttp2ConnectionTest { public class DefaultHttp2ConnectionTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
private DefaultHttp2Connection server; private DefaultHttp2Connection server;
private DefaultHttp2Connection client; private DefaultHttp2Connection client;
@ -69,17 +67,17 @@ public class DefaultHttp2ConnectionTest {
@Mock @Mock
private Http2Connection.Listener clientListener2; private Http2Connection.Listener clientListener2;
@BeforeClass @BeforeAll
public static void beforeClass() { public static void beforeClass() {
group = new DefaultEventLoopGroup(2); group = new DefaultEventLoopGroup(2);
} }
@AfterClass @AfterAll
public static void afterClass() { public static void afterClass() {
group.shutdownGracefully(); group.shutdownGracefully();
} }
@Before @BeforeEach
public void setup() { public void setup() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -350,22 +348,22 @@ public class DefaultHttp2ConnectionTest {
incrementAndGetStreamShouldSucceed(client.local()); incrementAndGetStreamShouldSucceed(client.local());
} }
@Test(expected = Http2NoMoreStreamIdsException.class) @Test
public void serverRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception { public void serverRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
incrementAndGetStreamShouldRespectOverflow(server.remote(), MAX_VALUE); incrementAndGetStreamShouldRespectOverflow(server.remote(), MAX_VALUE);
} }
@Test(expected = Http2NoMoreStreamIdsException.class) @Test
public void serverLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception { public void serverLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
incrementAndGetStreamShouldRespectOverflow(server.local(), MAX_VALUE - 1); incrementAndGetStreamShouldRespectOverflow(server.local(), MAX_VALUE - 1);
} }
@Test(expected = Http2NoMoreStreamIdsException.class) @Test
public void clientRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception { public void clientRemoteIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
incrementAndGetStreamShouldRespectOverflow(client.remote(), MAX_VALUE - 1); incrementAndGetStreamShouldRespectOverflow(client.remote(), MAX_VALUE - 1);
} }
@Test(expected = Http2NoMoreStreamIdsException.class) @Test
public void clientLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception { public void clientLocalIncrementAndGetStreamShouldRespectOverflow() throws Http2Exception {
incrementAndGetStreamShouldRespectOverflow(client.local(), MAX_VALUE); incrementAndGetStreamShouldRespectOverflow(client.local(), MAX_VALUE);
} }
@ -373,51 +371,82 @@ public class DefaultHttp2ConnectionTest {
@Test @Test
public void clientLocalCreateStreamExhaustedSpace() throws Http2Exception { public void clientLocalCreateStreamExhaustedSpace() throws Http2Exception {
client.local().createStream(MAX_VALUE, true); client.local().createStream(MAX_VALUE, true);
try { Http2Exception expected = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
client.local().createStream(MAX_VALUE, true); client.local().createStream(MAX_VALUE, true);
fail(); }
} catch (Http2Exception expected) { });
assertEquals(Http2Error.REFUSED_STREAM, expected.error()); assertEquals(Http2Error.REFUSED_STREAM, expected.error());
assertEquals(Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN, expected.shutdownHint()); assertEquals(Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN, expected.shutdownHint());
} }
}
@Test(expected = Http2Exception.class) @Test
public void newStreamBehindExpectedShouldThrow() throws Http2Exception { public void newStreamBehindExpectedShouldThrow() throws Http2Exception {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.local().createStream(0, true); server.local().createStream(0, true);
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void newStreamNotForServerShouldThrow() throws Http2Exception { public void newStreamNotForServerShouldThrow() throws Http2Exception {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.local().createStream(11, true); server.local().createStream(11, true);
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void newStreamNotForClientShouldThrow() throws Http2Exception { public void newStreamNotForClientShouldThrow() throws Http2Exception {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
client.local().createStream(10, true); client.local().createStream(10, true);
} }
});
@Test(expected = Http2Exception.class)
public void createShouldThrowWhenMaxAllowedStreamsOpenExceeded() throws Http2Exception {
server.local().maxActiveStreams(0);
server.local().createStream(2, true);
} }
@Test(expected = Http2Exception.class) @Test
public void createShouldThrowWhenMaxAllowedStreamsOpenExceeded() throws Http2Exception {
server.local().maxActiveStreams(0);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.local().createStream(2, true);
}
});
}
@Test
public void serverCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception { public void serverCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
server = new DefaultHttp2Connection(true, 0); server = new DefaultHttp2Connection(true, 0);
server.remote().maxActiveStreams(1); server.remote().maxActiveStreams(1);
Http2Stream requestStream = server.remote().createStream(3, false); final Http2Stream requestStream = server.remote().createStream(3, false);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.remote().reservePushStream(2, requestStream); server.remote().reservePushStream(2, requestStream);
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void clientCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception { public void clientCreatePushShouldFailOnRemoteEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
client = new DefaultHttp2Connection(false, 0); client = new DefaultHttp2Connection(false, 0);
client.remote().maxActiveStreams(1); client.remote().maxActiveStreams(1);
Http2Stream requestStream = client.remote().createStream(2, false); final Http2Stream requestStream = client.remote().createStream(2, false);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
client.remote().reservePushStream(4, requestStream); client.remote().reservePushStream(4, requestStream);
} }
});
}
@Test @Test
public void serverCreatePushShouldSucceedOnLocalEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception { public void serverCreatePushShouldSucceedOnLocalEndpointWhenMaxAllowedStreamsExceeded() throws Http2Exception {
@ -427,18 +456,28 @@ public class DefaultHttp2ConnectionTest {
assertNotNull(server.local().reservePushStream(2, requestStream)); assertNotNull(server.local().reservePushStream(2, requestStream));
} }
@Test(expected = Http2Exception.class) @Test
public void reserveWithPushDisallowedShouldThrow() throws Http2Exception { public void reserveWithPushDisallowedShouldThrow() throws Http2Exception {
Http2Stream stream = server.remote().createStream(3, true); final Http2Stream stream = server.remote().createStream(3, true);
server.remote().allowPushTo(false); server.remote().allowPushTo(false);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.local().reservePushStream(2, stream); server.local().reservePushStream(2, stream);
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void goAwayReceivedShouldDisallowLocalCreation() throws Http2Exception { public void goAwayReceivedShouldDisallowLocalCreation() throws Http2Exception {
server.goAwayReceived(0, 1L, Unpooled.EMPTY_BUFFER); server.goAwayReceived(0, 1L, Unpooled.EMPTY_BUFFER);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.local().createStream(3, true); server.local().createStream(3, true);
} }
});
}
@Test @Test
public void goAwayReceivedShouldAllowRemoteCreation() throws Http2Exception { public void goAwayReceivedShouldAllowRemoteCreation() throws Http2Exception {
@ -446,11 +485,17 @@ public class DefaultHttp2ConnectionTest {
server.remote().createStream(3, true); server.remote().createStream(3, true);
} }
@Test(expected = Http2Exception.class) @Test
public void goAwaySentShouldDisallowRemoteCreation() throws Http2Exception { public void goAwaySentShouldDisallowRemoteCreation() throws Http2Exception {
server.goAwaySent(0, 1L, Unpooled.EMPTY_BUFFER); server.goAwaySent(0, 1L, Unpooled.EMPTY_BUFFER);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
server.remote().createStream(2, true); server.remote().createStream(2, true);
} }
});
}
@Test @Test
public void goAwaySentShouldAllowLocalCreation() throws Http2Exception { public void goAwaySentShouldAllowLocalCreation() throws Http2Exception {
@ -491,16 +536,26 @@ public class DefaultHttp2ConnectionTest {
} }
@SuppressWarnings("NumericOverflow") @SuppressWarnings("NumericOverflow")
@Test(expected = Http2Exception.class) @Test
public void localStreamInvalidStreamIdShouldThrow() throws Http2Exception { public void localStreamInvalidStreamIdShouldThrow() {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
client.local().createStream(MAX_VALUE + 2, false); client.local().createStream(MAX_VALUE + 2, false);
} }
});
}
@SuppressWarnings("NumericOverflow") @SuppressWarnings("NumericOverflow")
@Test(expected = Http2Exception.class) @Test
public void remoteStreamInvalidStreamIdShouldThrow() throws Http2Exception { public void remoteStreamInvalidStreamIdShouldThrow() {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
client.remote().createStream(MAX_VALUE + 1, false); client.remote().createStream(MAX_VALUE + 1, false);
} }
});
}
/** /**
* We force {@link #clientListener} methods to all throw a {@link RuntimeException} and verify the following: * We force {@link #clientListener} methods to all throw a {@link RuntimeException} and verify the following:
@ -610,17 +665,22 @@ public class DefaultHttp2ConnectionTest {
assertTrue(latch.await(5, TimeUnit.SECONDS)); assertTrue(latch.await(5, TimeUnit.SECONDS));
} }
private static void incrementAndGetStreamShouldRespectOverflow(Endpoint<?> endpoint, int streamId) private static void incrementAndGetStreamShouldRespectOverflow(final Endpoint<?> endpoint, int streamId) {
throws Http2Exception {
assertTrue(streamId > 0); assertTrue(streamId > 0);
try { try {
endpoint.createStream(streamId, true); endpoint.createStream(streamId, true);
streamId = endpoint.incrementAndGetNextStreamId(); streamId = endpoint.incrementAndGetNextStreamId();
} catch (Throwable t) { } catch (Throwable t) {
fail(); fail(t);
} }
assertTrue(streamId < 0); assertTrue(streamId < 0);
endpoint.createStream(streamId, true); final int finalStreamId = streamId;
assertThrows(Http2NoMoreStreamIdsException.class, new Executable() {
@Override
public void execute() throws Throwable {
endpoint.createStream(finalStreamId, true);
}
});
} }
private static void incrementAndGetStreamShouldSucceed(Endpoint<?> endpoint) throws Http2Exception { private static void incrementAndGetStreamShouldSucceed(Endpoint<?> endpoint) throws Http2Exception {

View File

@ -18,14 +18,16 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.buffer.UnpooledByteBufAllocator; import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import static io.netty.handler.codec.http2.Http2CodecUtil.*; import static io.netty.handler.codec.http2.Http2CodecUtil.*;
import static io.netty.handler.codec.http2.Http2FrameTypes.*; import static io.netty.handler.codec.http2.Http2FrameTypes.*;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@ -44,7 +46,7 @@ public class DefaultHttp2FrameReaderTest {
// Used to generate frame // Used to generate frame
private HpackEncoder hpackEncoder; private HpackEncoder hpackEncoder;
@Before @BeforeEach
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -54,7 +56,7 @@ public class DefaultHttp2FrameReaderTest {
hpackEncoder = new HpackEncoder(); hpackEncoder = new HpackEncoder();
} }
@After @AfterEach
public void tearDown() { public void tearDown() {
frameReader.close(); frameReader.close();
} }
@ -123,11 +125,11 @@ public class DefaultHttp2FrameReaderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenUnknownFrameInMiddleOfHeaderBlock() throws Http2Exception { public void failedWhenUnknownFrameInMiddleOfHeaderBlock() throws Http2Exception {
final int streamId = 1; final int streamId = 1;
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
Http2Headers headers = new DefaultHttp2Headers() Http2Headers headers = new DefaultHttp2Headers()
.authority("foo") .authority("foo")
@ -137,15 +139,21 @@ public class DefaultHttp2FrameReaderTest {
Http2Flags flags = new Http2Flags().endOfHeaders(false).endOfStream(true); Http2Flags flags = new Http2Flags().endOfHeaders(false).endOfStream(true);
writeHeaderFrame(input, streamId, headers, flags); writeHeaderFrame(input, streamId, headers, flags);
writeFrameHeader(input, 0, (byte) 0xff, new Http2Flags(), streamId); writeFrameHeader(input, 0, (byte) 0xff, new Http2Flags(), streamId);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenContinuationFrameStreamIdMismatch() throws Http2Exception { public void failedWhenContinuationFrameStreamIdMismatch() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
Http2Headers headers = new DefaultHttp2Headers() Http2Headers headers = new DefaultHttp2Headers()
.authority("foo") .authority("foo")
@ -156,27 +164,38 @@ public class DefaultHttp2FrameReaderTest {
new Http2Flags().endOfHeaders(false).endOfStream(true)); new Http2Flags().endOfHeaders(false).endOfStream(true));
writeContinuationFrame(input, 3, new DefaultHttp2Headers().add("foo", "bar"), writeContinuationFrame(input, 3, new DefaultHttp2Headers().add("foo", "bar"),
new Http2Flags().endOfHeaders(true)); new Http2Flags().endOfHeaders(true));
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenContinuationFrameNotFollowHeaderFrame() throws Http2Exception { public void failedWhenContinuationFrameNotFollowHeaderFrame() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
writeContinuationFrame(input, 1, new DefaultHttp2Headers().add("foo", "bar"), writeContinuationFrame(input, 1, new DefaultHttp2Headers().add("foo", "bar"),
new Http2Flags().endOfHeaders(true)); new Http2Flags().endOfHeaders(true));
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenHeaderFrameDependsOnItself() throws Http2Exception { public void failedWhenHeaderFrameDependsOnItself() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
Http2Headers headers = new DefaultHttp2Headers() Http2Headers headers = new DefaultHttp2Headers()
.authority("foo") .authority("foo")
@ -187,7 +206,12 @@ public class DefaultHttp2FrameReaderTest {
input, 1, headers, input, 1, headers,
new Http2Flags().endOfHeaders(true).endOfStream(true).priorityPresent(true), new Http2Flags().endOfHeaders(true).endOfStream(true).priorityPresent(true),
1, 10); 1, 10);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
@ -216,16 +240,21 @@ public class DefaultHttp2FrameReaderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenDataFrameNotAssociateWithStream() throws Http2Exception { public void failedWhenDataFrameNotAssociateWithStream() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
ByteBuf payload = Unpooled.buffer(); ByteBuf payload = Unpooled.buffer();
try { try {
payload.writeByte(1); payload.writeByte(1);
writeFrameHeader(input, payload.readableBytes(), DATA, new Http2Flags().endOfStream(true), 0); writeFrameHeader(input, payload.readableBytes(), DATA, new Http2Flags().endOfStream(true), 0);
input.writeBytes(payload); input.writeBytes(payload);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
payload.release(); payload.release();
input.release(); input.release();
@ -243,24 +272,34 @@ public class DefaultHttp2FrameReaderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenPriorityFrameDependsOnItself() throws Http2Exception { public void failedWhenPriorityFrameDependsOnItself() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
writePriorityFrame(input, 1, 1, 10); writePriorityFrame(input, 1, 1, 10);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenWindowUpdateFrameWithZeroDelta() throws Http2Exception { public void failedWhenWindowUpdateFrameWithZeroDelta() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
writeFrameHeader(input, 4, WINDOW_UPDATE, new Http2Flags(), 0); writeFrameHeader(input, 4, WINDOW_UPDATE, new Http2Flags(), 0);
input.writeInt(0); input.writeInt(0);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
@ -294,39 +333,54 @@ public class DefaultHttp2FrameReaderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenSettingsFrameOnNonZeroStream() throws Http2Exception { public void failedWhenSettingsFrameOnNonZeroStream() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
writeFrameHeader(input, 6, SETTINGS, new Http2Flags(), 1); writeFrameHeader(input, 6, SETTINGS, new Http2Flags(), 1);
input.writeShort(SETTINGS_MAX_HEADER_LIST_SIZE); input.writeShort(SETTINGS_MAX_HEADER_LIST_SIZE);
input.writeInt(1024); input.writeInt(1024);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenAckSettingsFrameWithPayload() throws Http2Exception { public void failedWhenAckSettingsFrameWithPayload() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
writeFrameHeader(input, 1, SETTINGS, new Http2Flags().ack(true), 0); writeFrameHeader(input, 1, SETTINGS, new Http2Flags().ack(true), 0);
input.writeByte(1); input.writeByte(1);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void failedWhenSettingsFrameWithWrongPayloadLength() throws Http2Exception { public void failedWhenSettingsFrameWithWrongPayloadLength() throws Http2Exception {
ByteBuf input = Unpooled.buffer(); final ByteBuf input = Unpooled.buffer();
try { try {
writeFrameHeader(input, 8, SETTINGS, new Http2Flags(), 0); writeFrameHeader(input, 8, SETTINGS, new Http2Flags(), 0);
input.writeInt(SETTINGS_MAX_HEADER_LIST_SIZE); input.writeInt(SETTINGS_MAX_HEADER_LIST_SIZE);
input.writeInt(1024); input.writeInt(1024);
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
frameReader.readFrame(ctx, input, listener); frameReader.readFrame(ctx, input, listener);
}
});
} finally { } finally {
input.release(); input.release();
} }

View File

@ -15,7 +15,6 @@
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
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;
@ -25,9 +24,9 @@ import io.netty.channel.ChannelPromise;
import io.netty.channel.DefaultChannelPromise; import io.netty.channel.DefaultChannelPromise;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.ImmediateEventExecutor;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -37,7 +36,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
/** /**
@ -63,7 +64,7 @@ public class DefaultHttp2FrameWriterTest {
@Mock @Mock
private ChannelHandlerContext ctx; private ChannelHandlerContext ctx;
@Before @BeforeEach
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
http2HeadersEncoder = new DefaultHttp2HeadersEncoder( http2HeadersEncoder = new DefaultHttp2HeadersEncoder(
@ -96,7 +97,7 @@ public class DefaultHttp2FrameWriterTest {
when(ctx.executor()).thenReturn(ImmediateEventExecutor.INSTANCE); when(ctx.executor()).thenReturn(ImmediateEventExecutor.INSTANCE);
} }
@After @AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
outbound.release(); outbound.release();
expectedOutbound.release(); expectedOutbound.release();

View File

@ -18,8 +18,9 @@ package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_LIST_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_LIST_SIZE;
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_HEADER_LIST_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_HEADER_LIST_SIZE;
@ -27,8 +28,8 @@ import static io.netty.handler.codec.http2.Http2HeadersEncoder.NEVER_SENSITIVE;
import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder; import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
import static io.netty.handler.codec.http2.Http2TestUtil.randomBytes; import static io.netty.handler.codec.http2.Http2TestUtil.randomBytes;
import static io.netty.util.CharsetUtil.UTF_8; import static io.netty.util.CharsetUtil.UTF_8;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
* Tests for {@link DefaultHttp2HeadersDecoder}. * Tests for {@link DefaultHttp2HeadersDecoder}.
@ -37,7 +38,7 @@ public class DefaultHttp2HeadersDecoderTest {
private DefaultHttp2HeadersDecoder decoder; private DefaultHttp2HeadersDecoder decoder;
@Before @BeforeEach
public void setup() { public void setup() {
decoder = new DefaultHttp2HeadersDecoder(false); decoder = new DefaultHttp2HeadersDecoder(false);
} }
@ -55,14 +56,19 @@ public class DefaultHttp2HeadersDecoderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testExceedHeaderSize() throws Exception { public void testExceedHeaderSize() throws Exception {
final int maxListSize = 100; final int maxListSize = 100;
decoder.configuration().maxHeaderListSize(maxListSize, maxListSize); decoder.configuration().maxHeaderListSize(maxListSize, maxListSize);
ByteBuf buf = encode(randomBytes(maxListSize), randomBytes(1)); final ByteBuf buf = encode(randomBytes(maxListSize), randomBytes(1));
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decoder.decodeHeaders(0, buf); decoder.decodeHeaders(0, buf);
fail(); }
});
} finally { } finally {
buf.release(); buf.release();
} }
@ -71,27 +77,32 @@ public class DefaultHttp2HeadersDecoderTest {
@Test @Test
public void decodeLargerThanHeaderListSizeButLessThanGoAway() throws Exception { public void decodeLargerThanHeaderListSizeButLessThanGoAway() throws Exception {
decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MAX_HEADER_LIST_SIZE); decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MAX_HEADER_LIST_SIZE);
ByteBuf buf = encode(b(":method"), b("GET")); final ByteBuf buf = encode(b(":method"), b("GET"));
final int streamId = 1; final int streamId = 1;
try { Http2Exception.HeaderListSizeException e =
assertThrows(Http2Exception.HeaderListSizeException.class, new Executable() {
@Override
public void execute() throws Throwable {
decoder.decodeHeaders(streamId, buf); decoder.decodeHeaders(streamId, buf);
fail();
} catch (Http2Exception.HeaderListSizeException e) {
assertEquals(streamId, e.streamId());
} finally {
buf.release();
} }
});
assertEquals(streamId, e.streamId());
buf.release();
} }
@Test @Test
public void decodeLargerThanHeaderListSizeButLessThanGoAwayWithInitialDecoderSettings() throws Exception { public void decodeLargerThanHeaderListSizeButLessThanGoAwayWithInitialDecoderSettings() throws Exception {
ByteBuf buf = encode(b(":method"), b("GET"), b("test_header"), final ByteBuf buf = encode(b(":method"), b("GET"), b("test_header"),
b(String.format("%09000d", 0).replace('0', 'A'))); b(String.format("%09000d", 0).replace('0', 'A')));
final int streamId = 1; final int streamId = 1;
try { try {
Http2Exception.HeaderListSizeException e = assertThrows(Http2Exception.HeaderListSizeException.class,
new Executable() {
@Override
public void execute() throws Throwable {
decoder.decodeHeaders(streamId, buf); decoder.decodeHeaders(streamId, buf);
fail(); }
} catch (Http2Exception.HeaderListSizeException e) { });
assertEquals(streamId, e.streamId()); assertEquals(streamId, e.streamId());
} finally { } finally {
buf.release(); buf.release();
@ -101,12 +112,15 @@ public class DefaultHttp2HeadersDecoderTest {
@Test @Test
public void decodeLargerThanHeaderListSizeGoAway() throws Exception { public void decodeLargerThanHeaderListSizeGoAway() throws Exception {
decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MIN_HEADER_LIST_SIZE); decoder.maxHeaderListSize(MIN_HEADER_LIST_SIZE, MIN_HEADER_LIST_SIZE);
ByteBuf buf = encode(b(":method"), b("GET")); final ByteBuf buf = encode(b(":method"), b("GET"));
final int streamId = 1; final int streamId = 1;
try { try {
Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decoder.decodeHeaders(streamId, buf); decoder.decodeHeaders(streamId, buf);
fail(); }
} catch (Http2Exception e) { });
assertEquals(Http2Error.PROTOCOL_ERROR, e.error()); assertEquals(Http2Error.PROTOCOL_ERROR, e.error());
} finally { } finally {
buf.release(); buf.release();

View File

@ -19,11 +19,13 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http2.Http2Exception.StreamException; import io.netty.handler.codec.http2.Http2Exception.StreamException;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder; import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* Tests for {@link DefaultHttp2HeadersEncoder}. * Tests for {@link DefaultHttp2HeadersEncoder}.
@ -32,7 +34,7 @@ public class DefaultHttp2HeadersEncoderTest {
private DefaultHttp2HeadersEncoder encoder; private DefaultHttp2HeadersEncoder encoder;
@Before @BeforeEach
public void setup() { public void setup() {
encoder = new DefaultHttp2HeadersEncoder(Http2HeadersEncoder.NEVER_SENSITIVE, newTestEncoder()); encoder = new DefaultHttp2HeadersEncoder(Http2HeadersEncoder.NEVER_SENSITIVE, newTestEncoder());
} }
@ -49,12 +51,17 @@ public class DefaultHttp2HeadersEncoderTest {
} }
} }
@Test(expected = StreamException.class) @Test
public void headersExceedMaxSetSizeShouldFail() throws Http2Exception { public void headersExceedMaxSetSizeShouldFail() throws Http2Exception {
Http2Headers headers = headers(); final Http2Headers headers = headers();
encoder.maxHeaderListSize(2); encoder.maxHeaderListSize(2);
assertThrows(StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
encoder.encodeHeaders(3 /* randomly chosen */, headers, Unpooled.buffer()); encoder.encodeHeaders(3 /* randomly chosen */, headers, Unpooled.buffer());
} }
});
}
private static Http2Headers headers() { private static Http2Headers headers() {
return new DefaultHttp2Headers().method(new AsciiString("GET")).add(new AsciiString("a"), new AsciiString("1")) return new DefaultHttp2Headers().method(new AsciiString("GET")).add(new AsciiString("a"), new AsciiString("1"))

View File

@ -18,24 +18,40 @@ package io.netty.handler.codec.http2;
import io.netty.handler.codec.http2.Http2Headers.PseudoHeaderName; import io.netty.handler.codec.http2.Http2Headers.PseudoHeaderName;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import java.util.Map.Entry; import java.util.Map.Entry;
import static io.netty.util.AsciiString.*; import static io.netty.util.AsciiString.*;
import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class DefaultHttp2HeadersTest { public class DefaultHttp2HeadersTest {
@Test(expected = Http2Exception.class) @Test
public void nullHeaderNameNotAllowed() { public void nullHeaderNameNotAllowed() {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
new DefaultHttp2Headers().add(null, "foo"); new DefaultHttp2Headers().add(null, "foo");
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void emptyHeaderNameNotAllowed() { public void emptyHeaderNameNotAllowed() {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
new DefaultHttp2Headers().add(StringUtil.EMPTY_STRING, "foo"); new DefaultHttp2Headers().add(StringUtil.EMPTY_STRING, "foo");
} }
});
}
@Test @Test
public void testPseudoHeadersMustComeFirstWhenIterating() { public void testPseudoHeadersMustComeFirstWhenIterating() {
@ -126,12 +142,17 @@ public class DefaultHttp2HeadersTest {
assertEquals("value2", headers.get("name2")); assertEquals("value2", headers.get("name2"));
} }
@Test(expected = Http2Exception.class) @Test
public void testHeaderNameValidation() { public void testHeaderNameValidation() {
Http2Headers headers = newHeaders(); final Http2Headers headers = newHeaders();
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
headers.add(of("Foo"), of("foo")); headers.add(of("Foo"), of("foo"));
} }
});
}
@Test @Test
public void testClearResetsPseudoHeaderDivision() { public void testClearResetsPseudoHeaderDivision() {

View File

@ -18,16 +18,16 @@ package io.netty.handler.codec.http2;
import static io.netty.handler.codec.http2.DefaultHttp2LocalFlowController.DEFAULT_WINDOW_UPDATE_RATIO; import static io.netty.handler.codec.http2.DefaultHttp2LocalFlowController.DEFAULT_WINDOW_UPDATE_RATIO;
import static io.netty.handler.codec.http2.Http2CodecUtil.CONNECTION_STREAM_ID; import static io.netty.handler.codec.http2.Http2CodecUtil.CONNECTION_STREAM_ID;
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -39,8 +39,9 @@ import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http2.Http2Stream.State; import io.netty.handler.codec.http2.Http2Stream.State;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -68,7 +69,7 @@ public class DefaultHttp2LocalFlowControllerTest {
private DefaultHttp2Connection connection; private DefaultHttp2Connection connection;
@Before @BeforeEach
public void setup() throws Http2Exception { public void setup() throws Http2Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
setupChannelHandlerContext(false); setupChannelHandlerContext(false);
@ -136,11 +137,16 @@ public class DefaultHttp2LocalFlowControllerTest {
verifyNoMoreInteractions(frameWriter); verifyNoMoreInteractions(frameWriter);
} }
@Test(expected = Http2Exception.class) @Test
public void connectionFlowControlExceededShouldThrow() throws Http2Exception { public void connectionFlowControlExceededShouldThrow() throws Http2Exception {
// Window exceeded because of the padding. // Window exceeded because of the padding.
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
receiveFlowControlledFrame(STREAM_ID, DEFAULT_WINDOW_SIZE, 1, true); receiveFlowControlledFrame(STREAM_ID, DEFAULT_WINDOW_SIZE, 1, true);
} }
});
}
@Test @Test
public void windowUpdateShouldNotBeSentAfterEndOfStream() throws Http2Exception { public void windowUpdateShouldNotBeSentAfterEndOfStream() throws Http2Exception {
@ -342,9 +348,14 @@ public class DefaultHttp2LocalFlowControllerTest {
assertFalse(controller.consumeBytes(connection.stream(STREAM_ID), 0)); assertFalse(controller.consumeBytes(connection.stream(STREAM_ID), 0));
} }
@Test(expected = IllegalArgumentException.class) @Test
public void consumeBytesForNegativeNumBytesShouldFail() throws Http2Exception { public void consumeBytesForNegativeNumBytesShouldFail() throws Http2Exception {
assertFalse(controller.consumeBytes(connection.stream(STREAM_ID), -1)); assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.consumeBytes(connection.stream(STREAM_ID), -1);
}
});
} }
private void testRatio(float ratio, int newDefaultWindowSize, int newStreamId, boolean setStreamRatio) private void testRatio(float ratio, int newDefaultWindowSize, int newStreamId, boolean setStreamRatio)

View File

@ -30,14 +30,14 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
public class DefaultHttp2PushPromiseFrameTest { public class DefaultHttp2PushPromiseFrameTest {
@ -47,7 +47,7 @@ public class DefaultHttp2PushPromiseFrameTest {
private ChannelFuture connectionFuture; private ChannelFuture connectionFuture;
@Before @BeforeEach
public void setup() throws InterruptedException { public void setup() throws InterruptedException {
ServerBootstrap serverBootstrap = new ServerBootstrap() ServerBootstrap serverBootstrap = new ServerBootstrap()
.group(eventLoopGroup) .group(eventLoopGroup)
@ -101,7 +101,7 @@ public class DefaultHttp2PushPromiseFrameTest {
}); });
} }
@After @AfterEach
public void shutdown() { public void shutdown() {
eventLoopGroup.shutdownGracefully(); eventLoopGroup.shutdownGracefully();
} }

View File

@ -20,13 +20,14 @@ import io.netty.channel.ChannelConfig;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise; import io.netty.channel.ChannelPromise;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import junit.framework.AssertionFailedError; import org.junit.jupiter.api.BeforeEach;
import org.junit.Before; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.function.Executable;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.opentest4j.AssertionFailedError;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -35,12 +36,13 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE;
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT;
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atLeastOnce;
@ -86,7 +88,7 @@ public abstract class DefaultHttp2RemoteFlowControllerTest {
private DefaultHttp2Connection connection; private DefaultHttp2Connection connection;
@Before @BeforeEach
public void setup() throws Http2Exception { public void setup() throws Http2Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -733,15 +735,14 @@ public abstract class DefaultHttp2RemoteFlowControllerTest {
int windowBefore = window(STREAM_A); int windowBefore = window(STREAM_A);
try { Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.addFlowControlled(stream, flowControlled); controller.addFlowControlled(stream, flowControlled);
controller.writePendingBytes(); controller.writePendingBytes();
fail();
} catch (Http2Exception e) {
assertSame(fakeException, e.getCause());
} catch (Throwable t) {
fail();
} }
});
assertSame(fakeException, e.getCause());
verify(flowControlled, atLeastOnce()).write(any(ChannelHandlerContext.class), anyInt()); verify(flowControlled, atLeastOnce()).write(any(ChannelHandlerContext.class), anyInt());
verify(flowControlled).error(any(ChannelHandlerContext.class), any(Throwable.class)); verify(flowControlled).error(any(ChannelHandlerContext.class), any(Throwable.class));
@ -908,35 +909,65 @@ public abstract class DefaultHttp2RemoteFlowControllerTest {
dataA.assertFullyWritten(); dataA.assertFullyWritten();
} }
@Test(expected = AssertionError.class) @Test
public void invalidParentStreamIdThrows() { public void invalidParentStreamIdThrows() {
assertThrows(AssertionError.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.updateDependencyTree(STREAM_D, -1, DEFAULT_PRIORITY_WEIGHT, true); controller.updateDependencyTree(STREAM_D, -1, DEFAULT_PRIORITY_WEIGHT, true);
} }
});
}
@Test(expected = AssertionError.class) @Test
public void invalidChildStreamIdThrows() { public void invalidChildStreamIdThrows() {
assertThrows(AssertionError.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.updateDependencyTree(-1, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true); controller.updateDependencyTree(-1, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true);
} }
});
}
@Test(expected = AssertionError.class) @Test
public void connectionChildStreamIdThrows() { public void connectionChildStreamIdThrows() {
assertThrows(AssertionError.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.updateDependencyTree(0, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true); controller.updateDependencyTree(0, STREAM_D, DEFAULT_PRIORITY_WEIGHT, true);
} }
});
}
@Test(expected = AssertionError.class) @Test
public void invalidWeightTooSmallThrows() { public void invalidWeightTooSmallThrows() {
assertThrows(AssertionError.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MIN_WEIGHT - 1), true); controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MIN_WEIGHT - 1), true);
} }
});
@Test(expected = AssertionError.class)
public void invalidWeightTooBigThrows() {
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MAX_WEIGHT + 1), true);
} }
@Test(expected = AssertionError.class) @Test
public void invalidWeightTooBigThrows() {
assertThrows(AssertionError.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.updateDependencyTree(STREAM_A, STREAM_D, (short) (MAX_WEIGHT + 1), true);
}
});
}
@Test
public void dependencyOnSelfThrows() { public void dependencyOnSelfThrows() {
assertThrows(AssertionError.class, new Executable() {
@Override
public void execute() throws Throwable {
controller.updateDependencyTree(STREAM_A, STREAM_A, DEFAULT_PRIORITY_WEIGHT, true); controller.updateDependencyTree(STREAM_A, STREAM_A, DEFAULT_PRIORITY_WEIGHT, true);
} }
});
}
private void assertWritabilityChanged(int amt, boolean writable) { private void assertWritabilityChanged(int amt, boolean writable) {
verify(listener, times(amt)).writabilityChanged(stream(STREAM_A)); verify(listener, times(amt)).writabilityChanged(stream(STREAM_A));

View File

@ -18,7 +18,7 @@ import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import io.netty.util.internal.PlatformDependent; import io.netty.util.internal.PlatformDependent;
import org.junit.Ignore; import org.junit.jupiter.api.Disabled;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -37,7 +37,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
@Ignore @Disabled
public final class HashCollisionTest { public final class HashCollisionTest {
private HashCollisionTest() { } private HashCollisionTest() { }

View File

@ -34,10 +34,9 @@ package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Rule; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.function.Executable;
import org.junit.rules.ExpectedException;
import static io.netty.handler.codec.http2.HpackDecoder.decodeULE128; import static io.netty.handler.codec.http2.HpackDecoder.decodeULE128;
import static io.netty.handler.codec.http2.Http2HeadersEncoder.NEVER_SENSITIVE; import static io.netty.handler.codec.http2.Http2HeadersEncoder.NEVER_SENSITIVE;
@ -47,9 +46,8 @@ import static java.lang.Integer.MAX_VALUE;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@ -57,8 +55,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
public class HpackDecoderTest { public class HpackDecoderTest {
@Rule
public final ExpectedException expectedException = ExpectedException.none();
private HpackDecoder hpackDecoder; private HpackDecoder hpackDecoder;
private Http2Headers mockHeaders; private Http2Headers mockHeaders;
@ -77,7 +73,7 @@ public class HpackDecoderTest {
} }
} }
@Before @BeforeEach
public void setUp() { public void setUp() {
hpackDecoder = new HpackDecoder(8192); hpackDecoder = new HpackDecoder(8192);
mockHeaders = mock(Http2Headers.class); mockHeaders = mock(Http2Headers.class);
@ -94,26 +90,36 @@ public class HpackDecoderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testDecodeULE128IntOverflow1() throws Http2Exception { public void testDecodeULE128IntOverflow1() throws Http2Exception {
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07}; byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x07};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
final int readerIndex = in.readerIndex(); final int readerIndex = in.readerIndex();
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decodeULE128(in, 1); decodeULE128(in, 1);
}
});
} finally { } finally {
assertEquals(readerIndex, in.readerIndex()); assertEquals(readerIndex, in.readerIndex());
in.release(); in.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testDecodeULE128IntOverflow2() throws Http2Exception { public void testDecodeULE128IntOverflow2() throws Http2Exception {
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x08}; byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x08};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
final int readerIndex = in.readerIndex(); final int readerIndex = in.readerIndex();
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decodeULE128(in, 0); decodeULE128(in, 0);
}
});
} finally { } finally {
assertEquals(readerIndex, in.readerIndex()); assertEquals(readerIndex, in.readerIndex());
in.release(); in.release();
@ -132,28 +138,38 @@ public class HpackDecoderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testDecodeULE128LongOverflow1() throws Http2Exception { public void testDecodeULE128LongOverflow1() throws Http2Exception {
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xFF}; (byte) 0xFF, (byte) 0xFF};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
final int readerIndex = in.readerIndex(); final int readerIndex = in.readerIndex();
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decodeULE128(in, 0L); decodeULE128(in, 0L);
}
});
} finally { } finally {
assertEquals(readerIndex, in.readerIndex()); assertEquals(readerIndex, in.readerIndex());
in.release(); in.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testDecodeULE128LongOverflow2() throws Http2Exception { public void testDecodeULE128LongOverflow2() throws Http2Exception {
byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, byte[] input = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0x7F}; (byte) 0xFF, (byte) 0x7F};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
final int readerIndex = in.readerIndex(); final int readerIndex = in.readerIndex();
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decodeULE128(in, 1L); decodeULE128(in, 1L);
}
});
} finally { } finally {
assertEquals(readerIndex, in.readerIndex()); assertEquals(readerIndex, in.readerIndex());
in.release(); in.release();
@ -174,13 +190,18 @@ public class HpackDecoderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testSetTableSizeOverLimitFails() throws Http2Exception { public void testSetTableSizeOverLimitFails() throws Http2Exception {
byte[] input = {(byte) 0x3F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0E}; byte[] input = {(byte) 0x3F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0E};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
try { try {
hpackDecoder.setMaxHeaderTableSize(4026531870L - 1); // based on the input above ... 1 less than is above. hpackDecoder.setMaxHeaderTableSize(4026531870L - 1); // based on the input above ... 1 less than is above.
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(0, in, mockHeaders, true); hpackDecoder.decode(0, in, mockHeaders, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -198,69 +219,103 @@ public class HpackDecoderTest {
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testLiteralHuffmanEncodedWithPaddingGreaterThan7Throws() throws Http2Exception { public void testLiteralHuffmanEncodedWithPaddingGreaterThan7Throws() throws Http2Exception {
byte[] input = {0, (byte) 0x81, -1}; byte[] input = {0, (byte) 0x81, -1};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(0, in, mockHeaders, true); hpackDecoder.decode(0, in, mockHeaders, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testLiteralHuffmanEncodedWithDecodingEOSThrows() throws Http2Exception { public void testLiteralHuffmanEncodedWithDecodingEOSThrows() throws Http2Exception {
byte[] input = {0, (byte) 0x84, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; byte[] input = {0, (byte) 0x84, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(0, in, mockHeaders, true); hpackDecoder.decode(0, in, mockHeaders, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testLiteralHuffmanEncodedWithPaddingNotCorrespondingToMSBThrows() throws Http2Exception { public void testLiteralHuffmanEncodedWithPaddingNotCorrespondingToMSBThrows() throws Http2Exception {
byte[] input = {0, (byte) 0x81, 0}; byte[] input = {0, (byte) 0x81, 0};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(0, in, mockHeaders, true); hpackDecoder.decode(0, in, mockHeaders, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testIncompleteIndex() throws Http2Exception { public void testIncompleteIndex() throws Http2Exception {
byte[] compressed = StringUtil.decodeHexDump("FFF0"); byte[] compressed = StringUtil.decodeHexDump("FFF0");
ByteBuf in = Unpooled.wrappedBuffer(compressed); final ByteBuf in = Unpooled.wrappedBuffer(compressed);
try { try {
assertEquals(2, in.readableBytes());
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(0, in, mockHeaders, true); hpackDecoder.decode(0, in, mockHeaders, true);
assertEquals(1, in.readableBytes()); }
hpackDecoder.decode(0, in, mockHeaders, true); });
} finally { } finally {
in.release(); in.release();
} }
} }
@Test(expected = Http2Exception.class) @Test
public void testUnusedIndex() throws Http2Exception { public void testUnusedIndex() throws Http2Exception {
// Index 0 is not used // Index 0 is not used
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("80"); decode("80");
} }
});
@Test(expected = Http2Exception.class)
public void testIllegalIndex() throws Http2Exception {
// Index larger than the header table
decode("FF00");
} }
@Test(expected = Http2Exception.class) @Test
public void testIllegalIndex() throws Http2Exception {
// Index larger than the header table
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("FF00");
}
});
}
@Test
public void testInsidiousIndex() throws Http2Exception { public void testInsidiousIndex() throws Http2Exception {
// Insidious index so the last shift causes sign overflow // Insidious index so the last shift causes sign overflow
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("FF8080808007"); decode("FF8080808007");
} }
});
}
@Test @Test
public void testDynamicTableSizeUpdate() throws Http2Exception { public void testDynamicTableSizeUpdate() throws Http2Exception {
@ -277,18 +332,28 @@ public class HpackDecoderTest {
assertEquals(31, hpackDecoder.getMaxHeaderTableSize()); assertEquals(31, hpackDecoder.getMaxHeaderTableSize());
} }
@Test(expected = Http2Exception.class) @Test
public void testIllegalDynamicTableSizeUpdate() throws Http2Exception { public void testIllegalDynamicTableSizeUpdate() throws Http2Exception {
// max header table size = MAX_HEADER_TABLE_SIZE + 1 // max header table size = MAX_HEADER_TABLE_SIZE + 1
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("3FE21F"); decode("3FE21F");
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void testInsidiousMaxDynamicTableSize() throws Http2Exception { public void testInsidiousMaxDynamicTableSize() throws Http2Exception {
hpackDecoder.setMaxHeaderTableSize(MAX_VALUE); hpackDecoder.setMaxHeaderTableSize(MAX_VALUE);
// max header table size sign overflow // max header table size sign overflow
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("3FE1FFFFFF07"); decode("3FE1FFFFFF07");
} }
});
}
@Test @Test
public void testMaxValidDynamicTableSize() throws Http2Exception { public void testMaxValidDynamicTableSize() throws Http2Exception {
@ -306,19 +371,29 @@ public class HpackDecoderTest {
decode("2081"); decode("2081");
} }
@Test(expected = Http2Exception.class) @Test
public void testTooLargeDynamicTableSizeUpdate() throws Http2Exception { public void testTooLargeDynamicTableSizeUpdate() throws Http2Exception {
hpackDecoder.setMaxHeaderTableSize(0); hpackDecoder.setMaxHeaderTableSize(0);
assertEquals(0, hpackDecoder.getMaxHeaderTableSize()); assertEquals(0, hpackDecoder.getMaxHeaderTableSize());
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("21"); // encoder max header table size not small enough decode("21"); // encoder max header table size not small enough
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void testMissingDynamicTableSizeUpdate() throws Http2Exception { public void testMissingDynamicTableSizeUpdate() throws Http2Exception {
hpackDecoder.setMaxHeaderTableSize(0); hpackDecoder.setMaxHeaderTableSize(0);
assertEquals(0, hpackDecoder.getMaxHeaderTableSize()); assertEquals(0, hpackDecoder.getMaxHeaderTableSize());
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode("81"); decode("81");
} }
});
}
@Test @Test
public void testLiteralWithIncrementalIndexingWithEmptyName() throws Http2Exception { public void testLiteralWithIncrementalIndexingWithEmptyName() throws Http2Exception {
@ -355,18 +430,23 @@ public class HpackDecoderTest {
verifyNoMoreInteractions(mockHeaders); verifyNoMoreInteractions(mockHeaders);
} }
@Test(expected = Http2Exception.class) @Test
public void testLiteralWithIncrementalIndexingWithLargeValue() throws Http2Exception { public void testLiteralWithIncrementalIndexingWithLargeValue() throws Http2Exception {
// Ignore header that exceeds max header size // Ignore header that exceeds max header size
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("4004"); sb.append("4004");
sb.append(hex("name")); sb.append(hex("name"));
sb.append("7F813F"); sb.append("7F813F");
for (int i = 0; i < 8192; i++) { for (int i = 0; i < 8192; i++) {
sb.append("61"); // 'a' sb.append("61"); // 'a'
} }
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode(sb.toString()); decode(sb.toString());
} }
});
}
@Test @Test
public void testLiteralWithoutIndexingWithEmptyName() throws Http2Exception { public void testLiteralWithoutIndexingWithEmptyName() throws Http2Exception {
@ -374,30 +454,40 @@ public class HpackDecoderTest {
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value")); verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
} }
@Test(expected = Http2Exception.class) @Test
public void testLiteralWithoutIndexingWithLargeName() throws Http2Exception { public void testLiteralWithoutIndexingWithLargeName() throws Http2Exception {
// Ignore header name that exceeds max header size // Ignore header name that exceeds max header size
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("007F817F"); sb.append("007F817F");
for (int i = 0; i < 16384; i++) { for (int i = 0; i < 16384; i++) {
sb.append("61"); // 'a' sb.append("61"); // 'a'
} }
sb.append("00"); sb.append("00");
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode(sb.toString()); decode(sb.toString());
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void testLiteralWithoutIndexingWithLargeValue() throws Http2Exception { public void testLiteralWithoutIndexingWithLargeValue() throws Http2Exception {
// Ignore header that exceeds max header size // Ignore header that exceeds max header size
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("0004"); sb.append("0004");
sb.append(hex("name")); sb.append(hex("name"));
sb.append("7F813F"); sb.append("7F813F");
for (int i = 0; i < 8192; i++) { for (int i = 0; i < 8192; i++) {
sb.append("61"); // 'a' sb.append("61"); // 'a'
} }
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode(sb.toString()); decode(sb.toString());
} }
});
}
@Test @Test
public void testLiteralNeverIndexedWithEmptyName() throws Http2Exception { public void testLiteralNeverIndexedWithEmptyName() throws Http2Exception {
@ -405,34 +495,44 @@ public class HpackDecoderTest {
verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value")); verify(mockHeaders, times(1)).add(EMPTY_STRING, of("value"));
} }
@Test(expected = Http2Exception.class) @Test
public void testLiteralNeverIndexedWithLargeName() throws Http2Exception { public void testLiteralNeverIndexedWithLargeName() throws Http2Exception {
// Ignore header name that exceeds max header size // Ignore header name that exceeds max header size
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("107F817F"); sb.append("107F817F");
for (int i = 0; i < 16384; i++) { for (int i = 0; i < 16384; i++) {
sb.append("61"); // 'a' sb.append("61"); // 'a'
} }
sb.append("00"); sb.append("00");
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode(sb.toString()); decode(sb.toString());
} }
});
}
@Test(expected = Http2Exception.class) @Test
public void testLiteralNeverIndexedWithLargeValue() throws Http2Exception { public void testLiteralNeverIndexedWithLargeValue() throws Http2Exception {
// Ignore header that exceeds max header size // Ignore header that exceeds max header size
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("1004"); sb.append("1004");
sb.append(hex("name")); sb.append(hex("name"));
sb.append("7F813F"); sb.append("7F813F");
for (int i = 0; i < 8192; i++) { for (int i = 0; i < 8192; i++) {
sb.append("61"); // 'a' sb.append("61"); // 'a'
} }
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
decode(sb.toString()); decode(sb.toString());
} }
});
}
@Test @Test
public void testDecodeLargerThanMaxHeaderListSizeUpdatesDynamicTable() throws Http2Exception { public void testDecodeLargerThanMaxHeaderListSizeUpdatesDynamicTable() throws Http2Exception {
ByteBuf in = Unpooled.buffer(300); final ByteBuf in = Unpooled.buffer(300);
try { try {
hpackDecoder.setMaxHeaderListSize(200); hpackDecoder.setMaxHeaderListSize(200);
HpackEncoder hpackEncoder = new HpackEncoder(true); HpackEncoder hpackEncoder = new HpackEncoder(true);
@ -446,13 +546,13 @@ public class HpackDecoderTest {
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
// decode the headers, we should get an exception // decode the headers, we should get an exception
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
try { assertThrows(Http2Exception.HeaderListSizeException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in, decoded, true); hpackDecoder.decode(1, in, decoded, true);
fail();
} catch (Http2Exception e) {
assertTrue(e instanceof Http2Exception.HeaderListSizeException);
} }
});
// but the dynamic table should have been updated, so that later blocks // but the dynamic table should have been updated, so that later blocks
// can refer to earlier headers // can refer to earlier headers
@ -494,7 +594,7 @@ public class HpackDecoderTest {
@Test @Test
public void testAccountForHeaderOverhead() throws Exception { public void testAccountForHeaderOverhead() throws Exception {
ByteBuf in = Unpooled.buffer(100); final ByteBuf in = Unpooled.buffer(100);
try { try {
String headerName = "12345"; String headerName = "12345";
String headerValue = "56789"; String headerValue = "56789";
@ -506,14 +606,18 @@ public class HpackDecoderTest {
toEncode.add(headerName, headerValue); toEncode.add(headerName, headerValue);
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
// SETTINGS_MAX_HEADER_LIST_SIZE is big enough for the header to fit... // SETTINGS_MAX_HEADER_LIST_SIZE is big enough for the header to fit...
assertThat(hpackDecoder.getMaxHeaderListSize(), is(greaterThanOrEqualTo(headerSize))); assertThat(hpackDecoder.getMaxHeaderListSize(), is(greaterThanOrEqualTo(headerSize)));
// ... but decode should fail because we add some overhead for each header entry // ... but decode should fail because we add some overhead for each header entry
expectedException.expect(Http2Exception.HeaderListSizeException.class); assertThrows(Http2Exception.HeaderListSizeException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in, decoded, true); hpackDecoder.decode(1, in, decoded, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -523,10 +627,14 @@ public class HpackDecoderTest {
public void testIncompleteHeaderFieldRepresentation() throws Http2Exception { public void testIncompleteHeaderFieldRepresentation() throws Http2Exception {
// Incomplete Literal Header Field with Incremental Indexing // Incomplete Literal Header Field with Incremental Indexing
byte[] input = {(byte) 0x40}; byte[] input = {(byte) 0x40};
ByteBuf in = Unpooled.wrappedBuffer(input); final ByteBuf in = Unpooled.wrappedBuffer(input);
try { try {
expectedException.expect(Http2Exception.class); assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(0, in, mockHeaders, true); hpackDecoder.decode(0, in, mockHeaders, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -534,7 +642,7 @@ public class HpackDecoderTest {
@Test @Test
public void unknownPseudoHeader() throws Exception { public void unknownPseudoHeader() throws Exception {
ByteBuf in = Unpooled.buffer(200); final ByteBuf in = Unpooled.buffer(200);
try { try {
HpackEncoder hpackEncoder = new HpackEncoder(true); HpackEncoder hpackEncoder = new HpackEncoder(true);
@ -542,10 +650,14 @@ public class HpackDecoderTest {
toEncode.add(":test", "1"); toEncode.add(":test", "1");
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
expectedException.expect(Http2Exception.StreamException.class); assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in, decoded, true); hpackDecoder.decode(1, in, decoded, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -577,7 +689,7 @@ public class HpackDecoderTest {
@Test @Test
public void requestPseudoHeaderInResponse() throws Exception { public void requestPseudoHeaderInResponse() throws Exception {
ByteBuf in = Unpooled.buffer(200); final ByteBuf in = Unpooled.buffer(200);
try { try {
HpackEncoder hpackEncoder = new HpackEncoder(true); HpackEncoder hpackEncoder = new HpackEncoder(true);
@ -586,10 +698,14 @@ public class HpackDecoderTest {
toEncode.add(":method", "GET"); toEncode.add(":method", "GET");
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
expectedException.expect(Http2Exception.StreamException.class); assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in, decoded, true); hpackDecoder.decode(1, in, decoded, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -597,7 +713,7 @@ public class HpackDecoderTest {
@Test @Test
public void responsePseudoHeaderInRequest() throws Exception { public void responsePseudoHeaderInRequest() throws Exception {
ByteBuf in = Unpooled.buffer(200); final ByteBuf in = Unpooled.buffer(200);
try { try {
HpackEncoder hpackEncoder = new HpackEncoder(true); HpackEncoder hpackEncoder = new HpackEncoder(true);
@ -606,10 +722,14 @@ public class HpackDecoderTest {
toEncode.add(":status", "200"); toEncode.add(":status", "200");
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
expectedException.expect(Http2Exception.StreamException.class); assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in, decoded, true); hpackDecoder.decode(1, in, decoded, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -617,7 +737,7 @@ public class HpackDecoderTest {
@Test @Test
public void pseudoHeaderAfterRegularHeader() throws Exception { public void pseudoHeaderAfterRegularHeader() throws Exception {
ByteBuf in = Unpooled.buffer(200); final ByteBuf in = Unpooled.buffer(200);
try { try {
HpackEncoder hpackEncoder = new HpackEncoder(true); HpackEncoder hpackEncoder = new HpackEncoder(true);
@ -626,10 +746,14 @@ public class HpackDecoderTest {
toEncode.add(":method", "GET"); toEncode.add(":method", "GET");
hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in, toEncode, NEVER_SENSITIVE);
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
expectedException.expect(Http2Exception.StreamException.class); assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in, decoded, true); hpackDecoder.decode(1, in, decoded, true);
}
});
} finally { } finally {
in.release(); in.release();
} }
@ -637,7 +761,7 @@ public class HpackDecoderTest {
@Test @Test
public void failedValidationDoesntCorruptHpack() throws Exception { public void failedValidationDoesntCorruptHpack() throws Exception {
ByteBuf in1 = Unpooled.buffer(200); final ByteBuf in1 = Unpooled.buffer(200);
ByteBuf in2 = Unpooled.buffer(200); ByteBuf in2 = Unpooled.buffer(200);
try { try {
HpackEncoder hpackEncoder = new HpackEncoder(true); HpackEncoder hpackEncoder = new HpackEncoder(true);
@ -648,14 +772,16 @@ public class HpackDecoderTest {
toEncode.add("foo", "bar"); toEncode.add("foo", "bar");
hpackEncoder.encodeHeaders(1, in1, toEncode, NEVER_SENSITIVE); hpackEncoder.encodeHeaders(1, in1, toEncode, NEVER_SENSITIVE);
Http2Headers decoded = new DefaultHttp2Headers(); final Http2Headers decoded = new DefaultHttp2Headers();
try { Http2Exception.StreamException expected =
assertThrows(Http2Exception.StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackDecoder.decode(1, in1, decoded, true); hpackDecoder.decode(1, in1, decoded, true);
fail("Should have thrown a StreamException");
} catch (Http2Exception.StreamException expected) {
assertEquals(1, expected.streamId());
} }
});
assertEquals(1, expected.streamId());
// Do it again, this time without validation, to make sure the HPACK state is still sane. // Do it again, this time without validation, to make sure the HPACK state is still sane.
decoded.clear(); decoded.clear();

View File

@ -15,11 +15,12 @@
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertNull; import org.junit.jupiter.api.function.Executable;
import static org.junit.Assert.fail;
import org.junit.Test; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class HpackDynamicTableTest { public class HpackDynamicTableTest {
@ -47,24 +48,30 @@ public class HpackDynamicTableTest {
@Test @Test
public void testGetEntry() { public void testGetEntry() {
HpackDynamicTable table = new HpackDynamicTable(100); final HpackDynamicTable table = new HpackDynamicTable(100);
HpackHeaderField entry = new HpackHeaderField("foo", "bar"); HpackHeaderField entry = new HpackHeaderField("foo", "bar");
table.add(entry); table.add(entry);
assertEquals(entry, table.getEntry(1)); assertEquals(entry, table.getEntry(1));
table.clear(); table.clear();
try {
assertThrows(IndexOutOfBoundsException.class, new Executable() {
@Override
public void execute() throws Throwable {
table.getEntry(1); table.getEntry(1);
fail();
} catch (IndexOutOfBoundsException e) {
//success
} }
});
} }
@Test(expected = IndexOutOfBoundsException.class) @Test
public void testGetEntryExceptionally() { public void testGetEntryExceptionally() {
HpackDynamicTable table = new HpackDynamicTable(1); final HpackDynamicTable table = new HpackDynamicTable(1);
assertThrows(IndexOutOfBoundsException.class, new Executable() {
@Override
public void execute() throws Throwable {
table.getEntry(1); table.getEntry(1);
} }
});
}
@Test @Test
public void testRemove() { public void testRemove() {

View File

@ -17,12 +17,15 @@ package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_HEADER_LIST_SIZE;
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_TABLE_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_HEADER_TABLE_SIZE;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
public class HpackEncoderTest { public class HpackEncoderTest {
@ -30,7 +33,7 @@ public class HpackEncoderTest {
private HpackEncoder hpackEncoder; private HpackEncoder hpackEncoder;
private Http2Headers mockHeaders; private Http2Headers mockHeaders;
@Before @BeforeEach
public void setUp() { public void setUp() {
hpackEncoder = new HpackEncoder(); hpackEncoder = new HpackEncoder();
hpackDecoder = new HpackDecoder(DEFAULT_HEADER_LIST_SIZE); hpackDecoder = new HpackDecoder(DEFAULT_HEADER_LIST_SIZE);
@ -47,11 +50,16 @@ public class HpackEncoderTest {
buf.release(); buf.release();
} }
@Test(expected = Http2Exception.class) @Test
public void testSetMaxHeaderTableSizeOverflow() throws Http2Exception { public void testSetMaxHeaderTableSizeOverflow() throws Http2Exception {
ByteBuf buf = Unpooled.buffer(); final ByteBuf buf = Unpooled.buffer();
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackEncoder.setMaxHeaderTableSize(buf, MAX_HEADER_TABLE_SIZE + 1); hpackEncoder.setMaxHeaderTableSize(buf, MAX_HEADER_TABLE_SIZE + 1);
}
});
} finally { } finally {
buf.release(); buf.release();
} }
@ -82,10 +90,10 @@ public class HpackEncoderTest {
assertEquals(headersOut.get(bigHeaderName).toString(), bigHeaderVal); assertEquals(headersOut.get(bigHeaderName).toString(), bigHeaderVal);
} }
@Test(expected = Http2Exception.class) @Test
public void testSetMaxHeaderListSizeEnforcedAfterSet() throws Http2Exception { public void testSetMaxHeaderListSizeEnforcedAfterSet() throws Http2Exception {
ByteBuf buf = Unpooled.buffer(); final ByteBuf buf = Unpooled.buffer();
Http2Headers headers = new DefaultHttp2Headers().add( final Http2Headers headers = new DefaultHttp2Headers().add(
"x-big-header", "x-big-header",
new String(new char[1024 * 16]).replace('\0', 'X') new String(new char[1024 * 16]).replace('\0', 'X')
); );
@ -93,7 +101,12 @@ public class HpackEncoderTest {
hpackEncoder.setMaxHeaderListSize(1000); hpackEncoder.setMaxHeaderListSize(1000);
try { try {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
hpackEncoder.encodeHeaders(0, buf, headers, Http2HeadersEncoder.NEVER_SENSITIVE); hpackEncoder.encodeHeaders(0, buf, headers, Http2HeadersEncoder.NEVER_SENSITIVE);
}
});
} finally { } finally {
buf.release(); buf.release();
} }

View File

@ -33,43 +33,27 @@ package io.netty.handler.codec.http2;
import io.netty.util.internal.ObjectUtil; import io.netty.util.internal.ObjectUtil;
import io.netty.util.internal.ResourcesUtil; import io.netty.util.internal.ResourcesUtil;
import org.junit.Test; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.runner.RunWith; import org.junit.jupiter.params.provider.MethodSource;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
@RunWith(Parameterized.class)
public class HpackTest { public class HpackTest {
private static final String TEST_DIR = '/' + HpackTest.class.getPackage().getName().replaceAll("\\.", "/") private static final String TEST_DIR = '/' + HpackTest.class.getPackage().getName().replaceAll("\\.", "/")
+ "/testdata/"; + "/testdata/";
private final String fileName; public static File[] files() {
public HpackTest(String fileName) {
this.fileName = fileName;
}
@Parameters(name = "{0}")
public static Collection<Object[]> data() {
File[] files = ResourcesUtil.getFile(HpackTest.class, TEST_DIR).listFiles(); File[] files = ResourcesUtil.getFile(HpackTest.class, TEST_DIR).listFiles();
ObjectUtil.checkNotNull(files, "files"); ObjectUtil.checkNotNull(files, "files");
return files;
ArrayList<Object[]> data = new ArrayList<Object[]>();
for (File file : files) {
data.add(new Object[]{file.getName()});
}
return data;
} }
@Test @ParameterizedTest(name = "file = {0}")
public void test() throws Exception { @MethodSource("files")
InputStream is = HpackTest.class.getResourceAsStream(TEST_DIR + fileName); public void test(File file) throws Exception {
InputStream is = HpackTest.class.getResourceAsStream(TEST_DIR + file.getName());
HpackTestCase hpackTestCase = HpackTestCase.load(is); HpackTestCase hpackTestCase = HpackTestCase.load(is);
hpackTestCase.testCompress(); hpackTestCase.testCompress();
hpackTestCase.testDecompress(); hpackTestCase.testDecompress();

View File

@ -22,13 +22,12 @@ import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Test;
public class Http2ClientUpgradeCodecTest { public class Http2ClientUpgradeCodecTest {
@Test @Test

View File

@ -35,13 +35,13 @@ import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.ImmediateEventExecutor;
import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.Promise;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
@ -50,7 +50,6 @@ import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import static io.netty.buffer.Unpooled.copiedBuffer; import static io.netty.buffer.Unpooled.copiedBuffer;
import static io.netty.handler.codec.http2.Http2CodecUtil.connectionPrefaceBuf; import static io.netty.handler.codec.http2.Http2CodecUtil.connectionPrefaceBuf;
@ -63,10 +62,10 @@ import static io.netty.handler.codec.http2.Http2TestUtil.newVoidPromise;
import static io.netty.util.CharsetUtil.US_ASCII; import static io.netty.util.CharsetUtil.US_ASCII;
import static io.netty.util.CharsetUtil.UTF_8; import static io.netty.util.CharsetUtil.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -143,7 +142,7 @@ public class Http2ConnectionHandlerTest {
private String goAwayDebugCap; private String goAwayDebugCap;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -227,7 +226,7 @@ public class Http2ConnectionHandlerTest {
return handler; return handler;
} }
@After @AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
if (handler != null) { if (handler != null) {
handler.handlerRemoved(ctx); handler.handlerRemoved(ctx);
@ -237,23 +236,25 @@ public class Http2ConnectionHandlerTest {
@Test @Test
public void onHttpServerUpgradeWithoutHandlerAdded() throws Exception { public void onHttpServerUpgradeWithoutHandlerAdded() throws Exception {
handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(true).build(); handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(true).build();
try { Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
handler.onHttpServerUpgrade(new Http2Settings()); handler.onHttpServerUpgrade(new Http2Settings());
fail();
} catch (Http2Exception e) {
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
} }
});
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
} }
@Test @Test
public void onHttpClientUpgradeWithoutHandlerAdded() throws Exception { public void onHttpClientUpgradeWithoutHandlerAdded() throws Exception {
handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(false).build(); handler = new Http2ConnectionHandlerBuilder().frameListener(new Http2FrameAdapter()).server(false).build();
try { Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
handler.onHttpClientUpgrade(); handler.onHttpClientUpgrade();
fail();
} catch (Http2Exception e) {
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
} }
});
assertEquals(Http2Error.INTERNAL_ERROR, e.error());
} }
@Test @Test

View File

@ -40,9 +40,10 @@ import io.netty.util.AsciiString;
import io.netty.util.IllegalReferenceCountException; import io.netty.util.IllegalReferenceCountException;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -69,13 +70,13 @@ import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -115,14 +116,14 @@ public class Http2ConnectionRoundtripTest {
private CountDownLatch trailersLatch; private CountDownLatch trailersLatch;
private CountDownLatch goAwayLatch; private CountDownLatch goAwayLatch;
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mockFlowControl(clientListener); mockFlowControl(clientListener);
mockFlowControl(serverListener); mockFlowControl(serverListener);
} }
@After @AfterEach
public void teardown() throws Exception { public void teardown() throws Exception {
if (clientChannel != null) { if (clientChannel != null) {
clientChannel.close().syncUninterruptibly(); clientChannel.close().syncUninterruptibly();
@ -311,8 +312,8 @@ public class Http2ConnectionRoundtripTest {
}); });
assertTrue(clientDataWrite.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS)); assertTrue(clientDataWrite.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
assertNotNull("Header encode should have exceeded maxHeaderListSize!", clientHeadersWriteException.get()); assertNotNull(clientHeadersWriteException.get(), "Header encode should have exceeded maxHeaderListSize!");
assertNotNull("Data on closed stream should fail!", clientDataWriteException.get()); assertNotNull(clientDataWriteException.get(), "Data on closed stream should fail!");
// Set the maxHeaderListSize to the max value so we can send the headers. // Set the maxHeaderListSize to the max value so we can send the headers.
runInChannel(serverConnectedChannel, new Http2Runnable() { runInChannel(serverConnectedChannel, new Http2Runnable() {
@ -345,8 +346,8 @@ public class Http2ConnectionRoundtripTest {
}); });
assertTrue(clientHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS)); assertTrue(clientHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
assertNull("Client write of headers should succeed with increased header list size!", assertNull(clientHeadersWriteException2.get(),
clientHeadersWriteException2.get()); "Client write of headers should succeed with increased header list size!");
assertTrue(serverRevHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS)); assertTrue(serverRevHeadersLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), any(ByteBuf.class), verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), any(ByteBuf.class),
@ -724,12 +725,13 @@ public class Http2ConnectionRoundtripTest {
} }
}); });
try { ExecutionException e = assertThrows(ExecutionException.class, new Executable() {
@Override
public void execute() throws Throwable {
emptyDataPromise.get(); emptyDataPromise.get();
fail();
} catch (ExecutionException e) {
assertThat(e.getCause(), is(instanceOf(IllegalReferenceCountException.class)));
} }
});
assertThat(e.getCause(), is(instanceOf(IllegalReferenceCountException.class)));
} }
@Test @Test
@ -775,13 +777,13 @@ public class Http2ConnectionRoundtripTest {
} }
}); });
try { ExecutionException e = assertThrows(ExecutionException.class, new Executable() {
@Override
public void execute() throws Throwable {
dataPromise.get(); dataPromise.get();
fail();
} catch (ExecutionException e) {
assertThat(e.getCause(), is(instanceOf(IllegalStateException.class)));
} }
});
assertThat(e.getCause(), is(instanceOf(IllegalStateException.class)));
assertPromise.sync(); assertPromise.sync();
} }

View File

@ -25,13 +25,12 @@ import io.netty.channel.ChannelMetadata;
import io.netty.channel.ChannelPromise; import io.netty.channel.ChannelPromise;
import io.netty.channel.DefaultChannelPromise; import io.netty.channel.DefaultChannelPromise;
import io.netty.channel.DefaultMessageSizeEstimator; import io.netty.channel.DefaultMessageSizeEstimator;
import io.netty.handler.codec.http2.Http2Exception.ShutdownHint;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.ImmediateEventExecutor;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -44,7 +43,9 @@ import java.util.Queue;
import static io.netty.handler.codec.http2.Http2CodecUtil.*; import static io.netty.handler.codec.http2.Http2CodecUtil.*;
import static io.netty.handler.codec.http2.Http2Error.CANCEL; import static io.netty.handler.codec.http2.Http2Error.CANCEL;
import static io.netty.handler.codec.http2.Http2Error.ENHANCE_YOUR_CALM; import static io.netty.handler.codec.http2.Http2Error.ENHANCE_YOUR_CALM;
import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
/** /**
@ -79,7 +80,7 @@ public class Http2ControlFrameLimitEncoderTest {
/** /**
* Init fields and do mocking. * Init fields and do mocking.
*/ */
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -171,7 +172,7 @@ public class Http2ControlFrameLimitEncoderTest {
return promise; return promise;
} }
@After @AfterEach
public void teardown() { public void teardown() {
// Close and release any buffered frames. // Close and release any buffered frames.
encoder.close(); encoder.close();

View File

@ -17,9 +17,9 @@ package io.netty.handler.codec.http2;
import io.netty.buffer.DefaultByteBufHolder; import io.netty.buffer.DefaultByteBufHolder;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import org.junit.Test; import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
public class Http2DefaultFramesTest { public class Http2DefaultFramesTest {

View File

@ -15,13 +15,13 @@
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;

View File

@ -17,11 +17,12 @@ package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.Mock; import org.mockito.Mock;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@ -41,7 +42,7 @@ public class Http2EmptyDataFrameListenerTest {
private Http2EmptyDataFrameListener listener; private Http2EmptyDataFrameListener listener;
@Before @BeforeEach
public void setUp() { public void setUp() {
initMocks(this); initMocks(this);
when(nonEmpty.isReadable()).thenReturn(true); when(nonEmpty.isReadable()).thenReturn(true);
@ -53,67 +54,68 @@ public class Http2EmptyDataFrameListenerTest {
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
fail();
} catch (Http2Exception expected) {
// expected
} }
});
verify(frameListener, times(2)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false)); verify(frameListener, times(2)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
} }
@Test @Test
public void testEmptyDataFramesWithNonEmptyInBetween() throws Http2Exception { public void testEmptyDataFramesWithNonEmptyInBetween() throws Http2Exception {
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2); final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, nonEmpty, 0, false); listener.onDataRead(ctx, 1, nonEmpty, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
fail();
} catch (Http2Exception expected) {
// expected
} }
});
verify(frameListener, times(4)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false)); verify(frameListener, times(4)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
} }
@Test @Test
public void testEmptyDataFramesWithEndOfStreamInBetween() throws Http2Exception { public void testEmptyDataFramesWithEndOfStreamInBetween() throws Http2Exception {
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2); final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, true); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, true);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
fail();
} catch (Http2Exception expected) {
// expected
} }
});
verify(frameListener, times(1)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(true)); verify(frameListener, times(1)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(true));
verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false)); verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
} }
@Test @Test
public void testEmptyDataFramesWithHeaderFrameInBetween() throws Http2Exception { public void testEmptyDataFramesWithHeaderFrameInBetween() throws Http2Exception {
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2); final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, true); listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, true);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
fail();
} catch (Http2Exception expected) {
// expected
} }
});
verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1), eq(EmptyHttp2Headers.INSTANCE), eq(0), eq(true)); verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1), eq(EmptyHttp2Headers.INSTANCE), eq(0), eq(true));
verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false)); verify(frameListener, times(3)).onDataRead(eq(ctx), eq(1), any(ByteBuf.class), eq(0), eq(false));
@ -121,19 +123,19 @@ public class Http2EmptyDataFrameListenerTest {
@Test @Test
public void testEmptyDataFramesWithHeaderFrameInBetween2() throws Http2Exception { public void testEmptyDataFramesWithHeaderFrameInBetween2() throws Http2Exception {
Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2); final Http2EmptyDataFrameListener listener = new Http2EmptyDataFrameListener(frameListener, 2);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, (short) 0, false, 0, true); listener.onHeadersRead(ctx, 1, EmptyHttp2Headers.INSTANCE, 0, (short) 0, false, 0, true);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false); listener.onDataRead(ctx, 1, Unpooled.EMPTY_BUFFER, 0, false);
fail();
} catch (Http2Exception expected) {
// expected
} }
});
verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1), verify(frameListener, times(1)).onHeadersRead(eq(ctx), eq(1),
eq(EmptyHttp2Headers.INSTANCE), eq(0), eq((short) 0), eq(false), eq(0), eq(true)); eq(EmptyHttp2Headers.INSTANCE), eq(0), eq((short) 0), eq(false), eq(0), eq(true));

View File

@ -42,16 +42,19 @@ import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.GlobalEventExecutor; import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.Promise;
import io.netty.util.internal.ReflectionUtil; import io.netty.util.internal.ReflectionUtil;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Assume; import org.junit.jupiter.api.Assumptions;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid; import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid;
@ -62,12 +65,12 @@ import static io.netty.handler.codec.http2.Http2TestUtil.assertEqualsAndRelease;
import static io.netty.handler.codec.http2.Http2TestUtil.bb; import static io.netty.handler.codec.http2.Http2TestUtil.bb;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.anyLong;
@ -98,12 +101,12 @@ public class Http2FrameCodecTest {
private final Http2Headers response = new DefaultHttp2Headers() private final Http2Headers response = new DefaultHttp2Headers()
.status(HttpResponseStatus.OK.codeAsText()); .status(HttpResponseStatus.OK.codeAsText());
@Before @BeforeEach
public void setUp() throws Exception { public void setUp() throws Exception {
setUp(Http2FrameCodecBuilder.forServer(), new Http2Settings()); setUp(Http2FrameCodecBuilder.forServer(), new Http2Settings());
} }
@After @AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
if (inboundHandler != null) { if (inboundHandler != null) {
inboundHandler.finishAndReleaseAll(); inboundHandler.finishAndReleaseAll();
@ -425,12 +428,13 @@ public class Http2FrameCodecTest {
Http2HeadersFrame headersFrame = inboundHandler.readInboundMessageOrUserEvent(); Http2HeadersFrame headersFrame = inboundHandler.readInboundMessageOrUserEvent();
assertNotNull(headersFrame); assertNotNull(headersFrame);
try { Http2FrameStreamException e = assertThrows(Http2FrameStreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
inboundHandler.checkException(); inboundHandler.checkException();
fail("stream exception expected");
} catch (Http2FrameStreamException e) {
assertEquals(streamEx, e.getCause());
} }
});
assertEquals(streamEx, e.getCause());
assertNull(inboundHandler.readInboundMessageOrUserEvent()); assertNull(inboundHandler.readInboundMessageOrUserEvent());
} }
@ -576,7 +580,8 @@ public class Http2FrameCodecTest {
verify(frameWriter).writeSettings(eqFrameCodecCtx(), same(settings), any(ChannelPromise.class)); verify(frameWriter).writeSettings(eqFrameCodecCtx(), same(settings), any(ChannelPromise.class));
} }
@Test(timeout = 5000) @Test
@Timeout(value = 5000, unit = TimeUnit.MILLISECONDS)
public void newOutboundStream() { public void newOutboundStream() {
final Http2FrameStream stream = frameCodec.newStream(); final Http2FrameStream stream = frameCodec.newStream();
@ -847,7 +852,7 @@ public class Http2FrameCodecTest {
UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class); UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
// Check if we could make it accessible which may fail on java9. // Check if we could make it accessible which may fail on java9.
Assume.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null); Assumptions.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
HttpServerUpgradeHandler.UpgradeEvent upgradeEvent = constructor.newInstance( HttpServerUpgradeHandler.UpgradeEvent upgradeEvent = constructor.newInstance(
"HTTP/2", new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/")); "HTTP/2", new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));
@ -885,7 +890,7 @@ public class Http2FrameCodecTest {
UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class); UpgradeEvent.class.getDeclaredConstructor(CharSequence.class, FullHttpRequest.class);
// Check if we could make it accessible which may fail on java9. // Check if we could make it accessible which may fail on java9.
Assume.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null); Assumptions.assumeTrue(ReflectionUtil.trySetAccessible(constructor, true) == null);
String longString = new String(new char[70000]).replace("\0", "*"); String longString = new String(new char[70000]).replace("\0", "*");
DefaultFullHttpRequest request = DefaultFullHttpRequest request =

View File

@ -27,9 +27,10 @@ import io.netty.channel.DefaultChannelPromise;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.GlobalEventExecutor; import io.netty.util.concurrent.GlobalEventExecutor;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@ -47,9 +48,9 @@ import static io.netty.handler.codec.http2.Http2TestUtil.newTestEncoder;
import static io.netty.handler.codec.http2.Http2TestUtil.randomString; import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
import static io.netty.util.CharsetUtil.UTF_8; import static io.netty.util.CharsetUtil.UTF_8;
import static java.lang.Math.min; import static java.lang.Math.min;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -90,7 +91,7 @@ public class Http2FrameRoundtripTest {
private Http2FrameReader reader; private Http2FrameReader reader;
private final List<ByteBuf> needReleasing = new LinkedList<ByteBuf>(); private final List<ByteBuf> needReleasing = new LinkedList<ByteBuf>();
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -120,7 +121,7 @@ public class Http2FrameRoundtripTest {
reader = new DefaultHttp2FrameReader(new DefaultHttp2HeadersDecoder(false, newTestDecoder())); reader = new DefaultHttp2FrameReader(new DefaultHttp2HeadersDecoder(false, newTestDecoder()));
} }
@After @AfterEach
public void teardown() { public void teardown() {
try { try {
// Release all of the buffers. // Release all of the buffers.
@ -286,15 +287,16 @@ public class Http2FrameRoundtripTest {
reader.configuration().headersConfiguration().maxHeaderListSize(maxListSize, maxListSize); reader.configuration().headersConfiguration().maxHeaderListSize(maxListSize, maxListSize);
final Http2Headers headers = headersOfSize(maxListSize + 1); final Http2Headers headers = headersOfSize(maxListSize + 1);
writer.writeHeaders(ctx, STREAM_ID, headers, 2, (short) 3, true, MAX_PADDING, true, ctx.newPromise()); writer.writeHeaders(ctx, STREAM_ID, headers, 2, (short) 3, true, MAX_PADDING, true, ctx.newPromise());
try { assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
readFrames(); readFrames();
fail(); }
} catch (Http2Exception e) { });
verify(listener, never()).onHeadersRead(any(ChannelHandlerContext.class), anyInt(), verify(listener, never()).onHeadersRead(any(ChannelHandlerContext.class), anyInt(),
any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(), any(Http2Headers.class), anyInt(), anyShort(), anyBoolean(), anyInt(),
anyBoolean()); anyBoolean());
} }
}
@Test @Test
public void emptyPushPromiseShouldMatch() throws Exception { public void emptyPushPromiseShouldMatch() throws Exception {

View File

@ -18,12 +18,12 @@ package io.netty.handler.codec.http2;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import static io.netty.handler.codec.http2.Http2TestUtil.randomString; import static io.netty.handler.codec.http2.Http2TestUtil.randomString;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* Tests for encoding/decoding HTTP2 header blocks. * Tests for encoding/decoding HTTP2 header blocks.
@ -34,14 +34,14 @@ public class Http2HeaderBlockIOTest {
private DefaultHttp2HeadersEncoder encoder; private DefaultHttp2HeadersEncoder encoder;
private ByteBuf buffer; private ByteBuf buffer;
@Before @BeforeEach
public void setup() { public void setup() {
encoder = new DefaultHttp2HeadersEncoder(); encoder = new DefaultHttp2HeadersEncoder();
decoder = new DefaultHttp2HeadersDecoder(false); decoder = new DefaultHttp2HeadersDecoder(false);
buffer = Unpooled.buffer(); buffer = Unpooled.buffer();
} }
@After @AfterEach
public void teardown() { public void teardown() {
buffer.release(); buffer.release();
} }

View File

@ -14,17 +14,18 @@
*/ */
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import org.junit.Test;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public abstract class Http2MultiplexClientUpgradeTest<C extends Http2FrameCodec> { public abstract class Http2MultiplexClientUpgradeTest<C extends Http2FrameCodec> {
@ -76,14 +77,20 @@ public abstract class Http2MultiplexClientUpgradeTest<C extends Http2FrameCodec>
assertTrue(upgradeHandler.channelInactiveCalled); assertTrue(upgradeHandler.channelInactiveCalled);
} }
@Test(expected = Http2Exception.class) @Test
public void clientUpgradeWithoutUpgradeHandlerThrowsHttp2Exception() throws Http2Exception { public void clientUpgradeWithoutUpgradeHandlerThrowsHttp2Exception() throws Http2Exception {
C codec = newCodec(null); final C codec = newCodec(null);
EmbeddedChannel ch = new EmbeddedChannel(codec, newMultiplexer(null)); final EmbeddedChannel ch = new EmbeddedChannel(codec, newMultiplexer(null));
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Http2Exception {
try { try {
codec.onHttpClientUpgrade(); codec.onHttpClientUpgrade();
} finally { } finally {
assertTrue(ch.finishAndReleaseAll()); ch.finishAndReleaseAll();
} }
} }
});
}
} }

View File

@ -32,21 +32,23 @@ import io.netty.channel.EventLoopGroup;
import io.netty.channel.local.LocalAddress; import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel; import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel; import io.netty.channel.local.LocalServerChannel;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeAll;
import org.junit.BeforeClass; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid; import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
/** /**
* Unit tests for {@link Http2MultiplexCodec}. * Unit tests for {@link Http2MultiplexCodec}.
@ -59,12 +61,12 @@ public class Http2MultiplexCodecBuilderTest {
private Channel clientChannel; private Channel clientChannel;
private LastInboundHandler serverLastInboundHandler; private LastInboundHandler serverLastInboundHandler;
@BeforeClass @BeforeAll
public static void init() { public static void init() {
group = new DefaultEventLoop(); group = new DefaultEventLoop();
} }
@Before @BeforeEach
public void setUp() throws InterruptedException { public void setUp() throws InterruptedException {
final CountDownLatch serverChannelLatch = new CountDownLatch(1); final CountDownLatch serverChannelLatch = new CountDownLatch(1);
LocalAddress serverAddress = new LocalAddress(getClass().getName()); LocalAddress serverAddress = new LocalAddress(getClass().getName());
@ -115,7 +117,7 @@ public class Http2MultiplexCodecBuilderTest {
.handler(new Http2MultiplexCodecBuilder(false, new ChannelInitializer<Channel>() { .handler(new Http2MultiplexCodecBuilder(false, new ChannelInitializer<Channel>() {
@Override @Override
protected void initChannel(Channel ch) throws Exception { protected void initChannel(Channel ch) throws Exception {
Assert.fail("Should not be called for outbound streams"); fail("Should not be called for outbound streams");
} }
}).build()); }).build());
clientChannel = cb.connect(serverAddress).sync().channel(); clientChannel = cb.connect(serverAddress).sync().channel();
@ -127,7 +129,7 @@ public class Http2MultiplexCodecBuilderTest {
group.shutdownGracefully(0, 5, SECONDS); group.shutdownGracefully(0, 5, SECONDS);
} }
@After @AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
if (clientChannel != null) { if (clientChannel != null) {
clientChannel.close().syncUninterruptibly(); clientChannel.close().syncUninterruptibly();
@ -251,8 +253,13 @@ public class Http2MultiplexCodecBuilderTest {
assertNotNull(Http2MultiplexCodecBuilder.forServer(new SharableChannelHandler2())); assertNotNull(Http2MultiplexCodecBuilder.forServer(new SharableChannelHandler2()));
} }
@Test(expected = IllegalArgumentException.class) @Test
public void testUnsharableHandler() { public void testUnsharableHandler() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() throws Throwable {
Http2MultiplexCodecBuilder.forServer(new UnsharableChannelHandler()); Http2MultiplexCodecBuilder.forServer(new UnsharableChannelHandler());
} }
});
}
} }

View File

@ -33,10 +33,10 @@ import io.netty.handler.codec.http2.Http2Exception.StreamException;
import io.netty.handler.codec.http2.LastInboundHandler.Consumer; import io.netty.handler.codec.http2.LastInboundHandler.Consumer;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.AfterEach;
import org.junit.After; import org.junit.jupiter.api.BeforeEach;
import org.junit.Before; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatcher;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -56,13 +56,13 @@ import static io.netty.handler.codec.http2.Http2TestUtil.anyHttp2Settings;
import static io.netty.handler.codec.http2.Http2TestUtil.assertEqualsAndRelease; import static io.netty.handler.codec.http2.Http2TestUtil.assertEqualsAndRelease;
import static io.netty.handler.codec.http2.Http2TestUtil.bb; import static io.netty.handler.codec.http2.Http2TestUtil.bb;
import static io.netty.util.ReferenceCountUtil.release; import static io.netty.util.ReferenceCountUtil.release;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
@ -72,7 +72,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
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 static org.hamcrest.MatcherAssert.assertThat;
public abstract class Http2MultiplexTest<C extends Http2FrameCodec> { public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
private final Http2Headers request = new DefaultHttp2Headers() private final Http2Headers request = new DefaultHttp2Headers()
@ -90,7 +89,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
protected abstract C newCodec(TestChannelInitializer childChannelInitializer, Http2FrameWriter frameWriter); protected abstract C newCodec(TestChannelInitializer childChannelInitializer, Http2FrameWriter frameWriter);
protected abstract ChannelHandler newMultiplexer(TestChannelInitializer childChannelInitializer); protected abstract ChannelHandler newMultiplexer(TestChannelInitializer childChannelInitializer);
@Before @BeforeEach
public void setUp() { public void setUp() {
childChannelInitializer = new TestChannelInitializer(); childChannelInitializer = new TestChannelInitializer();
parentChannel = new EmbeddedChannel(); parentChannel = new EmbeddedChannel();
@ -130,7 +129,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
return eq(codec.ctx); return eq(codec.ctx);
} }
@After @AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
if (childChannelInitializer.handler instanceof LastInboundHandler) { if (childChannelInitializer.handler instanceof LastInboundHandler) {
((LastInboundHandler) childChannelInitializer.handler).finishAndReleaseAll(); ((LastInboundHandler) childChannelInitializer.handler).finishAndReleaseAll();
@ -233,16 +232,17 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
} }
private void headerMultipleContentLengthValidationShouldPropagate(boolean endStream) { private void headerMultipleContentLengthValidationShouldPropagate(boolean endStream) {
LastInboundHandler inboundHandler = new LastInboundHandler(); final LastInboundHandler inboundHandler = new LastInboundHandler();
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 0); request.addLong(HttpHeaderNames.CONTENT_LENGTH, 0);
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1); request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler); Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
try {
assertThrows(StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
inboundHandler.checkException(); inboundHandler.checkException();
fail();
} catch (Exception e) {
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
} }
});
assertNull(inboundHandler.readInbound()); assertNull(inboundHandler.readInbound());
assertFalse(channel.isActive()); assertFalse(channel.isActive());
} }
@ -268,15 +268,16 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
} }
private void headerSignContentLengthValidationShouldPropagateWithEndStream(boolean minus, boolean endStream) { private void headerSignContentLengthValidationShouldPropagateWithEndStream(boolean minus, boolean endStream) {
LastInboundHandler inboundHandler = new LastInboundHandler(); final LastInboundHandler inboundHandler = new LastInboundHandler();
request.add(HttpHeaderNames.CONTENT_LENGTH, (minus ? "-" : "+") + 1); request.add(HttpHeaderNames.CONTENT_LENGTH, (minus ? "-" : "+") + 1);
Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler); Http2StreamChannel channel = newInboundStream(3, endStream, inboundHandler);
try { assertThrows(StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
inboundHandler.checkException(); inboundHandler.checkException();
fail();
} catch (Exception e) {
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
} }
});
assertNull(inboundHandler.readInbound()); assertNull(inboundHandler.readInbound());
assertFalse(channel.isActive()); assertFalse(channel.isActive());
} }
@ -323,7 +324,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
private void headerContentLengthNotMatchValidationShouldPropagate( private void headerContentLengthNotMatchValidationShouldPropagate(
boolean closeLocal, boolean endStream, boolean trailer) { boolean closeLocal, boolean endStream, boolean trailer) {
LastInboundHandler inboundHandler = new LastInboundHandler(); final LastInboundHandler inboundHandler = new LastInboundHandler();
request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1); request.addLong(HttpHeaderNames.CONTENT_LENGTH, 1);
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler); Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
assertTrue(channel.isActive()); assertTrue(channel.isActive());
@ -341,12 +342,14 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
} else { } else {
frameInboundWriter.writeInboundData(channel.stream().id(), bb("foo"), 0, endStream); frameInboundWriter.writeInboundData(channel.stream().id(), bb("foo"), 0, endStream);
} }
try {
assertThrows(StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
inboundHandler.checkException(); inboundHandler.checkException();
fail();
} catch (Exception e) {
assertThat(e, CoreMatchers.<Exception>instanceOf(StreamException.class));
} }
});
Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(request).stream(channel.stream()); Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(request).stream(channel.stream());
assertEquals(headersFrame, inboundHandler.readInbound()); assertEquals(headersFrame, inboundHandler.readInbound());
assertNull(inboundHandler.readInbound()); assertNull(inboundHandler.readInbound());
@ -617,19 +620,25 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
anyLong(), anyChannelPromise()); anyLong(), anyChannelPromise());
} }
@Test(expected = StreamException.class) @Test
public void streamExceptionTriggersChildChannelExceptionAndClose() throws Exception { public void streamExceptionTriggersChildChannelExceptionAndClose() throws Exception {
LastInboundHandler inboundHandler = new LastInboundHandler(); final LastInboundHandler inboundHandler = new LastInboundHandler();
Http2StreamChannel channel = newInboundStream(3, false, inboundHandler); Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
assertTrue(channel.isActive()); assertTrue(channel.isActive());
StreamException cause = new StreamException(channel.stream().id(), Http2Error.PROTOCOL_ERROR, "baaam!"); StreamException cause = new StreamException(channel.stream().id(), Http2Error.PROTOCOL_ERROR, "baaam!");
parentChannel.pipeline().fireExceptionCaught(cause); parentChannel.pipeline().fireExceptionCaught(cause);
assertFalse(channel.isActive()); assertFalse(channel.isActive());
assertThrows(StreamException.class, new Executable() {
@Override
public void execute() throws Throwable {
inboundHandler.checkException(); inboundHandler.checkException();
} }
});
}
@Test(expected = ClosedChannelException.class) @Test
public void streamClosedErrorTranslatedToClosedChannelExceptionOnWrites() throws Exception { public void streamClosedErrorTranslatedToClosedChannelExceptionOnWrites() throws Exception {
LastInboundHandler inboundHandler = new LastInboundHandler(); LastInboundHandler inboundHandler = new LastInboundHandler();
@ -646,7 +655,8 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
new StreamException(childChannel.stream().id(), Http2Error.STREAM_CLOSED, "Stream Closed")); new StreamException(childChannel.stream().id(), Http2Error.STREAM_CLOSED, "Stream Closed"));
} }
}); });
ChannelFuture future = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers())); final ChannelFuture future = childChannel.writeAndFlush(
new DefaultHttp2HeadersFrame(new DefaultHttp2Headers()));
parentChannel.flush(); parentChannel.flush();
@ -655,8 +665,13 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
inboundHandler.checkException(); inboundHandler.checkException();
assertThrows(ClosedChannelException.class, new Executable() {
@Override
public void execute() {
future.syncUninterruptibly(); future.syncUninterruptibly();
} }
});
}
@Test @Test
public void creatingWritingReadingAndClosingOutboundStreamShouldWork() { public void creatingWritingReadingAndClosingOutboundStreamShouldWork() {
@ -692,7 +707,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
// Test failing the promise of the first headers frame of an outbound stream. In practice this error case would most // Test failing the promise of the first headers frame of an outbound stream. In practice this error case would most
// likely happen due to the max concurrent streams limit being hit or the channel running out of stream identifiers. // likely happen due to the max concurrent streams limit being hit or the channel running out of stream identifiers.
// //
@Test(expected = Http2NoMoreStreamIdsException.class) @Test
public void failedOutboundStreamCreationThrowsAndClosesChannel() throws Exception { public void failedOutboundStreamCreationThrowsAndClosesChannel() throws Exception {
LastInboundHandler handler = new LastInboundHandler(); LastInboundHandler handler = new LastInboundHandler();
Http2StreamChannel childChannel = newOutboundStream(handler); Http2StreamChannel childChannel = newOutboundStream(handler);
@ -709,7 +724,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
} }
}); });
ChannelFuture future = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(headers)); final ChannelFuture future = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(headers));
parentChannel.flush(); parentChannel.flush();
assertFalse(childChannel.isActive()); assertFalse(childChannel.isActive());
@ -717,8 +732,13 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
handler.checkException(); handler.checkException();
assertThrows(Http2NoMoreStreamIdsException.class, new Executable() {
@Override
public void execute() {
future.syncUninterruptibly(); future.syncUninterruptibly();
} }
});
}
@Test @Test
public void channelClosedWhenCloseListenerCompletes() { public void channelClosedWhenCloseListenerCompletes() {
@ -1352,7 +1372,7 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
int numFrames) { int numFrames) {
for (int i = 0; i < numFrames; i++) { for (int i = 0; i < numFrames; i++) {
Http2StreamFrame frame = inboundHandler.readInbound(); Http2StreamFrame frame = inboundHandler.readInbound();
assertNotNull(i + " out of " + numFrames + " received", frame); assertNotNull(frame, i + " out of " + numFrames + " received");
assertEquals(streamChannel.stream(), frame.stream()); assertEquals(streamChannel.stream(), frame.stream());
release(frame); release(frame);
} }

View File

@ -46,10 +46,11 @@ import io.netty.util.NetUtil;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener; import io.netty.util.concurrent.FutureListener;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Ignore; import org.junit.jupiter.api.Disabled;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
@ -64,8 +65,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assume.assumeTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue;
public class Http2MultiplexTransportTest { public class Http2MultiplexTransportTest {
private static final ChannelHandler DISCARD_HANDLER = new ChannelInboundHandlerAdapter() { private static final ChannelHandler DISCARD_HANDLER = new ChannelInboundHandlerAdapter() {
@ -91,12 +92,12 @@ public class Http2MultiplexTransportTest {
private Channel serverChannel; private Channel serverChannel;
private Channel serverConnectedChannel; private Channel serverConnectedChannel;
@Before @BeforeEach
public void setup() { public void setup() {
eventLoopGroup = new NioEventLoopGroup(); eventLoopGroup = new NioEventLoopGroup();
} }
@After @AfterEach
public void teardown() { public void teardown() {
if (clientChannel != null) { if (clientChannel != null) {
clientChannel.close(); clientChannel.close();
@ -110,12 +111,14 @@ public class Http2MultiplexTransportTest {
eventLoopGroup.shutdownGracefully(0, 0, MILLISECONDS); eventLoopGroup.shutdownGracefully(0, 0, MILLISECONDS);
} }
@Test(timeout = 10000) @Test
@Timeout(value = 10000, unit = MILLISECONDS)
public void asyncSettingsAckWithMultiplexCodec() throws InterruptedException { public void asyncSettingsAckWithMultiplexCodec() throws InterruptedException {
asyncSettingsAck0(new Http2MultiplexCodecBuilder(true, DISCARD_HANDLER).build(), null); asyncSettingsAck0(new Http2MultiplexCodecBuilder(true, DISCARD_HANDLER).build(), null);
} }
@Test(timeout = 10000) @Test
@Timeout(value = 10000, unit = MILLISECONDS)
public void asyncSettingsAckWithMultiplexHandler() throws InterruptedException { public void asyncSettingsAckWithMultiplexHandler() throws InterruptedException {
asyncSettingsAck0(new Http2FrameCodecBuilder(true).build(), asyncSettingsAck0(new Http2FrameCodecBuilder(true).build(),
new Http2MultiplexHandler(DISCARD_HANDLER)); new Http2MultiplexHandler(DISCARD_HANDLER));
@ -198,7 +201,8 @@ public class Http2MultiplexTransportTest {
serverAckAllLatch.await(); serverAckAllLatch.await();
} }
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testFlushNotDiscarded() public void testFlushNotDiscarded()
throws InterruptedException { throws InterruptedException {
final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
@ -276,24 +280,28 @@ public class Http2MultiplexTransportTest {
} }
} }
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testSSLExceptionOpenSslTLSv12() throws Exception { public void testSSLExceptionOpenSslTLSv12() throws Exception {
testSslException(SslProvider.OPENSSL, false); testSslException(SslProvider.OPENSSL, false);
} }
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testSSLExceptionOpenSslTLSv13() throws Exception { public void testSSLExceptionOpenSslTLSv13() throws Exception {
testSslException(SslProvider.OPENSSL, true); testSslException(SslProvider.OPENSSL, true);
} }
@Ignore("JDK SSLEngine does not produce an alert") @Disabled("JDK SSLEngine does not produce an alert")
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testSSLExceptionJDKTLSv12() throws Exception { public void testSSLExceptionJDKTLSv12() throws Exception {
testSslException(SslProvider.JDK, false); testSslException(SslProvider.JDK, false);
} }
@Ignore("JDK SSLEngine does not produce an alert") @Disabled("JDK SSLEngine does not produce an alert")
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testSSLExceptionJDKTLSv13() throws Exception { public void testSSLExceptionJDKTLSv13() throws Exception {
testSslException(SslProvider.JDK, true); testSslException(SslProvider.JDK, true);
} }
@ -446,13 +454,15 @@ public class Http2MultiplexTransportTest {
} }
} }
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testFireChannelReadAfterHandshakeSuccess_JDK() throws Exception { public void testFireChannelReadAfterHandshakeSuccess_JDK() throws Exception {
assumeTrue(SslProvider.isAlpnSupported(SslProvider.JDK)); assumeTrue(SslProvider.isAlpnSupported(SslProvider.JDK));
testFireChannelReadAfterHandshakeSuccess(SslProvider.JDK); testFireChannelReadAfterHandshakeSuccess(SslProvider.JDK);
} }
@Test(timeout = 5000L) @Test
@Timeout(value = 5000L, unit = MILLISECONDS)
public void testFireChannelReadAfterHandshakeSuccess_OPENSSL() throws Exception { public void testFireChannelReadAfterHandshakeSuccess_OPENSSL() throws Exception {
assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.isAvailable());
assumeTrue(SslProvider.isAlpnSupported(SslProvider.OPENSSL)); assumeTrue(SslProvider.isAlpnSupported(SslProvider.OPENSSL));

View File

@ -20,9 +20,9 @@ import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider; import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter; import io.netty.handler.ssl.SupportedCipherSuiteFilter;
import org.junit.Assert; import org.junit.jupiter.api.Assertions;
import org.junit.Assume; import org.junit.jupiter.api.Assumptions;
import org.junit.Test; import org.junit.jupiter.api.Test;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
@ -31,7 +31,7 @@ public class Http2SecurityUtilTest {
@Test @Test
public void testTLSv13CiphersIncluded() throws SSLException { public void testTLSv13CiphersIncluded() throws SSLException {
Assume.assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK)); Assumptions.assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK));
testCiphersIncluded("TLSv1.3"); testCiphersIncluded("TLSv1.3");
} }
@ -44,6 +44,6 @@ public class Http2SecurityUtilTest {
SslContext context = SslContextBuilder.forClient().sslProvider(SslProvider.JDK).protocols(protocol) SslContext context = SslContextBuilder.forClient().sslProvider(SslProvider.JDK).protocols(protocol)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).build(); .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).build();
SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT); SSLEngine engine = context.newEngine(UnpooledByteBufAllocator.DEFAULT);
Assert.assertTrue("No " + protocol + " ciphers found", engine.getEnabledCipherSuites().length > 0); Assertions.assertTrue(engine.getEnabledCipherSuites().length > 0, "No " + protocol + " ciphers found");
} }
} }

View File

@ -28,12 +28,12 @@ import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
public class Http2ServerUpgradeCodecTest { public class Http2ServerUpgradeCodecTest {

View File

@ -15,14 +15,17 @@
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import org.junit.Before;
import org.junit.Test; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_FRAME_SIZE_UPPER_BOUND;
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_UNSIGNED_INT; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_UNSIGNED_INT;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* Tests for {@link Http2Settings}. * Tests for {@link Http2Settings}.
@ -31,7 +34,7 @@ public class Http2SettingsTest {
private Http2Settings settings; private Http2Settings settings;
@Before @BeforeEach
public void setup() { public void setup() {
settings = new Http2Settings(); settings = new Http2Settings();
} }
@ -83,10 +86,15 @@ public class Http2SettingsTest {
assertEquals(MAX_UNSIGNED_INT, (long) settings.maxHeaderListSize()); assertEquals(MAX_UNSIGNED_INT, (long) settings.maxHeaderListSize());
} }
@Test(expected = IllegalArgumentException.class) @Test
public void headerListSizeBoundCheck() { public void headerListSizeBoundCheck() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
settings.maxHeaderListSize(Long.MAX_VALUE); settings.maxHeaderListSize(Long.MAX_VALUE);
} }
});
}
@Test @Test
public void headerTableSizeUnsignedInt() { public void headerTableSizeUnsignedInt() {
@ -94,13 +102,23 @@ public class Http2SettingsTest {
assertEquals(MAX_UNSIGNED_INT, (long) settings.get(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE)); assertEquals(MAX_UNSIGNED_INT, (long) settings.get(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE));
} }
@Test(expected = IllegalArgumentException.class) @Test
public void headerTableSizeBoundCheck() { public void headerTableSizeBoundCheck() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, (Long) Long.MAX_VALUE); settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, (Long) Long.MAX_VALUE);
} }
});
}
@Test(expected = IllegalArgumentException.class) @Test
public void headerTableSizeBoundCheck2() { public void headerTableSizeBoundCheck2() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, Long.valueOf(-1L)); settings.put(Http2CodecUtil.SETTINGS_HEADER_TABLE_SIZE, Long.valueOf(-1L));
} }
});
}
} }

View File

@ -32,9 +32,8 @@ import io.netty.util.concurrent.Promise;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
import org.hamcrest.core.IsInstanceOf; import org.hamcrest.core.IsInstanceOf;
import org.junit.Rule; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.function.Executable;
import org.junit.rules.ExpectedException;
import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedChannelException;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
@ -46,7 +45,8 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -55,9 +55,6 @@ public class Http2StreamChannelBootstrapTest {
private static final InternalLogger logger = private static final InternalLogger logger =
InternalLoggerFactory.getInstance(Http2StreamChannelBootstrapTest.class); InternalLoggerFactory.getInstance(Http2StreamChannelBootstrapTest.class);
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
private volatile Channel serverConnectedChannel; private volatile Channel serverConnectedChannel;
@Test @Test
@ -109,14 +106,18 @@ public class Http2StreamChannelBootstrapTest {
}); });
Http2StreamChannelBootstrap bootstrap = new Http2StreamChannelBootstrap(clientChannel); Http2StreamChannelBootstrap bootstrap = new Http2StreamChannelBootstrap(clientChannel);
Promise<Http2StreamChannel> promise = clientChannel.eventLoop().newPromise(); final Promise<Http2StreamChannel> promise = clientChannel.eventLoop().newPromise();
bootstrap.open(promise); bootstrap.open(promise);
assertThat(promise.isDone(), is(false)); assertThat(promise.isDone(), is(false));
closeLatch.countDown(); closeLatch.countDown();
exceptionRule.expect(ExecutionException.class); ExecutionException exception = assertThrows(ExecutionException.class, new Executable() {
exceptionRule.expectCause(IsInstanceOf.<Throwable>instanceOf(ClosedChannelException.class)); @Override
public void execute() throws Throwable {
promise.get(3, SECONDS); promise.get(3, SECONDS);
}
});
assertThat(exception.getCause(), IsInstanceOf.<Throwable>instanceOf(ClosedChannelException.class));
} finally { } finally {
safeClose(clientChannel); safeClose(clientChannel);
safeClose(serverConnectedChannel); safeClose(serverConnectedChannel);

View File

@ -14,20 +14,18 @@
*/ */
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import org.junit.Test;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelId; import io.netty.channel.ChannelId;
import io.netty.channel.DefaultChannelId; import io.netty.channel.DefaultChannelId;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertEquals;
public class Http2StreamChannelIdTest { public class Http2StreamChannelIdTest {

View File

@ -47,8 +47,8 @@ import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider; import io.netty.handler.ssl.SslProvider;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.function.Executable;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
@ -56,10 +56,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
public class Http2StreamFrameToHttpObjectCodecTest { public class Http2StreamFrameToHttpObjectCodecTest {
@ -90,15 +91,17 @@ public class Http2StreamFrameToHttpObjectCodecTest {
assertFalse(ch.finish()); assertFalse(ch.finish());
} }
@Test (expected = EncoderException.class) @Test
public void encodeNonFullHttpResponse100ContinueIsRejected() throws Exception { public void encodeNonFullHttpResponse100ContinueIsRejected() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true)); final EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
try { assertThrows(EncoderException.class, new Executable() {
@Override
public void execute() {
ch.writeOutbound(new DefaultHttpResponse( ch.writeOutbound(new DefaultHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE)); HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE));
} finally {
ch.finishAndReleaseAll();
} }
});
ch.finishAndReleaseAll();
} }
@Test @Test

View File

@ -21,7 +21,8 @@ import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
import static io.netty.handler.codec.http.HttpHeaderNames.COOKIE; import static io.netty.handler.codec.http.HttpHeaderNames.COOKIE;
@ -33,12 +34,13 @@ import static io.netty.handler.codec.http.HttpHeaderNames.TRANSFER_ENCODING;
import static io.netty.handler.codec.http.HttpHeaderNames.UPGRADE; import static io.netty.handler.codec.http.HttpHeaderNames.UPGRADE;
import static io.netty.handler.codec.http.HttpHeaderValues.GZIP; import static io.netty.handler.codec.http.HttpHeaderValues.GZIP;
import static io.netty.handler.codec.http.HttpHeaderValues.TRAILERS; import static io.netty.handler.codec.http.HttpHeaderValues.TRAILERS;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.Assert.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class HttpConversionUtilTest { public class HttpConversionUtilTest {
@ -84,10 +86,15 @@ public class HttpConversionUtilTest {
assertSame(AsciiString.EMPTY_STRING, headers.authority()); assertSame(AsciiString.EMPTY_STRING, headers.authority());
} }
@Test(expected = IllegalArgumentException.class) @Test
public void setHttp2AuthorityWithEmptyAuthority() { public void setHttp2AuthorityWithEmptyAuthority() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
HttpConversionUtil.setHttp2Authority("info@", new DefaultHttp2Headers()); HttpConversionUtil.setHttp2Authority("info@", new DefaultHttp2Headers());
} }
});
}
@Test @Test
public void stripTEHeaders() { public void stripTEHeaders() {

View File

@ -67,7 +67,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;

View File

@ -46,9 +46,9 @@ import io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@ -61,9 +61,9 @@ import static io.netty.handler.codec.http2.Http2Exception.isStreamError;
import static io.netty.handler.codec.http2.Http2TestUtil.of; import static io.netty.handler.codec.http2.Http2TestUtil.of;
import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel; import static io.netty.handler.codec.http2.Http2TestUtil.runInChannel;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -102,12 +102,12 @@ public class InboundHttp2ToHttpAdapterTest {
private HttpSettingsDelegator settingsDelegator; private HttpSettingsDelegator settingsDelegator;
private Http2Exception clientException; private Http2Exception clientException;
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
} }
@After @AfterEach
public void teardown() throws Exception { public void teardown() throws Exception {
cleanupCapturedRequests(); cleanupCapturedRequests();
cleanupCapturedResponses(); cleanupCapturedResponses();

View File

@ -16,47 +16,77 @@
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import io.netty.util.AsciiString; import io.netty.util.AsciiString;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import static io.netty.handler.codec.http2.DefaultHttp2HeadersTest.*; import static io.netty.handler.codec.http2.DefaultHttp2HeadersTest.*;
import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ReadOnlyHttp2HeadersTest { public class ReadOnlyHttp2HeadersTest {
@Test(expected = IllegalArgumentException.class) @Test
public void notKeyValuePairThrows() { public void notKeyValuePairThrows() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
ReadOnlyHttp2Headers.trailers(false, new AsciiString[]{ null }); ReadOnlyHttp2Headers.trailers(false, new AsciiString[]{ null });
} }
});
}
@Test(expected = NullPointerException.class) @Test
public void nullTrailersNotAllowed() { public void nullTrailersNotAllowed() {
assertThrows(NullPointerException.class, new Executable() {
@Override
public void execute() {
ReadOnlyHttp2Headers.trailers(false, (AsciiString[]) null); ReadOnlyHttp2Headers.trailers(false, (AsciiString[]) null);
} }
});
}
@Test @Test
public void nullHeaderNameNotChecked() { public void nullHeaderNameNotChecked() {
ReadOnlyHttp2Headers.trailers(false, null, null); ReadOnlyHttp2Headers.trailers(false, null, null);
} }
@Test(expected = Http2Exception.class) @Test
public void nullHeaderNameValidated() { public void nullHeaderNameValidated() {
assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() {
ReadOnlyHttp2Headers.trailers(true, null, new AsciiString("foo")); ReadOnlyHttp2Headers.trailers(true, null, new AsciiString("foo"));
} }
});
}
@Test(expected = IllegalArgumentException.class) @Test
public void pseudoHeaderNotAllowedAfterNonPseudoHeaders() { public void pseudoHeaderNotAllowedAfterNonPseudoHeaders() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
ReadOnlyHttp2Headers.trailers(true, new AsciiString(":name"), new AsciiString("foo"), ReadOnlyHttp2Headers.trailers(true, new AsciiString(":name"), new AsciiString("foo"),
new AsciiString("othername"), new AsciiString("goo"), new AsciiString("othername"), new AsciiString("goo"),
new AsciiString(":pseudo"), new AsciiString("val")); new AsciiString(":pseudo"), new AsciiString("val"));
} }
});
}
@Test(expected = IllegalArgumentException.class) @Test
public void nullValuesAreNotAllowed() { public void nullValuesAreNotAllowed() {
assertThrows(IllegalArgumentException.class, new Executable() {
@Override
public void execute() {
ReadOnlyHttp2Headers.trailers(true, new AsciiString("foo"), null); ReadOnlyHttp2Headers.trailers(true, new AsciiString("foo"), null);
} }
});
}
@Test @Test
public void emptyHeaderNameAllowed() { public void emptyHeaderNameAllowed() {
@ -75,35 +105,65 @@ public class ReadOnlyHttp2HeadersTest {
verifyPseudoHeadersFirst(headers); verifyPseudoHeadersFirst(headers);
} }
@Test(expected = UnsupportedOperationException.class) @Test
public void testIteratorReadOnlyClient() { public void testIteratorReadOnlyClient() {
assertThrows(UnsupportedOperationException.class, new Executable() {
@Override
public void execute() {
testIteratorReadOnly(newClientHeaders()); testIteratorReadOnly(newClientHeaders());
} }
});
}
@Test(expected = UnsupportedOperationException.class) @Test
public void testIteratorReadOnlyServer() { public void testIteratorReadOnlyServer() {
assertThrows(UnsupportedOperationException.class, new Executable() {
@Override
public void execute() {
testIteratorReadOnly(newServerHeaders()); testIteratorReadOnly(newServerHeaders());
} }
});
}
@Test(expected = UnsupportedOperationException.class) @Test
public void testIteratorReadOnlyTrailers() { public void testIteratorReadOnlyTrailers() {
assertThrows(UnsupportedOperationException.class, new Executable() {
@Override
public void execute() {
testIteratorReadOnly(newTrailers()); testIteratorReadOnly(newTrailers());
} }
});
}
@Test(expected = UnsupportedOperationException.class) @Test
public void testIteratorEntryReadOnlyClient() { public void testIteratorEntryReadOnlyClient() {
assertThrows(UnsupportedOperationException.class, new Executable() {
@Override
public void execute() {
testIteratorEntryReadOnly(newClientHeaders()); testIteratorEntryReadOnly(newClientHeaders());
} }
});
@Test(expected = UnsupportedOperationException.class)
public void testIteratorEntryReadOnlyServer() {
testIteratorEntryReadOnly(newServerHeaders());
} }
@Test(expected = UnsupportedOperationException.class) @Test
public void testIteratorEntryReadOnlyServer() {
assertThrows(UnsupportedOperationException.class, new Executable() {
@Override
public void execute() {
testIteratorEntryReadOnly(newServerHeaders());
}
});
}
@Test
public void testIteratorEntryReadOnlyTrailers() { public void testIteratorEntryReadOnlyTrailers() {
assertThrows(UnsupportedOperationException.class, new Executable() {
@Override
public void execute() {
testIteratorEntryReadOnly(newTrailers()); testIteratorEntryReadOnly(newTrailers());
} }
});
}
@Test @Test
public void testSize() { public void testSize() {
@ -172,14 +232,14 @@ public class ReadOnlyHttp2HeadersTest {
@Test @Test
public void testEmptyValueIterator() { public void testEmptyValueIterator() {
Http2Headers headers = newServerHeaders(); Http2Headers headers = newServerHeaders();
Iterator<CharSequence> itr = headers.valueIterator("foo"); final Iterator<CharSequence> itr = headers.valueIterator("foo");
assertFalse(itr.hasNext()); assertFalse(itr.hasNext());
try { assertThrows(NoSuchElementException.class, new Executable() {
@Override
public void execute() {
itr.next(); itr.next();
fail();
} catch (NoSuchElementException ignored) {
// ignored
} }
});
} }
@Test @Test

View File

@ -21,10 +21,10 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
import static io.netty.handler.codec.http2.Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS; import static io.netty.handler.codec.http2.Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS;
import static io.netty.handler.codec.http2.Http2Error.CANCEL; import static io.netty.handler.codec.http2.Http2Error.CANCEL;
import static io.netty.handler.codec.http2.Http2Stream.State.HALF_CLOSED_LOCAL; import static io.netty.handler.codec.http2.Http2Stream.State.HALF_CLOSED_LOCAL;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@ -53,9 +53,9 @@ import io.netty.handler.codec.http2.StreamBufferingEncoder.Http2GoAwayException;
import io.netty.util.ReferenceCountUtil; import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.ImmediateEventExecutor;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@ -96,7 +96,7 @@ public class StreamBufferingEncoderTest {
/** /**
* Init fields and do mocking. * Init fields and do mocking.
*/ */
@Before @BeforeEach
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -155,7 +155,7 @@ public class StreamBufferingEncoderTest {
handler.handlerAdded(ctx); handler.handlerAdded(ctx);
} }
@After @AfterEach
public void teardown() { public void teardown() {
// Close and release any buffered frames. // Close and release any buffered frames.
encoder.close(); encoder.close();

View File

@ -17,8 +17,9 @@ package io.netty.handler.codec.http2;
import io.netty.handler.codec.http2.Http2TestUtil.TestStreamByteDistributorStreamState; import io.netty.handler.codec.http2.Http2TestUtil.TestStreamByteDistributorStreamState;
import io.netty.util.collection.IntObjectHashMap; import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap; import io.netty.util.collection.IntObjectMap;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@ -28,11 +29,11 @@ import org.mockito.verification.VerificationMode;
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_MIN_ALLOCATION_CHUNK; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_MIN_ALLOCATION_CHUNK;
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atMost; import static org.mockito.Mockito.atMost;
@ -63,7 +64,7 @@ public class UniformStreamByteDistributorTest {
@Mock @Mock
private StreamByteDistributor.Writer writer; private StreamByteDistributor.Writer writer;
@Before @BeforeEach
public void setup() throws Http2Exception { public void setup() throws Http2Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -130,14 +131,15 @@ public class UniformStreamByteDistributorTest {
Exception fakeException = new RuntimeException("Fake exception"); Exception fakeException = new RuntimeException("Fake exception");
doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3)); doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3));
try { Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
write(10); write(10);
fail("Expected an exception"); }
} catch (Http2Exception e) { });
assertFalse(Http2Exception.isStreamError(e)); assertFalse(Http2Exception.isStreamError(e));
assertEquals(Http2Error.INTERNAL_ERROR, e.error()); assertEquals(Http2Error.INTERNAL_ERROR, e.error());
assertSame(fakeException, e.getCause()); assertSame(fakeException, e.getCause());
}
verifyWrite(atMost(1), STREAM_A, 1); verifyWrite(atMost(1), STREAM_A, 1);
verifyWrite(atMost(1), STREAM_B, 2); verifyWrite(atMost(1), STREAM_B, 2);

View File

@ -14,17 +14,17 @@
*/ */
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT;
import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT;
import static io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.INITIAL_CHILDREN_MAP_SIZE; import static io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.INITIAL_CHILDREN_MAP_SIZE;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
@ -42,7 +42,7 @@ public class WeightedFairQueueByteDistributorDependencyTreeTest extends
private static final short speculativeWeight = 1; private static final short speculativeWeight = 1;
private static final short followersWeight = 1; private static final short followersWeight = 1;
@Before @BeforeEach
public void setup() throws Http2Exception { public void setup() throws Http2Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);

View File

@ -14,18 +14,19 @@
*/ */
package io.netty.handler.codec.http2; package io.netty.handler.codec.http2;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.verification.VerificationMode; import org.mockito.verification.VerificationMode;
import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atLeastOnce;
@ -47,7 +48,7 @@ public class WeightedFairQueueByteDistributorTest extends AbstractWeightedFairQu
private static final int STREAM_E = 9; private static final int STREAM_E = 9;
private static final int ALLOCATION_QUANTUM = 100; private static final int ALLOCATION_QUANTUM = 100;
@Before @BeforeEach
public void setup() throws Http2Exception { public void setup() throws Http2Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@ -152,14 +153,15 @@ public class WeightedFairQueueByteDistributorTest extends AbstractWeightedFairQu
Exception fakeException = new RuntimeException("Fake exception"); Exception fakeException = new RuntimeException("Fake exception");
doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3)); doThrow(fakeException).when(writer).write(same(stream(STREAM_C)), eq(3));
try { Http2Exception e = assertThrows(Http2Exception.class, new Executable() {
@Override
public void execute() throws Throwable {
write(10); write(10);
fail("Expected an exception"); }
} catch (Http2Exception e) { });
assertFalse(Http2Exception.isStreamError(e)); assertFalse(Http2Exception.isStreamError(e));
assertEquals(Http2Error.INTERNAL_ERROR, e.error()); assertEquals(Http2Error.INTERNAL_ERROR, e.error());
assertSame(fakeException, e.getCause()); assertSame(fakeException, e.getCause());
}
verifyWrite(atMost(1), STREAM_A, 1); verifyWrite(atMost(1), STREAM_A, 1);
verifyWrite(atMost(1), STREAM_B, 2); verifyWrite(atMost(1), STREAM_B, 2);