Search in sources :

Example 16 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method writeUnknownFrame.

// TODO(buchgr): Flush from child channel
// TODO(buchgr): ChildChannel.childReadComplete()
// TODO(buchgr): GOAWAY Logic
// TODO(buchgr): Test ChannelConfig.setMaxMessagesPerRead
@Test
public void writeUnknownFrame() {
    Http2StreamChannel childChannel = newOutboundStream(new ChannelInboundHandlerAdapter() {

        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers()));
            ctx.writeAndFlush(new DefaultHttp2UnknownFrame((byte) 99, new Http2Flags()));
            ctx.fireChannelActive();
        }
    });
    assertTrue(childChannel.isActive());
    parentChannel.runPendingTasks();
    verify(frameWriter).writeFrame(eq(codec.ctx), eq((byte) 99), eqStreamId(childChannel), any(Http2Flags.class), any(ByteBuf.class), any(ChannelPromise.class));
}
Also used : ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelPromise(io.netty.channel.ChannelPromise) Http2TestUtil.anyChannelPromise(io.netty.handler.codec.http2.Http2TestUtil.anyChannelPromise) ByteBuf(io.netty.buffer.ByteBuf) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 17 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopNoAutoRead.

@Test
public void childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopNoAutoRead() {
    final AtomicInteger numReads = new AtomicInteger(1);
    final AtomicInteger channelReadCompleteCount = new AtomicInteger(0);
    final AtomicBoolean shouldDisableAutoRead = new AtomicBoolean();
    Consumer<ChannelHandlerContext> ctxConsumer = new Consumer<ChannelHandlerContext>() {

        @Override
        public void accept(ChannelHandlerContext obj) {
            channelReadCompleteCount.incrementAndGet();
            if (shouldDisableAutoRead.get()) {
                obj.channel().config().setAutoRead(false);
            }
        }
    };
    final LastInboundHandler inboundHandler = new LastInboundHandler(ctxConsumer);
    Http2StreamChannel childChannel = newInboundStream(3, false, numReads, inboundHandler);
    childChannel.config().setAutoRead(false);
    Http2DataFrame dataFrame1 = new DefaultHttp2DataFrame(bb("1")).stream(childChannel.stream());
    Http2DataFrame dataFrame2 = new DefaultHttp2DataFrame(bb("2")).stream(childChannel.stream());
    Http2DataFrame dataFrame3 = new DefaultHttp2DataFrame(bb("3")).stream(childChannel.stream());
    Http2DataFrame dataFrame4 = new DefaultHttp2DataFrame(bb("4")).stream(childChannel.stream());
    assertEquals(new DefaultHttp2HeadersFrame(request).stream(childChannel.stream()), inboundHandler.readInbound());
    ChannelHandler readCompleteSupressHandler = new ChannelInboundHandlerAdapter() {

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // We want to simulate the parent channel calling channelRead and delay calling channelReadComplete.
        }
    };
    parentChannel.pipeline().addFirst(readCompleteSupressHandler);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("1"), 0, false);
    assertEqualsAndRelease(dataFrame1, inboundHandler.<Http2Frame>readInbound());
    // We want one item to be in the queue, and allow the numReads to be larger than 1. This will ensure that
    // when beginRead() is called the child channel is added to the readPending queue of the parent channel.
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("2"), 0, false);
    numReads.set(2);
    childChannel.read();
    assertEqualsAndRelease(dataFrame2, inboundHandler.<Http2Frame>readInbound());
    assertNull(inboundHandler.readInbound());
    // This is the second item that was read, this should be the last until we call read() again. This should also
    // notify of readComplete().
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("3"), 0, false);
    assertEqualsAndRelease(dataFrame3, inboundHandler.<Http2Frame>readInbound());
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("4"), 0, false);
    assertNull(inboundHandler.readInbound());
    childChannel.read();
    assertEqualsAndRelease(dataFrame4, inboundHandler.<Http2Frame>readInbound());
    assertNull(inboundHandler.readInbound());
    // Now we want to call channelReadComplete and simulate the end of the read loop.
    parentChannel.pipeline().remove(readCompleteSupressHandler);
    parentChannel.flushInbound();
    // 3 = 1 for initialization + 1 for first read of 2 items + 1 for second read of 2 items +
    // 1 for parent channel readComplete
    assertEquals(4, channelReadCompleteCount.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Consumer(io.netty.handler.codec.http2.LastInboundHandler.Consumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelHandler(io.netty.channel.ChannelHandler) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 18 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method streamExceptionTriggersChildChannelExceptionAndClose.

@Test
public void streamExceptionTriggersChildChannelExceptionAndClose() throws Exception {
    final LastInboundHandler inboundHandler = new LastInboundHandler();
    Http2StreamChannel channel = newInboundStream(3, false, inboundHandler);
    assertTrue(channel.isActive());
    StreamException cause = new StreamException(channel.stream().id(), Http2Error.PROTOCOL_ERROR, "baaam!");
    parentChannel.pipeline().fireExceptionCaught(cause);
    assertFalse(channel.isActive());
    assertThrows(StreamException.class, new Executable() {

        @Override
        public void execute() throws Throwable {
            inboundHandler.checkException();
        }
    });
}
Also used : Executable(org.junit.jupiter.api.function.Executable) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) Test(org.junit.jupiter.api.Test)

Example 19 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method channelInactiveHappensAfterExceptionCaughtEvents.

@Test
public void channelInactiveHappensAfterExceptionCaughtEvents() throws Exception {
    final AtomicInteger count = new AtomicInteger(0);
    final AtomicInteger exceptionCaught = new AtomicInteger(-1);
    final AtomicInteger channelInactive = new AtomicInteger(-1);
    final AtomicInteger channelUnregistered = new AtomicInteger(-1);
    Http2StreamChannel childChannel = newOutboundStream(new ChannelInboundHandlerAdapter() {

        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            ctx.close();
            throw new Exception("exception");
        }
    });
    childChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {

        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            channelInactive.set(count.getAndIncrement());
            super.channelInactive(ctx);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            exceptionCaught.set(count.getAndIncrement());
            super.exceptionCaught(ctx, cause);
        }

        @Override
        public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
            channelUnregistered.set(count.getAndIncrement());
            super.channelUnregistered(ctx);
        }
    });
    childChannel.pipeline().fireUserEventTriggered(new Object());
    parentChannel.runPendingTasks();
    // The events should have happened in this order because the inactive and deregistration events
    // get deferred as they do in the AbstractChannel.
    assertEquals(0, exceptionCaught.get());
    assertEquals(1, channelInactive.get());
    assertEquals(2, channelUnregistered.get());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) ClosedChannelException(java.nio.channels.ClosedChannelException) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 20 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method channelClosedWhenCloseListenerCompletes.

@Test
public void channelClosedWhenCloseListenerCompletes() {
    LastInboundHandler inboundHandler = new LastInboundHandler();
    Http2StreamChannel childChannel = newInboundStream(3, false, inboundHandler);
    assertTrue(childChannel.isOpen());
    assertTrue(childChannel.isActive());
    final AtomicBoolean channelOpen = new AtomicBoolean(true);
    final AtomicBoolean channelActive = new AtomicBoolean(true);
    // Create a promise before actually doing the close, because otherwise we would be adding a listener to a future
    // that is already completed because we are using EmbeddedChannel which executes code in the JUnit thread.
    ChannelPromise p = childChannel.newPromise();
    p.addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) {
            channelOpen.set(future.channel().isOpen());
            channelActive.set(future.channel().isActive());
        }
    });
    childChannel.close(p).syncUninterruptibly();
    assertFalse(channelOpen.get());
    assertFalse(channelActive.get());
    assertFalse(childChannel.isActive());
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ChannelPromise(io.netty.channel.ChannelPromise) Http2TestUtil.anyChannelPromise(io.netty.handler.codec.http2.Http2TestUtil.anyChannelPromise) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Test(org.junit.jupiter.api.Test)

Aggregations

Test (org.junit.jupiter.api.Test)14 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)9 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)9 StreamException (io.netty.handler.codec.http2.Http2Exception.StreamException)9 ChannelPromise (io.netty.channel.ChannelPromise)7 Http2TestUtil.anyChannelPromise (io.netty.handler.codec.http2.Http2TestUtil.anyChannelPromise)7 ClosedChannelException (java.nio.channels.ClosedChannelException)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)6 Channel (io.netty.channel.Channel)5 ChannelFuture (io.netty.channel.ChannelFuture)5 Http2StreamChannel (io.netty.handler.codec.http2.Http2StreamChannel)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 InvocationOnMock (org.mockito.invocation.InvocationOnMock)4 ChannelHandler (io.netty.channel.ChannelHandler)3 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)3 Http2StreamChannelBootstrap (io.netty.handler.codec.http2.Http2StreamChannelBootstrap)3 Consumer (io.netty.handler.codec.http2.LastInboundHandler.Consumer)3 ArrayList (java.util.ArrayList)3 MetricRegistry (com.codahale.metrics.MetricRegistry)2 MultiplexedChannelRecordTest (com.github.ambry.network.http2.MultiplexedChannelRecordTest)2