diff --git a/server/src/test/java/org/elasticsearch/discovery/single/SingleNodeDiscoveryIT.java b/server/src/test/java/org/elasticsearch/discovery/single/SingleNodeDiscoveryIT.java index 2ccf8eaa882..1c0dffee240 100644 --- a/server/src/test/java/org/elasticsearch/discovery/single/SingleNodeDiscoveryIT.java +++ b/server/src/test/java/org/elasticsearch/discovery/single/SingleNodeDiscoveryIT.java @@ -34,7 +34,6 @@ import org.elasticsearch.test.InternalTestCluster; import org.elasticsearch.test.MockHttpTransport; import org.elasticsearch.test.MockLogAppender; import org.elasticsearch.test.NodeConfigurationSource; -import org.elasticsearch.test.transport.MockTransportService; import org.elasticsearch.transport.RemoteTransportException; import org.elasticsearch.transport.TransportService; @@ -60,7 +59,7 @@ public class SingleNodeDiscoveryIT extends ESIntegTestCase { .builder() .put(super.nodeSettings(nodeOrdinal)) .put("discovery.type", "single-node") - .put("transport.port", MockTransportService.getPortRange()) + .put("transport.port", getPortRange()) .build(); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java index 696fc350175..72ee2c0aff0 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java @@ -1339,4 +1339,29 @@ public abstract class ESTestCase extends LuceneTestCase { public static boolean inFipsJvm() { return Security.getProviders()[0].getName().toLowerCase(Locale.ROOT).contains("fips"); } + + /** + * Returns a unique port range for this JVM starting from the computed base port + */ + public static String getPortRange() { + return getBasePort() + "-" + (getBasePort() + 99); // upper bound is inclusive + } + + protected static int getBasePort() { + // some tests use MockTransportService to do network based testing. Yet, we run tests in multiple JVMs that means + // concurrent tests could claim port that another JVM just released and if that test tries to simulate a disconnect it might + // be smart enough to re-connect depending on what is tested. To reduce the risk, since this is very hard to debug we use + // a different default port range per JVM unless the incoming settings override it + // use a non-default base port otherwise some cluster in this JVM might reuse a port + + // We rely on Gradle implementation details here, the worker IDs are long values incremented by one for the + // lifespan of the daemon this means that they can get larger than the allowed port range. + // Ephemeral ports on Linux start at 32768 so we modulo to make sure that we don't exceed that. + // This is safe as long as we have fewer than 224 Gradle workers running in parallel + // See also: https://github.com/elastic/elasticsearch/issues/44134 + final String workerId = System.getProperty(ESTestCase.TEST_WORKER_SYS_PROPERTY); + final int startAt = workerId == null ? 0 : (int) Math.floorMod(Long.valueOf(workerId), 223); + assert startAt >= 0 : "Unexpected test worker Id, resulting port range would be negative"; + return 10300 + (startAt * 100); + } } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java b/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java index 74edfd3a465..c45ad85dbdb 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ExternalTestCluster.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.env.Environment; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.transport.MockTransportClient; +import org.elasticsearch.transport.TransportSettings; import org.elasticsearch.transport.nio.MockNioTransportPlugin; import java.io.IOException; @@ -77,6 +78,7 @@ public final class ExternalTestCluster extends TestCluster { .put(additionalSettings) .put("node.name", InternalTestCluster.TRANSPORT_CLIENT_PREFIX + EXTERNAL_CLUSTER_PREFIX + counter.getAndIncrement()) .put("client.transport.ignore_cluster_name", true) + .put(TransportSettings.PORT.getKey(), ESTestCase.getPortRange()) .put(Environment.PATH_HOME_SETTING.getKey(), tempDir); boolean addMockTcpTransport = additionalSettings.get(NetworkModule.TRANSPORT_TYPE_KEY) == null; diff --git a/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java b/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java index 3bda71343fc..3ecb76b0dee 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java +++ b/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java @@ -105,33 +105,8 @@ public final class MockTransportService extends TransportService { return createNewService(settings, mockTransport, version, threadPool, clusterSettings, Collections.emptySet()); } - /** - * Returns a unique port range for this JVM starting from the computed base port - */ - public static String getPortRange() { - return getBasePort() + "-" + (getBasePort() + 99); // upper bound is inclusive - } - - protected static int getBasePort() { - // some tests use MockTransportService to do network based testing. Yet, we run tests in multiple JVMs that means - // concurrent tests could claim port that another JVM just released and if that test tries to simulate a disconnect it might - // be smart enough to re-connect depending on what is tested. To reduce the risk, since this is very hard to debug we use - // a different default port range per JVM unless the incoming settings override it - // use a non-default base port otherwise some cluster in this JVM might reuse a port - - // We rely on Gradle implementation details here, the worker IDs are long values incremented by one for the - // lifespan of the daemon this means that they can get larger than the allowed port range. - // Ephemeral ports on Linux start at 32768 so we modulo to make sure that we don't exceed that. - // This is safe as long as we have fewer than 224 Gradle workers running in parallel - // See also: https://github.com/elastic/elasticsearch/issues/44134 - final String workerId = System.getProperty(ESTestCase.TEST_WORKER_SYS_PROPERTY); - final int startAt = workerId == null ? 0 : (int) Math.floorMod(Long.valueOf(workerId), 223); - assert startAt >= 0 : "Unexpected test worker Id, resulting port range would be negative"; - return 10300 + (startAt * 100); - } - public static MockNioTransport newMockTransport(Settings settings, Version version, ThreadPool threadPool) { - settings = Settings.builder().put(TransportSettings.PORT.getKey(), getPortRange()).put(settings).build(); + settings = Settings.builder().put(TransportSettings.PORT.getKey(), ESTestCase.getPortRange()).put(settings).build(); NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry(ClusterModule.getNamedWriteables()); return new MockNioTransport(settings, version, threadPool, new NetworkService(Collections.emptyList()), new MockPageCacheRecycler(settings), namedWriteableRegistry, new NoneCircuitBreakerService()); diff --git a/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java b/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java index 241a3562d80..7f9fae23361 100644 --- a/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/transport/AbstractSimpleTransportTestCase.java @@ -92,7 +92,7 @@ import java.util.stream.Collectors; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; -import static org.elasticsearch.test.transport.MockTransportService.getPortRange; +import static org.elasticsearch.test.ESTestCase.getPortRange; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; diff --git a/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java b/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java index 2450b5658be..af041a70d97 100644 --- a/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java +++ b/test/framework/src/test/java/org/elasticsearch/test/test/ESTestCaseTests.java @@ -188,4 +188,15 @@ public class ESTestCaseTests extends ESTestCase { assertThat(ESTestCase.TEST_WORKER_VM_ID, not(equals(ESTestCase.DEFAULT_TEST_WORKER_ID))); } + + public void testBasePortGradle() { + assumeTrue("requires running tests with Gradle", System.getProperty("tests.gradle") != null); + // Gradle worker IDs are 1 based + assertNotEquals(10300, ESTestCase.getBasePort()); + } + + public void testBasePortIDE() { + assumeTrue("requires running tests without Gradle", System.getProperty("tests.gradle") == null); + assertEquals(10300, ESTestCase.getBasePort()); + } } diff --git a/test/framework/src/test/java/org/elasticsearch/test/transport/MockTransportServiceTests.java b/test/framework/src/test/java/org/elasticsearch/test/transport/MockTransportServiceTests.java deleted file mode 100644 index 5bb074e4b59..00000000000 --- a/test/framework/src/test/java/org/elasticsearch/test/transport/MockTransportServiceTests.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch 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.elasticsearch.test.transport; - -import org.elasticsearch.test.ESTestCase; - -public class MockTransportServiceTests extends ESTestCase { - - public void testBasePortGradle() { - assumeTrue("requires running tests with Gradle", System.getProperty("tests.gradle") != null); - // Gradle worker IDs are 1 based - assertNotEquals(10300, MockTransportService.getBasePort()); - } - - public void testBasePortIDE() { - assumeTrue("requires running tests without Gradle", System.getProperty("tests.gradle") == null); - assertEquals(10300, MockTransportService.getBasePort()); - } - -}