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