View Javadoc
1   /*
2    * Copyright 2016 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.testsuite.transport.socket;
17  
18  import io.netty5.bootstrap.Bootstrap;
19  import io.netty5.bootstrap.ServerBootstrap;
20  import io.netty5.buffer.api.Buffer;
21  import io.netty5.buffer.api.DefaultBufferAllocators;
22  import io.netty5.channel.Channel;
23  import io.netty5.channel.ChannelHandler;
24  import io.netty5.channel.ChannelHandlerAdapter;
25  import io.netty5.channel.ChannelHandlerContext;
26  import io.netty5.channel.ChannelShutdownDirection;
27  import io.netty5.channel.SingleThreadEventLoop;
28  import io.netty5.channel.nio.NioHandler;
29  import io.netty5.channel.socket.SocketChannel;
30  import io.netty5.channel.socket.nio.NioServerSocketChannel;
31  import io.netty5.handler.codec.ByteToMessageDecoder;
32  import io.netty5.util.concurrent.DefaultThreadFactory;
33  import org.junit.jupiter.api.Test;
34  import org.junit.jupiter.api.TestInfo;
35  import org.junit.jupiter.api.Timeout;
36  
37  import java.nio.channels.NotYetConnectedException;
38  import java.util.concurrent.CountDownLatch;
39  
40  import static org.assertj.core.api.Assertions.assertThat;
41  import static org.junit.jupiter.api.Assertions.assertFalse;
42  import static org.junit.jupiter.api.Assertions.fail;
43  
44  public class SocketChannelNotYetConnectedTest extends AbstractClientSocketTest {
45      @Test
46      @Timeout(30)
47      public void testShutdownNotYetConnected(TestInfo testInfo) throws Throwable {
48          run(testInfo, this::testShutdownNotYetConnected);
49      }
50  
51      public void testShutdownNotYetConnected(Bootstrap cb) throws Throwable {
52          SocketChannel ch = (SocketChannel) cb.handler(new ChannelHandler() { })
53                                               .bind(newSocketAddress()).asStage().get();
54          try {
55              try {
56                  ch.shutdown(ChannelShutdownDirection.Inbound).asStage().sync();
57                  fail();
58              } catch (Throwable cause) {
59                  assertThat(cause).hasCauseInstanceOf(NotYetConnectedException.class);
60              }
61  
62              try {
63                  ch.shutdown(ChannelShutdownDirection.Outbound).asStage().sync();
64                  fail();
65              } catch (Throwable cause) {
66                  assertThat(cause).hasCauseInstanceOf(NotYetConnectedException.class);
67              }
68          } finally {
69              ch.close().asStage().sync();
70          }
71      }
72  
73      @Test
74      @Timeout(30)
75      public void readMustBePendingUntilChannelIsActive(TestInfo info) throws Throwable {
76          run(info, new Runner<>() {
77              @Override
78              public void run(Bootstrap bootstrap) throws Throwable {
79                  SingleThreadEventLoop group = new SingleThreadEventLoop(
80                          new DefaultThreadFactory(getClass()), NioHandler.newFactory().newHandler());
81                  ServerBootstrap sb = new ServerBootstrap().group(group);
82                  Channel serverChannel = sb.childHandler(new ChannelHandlerAdapter() {
83                      @Override
84                      public void channelActive(ChannelHandlerContext ctx) throws Exception {
85                          ctx.writeAndFlush(DefaultBufferAllocators.preferredAllocator().allocate(4).writeInt(42));
86                      }
87                  }).channel(NioServerSocketChannel.class).bind(0).asStage().get();
88  
89                  final CountDownLatch readLatch = new CountDownLatch(1);
90                  bootstrap.handler(new ByteToMessageDecoder() {
91                      @Override
92                      public void handlerAdded0(ChannelHandlerContext ctx) throws Exception {
93                          assertFalse(ctx.channel().isActive());
94                          ctx.read();
95                      }
96  
97                      @Override
98                      protected void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
99                          assertThat(in.readableBytes()).isLessThanOrEqualTo(Integer.BYTES);
100                         if (in.readableBytes() == Integer.BYTES) {
101                             assertThat(in.readInt()).isEqualTo(42);
102                             readLatch.countDown();
103                         }
104                     }
105                 });
106                 bootstrap.connect(serverChannel.localAddress()).asStage().sync();
107 
108                 readLatch.await();
109                 group.shutdownGracefully().asStage().await();
110             }
111         });
112     }
113 }