1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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 }