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.netty.testsuite.transport.socket;
17  
18  import io.netty.bootstrap.Bootstrap;
19  import io.netty.bootstrap.ServerBootstrap;
20  import io.netty.buffer.ByteBuf;
21  import io.netty.buffer.Unpooled;
22  import io.netty.channel.Channel;
23  import io.netty.channel.ChannelHandlerContext;
24  import io.netty.channel.ChannelInboundHandlerAdapter;
25  import io.netty.channel.EventLoopGroup;
26  import io.netty.channel.MultiThreadIoEventLoopGroup;
27  import io.netty.channel.nio.NioIoHandler;
28  import io.netty.channel.socket.SocketChannel;
29  import io.netty.channel.socket.nio.NioServerSocketChannel;
30  import io.netty.handler.codec.ByteToMessageDecoder;
31  import org.junit.jupiter.api.Test;
32  import org.junit.jupiter.api.TestInfo;
33  import org.junit.jupiter.api.Timeout;
34  
35  import java.net.SocketException;
36  import java.nio.channels.NotYetConnectedException;
37  import java.util.List;
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, new Runner<Bootstrap>() {
49              @Override
50              public void run(Bootstrap bootstrap) throws Throwable {
51                  testShutdownNotYetConnected(bootstrap);
52              }
53          });
54      }
55  
56      public void testShutdownNotYetConnected(Bootstrap cb) throws Throwable {
57          SocketChannel ch = (SocketChannel) cb.handler(new ChannelInboundHandlerAdapter())
58                  .bind(newSocketAddress()).syncUninterruptibly().channel();
59          try {
60              try {
61                  ch.shutdownInput().syncUninterruptibly();
62                  fail();
63              } catch (Throwable cause) {
64                  checkThrowable(cause);
65              }
66  
67              try {
68                  ch.shutdownOutput().syncUninterruptibly();
69                  fail();
70              } catch (Throwable cause) {
71                  checkThrowable(cause);
72              }
73          } finally {
74              ch.close().syncUninterruptibly();
75          }
76      }
77  
78      private static void checkThrowable(Throwable cause) throws Throwable {
79          // Depending on OIO / NIO both are ok
80          if (!(cause instanceof NotYetConnectedException) && !(cause instanceof SocketException)) {
81              throw cause;
82          }
83      }
84  
85      @Test
86      @Timeout(30)
87      public void readMustBePendingUntilChannelIsActive(TestInfo info) throws Throwable {
88          run(info, new Runner<Bootstrap>() {
89              @Override
90              public void run(Bootstrap bootstrap) throws Throwable {
91                  EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory());
92                  ServerBootstrap sb = new ServerBootstrap().group(group);
93                  Channel serverChannel = sb.childHandler(new ChannelInboundHandlerAdapter() {
94                      @Override
95                      public void channelActive(ChannelHandlerContext ctx) throws Exception {
96                          ctx.writeAndFlush(Unpooled.copyInt(42));
97                      }
98                  }).channel(NioServerSocketChannel.class).bind(0).sync().channel();
99  
100                 final CountDownLatch readLatch = new CountDownLatch(1);
101                 bootstrap.handler(new ByteToMessageDecoder() {
102                     @Override
103                     public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
104                         assertFalse(ctx.channel().isActive());
105                         ctx.read();
106                     }
107 
108                     @Override
109                     protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
110                         assertThat(in.readableBytes()).isLessThanOrEqualTo(Integer.BYTES);
111                         if (in.readableBytes() == Integer.BYTES) {
112                             assertThat(in.readInt()).isEqualTo(42);
113                             readLatch.countDown();
114                         }
115                     }
116                 });
117                 bootstrap.connect(serverChannel.localAddress()).sync();
118 
119                 readLatch.await();
120                 group.shutdownGracefully().await();
121             }
122         });
123     }
124 }