You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by up...@apache.org on 2018/08/31 18:38:13 UTC

[geode] branch develop updated: GEODE-5622: Add unique port supplier that remembers supplied ports (#2410)

This is an automated email from the ASF dual-hosted git repository.

upthewaterspout pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new dcac15d  GEODE-5622: Add unique port supplier that remembers supplied ports (#2410)
dcac15d is described below

commit dcac15dcb3450983a619e5e7dd52711332812e84
Author: Dan Smith <ds...@pivotal.io>
AuthorDate: Fri Aug 31 11:38:06 2018 -0700

    GEODE-5622: Add unique port supplier that remembers supplied ports (#2410)
    
    Adding a utility to hand out unique ports that don't conflict with
    each other, and using that in the MemberStarterRule. This should fix port
    conflicts in AlterRuntimeCommandDUnitTest and others.
    
    Co-authored-by: Dale Emery <da...@dhemery.com>
---
 .../geode/test/junit/rules/MemberStarterRule.java  | 15 +++++--
 .../apache/geode/internal/UniquePortSupplier.java  | 47 +++++++++++++++++++++
 .../geode/internal/UniquePortSupplierTest.java     | 48 ++++++++++++++++++++++
 3 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/MemberStarterRule.java b/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/MemberStarterRule.java
index 9fa1ddc..e78683c 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/MemberStarterRule.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/junit/rules/MemberStarterRule.java
@@ -55,7 +55,7 @@ import org.junit.rules.TemporaryFolder;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper;
-import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.UniquePortSupplier;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier;
 import org.apache.geode.internal.cache.tier.sockets.CacheClientProxy;
@@ -89,6 +89,7 @@ public abstract class MemberStarterRule<T> extends SerializableExternalResource
   protected Properties properties = new Properties();
 
   protected boolean autoStart = false;
+  private final transient UniquePortSupplier portSupplier;
 
   public static void setWaitUntilTimeout(int waitUntilTimeout) {
     WAIT_UNTIL_TIMEOUT = waitUntilTimeout;
@@ -97,6 +98,11 @@ public abstract class MemberStarterRule<T> extends SerializableExternalResource
   private static int WAIT_UNTIL_TIMEOUT = 30;
 
   public MemberStarterRule() {
+    this(new UniquePortSupplier());
+  }
+
+  public MemberStarterRule(UniquePortSupplier portSupplier) {
+    this.portSupplier = portSupplier;
     oldUserDir = System.getProperty("user.dir");
 
     // initial values
@@ -231,7 +237,7 @@ public abstract class MemberStarterRule<T> extends SerializableExternalResource
     if (!useProductDefaultPorts) {
       // do no override these properties if already exists
       properties.putIfAbsent(JMX_MANAGER_PORT,
-          AvailablePortHelper.getRandomAvailableTCPPort() + "");
+          portSupplier.getAvailablePort() + "");
       this.jmxPort = Integer.parseInt(properties.getProperty(JMX_MANAGER_PORT));
     } else {
       // the real port numbers will be set after we started the server/locator.
@@ -245,8 +251,9 @@ public abstract class MemberStarterRule<T> extends SerializableExternalResource
   public T withHttpService(boolean useDefaultPort) {
     properties.setProperty(HTTP_SERVICE_BIND_ADDRESS, "localhost");
     if (!useDefaultPort) {
-      httpPort = AvailablePortHelper.getRandomAvailableTCPPort();
-      properties.put(HTTP_SERVICE_PORT, httpPort + "");
+      properties.putIfAbsent(HTTP_SERVICE_PORT,
+          portSupplier.getAvailablePort() + "");
+      this.httpPort = Integer.parseInt(properties.getProperty(HTTP_SERVICE_PORT));
     } else {
       // indicate start http service but with default port
       // (different from Gemfire properties, 0 means do not start http service)
diff --git a/geode-junit/src/main/java/org/apache/geode/internal/UniquePortSupplier.java b/geode-junit/src/main/java/org/apache/geode/internal/UniquePortSupplier.java
new file mode 100644
index 0000000..af75da9
--- /dev/null
+++ b/geode-junit/src/main/java/org/apache/geode/internal/UniquePortSupplier.java
@@ -0,0 +1,47 @@
+/*
+ * 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 java.util.HashSet;
+import java.util.Set;
+import java.util.function.IntSupplier;
+import java.util.stream.IntStream;
+
+/**
+ * Supplies unique ports that have not already been supplied by this instance of PortSupplier
+ */
+public class UniquePortSupplier {
+
+  private final IntSupplier supplier;
+  private final Set<Integer> usedPorts = new HashSet<>();
+
+  public UniquePortSupplier() {
+    supplier = () -> AvailablePortHelper.getRandomAvailableTCPPort();
+  }
+
+  public UniquePortSupplier(IntSupplier supplier) {
+    this.supplier = supplier;
+  }
+
+  public synchronized int getAvailablePort() {
+    int result = IntStream.generate(supplier)
+        .filter(port -> !usedPorts.contains(port))
+        .findFirst()
+        .getAsInt();
+
+    usedPorts.add(result);
+    return result;
+  }
+}
diff --git a/geode-junit/src/test/java/org/apache/geode/internal/UniquePortSupplierTest.java b/geode-junit/src/test/java/org/apache/geode/internal/UniquePortSupplierTest.java
new file mode 100644
index 0000000..0690426
--- /dev/null
+++ b/geode-junit/src/test/java/org/apache/geode/internal/UniquePortSupplierTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.assertj.core.api.Assertions.assertThat;
+
+import java.util.PrimitiveIterator;
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+
+public class UniquePortSupplierTest {
+
+  @Test
+  public void returnsUniquePorts() {
+    // Create a stream that returns the same number more than once, make sure we find
+    // a unique port
+    PrimitiveIterator.OfInt iterator = IntStream.of(0, 0, 0, 0, 0, 1).iterator();
+    UniquePortSupplier supplier = new UniquePortSupplier(iterator::nextInt);
+    int port0 = supplier.getAvailablePort();
+    int port1 = supplier.getAvailablePort();
+
+    assertThat(port0).isEqualTo(0);
+    assertThat(port1).isEqualTo(1);
+  }
+
+  @Test
+  public void getsPortsFromProvidedSupplier() {
+    int expectedPort = 555;
+
+    UniquePortSupplier supplier = new UniquePortSupplier(() -> expectedPort);
+    int port = supplier.getAvailablePort();
+
+    assertThat(port).isEqualTo(expectedPort);
+  }
+}