You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2014/12/19 13:28:05 UTC
[1/5] incubator-brooklyn git commit: Tests for catalog items
versioning functionality.
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master d26463b65 -> 72cb9724c
Tests for catalog items versioning functionality.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/5ad1fdd7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/5ad1fdd7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/5ad1fdd7
Branch: refs/heads/master
Commit: 5ad1fdd7c7eff37098446c0a8808a9847652d7fb
Parents: 67d05d6
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Mon Dec 15 18:07:28 2014 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Mon Dec 15 18:07:28 2014 +0200
----------------------------------------------------------------------
.../catalog/internal/CatalogVersioningTest.java | 133 ++++++++++++
.../catalog/CatalogYamlVersioningTest.java | 203 +++++++++++++++++++
2 files changed, 336 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5ad1fdd7/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java b/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
new file mode 100644
index 0000000..179ce8f
--- /dev/null
+++ b/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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 brooklyn.catalog.internal;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.catalog.BrooklynCatalog;
+import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class CatalogVersioningTest {
+ private LocalManagementContext managementContext;
+ private BrooklynCatalog catalog;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception {
+ managementContext = LocalManagementContextForTests.newInstance();
+ catalog = managementContext.getCatalog();
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws Exception {
+ if (managementContext != null) Entities.destroyAll(managementContext);
+ }
+
+ @Test
+ public void testAddVersioned() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ createCatalogItem(symbolicName, version);
+ assertSingleCatalogItem(symbolicName, version);
+ }
+
+ @Test
+ public void testAddSameVersionFails() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ createCatalogItem(symbolicName, version);
+ createCatalogItem(symbolicName, version);
+ //forced update assumed in the above call
+ assertSingleCatalogItem(symbolicName, version);
+ }
+
+ @Test
+ public void testGetLatest() {
+ String symbolicName = "sampleId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0";
+ createCatalogItem(symbolicName, v1);
+ createCatalogItem(symbolicName, v2);
+ CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+ assertEquals(item.getSymbolicName(), symbolicName);
+ assertEquals(item.getVersion(), v2);
+ }
+
+ @Test
+ public void testGetLatestStable() {
+ String symbolicName = "sampleId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0-SNAPSHOT";
+ createCatalogItem(symbolicName, v1);
+ createCatalogItem(symbolicName, v2);
+ CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+ assertEquals(item.getSymbolicName(), symbolicName);
+ assertEquals(item.getVersion(), v1);
+ }
+
+ @Test
+ public void testDelete() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ createCatalogItem(symbolicName, version);
+ assertSingleCatalogItem(symbolicName, version);
+ assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+ catalog.deleteCatalogItem(symbolicName, version);
+ assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+ }
+
+ @Test
+ public void testList() {
+ String symbolicName = "sampleId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0-SNAPSHOT";
+ createCatalogItem(symbolicName, v1);
+ createCatalogItem(symbolicName, v2);
+ Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+ assertEquals(Iterables.size(items), 2);
+ }
+
+ @SuppressWarnings("deprecation")
+ private void createCatalogItem(String symbolicName, String version) {
+ catalog.addItem(CatalogItemBuilder.newEntity(symbolicName, version).
+ plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+ .build());
+ }
+
+ private void assertSingleCatalogItem(String symbolicName, String version) {
+ Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+ CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);
+ assertEquals(item.getSymbolicName(), symbolicName);
+ assertEquals(item.getVersion(), version);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5ad1fdd7/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
new file mode 100644
index 0000000..5b43c99
--- /dev/null
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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 io.brooklyn.camp.brooklyn.catalog;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import io.brooklyn.camp.brooklyn.AbstractYamlTest;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.catalog.BrooklynCatalog;
+import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.catalog.internal.BasicBrooklynCatalog;
+import brooklyn.entity.Entity;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class CatalogYamlVersioningTest extends AbstractYamlTest {
+
+ private BrooklynCatalog catalog;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() {
+ super.setUp();
+ catalog = mgmt().getCatalog();
+ }
+
+ @Test
+ public void testAddItem() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ addCatalogEntity(symbolicName, version);
+ assertSingleCatalogItem(symbolicName, version);
+ }
+
+ @Test
+ public void testAddUnversionedItem() {
+ String symbolicName = "sampleId";
+ addCatalogEntity(symbolicName, null);
+ assertSingleCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
+ }
+
+ @Test
+ public void testAddSameVersionFails() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ addCatalogEntity(symbolicName, version);
+ try {
+ addCatalogEntity(symbolicName, version);
+ fail("Expected to fail");
+ } catch (IllegalStateException e) {
+ assertEquals(e.getMessage(), "Updating existing catalog entries is forbidden: " + symbolicName + ":" + version + ". Use forceUpdate argument to override.");
+ }
+ }
+
+ @Test
+ public void testAddSameVersionForce() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ addCatalogEntity(symbolicName, version);
+ forceCatalogUpdate();
+ String expectedType = "brooklyn.entity.basic.BasicApplication";
+ addCatalogEntity(symbolicName, version, expectedType);
+ CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, version);
+ assertTrue(item.getPlanYaml().contains(expectedType), "Version not updated");
+ }
+
+ @Test
+ public void testGetLatest() {
+ String symbolicName = "sampleId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0";
+ addCatalogEntity(symbolicName, v1);
+ addCatalogEntity(symbolicName, v2);
+ CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+ assertEquals(item.getVersion(), v2);
+ }
+
+ @Test
+ public void testGetLatestStable() {
+ String symbolicName = "sampleId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0-SNAPSHOT";
+ addCatalogEntity(symbolicName, v1);
+ addCatalogEntity(symbolicName, v2);
+ CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+ assertEquals(item.getVersion(), v1);
+ }
+
+ @Test
+ public void testDelete() {
+ String symbolicName = "sampleId";
+ String version = "0.1.0";
+ addCatalogEntity(symbolicName, version);
+ assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+ catalog.deleteCatalogItem(symbolicName, version);
+ assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+ }
+
+ @Test
+ public void testDeleteDefault() {
+ String symbolicName = "sampleId";
+ addCatalogEntity(symbolicName, null);
+ assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+ catalog.deleteCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
+ assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+ }
+
+ @Test
+ public void testList() {
+ String symbolicName = "sampleId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0-SNAPSHOT";
+ addCatalogEntity(symbolicName, v1);
+ addCatalogEntity(symbolicName, v2);
+ Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+ assertEquals(Iterables.size(items), 2);
+ }
+
+ @Test
+ public void testVersionedReference() throws Exception {
+ String symbolicName = "sampleId";
+ String parentName = "parentId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0";
+ String expectedType = "brooklyn.entity.basic.BasicApplication";
+
+ addCatalogEntity(symbolicName, v1, expectedType);
+ addCatalogEntity(symbolicName, v2);
+ addCatalogEntity(parentName, v1, symbolicName + ":" + v1);
+
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + parentName + ":" + v1);
+
+ assertEquals(app.getEntityType().getName(), expectedType);
+ }
+
+ @Test
+ public void testUnversionedReference() throws Exception {
+ String symbolicName = "sampleId";
+ String parentName = "parentId";
+ String v1 = "0.1.0";
+ String v2 = "0.2.0";
+ String expectedType = "brooklyn.entity.basic.BasicApplication";
+
+ addCatalogEntity(symbolicName, v1);
+ addCatalogEntity(symbolicName, v2, expectedType);
+ addCatalogEntity(parentName, v1, symbolicName);
+
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + parentName + ":" + v1);
+
+ assertEquals(app.getEntityType().getName(), expectedType);
+ }
+
+ private void assertSingleCatalogItem(String symbolicName, String version) {
+ Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+ CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);
+ assertEquals(item.getSymbolicName(), symbolicName);
+ assertEquals(item.getVersion(), version);
+ }
+
+ private void addCatalogEntity(String symbolicName, String version) {
+ addCatalogEntity(symbolicName, version, "brooklyn.entity.basic.BasicEntity");
+ }
+
+ private void addCatalogEntity(String symbolicName, String version, String type) {
+ addCatalogItem(
+ "brooklyn.catalog:",
+ " id: " + symbolicName,
+ " name: My Catalog App",
+ " description: My description",
+ " icon_url: classpath://path/to/myicon.jpg",
+ (version != null ? " version: " + version : ""),
+ "",
+ "services:",
+ "- type: " + type);
+ }
+
+}
[4/5] incubator-brooklyn git commit: This closes #407
Posted by sj...@apache.org.
This closes #407
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/3200c0cf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/3200c0cf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/3200c0cf
Branch: refs/heads/master
Commit: 3200c0cf2d11dad490661d620f5254c699ef7d40
Parents: d26463b 25aaff9
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Fri Dec 19 12:20:16 2014 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Fri Dec 19 12:20:16 2014 +0000
----------------------------------------------------------------------
.../main/java/brooklyn/util/net/Networking.java | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
[5/5] incubator-brooklyn git commit: This closes #396
Posted by sj...@apache.org.
This closes #396
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/72cb9724
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/72cb9724
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/72cb9724
Branch: refs/heads/master
Commit: 72cb9724cfc95c7573ec6eb2b65776c9d80fc873
Parents: 3200c0c 5ad1fdd
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Fri Dec 19 12:21:54 2014 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Fri Dec 19 12:21:54 2014 +0000
----------------------------------------------------------------------
.../catalog/internal/CatalogVersioningTest.java | 133 ++++++++++++
.../catalog/CatalogYamlVersioningTest.java | 203 +++++++++++++++++++
2 files changed, 336 insertions(+)
----------------------------------------------------------------------
[2/5] incubator-brooklyn git commit: Fix illegal argument in
isPortAvailable
Posted by sj...@apache.org.
Fix illegal argument in isPortAvailable
JRE docs say that the wildcard address can only be used on bind()
operations, but there's a case where we might use it in a connect()
call - this is undefined behaviour. Correct the code to pass in the
loopback address to connect() instead of the wildcard address.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/25aaff93
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/25aaff93
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/25aaff93
Branch: refs/heads/master
Commit: 25aaff937a31f73a94f6caadb2fd6da303670f8b
Parents: 22e1c68
Author: Richard Downer <ri...@apache.org>
Authored: Thu Dec 18 14:02:57 2014 +0000
Committer: Richard Downer <ri...@apache.org>
Committed: Fri Dec 19 09:33:24 2014 +0000
----------------------------------------------------------------------
.../src/main/java/brooklyn/util/net/Networking.java | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25aaff93/utils/common/src/main/java/brooklyn/util/net/Networking.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/net/Networking.java b/utils/common/src/main/java/brooklyn/util/net/Networking.java
index 98fd828..77edb6f 100644
--- a/utils/common/src/main/java/brooklyn/util/net/Networking.java
+++ b/utils/common/src/main/java/brooklyn/util/net/Networking.java
@@ -78,12 +78,19 @@ public class Networking {
if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
throw new IllegalArgumentException("Invalid start port: " + port);
}
+
+ // For some operations it's not valid to pass ANY_NIC (0.0.0.0).
+ // We substitute for the loopback address in those cases.
+ InetAddress localAddressNotAny = (localAddress==null || ANY_NIC.equals(localAddress))
+ ? LOOPBACK
+ : ANY_NIC;
+
Stopwatch watch = Stopwatch.createStarted();
try {
try {
Socket s = new Socket();
s.setSoTimeout(250);
- s.connect(new InetSocketAddress(localAddress, port), 250);
+ s.connect(new InetSocketAddress(localAddressNotAny, port), 250);
try {
s.close();
} catch (Exception e) {}
@@ -123,7 +130,8 @@ public class Networking {
if (localAddress==null || ANY_NIC.equals(localAddress)) {
- // sometimes 0.0.0.0 can be bound to even if 127.0.0.1 has the port as in use; check 127.0.0.1 if 0.0.0.0 was requested
+ // sometimes 0.0.0.0 can be bound to even if 127.0.0.1 has the port as in use;
+ // check all interfaces if 0.0.0.0 was requested
Enumeration<NetworkInterface> nis = null;
try {
nis = NetworkInterface.getNetworkInterfaces();
[3/5] incubator-brooklyn git commit: nextAvailablePort,
give better error messages
Posted by sj...@apache.org.
nextAvailablePort, give better error messages
Validate that the given argument is in the valid range for port numbers.
If not possible to find a port in the valid range, throw a descriptive
exception message (instead of trying an invalid port number and getting
an IllegalArgumentException from the JRE)
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/22e1c68d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/22e1c68d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/22e1c68d
Branch: refs/heads/master
Commit: 22e1c68d8e0561e6e9152e1ab0c3c2083af5b32e
Parents: c4d907a
Author: Richard Downer <ri...@apache.org>
Authored: Thu Dec 18 14:01:06 2014 +0000
Committer: Richard Downer <ri...@apache.org>
Committed: Fri Dec 19 09:33:24 2014 +0000
----------------------------------------------------------------------
utils/common/src/main/java/brooklyn/util/net/Networking.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/22e1c68d/utils/common/src/main/java/brooklyn/util/net/Networking.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/net/Networking.java b/utils/common/src/main/java/brooklyn/util/net/Networking.java
index d338080..98fd828 100644
--- a/utils/common/src/main/java/brooklyn/util/net/Networking.java
+++ b/utils/common/src/main/java/brooklyn/util/net/Networking.java
@@ -48,6 +48,8 @@ import com.google.common.base.Throwables;
import com.google.common.net.HostAndPort;
import com.google.common.primitives.UnsignedBytes;
+import static com.google.common.base.Preconditions.checkArgument;
+
public class Networking {
private static final Logger log = LoggerFactory.getLogger(Networking.class);
@@ -148,7 +150,11 @@ public class Networking {
}
/** returns the first port available on the local machine >= the port supplied */
public static int nextAvailablePort(int port) {
- while (!isPortAvailable(port)) port++;
+ checkArgument(port >= MIN_PORT_NUMBER && port <= MAX_PORT_NUMBER, "requested port %s is outside the valid range of %s to %s", port, MIN_PORT_NUMBER, MAX_PORT_NUMBER);
+ int originalPort = port;
+ while (!isPortAvailable(port) && port <= MAX_PORT_NUMBER) port++;
+ if (port > MAX_PORT_NUMBER)
+ throw new RuntimeException("unable to find a free port at or above " + originalPort);
return port;
}