Repository: geode Updated Branches: refs/heads/develop cb8f0c40e -> 4018543ac
GEODE-2593: add port range to AvailablePortHelper to fix testUDPPortRange Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/9852f640 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/9852f640 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/9852f640 Branch: refs/heads/develop Commit: 9852f640096e324126a53b73f4fbaf6648a89ce0 Parents: 22d8b40 Author: Kirk Lund <[email protected]> Authored: Fri Mar 3 17:36:07 2017 -0800 Committer: Kevin J. Duling <[email protected]> Committed: Wed Mar 8 10:43:28 2017 -0800 ---------------------------------------------------------------------- .../distributed/DistributedSystemDUnitTest.java | 50 ++-- .../geode/internal/AvailablePortHelper.java | 64 ++++- .../AvailablePortHelperIntegrationTest.java | 264 +++++++++++++++++++ 3 files changed, 361 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/9852f640/geode-core/src/test/java/org/apache/geode/distributed/DistributedSystemDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/distributed/DistributedSystemDUnitTest.java b/geode-core/src/test/java/org/apache/geode/distributed/DistributedSystemDUnitTest.java index c57ad17..c1ea5e6 100644 --- a/geode-core/src/test/java/org/apache/geode/distributed/DistributedSystemDUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/distributed/DistributedSystemDUnitTest.java @@ -14,6 +14,10 @@ */ package org.apache.geode.distributed; +import static org.apache.geode.distributed.ConfigurationProperties.*; +import static org.apache.geode.internal.AvailablePort.*; +import static org.junit.Assert.*; + import org.apache.geode.CancelException; import org.apache.geode.GemFireConfigException; import org.apache.geode.SystemConnectException; @@ -22,7 +26,12 @@ import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache30.CacheSerializableRunnable; -import org.apache.geode.distributed.internal.*; +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.DistributionException; +import org.apache.geode.distributed.internal.DistributionManager; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.distributed.internal.SerialDistributionMessage; +import org.apache.geode.distributed.internal.SizeableRunnable; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper; import org.apache.geode.distributed.internal.membership.gms.messenger.JGroupsMessenger; @@ -30,12 +39,19 @@ import org.apache.geode.distributed.internal.membership.gms.mgr.GMSMembershipMan import org.apache.geode.internal.AvailablePort; import org.apache.geode.internal.AvailablePortHelper; import org.apache.geode.internal.net.SocketCreator; -import org.apache.geode.test.dunit.*; +import org.apache.geode.test.dunit.DistributedTestUtils; +import org.apache.geode.test.dunit.Host; +import org.apache.geode.test.dunit.LogWriterUtils; +import org.apache.geode.test.dunit.RMIException; +import org.apache.geode.test.dunit.VM; import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; import org.apache.geode.test.junit.categories.DistributedTest; import org.apache.geode.test.junit.categories.FlakyTest; import org.apache.geode.test.junit.categories.MembershipTest; -import org.junit.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import org.junit.experimental.categories.Category; import java.net.Inet4Address; @@ -46,20 +62,19 @@ import java.util.Enumeration; import java.util.Properties; import java.util.concurrent.TimeoutException; -import static org.apache.geode.distributed.ConfigurationProperties.*; -import static org.apache.geode.internal.AvailablePort.SOCKET; -import static org.junit.Assert.*; - /** * Tests the functionality of the {@link DistributedSystem} class. - * - * @see InternalDistributedSystemJUnitTest - * */ @Category({DistributedTest.class, MembershipTest.class}) public class DistributedSystemDUnitTest extends JUnit4DistributedTestCase { - public void postSetUp() throws Exception { + @Before + public void before() throws Exception { + disconnectAllFromDS(); + } + + @After + public void after() throws Exception { disconnectAllFromDS(); } @@ -298,18 +313,21 @@ public class DistributedSystemDUnitTest extends JUnit4DistributedTestCase { @Test public void testUDPPortRange() throws Exception { + int[] unicastPort = AvailablePortHelper.getRandomAvailableTCPPortRange(3, true); + Properties config = new Properties(); - int unicastPort = - AvailablePort.getRandomAvailablePort(SOCKET, AvailablePort.getAddress(SOCKET), true); config.put(LOCATORS, "localhost[" + DistributedTestUtils.getDUnitLocatorPort() + "]"); // Minimum 3 ports required in range for UDP, FD_SOCK and TcpConduit. - config.setProperty(MEMBERSHIP_PORT_RANGE, "" + unicastPort + "-" + (unicastPort + 2)); + config.setProperty(MEMBERSHIP_PORT_RANGE, unicastPort[0] + "-" + unicastPort[2]); + InternalDistributedSystem system = getSystem(config); DistributionManager dm = (DistributionManager) system.getDistributionManager(); InternalDistributedMember idm = dm.getDistributionManagerId(); + + assertTrue(unicastPort[0] <= idm.getPort() && idm.getPort() <= unicastPort[2]); + assertTrue(unicastPort[0] <= idm.getPort() && idm.getDirectChannelPort() <= unicastPort[2]); + system.disconnect(); - assertTrue(unicastPort <= idm.getPort() && idm.getPort() <= unicastPort + 2); - assertTrue(unicastPort <= idm.getPort() && idm.getDirectChannelPort() <= unicastPort + 2); } /*** http://git-wip-us.apache.org/repos/asf/geode/blob/9852f640/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelper.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelper.java b/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelper.java index e09a7a0..6a1c1d4 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelper.java +++ b/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelper.java @@ -14,6 +14,10 @@ */ package org.apache.geode.internal; +import static org.apache.geode.distributed.internal.DistributionConfig.*; +import static org.apache.geode.internal.AvailablePort.*; + +import java.net.InetAddress; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -66,11 +70,69 @@ public class AvailablePortHelper { List<Keeper> result = new ArrayList<Keeper>(); while (result.size() < count) { result.add(AvailablePort.getRandomAvailablePortKeeper(AvailablePort.SOCKET, - AvailablePort.getAddress(AvailablePort.SOCKET), useMembershipPortRange)); + getAddress(AvailablePort.SOCKET), useMembershipPortRange)); + } + return result; + } + + public static int[] getRandomAvailableTCPPortRange(final int count) { + return getRandomAvailableTCPPortRange(count, false); + } + + public static int[] getRandomAvailableTCPPortRange(final int count, + final boolean useMembershipPortRange) { + List<Keeper> list = getRandomAvailableTCPPortRangeKeepers(count, useMembershipPortRange); + int[] ports = new int[list.size()]; + int i = 0; + for (Keeper k : list) { + ports[i] = k.getPort(); + k.release(); + i++; + } + return ports; + } + + public static List<Keeper> getRandomAvailableTCPPortRangeKeepers(final int count) { + return getRandomAvailableTCPPortRangeKeepers(count, false); + } + + public static List<Keeper> getRandomAvailableTCPPortRangeKeepers(final int count, + final boolean useMembershipPortRange) { + List<Keeper> result = new ArrayList<>(); + + InetAddress addr = getAddress(AvailablePort.SOCKET); + + int lowerBound = + useMembershipPortRange ? DEFAULT_MEMBERSHIP_PORT_RANGE[0] : AVAILABLE_PORTS_LOWER_BOUND; + + int upperBound = + useMembershipPortRange ? DEFAULT_MEMBERSHIP_PORT_RANGE[1] : AVAILABLE_PORTS_UPPER_BOUND; + + for (int i = lowerBound; i <= upperBound; i++) { + for (int j = 0; j < count && ((i + j) <= upperBound); j++) { + int port = i + j; + Keeper keeper = isPortKeepable(port, SOCKET, addr); + if (keeper == null) { + releaseKeepers(result); + result.clear(); + break; + } + result.add(keeper); + if (result.size() == count) { + return result; + } + } } + return result; } + private static void releaseKeepers(List<Keeper> keepers) { + for (Keeper keeper : keepers) { + keeper.release(); + } + } + /** * Returns array of unique randomly available tcp ports of specified count. */ http://git-wip-us.apache.org/repos/asf/geode/blob/9852f640/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelperIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelperIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelperIntegrationTest.java new file mode 100644 index 0000000..d6cfddc --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/internal/AvailablePortHelperIntegrationTest.java @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal; + +import static org.apache.geode.distributed.internal.DistributionConfig.*; +import static org.apache.geode.internal.AvailablePort.*; +import static org.apache.geode.internal.AvailablePortHelper.*; +import static org.assertj.core.api.Assertions.*; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import org.apache.geode.internal.AvailablePort.Keeper; +import org.apache.geode.test.junit.categories.IntegrationTest; + +@Category(IntegrationTest.class) +@RunWith(JUnitParamsRunner.class) +public class AvailablePortHelperIntegrationTest { + + private Set<ServerSocket> serverSockets; + + @Before + public void before() throws Exception { + this.serverSockets = new HashSet<>(); + } + + @After + public void after() throws Exception { + for (ServerSocket serverSocket : this.serverSockets) { + try { + if (serverSocket != null && !serverSocket.isClosed()) { + serverSocket.close(); + } + } catch (IOException ignore) { + System.err.println("Unable to close " + serverSocket); + } + } + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRange_zero(final boolean useMembershipPortRange) + throws Exception { + int[] results = getRandomAvailableTCPPortRange(0, useMembershipPortRange); + assertThat(results).isEmpty(); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRange_one_returnsOne(final boolean useMembershipPortRange) + throws Exception { + int[] results = getRandomAvailableTCPPortRange(1, useMembershipPortRange); + assertThat(results).hasSize(1); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRange_two_returnsTwo(final boolean useMembershipPortRange) + throws Exception { + int[] results = getRandomAvailableTCPPortRange(2, useMembershipPortRange); + assertThat(results).hasSize(2); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRange_many_returnsMany(final boolean useMembershipPortRange) + throws Exception { + int[] results = getRandomAvailableTCPPortRange(10, useMembershipPortRange); + assertThat(results).hasSize(10); + assertPortsAreUsable(results); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRange_returnsUniquePorts( + final boolean useMembershipPortRange) throws Exception { + int[] results = getRandomAvailableTCPPortRange(10, useMembershipPortRange); + + Set<Integer> ports = new HashSet<>(); + for (int port : results) { + ports.add(port); + } + + assertThat(ports).hasSize(results.length); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRange_returnsConsecutivePorts( + final boolean useMembershipPortRange) throws Exception { + int[] results = getRandomAvailableTCPPortRange(10, useMembershipPortRange); + + List<Integer> ports = new ArrayList<>(); + for (int port : results) { + if (useMembershipPortRange) { + assertThat(port).isGreaterThanOrEqualTo(DEFAULT_MEMBERSHIP_PORT_RANGE[0]) + .isLessThanOrEqualTo(DEFAULT_MEMBERSHIP_PORT_RANGE[1]); + } else { + assertThat(port).isGreaterThanOrEqualTo(AVAILABLE_PORTS_LOWER_BOUND) + .isLessThanOrEqualTo(AVAILABLE_PORTS_UPPER_BOUND); + } + ports.add(port); + } + + assertThat(ports).hasSize(10); + + int previousPort = 0; + for (int port : ports) { + if (previousPort != 0) { + assertThat(port).isEqualTo(previousPort + 1); + } + previousPort = port; + } + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_zero(final boolean useMembershipPortRange) + throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(0, useMembershipPortRange); + assertThat(results).isEmpty(); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_one_returnsOne( + final boolean useMembershipPortRange) throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(1, useMembershipPortRange); + assertThat(results).hasSize(1); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_two_returnsTwo( + final boolean useMembershipPortRange) throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(2, useMembershipPortRange); + assertThat(results).hasSize(2); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_many_returnsMany( + final boolean useMembershipPortRange) throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(10, useMembershipPortRange); + assertThat(results).hasSize(10); + assertKeepersAreUsable(results); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_returnsUsableKeeper( + final boolean useMembershipPortRange) throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(1, useMembershipPortRange); + assertKeepersAreUsable(results); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_returnsUniqueKeepers( + final boolean useMembershipPortRange) throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(10, useMembershipPortRange); + + Set<Integer> ports = new HashSet<>(); + for (Keeper keeper : results) { + ports.add(keeper.getPort()); + } + + assertThat(ports).hasSize(results.size()); + } + + @Test + @Parameters({"true", "false"}) + public void getRandomAvailableTCPPortRangeKeepers_returnsConsecutivePorts( + final boolean useMembershipPortRange) throws Exception { + List<Keeper> results = getRandomAvailableTCPPortRangeKeepers(10, useMembershipPortRange); + + List<Integer> ports = new ArrayList<>(); + for (Keeper keeper : results) { + assertThat(keeper).isNotNull(); + int port = keeper.getPort(); + if (useMembershipPortRange) { + assertThat(port).isGreaterThanOrEqualTo(DEFAULT_MEMBERSHIP_PORT_RANGE[0]) + .isLessThanOrEqualTo(DEFAULT_MEMBERSHIP_PORT_RANGE[1]); + } else { + assertThat(port).isGreaterThanOrEqualTo(AVAILABLE_PORTS_LOWER_BOUND) + .isLessThanOrEqualTo(AVAILABLE_PORTS_UPPER_BOUND); + } + ports.add(port); + } + + assertThat(ports).hasSize(10); + + int previousPort = 0; + for (int port : ports) { + if (previousPort != 0) { + assertThat(port).isEqualTo(previousPort + 1); + } + previousPort = port; + } + } + + private void assertPortsAreUsable(int[] ports) throws IOException { + for (int port : ports) { + assertPortIsUsable(port); + } + } + + private void assertPortIsUsable(int port) throws IOException { + ServerSocket serverSocket = createServerSocket(); + serverSocket.setReuseAddress(true); + + serverSocket.bind(new InetSocketAddress(port)); + + assertThat(serverSocket.isBound()).isTrue(); + assertThat(serverSocket.isClosed()).isFalse(); + serverSocket.close(); + assertThat(serverSocket.isClosed()).isTrue(); + } + + private void assertKeepersAreUsable(Collection<Keeper> keepers) throws IOException { + for (Keeper keeper : keepers) { + assertKeeperIsUsable(keeper); + } + } + + private void assertKeeperIsUsable(Keeper keeper) throws IOException { + int port = keeper.getPort(); + keeper.release(); + assertPortIsUsable(port); + } + + private ServerSocket createServerSocket() throws IOException { + ServerSocket serverSocket = new ServerSocket(); + this.serverSockets.add(serverSocket); + return serverSocket; + } + +}
