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