| 1 | package fr.sii.ogham.testing.util.port; | |
| 2 | ||
| 3 | import java.util.Random; | |
| 4 | import java.util.SortedSet; | |
| 5 | import java.util.TreeSet; | |
| 6 | import java.util.function.IntPredicate; | |
| 7 | ||
| 8 | import fr.sii.ogham.testing.util.RandomPortUtils; | |
| 9 | ||
| 10 | /** | |
| 11 | * Default implementation that search for ports by delegating port availability | |
| 12 | * check to a function. | |
| 13 | * | |
| 14 | * @author Aurélien Baudet | |
| 15 | * | |
| 16 | */ | |
| 17 | public class DefaultPortFinder implements PortFinder { | |
| 18 | protected final Random random; | |
| 19 | protected final String protocol; | |
| 20 | protected final IntPredicate isPortAvailable; | |
| 21 | ||
| 22 | /** | |
| 23 | * Initialize with a function to check if a port is available or not. | |
| 24 | * | |
| 25 | * @param protocol | |
| 26 | * the protocol | |
| 27 | * @param isPortAvailable | |
| 28 | * Determine if the specified port for this {@code SocketType} is | |
| 29 | * currently available on {@code localhost}. | |
| 30 | */ | |
| 31 | @SuppressWarnings("java:S2245") | |
| 32 | public DefaultPortFinder(String protocol, IntPredicate isPortAvailable) { | |
| 33 | this(protocol, isPortAvailable, new Random(System.nanoTime())); | |
| 34 | } | |
| 35 | ||
| 36 | /** | |
| 37 | * Initialize with a function to check if a port is available or not. | |
| 38 | * | |
| 39 | * @param protocol | |
| 40 | * the protocol | |
| 41 | * @param isPortAvailable | |
| 42 | * Determine if the specified port for this {@code SocketType} is | |
| 43 | * currently available on {@code localhost}. | |
| 44 | * @param random | |
| 45 | * the random implementation to use | |
| 46 | */ | |
| 47 | public DefaultPortFinder(String protocol, IntPredicate isPortAvailable, Random random) { | |
| 48 | super(); | |
| 49 | this.protocol = protocol; | |
| 50 | this.isPortAvailable = isPortAvailable; | |
| 51 | this.random = random; | |
| 52 | } | |
| 53 | ||
| 54 | /** | |
| 55 | * Find an available port for this {@code SocketType}, randomly selected | |
| 56 | * from the range [{@code minPort}, {@code maxPort}]. | |
| 57 | * | |
| 58 | * @param minPort | |
| 59 | * the minimum port number | |
| 60 | * @param maxPort | |
| 61 | * the maximum port number | |
| 62 | * @return an available port number for this socket type | |
| 63 | * @throws IllegalStateException | |
| 64 | * if no available port could be found | |
| 65 | */ | |
| 66 | public int findAvailablePort(int minPort, int maxPort) { | |
| 67 |
3
1. findAvailablePort : negated conditional → RUN_ERROR 2. findAvailablePort : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → RUN_ERROR 3. findAvailablePort : changed conditional boundary → RUN_ERROR |
assertIsTrue(minPort > 0, "'minPort' must be greater than 0"); |
| 68 |
3
1. findAvailablePort : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → RUN_ERROR 2. findAvailablePort : changed conditional boundary → RUN_ERROR 3. findAvailablePort : negated conditional → RUN_ERROR |
assertIsTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); |
| 69 |
3
1. findAvailablePort : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → RUN_ERROR 2. findAvailablePort : changed conditional boundary → RUN_ERROR 3. findAvailablePort : negated conditional → RUN_ERROR |
assertIsTrue(maxPort <= RandomPortUtils.PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + RandomPortUtils.PORT_RANGE_MAX); |
| 70 | ||
| 71 |
1
1. findAvailablePort : Replaced integer subtraction with addition → RUN_ERROR |
int portRange = maxPort - minPort; |
| 72 | int candidatePort; | |
| 73 | int searchCounter = 0; | |
| 74 | do { | |
| 75 |
2
1. findAvailablePort : changed conditional boundary → RUN_ERROR 2. findAvailablePort : negated conditional → RUN_ERROR |
if (searchCounter > portRange) { |
| 76 | throw new IllegalStateException(String.format("Could not find an available %s port in the range [%d, %d] after %d attempts", protocol, minPort, maxPort, searchCounter)); | |
| 77 | } | |
| 78 | candidatePort = findRandomPort(minPort, maxPort); | |
| 79 |
1
1. findAvailablePort : Changed increment from 1 to -1 → RUN_ERROR |
searchCounter++; |
| 80 |
1
1. findAvailablePort : negated conditional → RUN_ERROR |
} while (!isPortAvailable.test(candidatePort)); |
| 81 | ||
| 82 |
1
1. findAvailablePort : replaced int return with 0 for fr/sii/ogham/testing/util/port/DefaultPortFinder::findAvailablePort → RUN_ERROR |
return candidatePort; |
| 83 | } | |
| 84 | ||
| 85 | /** | |
| 86 | * Find the requested number of available ports for this {@code SocketType}, | |
| 87 | * each randomly selected from the range [{@code minPort}, {@code maxPort}]. | |
| 88 | * | |
| 89 | * @param numRequested | |
| 90 | * the number of available ports to find | |
| 91 | * @param minPort | |
| 92 | * the minimum port number | |
| 93 | * @param maxPort | |
| 94 | * the maximum port number | |
| 95 | * @return a sorted set of available port numbers for this socket type | |
| 96 | * @throws IllegalStateException | |
| 97 | * if the requested number of available ports could not be found | |
| 98 | */ | |
| 99 | public SortedSet<Integer> findAvailablePorts(int numRequested, int minPort, int maxPort) { | |
| 100 |
3
1. findAvailablePorts : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → NO_COVERAGE 2. findAvailablePorts : negated conditional → NO_COVERAGE 3. findAvailablePorts : changed conditional boundary → NO_COVERAGE |
assertIsTrue(minPort > 0, "'minPort' must be greater than 0"); |
| 101 |
3
1. findAvailablePorts : negated conditional → NO_COVERAGE 2. findAvailablePorts : changed conditional boundary → NO_COVERAGE 3. findAvailablePorts : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → NO_COVERAGE |
assertIsTrue(maxPort > minPort, "'maxPort' must be greater than 'minPort'"); |
| 102 |
3
1. findAvailablePorts : negated conditional → NO_COVERAGE 2. findAvailablePorts : changed conditional boundary → NO_COVERAGE 3. findAvailablePorts : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → NO_COVERAGE |
assertIsTrue(maxPort <= RandomPortUtils.PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + RandomPortUtils.PORT_RANGE_MAX); |
| 103 |
3
1. findAvailablePorts : changed conditional boundary → NO_COVERAGE 2. findAvailablePorts : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → NO_COVERAGE 3. findAvailablePorts : negated conditional → NO_COVERAGE |
assertIsTrue(numRequested > 0, "'numRequested' must be greater than 0"); |
| 104 |
4
1. findAvailablePorts : changed conditional boundary → NO_COVERAGE 2. findAvailablePorts : negated conditional → NO_COVERAGE 3. findAvailablePorts : Replaced integer subtraction with addition → NO_COVERAGE 4. findAvailablePorts : removed call to fr/sii/ogham/testing/util/port/DefaultPortFinder::assertIsTrue → NO_COVERAGE |
assertIsTrue((maxPort - minPort) >= numRequested, "'numRequested' must not be greater than 'maxPort' - 'minPort'"); |
| 105 | ||
| 106 | SortedSet<Integer> availablePorts = new TreeSet<>(); | |
| 107 | int attemptCount = 0; | |
| 108 |
6
1. findAvailablePorts : changed conditional boundary → NO_COVERAGE 2. findAvailablePorts : changed conditional boundary → NO_COVERAGE 3. findAvailablePorts : Changed increment from 1 to -1 → NO_COVERAGE 4. findAvailablePorts : negated conditional → NO_COVERAGE 5. findAvailablePorts : Replaced integer addition with subtraction → NO_COVERAGE 6. findAvailablePorts : negated conditional → NO_COVERAGE |
while ((++attemptCount <= numRequested + 100) && availablePorts.size() < numRequested) { |
| 109 | availablePorts.add(findAvailablePort(minPort, maxPort)); | |
| 110 | } | |
| 111 | ||
| 112 |
1
1. findAvailablePorts : negated conditional → NO_COVERAGE |
if (availablePorts.size() != numRequested) { |
| 113 | throw new IllegalStateException(String.format("Could not find %d available %s ports in the range [%d, %d]", numRequested, protocol, minPort, maxPort)); | |
| 114 | } | |
| 115 | ||
| 116 |
1
1. findAvailablePorts : replaced return value with null for fr/sii/ogham/testing/util/port/DefaultPortFinder::findAvailablePorts → NO_COVERAGE |
return availablePorts; |
| 117 | } | |
| 118 | | |
| 119 | /** | |
| 120 | * Find a pseudo-random port number within the range [{@code minPort}, | |
| 121 | * {@code maxPort}]. | |
| 122 | * | |
| 123 | * @param minPort | |
| 124 | * the minimum port number | |
| 125 | * @param maxPort | |
| 126 | * the maximum port number | |
| 127 | * @return a random port number within the specified range | |
| 128 | */ | |
| 129 | private int findRandomPort(int minPort, int maxPort) { | |
| 130 |
1
1. findRandomPort : Replaced integer subtraction with addition → RUN_ERROR |
int portRange = maxPort - minPort; |
| 131 |
3
1. findRandomPort : replaced int return with 0 for fr/sii/ogham/testing/util/port/DefaultPortFinder::findRandomPort → RUN_ERROR 2. findRandomPort : Replaced integer addition with subtraction → RUN_ERROR 3. findRandomPort : Replaced integer addition with subtraction → RUN_ERROR |
return minPort + random.nextInt(portRange + 1); |
| 132 | } | |
| 133 | ||
| 134 | private static void assertIsTrue(boolean condition, String message) { | |
| 135 |
1
1. assertIsTrue : negated conditional → RUN_ERROR |
if (!condition) { |
| 136 | throw new IllegalArgumentException(message); | |
| 137 | } | |
| 138 | } | |
| 139 | } | |
Mutations | ||
| 67 |
1.1 2.2 3.3 |
|
| 68 |
1.1 2.2 3.3 |
|
| 69 |
1.1 2.2 3.3 |
|
| 71 |
1.1 |
|
| 75 |
1.1 2.2 |
|
| 79 |
1.1 |
|
| 80 |
1.1 |
|
| 82 |
1.1 |
|
| 100 |
1.1 2.2 3.3 |
|
| 101 |
1.1 2.2 3.3 |
|
| 102 |
1.1 2.2 3.3 |
|
| 103 |
1.1 2.2 3.3 |
|
| 104 |
1.1 2.2 3.3 4.4 |
|
| 108 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
| 112 |
1.1 |
|
| 116 |
1.1 |
|
| 130 |
1.1 |
|
| 131 |
1.1 2.2 3.3 |
|
| 135 |
1.1 |