RandomPortUtils.java

1
package fr.sii.ogham.testing.util;
2
3
import java.net.DatagramSocket;
4
import java.net.InetAddress;
5
import java.net.ServerSocket;
6
import java.util.SortedSet;
7
8
import javax.net.ServerSocketFactory;
9
10
import fr.sii.ogham.testing.util.port.CrossJvmPortFinderLock;
11
import fr.sii.ogham.testing.util.port.DefaultPortFinder;
12
import fr.sii.ogham.testing.util.port.PortFinder;
13
14
/**
15
 * Simple utility methods for finding available ports on {@code localhost}.
16
 *
17
 * <p>
18
 * Within this class, a TCP port refers to a port for a {@link ServerSocket};
19
 * whereas, a UDP port refers to a port for a {@link DatagramSocket}.
20
 * 
21
 * <strong>NOTE:</strong> This code has been borrowed from Spring Framework.
22
 * 
23
 * @see "https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/util/SocketUtils.java"
24
 */
25
public final class RandomPortUtils {
26
27
	/**
28
	 * The default minimum value for port ranges used when finding an available
29
	 * socket port.
30
	 */
31
	public static final int PORT_RANGE_MIN = 1024;
32
33
	/**
34
	 * The default maximum value for port ranges used when finding an available
35
	 * socket port.
36
	 */
37
	public static final int PORT_RANGE_MAX = 65535;
38
39
	/**
40
	 * Find an available TCP port randomly selected from the range
41
	 * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}].
42
	 * 
43
	 * @return an available TCP port number
44
	 * @throws IllegalStateException
45
	 *             if no available port could be found
46
	 */
47
	public static int findAvailableTcpPort() {
48 1 1. findAvailableTcpPort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPort → NO_COVERAGE
		return findAvailableTcpPort(PORT_RANGE_MIN);
49
	}
50
51
	/**
52
	 * Find an available TCP port randomly selected from the range
53
	 * [{@code minPort}, {@value #PORT_RANGE_MAX}].
54
	 * 
55
	 * @param minPort
56
	 *            the minimum port number
57
	 * @return an available TCP port number
58
	 * @throws IllegalStateException
59
	 *             if no available port could be found
60
	 */
61
	public static int findAvailableTcpPort(int minPort) {
62 1 1. findAvailableTcpPort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPort → NO_COVERAGE
		return findAvailableTcpPort(minPort, PORT_RANGE_MAX);
63
	}
64
65
	/**
66
	 * Find an available TCP port randomly selected from the range
67
	 * [{@code minPort}, {@code maxPort}].
68
	 * 
69
	 * @param minPort
70
	 *            the minimum port number
71
	 * @param maxPort
72
	 *            the maximum port number
73
	 * @return an available TCP port number
74
	 * @throws IllegalStateException
75
	 *             if no available port could be found
76
	 */
77
	public static int findAvailableTcpPort(int minPort, int maxPort) {
78 1 1. findAvailableTcpPort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPort → RUN_ERROR
		return SocketType.TCP.findAvailablePort(minPort, maxPort);
79
	}
80
81
	/**
82
	 * Find the requested number of available TCP ports, each randomly selected
83
	 * from the range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}].
84
	 * 
85
	 * @param numRequested
86
	 *            the number of available ports to find
87
	 * @return a sorted set of available TCP port numbers
88
	 * @throws IllegalStateException
89
	 *             if the requested number of available ports could not be found
90
	 */
91
	public static SortedSet<Integer> findAvailableTcpPorts(int numRequested) {
92 1 1. findAvailableTcpPorts : replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPorts → NO_COVERAGE
		return findAvailableTcpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX);
93
	}
94
95
	/**
96
	 * Find the requested number of available TCP ports, each randomly selected
97
	 * from the range [{@code minPort}, {@code maxPort}].
98
	 * 
99
	 * @param numRequested
100
	 *            the number of available ports to find
101
	 * @param minPort
102
	 *            the minimum port number
103
	 * @param maxPort
104
	 *            the maximum port number
105
	 * @return a sorted set of available TCP port numbers
106
	 * @throws IllegalStateException
107
	 *             if the requested number of available ports could not be found
108
	 */
109
	public static SortedSet<Integer> findAvailableTcpPorts(int numRequested, int minPort, int maxPort) {
110 1 1. findAvailableTcpPorts : replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPorts → NO_COVERAGE
		return SocketType.TCP.findAvailablePorts(numRequested, minPort, maxPort);
111
	}
112
113
	/**
114
	 * Find an available UDP port randomly selected from the range
115
	 * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}].
116
	 * 
117
	 * @return an available UDP port number
118
	 * @throws IllegalStateException
119
	 *             if no available port could be found
120
	 */
121
	public static int findAvailableUdpPort() {
122 1 1. findAvailableUdpPort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPort → NO_COVERAGE
		return findAvailableUdpPort(PORT_RANGE_MIN);
123
	}
124
125
	/**
126
	 * Find an available UDP port randomly selected from the range
127
	 * [{@code minPort}, {@value #PORT_RANGE_MAX}].
128
	 * 
129
	 * @param minPort
130
	 *            the minimum port number
131
	 * @return an available UDP port number
132
	 * @throws IllegalStateException
133
	 *             if no available port could be found
134
	 */
135
	public static int findAvailableUdpPort(int minPort) {
136 1 1. findAvailableUdpPort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPort → NO_COVERAGE
		return findAvailableUdpPort(minPort, PORT_RANGE_MAX);
137
	}
138
139
	/**
140
	 * Find an available UDP port randomly selected from the range
141
	 * [{@code minPort}, {@code maxPort}].
142
	 * 
143
	 * @param minPort
144
	 *            the minimum port number
145
	 * @param maxPort
146
	 *            the maximum port number
147
	 * @return an available UDP port number
148
	 * @throws IllegalStateException
149
	 *             if no available port could be found
150
	 */
151
	public static int findAvailableUdpPort(int minPort, int maxPort) {
152 1 1. findAvailableUdpPort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPort → NO_COVERAGE
		return SocketType.UDP.findAvailablePort(minPort, maxPort);
153
	}
154
155
	/**
156
	 * Find the requested number of available UDP ports, each randomly selected
157
	 * from the range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}].
158
	 * 
159
	 * @param numRequested
160
	 *            the number of available ports to find
161
	 * @return a sorted set of available UDP port numbers
162
	 * @throws IllegalStateException
163
	 *             if the requested number of available ports could not be found
164
	 */
165
	public static SortedSet<Integer> findAvailableUdpPorts(int numRequested) {
166 1 1. findAvailableUdpPorts : replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPorts → NO_COVERAGE
		return findAvailableUdpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX);
167
	}
168
169
	/**
170
	 * Find the requested number of available UDP ports, each randomly selected
171
	 * from the range [{@code minPort}, {@code maxPort}].
172
	 * 
173
	 * @param numRequested
174
	 *            the number of available ports to find
175
	 * @param minPort
176
	 *            the minimum port number
177
	 * @param maxPort
178
	 *            the maximum port number
179
	 * @return a sorted set of available UDP port numbers
180
	 * @throws IllegalStateException
181
	 *             if the requested number of available ports could not be found
182
	 */
183
	public static SortedSet<Integer> findAvailableUdpPorts(int numRequested, int minPort, int maxPort) {
184 1 1. findAvailableUdpPorts : replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPorts → NO_COVERAGE
		return SocketType.UDP.findAvailablePorts(numRequested, minPort, maxPort);
185
	}
186
187
	@SuppressWarnings("squid:IndentationCheck")
188
	private enum SocketType implements PortFinder {
189
190
		TCP {
191
			@Override
192
			protected boolean isPortAvailable(int port) {
193
				try (ServerSocket ignored = ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName("localhost"))) {
194
					return true;
195
				} catch (Exception ex) {
196 1 1. isPortAvailable : replaced boolean return with true for fr/sii/ogham/testing/util/RandomPortUtils$SocketType$1::isPortAvailable → NO_COVERAGE
					return false;
197
				}
198
			}
199
		},
200
201
		UDP {
202
			@Override
203
			protected boolean isPortAvailable(int port) {
204
				try (DatagramSocket ignored = new DatagramSocket(port, InetAddress.getByName("localhost"))) {
205
					return true;
206
				} catch (Exception ex) {
207 1 1. isPortAvailable : replaced boolean return with true for fr/sii/ogham/testing/util/RandomPortUtils$SocketType$2::isPortAvailable → NO_COVERAGE
					return false;
208
				}
209
			}
210
		};
211
		
212
		private PortFinder delegate;
213
		
214
		SocketType() {
215
			this.delegate = new DefaultPortFinder(name(), this::isPortAvailable);
216
		}
217
218
		protected abstract boolean isPortAvailable(int port);
219
		
220
		/**
221
		 * Find an available port for this {@code SocketType}, randomly selected
222
		 * from the range [{@code minPort}, {@code maxPort}].
223
		 * 
224
		 * @param minPort
225
		 *            the minimum port number
226
		 * @param maxPort
227
		 *            the maximum port number
228
		 * @return an available port number for this socket type
229
		 * @throws IllegalStateException
230
		 *             if no available port could be found
231
		 */
232
		@Override
233
		public int findAvailablePort(int minPort, int maxPort) {
234 1 1. findAvailablePort : replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils$SocketType::findAvailablePort → RUN_ERROR
			return delegate.findAvailablePort(minPort, maxPort);
235
		}
236
		
237
		/**
238
		 * Find the requested number of available ports for this
239
		 * {@code SocketType}, each randomly selected from the range
240
		 * [{@code minPort}, {@code maxPort}].
241
		 * 
242
		 * @param numRequested
243
		 *            the number of available ports to find
244
		 * @param minPort
245
		 *            the minimum port number
246
		 * @param maxPort
247
		 *            the maximum port number
248
		 * @return a sorted set of available port numbers for this socket type
249
		 * @throws IllegalStateException
250
		 *             if the requested number of available ports could not be
251
		 *             found
252
		 */
253
		@Override
254
		public SortedSet<Integer> findAvailablePorts(int numRequested, int minPort, int maxPort) {
255 1 1. findAvailablePorts : replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils$SocketType::findAvailablePorts → NO_COVERAGE
			return delegate.findAvailablePorts(numRequested, minPort, maxPort);
256
		}
257
	}
258
259
	private RandomPortUtils() {
260
		super();
261
	}
262
263
}

Mutations

48

1.1
Location : findAvailableTcpPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPort → NO_COVERAGE

62

1.1
Location : findAvailableTcpPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPort → NO_COVERAGE

78

1.1
Location : findAvailableTcpPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPort → RUN_ERROR

92

1.1
Location : findAvailableTcpPorts
Killed by :
replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPorts → NO_COVERAGE

110

1.1
Location : findAvailableTcpPorts
Killed by :
replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableTcpPorts → NO_COVERAGE

122

1.1
Location : findAvailableUdpPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPort → NO_COVERAGE

136

1.1
Location : findAvailableUdpPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPort → NO_COVERAGE

152

1.1
Location : findAvailableUdpPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPort → NO_COVERAGE

166

1.1
Location : findAvailableUdpPorts
Killed by :
replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPorts → NO_COVERAGE

184

1.1
Location : findAvailableUdpPorts
Killed by :
replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils::findAvailableUdpPorts → NO_COVERAGE

196

1.1
Location : isPortAvailable
Killed by :
replaced boolean return with true for fr/sii/ogham/testing/util/RandomPortUtils$SocketType$1::isPortAvailable → NO_COVERAGE

207

1.1
Location : isPortAvailable
Killed by :
replaced boolean return with true for fr/sii/ogham/testing/util/RandomPortUtils$SocketType$2::isPortAvailable → NO_COVERAGE

234

1.1
Location : findAvailablePort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/util/RandomPortUtils$SocketType::findAvailablePort → RUN_ERROR

255

1.1
Location : findAvailablePorts
Killed by :
replaced return value with null for fr/sii/ogham/testing/util/RandomPortUtils$SocketType::findAvailablePorts → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.13.1