View Javadoc
1   /*
2    * Copyright 2012 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.AbstractBootstrap;
19  import io.netty.bootstrap.Bootstrap;
20  import io.netty.bootstrap.ServerBootstrap;
21  import io.netty.channel.Channel;
22  import io.netty.channel.ChannelFactory;
23  import io.netty.channel.ChannelOption;
24  import io.netty.channel.EventLoopGroup;
25  import io.netty.channel.MultiThreadIoEventLoopGroup;
26  import io.netty.channel.nio.NioIoHandler;
27  import io.netty.channel.oio.OioEventLoopGroup;
28  import io.netty.channel.socket.SocketProtocolFamily;
29  import io.netty.channel.socket.nio.NioDatagramChannel;
30  import io.netty.channel.socket.nio.NioServerSocketChannel;
31  import io.netty.channel.socket.nio.NioSocketChannel;
32  import io.netty.channel.socket.oio.OioDatagramChannel;
33  import io.netty.channel.socket.oio.OioServerSocketChannel;
34  import io.netty.channel.socket.oio.OioSocketChannel;
35  import io.netty.testsuite.transport.TestsuitePermutation.BootstrapComboFactory;
36  import io.netty.testsuite.transport.TestsuitePermutation.BootstrapFactory;
37  import io.netty.util.concurrent.DefaultThreadFactory;
38  import io.netty.util.internal.SystemPropertyUtil;
39  import io.netty.util.internal.logging.InternalLogger;
40  import io.netty.util.internal.logging.InternalLoggerFactory;
41  
42  import java.util.ArrayList;
43  import java.util.Arrays;
44  import java.util.List;
45  
46  public class SocketTestPermutation {
47  
48      static final String BAD_HOST = SystemPropertyUtil.get("io.netty.testsuite.badHost", "198.51.100.254");
49      static final int BAD_PORT = SystemPropertyUtil.getInt("io.netty.testsuite.badPort", 65535);
50  
51      static {
52          InternalLogger logger = InternalLoggerFactory.getInstance(SocketConnectionAttemptTest.class);
53          logger.debug("-Dio.netty.testsuite.badHost: {}", BAD_HOST);
54          logger.debug("-Dio.netty.testsuite.badPort: {}", BAD_PORT);
55      }
56  
57      static final SocketTestPermutation INSTANCE = new SocketTestPermutation();
58  
59      protected static final int BOSSES = 2;
60      protected static final int WORKERS = 3;
61  
62      protected static final int OIO_SO_TIMEOUT = 10;  // Use short timeout for faster runs.
63  
64      protected final EventLoopGroup nioBossGroup = new MultiThreadIoEventLoopGroup(
65              BOSSES, new DefaultThreadFactory("testsuite-nio-boss", true), NioIoHandler.newFactory());
66      protected final EventLoopGroup nioWorkerGroup = new MultiThreadIoEventLoopGroup(
67              WORKERS, new DefaultThreadFactory("testsuite-nio-worker", true), NioIoHandler.newFactory());
68      protected final EventLoopGroup oioBossGroup =
69              new OioEventLoopGroup(Integer.MAX_VALUE, new DefaultThreadFactory("testsuite-oio-boss", true));
70      protected final EventLoopGroup oioWorkerGroup =
71              new OioEventLoopGroup(Integer.MAX_VALUE, new DefaultThreadFactory("testsuite-oio-worker", true));
72  
73      protected <A extends AbstractBootstrap<?, ?>, B extends AbstractBootstrap<?, ?>>
74  
75      List<BootstrapComboFactory<A, B>> combo(List<BootstrapFactory<A>> sbfs, List<BootstrapFactory<B>> cbfs) {
76  
77          List<BootstrapComboFactory<A, B>> list = new ArrayList<BootstrapComboFactory<A, B>>();
78  
79          // Populate the combinations
80          for (BootstrapFactory<A> sbf: sbfs) {
81              for (BootstrapFactory<B> cbf: cbfs) {
82                  final BootstrapFactory<A> sbf0 = sbf;
83                  final BootstrapFactory<B> cbf0 = cbf;
84                  list.add(new BootstrapComboFactory<A, B>() {
85                      @Override
86                      public A newServerInstance() {
87                          return sbf0.newInstance();
88                      }
89  
90                      @Override
91                      public B newClientInstance() {
92                          return cbf0.newInstance();
93                      }
94                  });
95              }
96          }
97  
98          return list;
99      }
100 
101     public List<BootstrapComboFactory<ServerBootstrap, Bootstrap>> socket() {
102         // Make the list of ServerBootstrap factories.
103         List<BootstrapFactory<ServerBootstrap>> sbfs = serverSocket();
104 
105         // Make the list of Bootstrap factories.
106         List<BootstrapFactory<Bootstrap>> cbfs = clientSocket();
107 
108         // Populate the combinations
109         List<BootstrapComboFactory<ServerBootstrap, Bootstrap>> list = combo(sbfs, cbfs);
110 
111         // Remove the OIO-OIO case which often leads to a dead lock by its nature.
112         list.remove(list.size() - 1);
113 
114         return list;
115     }
116 
117     public List<BootstrapComboFactory<ServerBootstrap, Bootstrap>> socketWithFastOpen() {
118         // Make the list of ServerBootstrap factories.
119         List<BootstrapFactory<ServerBootstrap>> sbfs = serverSocket();
120 
121         // Make the list of Bootstrap factories.
122         List<BootstrapFactory<Bootstrap>> cbfs = clientSocketWithFastOpen();
123 
124         // Populate the combinations
125         List<BootstrapComboFactory<ServerBootstrap, Bootstrap>> list = combo(sbfs, cbfs);
126 
127         // Remove the OIO-OIO case which often leads to a dead lock by its nature.
128         list.remove(list.size() - 1);
129 
130         return list;
131     }
132 
133     public List<BootstrapComboFactory<Bootstrap, Bootstrap>> datagram(final SocketProtocolFamily family) {
134         // Make the list of Bootstrap factories.
135         List<BootstrapFactory<Bootstrap>> bfs = Arrays.asList(
136                 new BootstrapFactory<Bootstrap>() {
137                     @Override
138                     public Bootstrap newInstance() {
139                         return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
140                             @Override
141                             public Channel newChannel() {
142                                 return new NioDatagramChannel(family);
143                             }
144 
145                             @Override
146                             public String toString() {
147                                 return NioDatagramChannel.class.getSimpleName() + ".class";
148                             }
149                         });
150                     }
151                 },
152                 new BootstrapFactory<Bootstrap>() {
153                     @Override
154                     public Bootstrap newInstance() {
155                         return new Bootstrap().group(oioWorkerGroup).channel(OioDatagramChannel.class)
156                                 .option(ChannelOption.SO_TIMEOUT, OIO_SO_TIMEOUT);
157                     }
158                 }
159         );
160 
161         // Populare the combinations.
162         return combo(bfs, bfs);
163     }
164 
165     public List<BootstrapFactory<ServerBootstrap>> serverSocket() {
166         return Arrays.asList(
167                 new BootstrapFactory<ServerBootstrap>() {
168                     @Override
169                     public ServerBootstrap newInstance() {
170                         return new ServerBootstrap().group(nioBossGroup, nioWorkerGroup)
171                                 .channel(NioServerSocketChannel.class);
172                     }
173                 },
174                 new BootstrapFactory<ServerBootstrap>() {
175                     @Override
176                     public ServerBootstrap newInstance() {
177                         return new ServerBootstrap().group(oioBossGroup, oioWorkerGroup)
178                                 .channel(OioServerSocketChannel.class)
179                                 .option(ChannelOption.SO_TIMEOUT, OIO_SO_TIMEOUT);
180                     }
181                 }
182         );
183     }
184 
185     public List<BootstrapFactory<Bootstrap>> clientSocket() {
186         return Arrays.asList(
187                 new BootstrapFactory<Bootstrap>() {
188                     @Override
189                     public Bootstrap newInstance() {
190                         return new Bootstrap().group(nioWorkerGroup).channel(NioSocketChannel.class);
191                     }
192                 },
193                 new BootstrapFactory<Bootstrap>() {
194                     @Override
195                     public Bootstrap newInstance() {
196                         return new Bootstrap().group(oioWorkerGroup).channel(OioSocketChannel.class)
197                                 .option(ChannelOption.SO_TIMEOUT, OIO_SO_TIMEOUT);
198                     }
199                 }
200         );
201     }
202 
203     public List<BootstrapFactory<Bootstrap>> clientSocketWithFastOpen() {
204         return clientSocket();
205     }
206 
207     public List<BootstrapFactory<Bootstrap>> datagramSocket() {
208         return Arrays.asList(
209                 new BootstrapFactory<Bootstrap>() {
210                     @Override
211                     public Bootstrap newInstance() {
212                         return new Bootstrap().group(nioWorkerGroup).channel(NioDatagramChannel.class);
213                     }
214                 },
215                 new BootstrapFactory<Bootstrap>() {
216                     @Override
217                     public Bootstrap newInstance() {
218                         return new Bootstrap().group(oioWorkerGroup).channel(OioDatagramChannel.class)
219                                 .option(ChannelOption.SO_TIMEOUT, OIO_SO_TIMEOUT);
220                     }
221                 }
222         );
223     }
224 }