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