From 4ad9ed5c3297482203b7704357ce5450a11bce07 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 25 Mar 2021 19:41:20 +0200 Subject: [PATCH] Reimplement finding open ports (#2629) --- .../apachecamel/RestCamelTest.groovy | 2 +- .../apachecamel/SingleServiceCamelTest.groovy | 2 +- .../apachecamel/SqsCamelTest.groovy | 2 +- ...woServicesWithDirectClientCamelTest.groovy | 4 +- .../apachedubbo/v2_7/AbstractDubboTest.groovy | 4 +- .../v1_11/AbstractSqsTracingTest.groovy | 2 +- .../groovy/util/AbstractCouchbaseTest.groovy | 2 +- .../src/test/groovy/DropwizardTest.groovy | 2 +- .../v1_5/AbstractGrpcStreamingTest.groovy | 2 +- .../grpc/v1_5/AbstractGrpcTest.groovy | 10 +- .../src/test/groovy/JedisClientTest.groovy | 2 +- .../src/test/groovy/Jedis30ClientTest.groovy | 2 +- .../JspInstrumentationBasicTests.groovy | 2 +- .../JspInstrumentationForwardTests.groovy | 2 +- .../test/groovy/LettuceAsyncClientTest.groovy | 4 +- .../test/groovy/LettuceSyncClientTest.groovy | 4 +- .../test/groovy/LettuceAsyncClientTest.groovy | 4 +- .../groovy/LettuceReactiveClientTest.groovy | 2 +- .../test/groovy/LettuceSyncClientTest.groovy | 4 +- .../AbstractLettuceAsyncClientTest.groovy | 4 +- .../AbstractLettuceReactiveClientTest.groovy | 2 +- .../AbstractLettuceSyncClientAuthTest.groovy | 2 +- .../v5_1/AbstractLettuceSyncClientTest.groovy | 4 +- .../src/main/groovy/MongoBaseTest.groovy | 2 +- .../test/groovy/RediscalaClientTest.groovy | 2 +- .../groovy/RedissonAsyncClientTest.groovy | 2 +- .../src/test/groovy/RedissonClientTest.groovy | 2 +- .../javaagent/src/test/groovy/RmiTest.groovy | 2 +- .../main/java/base/IntegrationTestBase.java | 17 +-- .../src/test/groovy/SparkJavaBasedTest.groovy | 2 +- .../VertxReactivePropagationTest.groovy | 2 +- .../test/base/HttpServerTestTrait.groovy | 2 +- .../test/utils/PortAllocator.java | 129 ++++++++++++++++++ .../instrumentation/test/utils/PortUtils.java | 23 ++-- .../test/utils/PortAllocatorTest.java | 80 +++++++++++ 35 files changed, 268 insertions(+), 67 deletions(-) create mode 100644 testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortAllocator.java create mode 100644 testing-common/src/test/java/io/opentelemetry/instrumentation/test/utils/PortAllocatorTest.java diff --git a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy index ecc8277ea3..2207c49ca7 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy +++ b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy @@ -33,7 +33,7 @@ class RestCamelTest extends AgentInstrumentationSpecification implements RetryOn } def setupSpecUnderRetry() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() def app = new SpringApplication(RestConfig) app.setDefaultProperties(["restServer.port": port]) server = app.run() diff --git a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SingleServiceCamelTest.groovy b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SingleServiceCamelTest.groovy index 79fa41070d..a881ff0469 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SingleServiceCamelTest.groovy +++ b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SingleServiceCamelTest.groovy @@ -38,7 +38,7 @@ class SingleServiceCamelTest extends AgentInstrumentationSpecification implement } def setupSpecUnderRetry() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() address = new URI("http://localhost:$port/") def app = new SpringApplication(SingleServiceConfig) app.setDefaultProperties(["camelService.port": port]) diff --git a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SqsCamelTest.groovy b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SqsCamelTest.groovy index a790ddfc35..0a99b13435 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SqsCamelTest.groovy +++ b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/SqsCamelTest.groovy @@ -46,7 +46,7 @@ class SqsCamelTest extends AgentInstrumentationSpecification { void initialize(AbstractApplicationContext applicationContext) {applicationContext.getBeanFactory().registerSingleton("localStack", sqs)}}) server = app.run()**/ - sqsPort = PortUtils.randomOpenPort() + sqsPort = PortUtils.findOpenPort() sqs = SQSRestServerBuilder.withPort(sqsPort).withInterface("localhost").start() println getClass().name + " SQS server started at: localhost:$sqsPort/" diff --git a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy index b2411e3b1c..fd8d80b366 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy +++ b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy @@ -39,8 +39,8 @@ class TwoServicesWithDirectClientCamelTest extends AgentInstrumentationSpecifica } def setupSpecUnderRetry() { - portOne = PortUtils.randomOpenPort() - portTwo = PortUtils.randomOpenPort() + portOne = PortUtils.findOpenPort() + portTwo = PortUtils.findOpenPort() def app = new SpringApplication(TwoServicesConfig) app.setDefaultProperties(["service.one.port": portOne, "service.two.port": portTwo]) server = app.run() diff --git a/instrumentation/apache-dubbo/apache-dubbo-2.7/testing/src/main/groovy/io/opentelemetry/instrumentation/apachedubbo/v2_7/AbstractDubboTest.groovy b/instrumentation/apache-dubbo/apache-dubbo-2.7/testing/src/main/groovy/io/opentelemetry/instrumentation/apachedubbo/v2_7/AbstractDubboTest.groovy index 55a7faaf90..beb59cb16d 100644 --- a/instrumentation/apache-dubbo/apache-dubbo-2.7/testing/src/main/groovy/io/opentelemetry/instrumentation/apachedubbo/v2_7/AbstractDubboTest.groovy +++ b/instrumentation/apache-dubbo/apache-dubbo-2.7/testing/src/main/groovy/io/opentelemetry/instrumentation/apachedubbo/v2_7/AbstractDubboTest.groovy @@ -52,7 +52,7 @@ abstract class AbstractDubboTest extends InstrumentationSpecification { def "test apache dubbo base #dubbo"() { setup: - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() protocolConfig.setPort(port) DubboBootstrap bootstrap = DubboBootstrap.getInstance() @@ -121,7 +121,7 @@ abstract class AbstractDubboTest extends InstrumentationSpecification { def "test apache dubbo test #dubbo"() { setup: - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() protocolConfig.setPort(port) DubboBootstrap bootstrap = DubboBootstrap.getInstance() diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/testing/src/main/groovy/io/opentelemetry/instrumentation/awssdk/v1_11/AbstractSqsTracingTest.groovy b/instrumentation/aws-sdk/aws-sdk-1.11/testing/src/main/groovy/io/opentelemetry/instrumentation/awssdk/v1_11/AbstractSqsTracingTest.groovy index 3f6cd1cd07..901615b737 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/testing/src/main/groovy/io/opentelemetry/instrumentation/awssdk/v1_11/AbstractSqsTracingTest.groovy +++ b/instrumentation/aws-sdk/aws-sdk-1.11/testing/src/main/groovy/io/opentelemetry/instrumentation/awssdk/v1_11/AbstractSqsTracingTest.groovy @@ -34,7 +34,7 @@ abstract class AbstractSqsTracingTest extends InstrumentationSpecification { def setupSpec() { - sqsPort = PortUtils.randomOpenPort() + sqsPort = PortUtils.findOpenPort() sqs = SQSRestServerBuilder.withPort(sqsPort).withInterface("localhost").start() println getClass().name + " SQS server started at: localhost:$sqsPort/" diff --git a/instrumentation/couchbase/couchbase-testing/src/main/groovy/util/AbstractCouchbaseTest.groovy b/instrumentation/couchbase/couchbase-testing/src/main/groovy/util/AbstractCouchbaseTest.groovy index 6fca2f3d06..8dfa53d20e 100644 --- a/instrumentation/couchbase/couchbase-testing/src/main/groovy/util/AbstractCouchbaseTest.groovy +++ b/instrumentation/couchbase/couchbase-testing/src/main/groovy/util/AbstractCouchbaseTest.groovy @@ -31,7 +31,7 @@ abstract class AbstractCouchbaseTest extends AgentInstrumentationSpecification { static final PASSWORD = "password" @Shared - private int port = PortUtils.randomOpenPort() + private int port = PortUtils.findOpenPort() @Shared private String testBucketName = this.getClass().simpleName diff --git a/instrumentation/dropwizard-testing/src/test/groovy/DropwizardTest.groovy b/instrumentation/dropwizard-testing/src/test/groovy/DropwizardTest.groovy index f5a950a297..f2f9280629 100644 --- a/instrumentation/dropwizard-testing/src/test/groovy/DropwizardTest.groovy +++ b/instrumentation/dropwizard-testing/src/test/groovy/DropwizardTest.groovy @@ -38,7 +38,7 @@ class DropwizardTest extends HttpServerTest implements Ag def testSupport = new DropwizardTestSupport(testApp(), null, ConfigOverride.config("server.applicationConnectors[0].port", "$port"), - ConfigOverride.config("server.adminConnectors[0].port", PortUtils.randomOpenPort().toString())) + ConfigOverride.config("server.adminConnectors[0].port", PortUtils.findOpenPort().toString())) testSupport.before() return testSupport } diff --git a/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcStreamingTest.groovy b/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcStreamingTest.groovy index 57bc337950..e24c82627f 100644 --- a/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcStreamingTest.groovy +++ b/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcStreamingTest.groovy @@ -65,7 +65,7 @@ abstract class AbstractGrpcStreamingTest extends InstrumentationSpecification { } } } - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() Server server = configureServer(ServerBuilder.forPort(port).addService(greeter)).build().start() ManagedChannelBuilder channelBuilder = configureClient(ManagedChannelBuilder.forAddress("localhost", port)) diff --git a/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcTest.groovy b/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcTest.groovy index 441a64cb7a..c080a40a3d 100644 --- a/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcTest.groovy +++ b/instrumentation/grpc-1.5/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_5/AbstractGrpcTest.groovy @@ -58,7 +58,7 @@ abstract class AbstractGrpcTest extends InstrumentationSpecification { responseObserver.onCompleted() } } - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() Server server = configureServer(ServerBuilder.forPort(port).addService(greeter)).build().start() ManagedChannelBuilder channelBuilder = configureClient(ManagedChannelBuilder.forAddress("localhost", port)) @@ -141,7 +141,7 @@ abstract class AbstractGrpcTest extends InstrumentationSpecification { responseObserver.onError(error) } } - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() Server server = configureServer(ServerBuilder.forPort(port).addService(greeter)).build().start() ManagedChannelBuilder channelBuilder = configureClient(ManagedChannelBuilder.forAddress("localhost", port)) @@ -227,7 +227,7 @@ abstract class AbstractGrpcTest extends InstrumentationSpecification { throw error } } - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() Server server = configureServer(ServerBuilder.forPort(port).addService(greeter)).build().start() ManagedChannelBuilder channelBuilder = configureClient(ManagedChannelBuilder.forAddress("localhost", port)) @@ -325,7 +325,7 @@ abstract class AbstractGrpcTest extends InstrumentationSpecification { responseObserver.onCompleted() } } - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() Server server server = configureServer(ServerBuilder.forPort(port) .addService(greeter) @@ -466,7 +466,7 @@ abstract class AbstractGrpcTest extends InstrumentationSpecification { responseObserver.onNext(Helloworld.Response.getDefaultInstance()) } } - def port = PortUtils.randomOpenPort() + def port = PortUtils.findOpenPort() Server server server = configureServer(ServerBuilder.forPort(port) .addService(greeter)) diff --git a/instrumentation/jedis/jedis-1.4/javaagent/src/test/groovy/JedisClientTest.groovy b/instrumentation/jedis/jedis-1.4/javaagent/src/test/groovy/JedisClientTest.groovy index 870dabe49e..bbcac35513 100644 --- a/instrumentation/jedis/jedis-1.4/javaagent/src/test/groovy/JedisClientTest.groovy +++ b/instrumentation/jedis/jedis-1.4/javaagent/src/test/groovy/JedisClientTest.groovy @@ -15,7 +15,7 @@ import spock.lang.Shared class JedisClientTest extends AgentInstrumentationSpecification { @Shared - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() @Shared RedisServer redisServer = RedisServer.builder() diff --git a/instrumentation/jedis/jedis-3.0/javaagent/src/test/groovy/Jedis30ClientTest.groovy b/instrumentation/jedis/jedis-3.0/javaagent/src/test/groovy/Jedis30ClientTest.groovy index 69eff7007e..2101ccb699 100644 --- a/instrumentation/jedis/jedis-3.0/javaagent/src/test/groovy/Jedis30ClientTest.groovy +++ b/instrumentation/jedis/jedis-3.0/javaagent/src/test/groovy/Jedis30ClientTest.groovy @@ -15,7 +15,7 @@ import spock.lang.Shared class Jedis30ClientTest extends AgentInstrumentationSpecification { @Shared - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() @Shared RedisServer redisServer = RedisServer.builder() diff --git a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy index 59fa20257a..7ced2ca98c 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy +++ b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy @@ -44,7 +44,7 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { baseDir = Files.createTempDirectory("jsp").toFile() baseDir.deleteOnExit() - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() tomcatServer = new Tomcat() tomcatServer.setBaseDir(baseDir.getAbsolutePath()) diff --git a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy index 9f96823f1b..6ba89c0ac1 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy +++ b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy @@ -41,7 +41,7 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { baseDir = Files.createTempDirectory("jsp").toFile() baseDir.deleteOnExit() - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() tomcatServer = new Tomcat() tomcatServer.setBaseDir(baseDir.getAbsolutePath()) diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy b/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy index 70b75e5060..bafa0e1c75 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy @@ -63,8 +63,8 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification { RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() - incorrectPort = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() + incorrectPort = PortUtils.findOpenPort() dbAddr = HOST + ":" + port + "/" + DB_INDEX dbAddrNonExistent = HOST + ":" + incorrectPort + "/" + DB_INDEX dbUriNonExistent = "redis://" + dbAddrNonExistent diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy b/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy index 603089304b..837f5e2f99 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy @@ -50,8 +50,8 @@ class LettuceSyncClientTest extends AgentInstrumentationSpecification { RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() - incorrectPort = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() + incorrectPort = PortUtils.findOpenPort() dbAddr = HOST + ":" + port + "/" + DB_INDEX dbAddrNonExistent = HOST + ":" + incorrectPort + "/" + DB_INDEX dbUriNonExistent = "redis://" + dbAddrNonExistent diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy index c85c16f988..2a298d2139 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy @@ -66,8 +66,8 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification { RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() - incorrectPort = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() + incorrectPort = PortUtils.findOpenPort() dbAddr = PEER_NAME + ":" + port + "/" + DB_INDEX dbAddrNonExistent = PEER_NAME + ":" + incorrectPort + "/" + DB_INDEX dbUriNonExistent = "redis://" + dbAddrNonExistent diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceReactiveClientTest.groovy b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceReactiveClientTest.groovy index 81b61154ae..68ff24010d 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceReactiveClientTest.groovy +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceReactiveClientTest.groovy @@ -39,7 +39,7 @@ class LettuceReactiveClientTest extends AgentInstrumentationSpecification { RedisCommands syncCommands def setupSpec() { - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() String dbAddr = PEER_HOST + ":" + port + "/" + DB_INDEX embeddedDbUri = "redis://" + dbAddr diff --git a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy index 886b5d2cc8..8217d5bd89 100644 --- a/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy +++ b/instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceSyncClientTest.groovy @@ -52,8 +52,8 @@ class LettuceSyncClientTest extends AgentInstrumentationSpecification { RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() - incorrectPort = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() + incorrectPort = PortUtils.findOpenPort() dbAddr = PEER_NAME + ":" + port + "/" + DB_INDEX dbAddrNonExistent = PEER_NAME + ":" + incorrectPort + "/" + DB_INDEX dbUriNonExistent = "redis://" + dbAddrNonExistent diff --git a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceAsyncClientTest.groovy b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceAsyncClientTest.groovy index 704b8092ff..55b8028fdf 100644 --- a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceAsyncClientTest.groovy +++ b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceAsyncClientTest.groovy @@ -63,8 +63,8 @@ abstract class AbstractLettuceAsyncClientTest extends InstrumentationSpecificati RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() - incorrectPort = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() + incorrectPort = PortUtils.findOpenPort() dbAddr = HOST + ":" + port + "/" + DB_INDEX dbAddrNonExistent = HOST + ":" + incorrectPort + "/" + DB_INDEX dbUriNonExistent = "redis://" + dbAddrNonExistent diff --git a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceReactiveClientTest.groovy b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceReactiveClientTest.groovy index 73617ac1b6..ba39f7e5fa 100644 --- a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceReactiveClientTest.groovy +++ b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceReactiveClientTest.groovy @@ -40,7 +40,7 @@ abstract class AbstractLettuceReactiveClientTest extends InstrumentationSpecific RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() String dbAddr = HOST + ":" + port + "/" + DB_INDEX embeddedDbUri = "redis://" + dbAddr diff --git a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientAuthTest.groovy b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientAuthTest.groovy index 48423383b7..9be9cd6d3f 100644 --- a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientAuthTest.groovy +++ b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientAuthTest.groovy @@ -35,7 +35,7 @@ abstract class AbstractLettuceSyncClientAuthTest extends InstrumentationSpecific RedisClient redisClient def setupSpec() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() dbAddr = HOST + ":" + port + "/" + DB_INDEX embeddedDbUri = "redis://" + dbAddr password = "password" diff --git a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientTest.groovy b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientTest.groovy index d64d7a1c50..b907f9dec2 100644 --- a/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientTest.groovy +++ b/instrumentation/lettuce/lettuce-5.1/testing/src/main/groovy/io/opentelemetry/instrumentation/lettuce/v5_1/AbstractLettuceSyncClientTest.groovy @@ -56,8 +56,8 @@ abstract class AbstractLettuceSyncClientTest extends InstrumentationSpecificatio RedisCommands syncCommands def setupSpec() { - port = PortUtils.randomOpenPort() - incorrectPort = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() + incorrectPort = PortUtils.findOpenPort() dbAddr = HOST + ":" + port + "/" + DB_INDEX dbAddrNonExistent = HOST + ":" + incorrectPort + "/" + DB_INDEX dbUriNonExistent = "redis://" + dbAddrNonExistent diff --git a/instrumentation/mongo/mongo-testing/src/main/groovy/MongoBaseTest.groovy b/instrumentation/mongo/mongo-testing/src/main/groovy/MongoBaseTest.groovy index fcaa6921e2..1ec50c6a7e 100644 --- a/instrumentation/mongo/mongo-testing/src/main/groovy/MongoBaseTest.groovy +++ b/instrumentation/mongo/mongo-testing/src/main/groovy/MongoBaseTest.groovy @@ -30,7 +30,7 @@ class MongoBaseTest extends AgentInstrumentationSpecification { private static final MongodStarter STARTER = MongodStarter.getDefaultInstance() @Shared - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() @Shared MongodExecutable mongodExe @Shared diff --git a/instrumentation/rediscala-1.8/javaagent/src/test/groovy/RediscalaClientTest.groovy b/instrumentation/rediscala-1.8/javaagent/src/test/groovy/RediscalaClientTest.groovy index 141bf32682..6dd6e5484d 100644 --- a/instrumentation/rediscala-1.8/javaagent/src/test/groovy/RediscalaClientTest.groovy +++ b/instrumentation/rediscala-1.8/javaagent/src/test/groovy/RediscalaClientTest.groovy @@ -22,7 +22,7 @@ import spock.lang.Shared class RediscalaClientTest extends AgentInstrumentationSpecification { @Shared - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() @Shared RedisServer redisServer = RedisServer.builder() diff --git a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy b/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy index d6a3527c64..0104861ee1 100644 --- a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy +++ b/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonAsyncClientTest.groovy @@ -23,7 +23,7 @@ import spock.lang.Shared class RedissonAsyncClientTest extends AgentInstrumentationSpecification { @Shared - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() @Shared RedisServer redisServer = RedisServer.builder() diff --git a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy b/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy index 839771d2c3..0b81fc268e 100644 --- a/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy +++ b/instrumentation/redisson-3.0/javaagent/src/test/groovy/RedissonClientTest.groovy @@ -28,7 +28,7 @@ import spock.lang.Shared class RedissonClientTest extends AgentInstrumentationSpecification { @Shared - int port = PortUtils.randomOpenPort() + int port = PortUtils.findOpenPort() @Shared RedisServer redisServer = RedisServer.builder() diff --git a/instrumentation/rmi/javaagent/src/test/groovy/RmiTest.groovy b/instrumentation/rmi/javaagent/src/test/groovy/RmiTest.groovy index 76539cbfba..d29becdf82 100644 --- a/instrumentation/rmi/javaagent/src/test/groovy/RmiTest.groovy +++ b/instrumentation/rmi/javaagent/src/test/groovy/RmiTest.groovy @@ -18,7 +18,7 @@ import rmi.app.Server import rmi.app.ServerLegacy class RmiTest extends AgentInstrumentationSpecification { - def registryPort = PortUtils.randomOpenPort() + def registryPort = PortUtils.findOpenPort() def serverRegistry = LocateRegistry.createRegistry(registryPort) def clientRegistry = LocateRegistry.getRegistry("localhost", registryPort) diff --git a/instrumentation/rocketmq-client-4.8/testing/src/main/java/base/IntegrationTestBase.java b/instrumentation/rocketmq-client-4.8/testing/src/main/java/base/IntegrationTestBase.java index 6bdd08850c..af7903a9df 100644 --- a/instrumentation/rocketmq-client-4.8/testing/src/main/java/base/IntegrationTestBase.java +++ b/instrumentation/rocketmq-client-4.8/testing/src/main/java/base/IntegrationTestBase.java @@ -5,6 +5,7 @@ package base; +import io.opentelemetry.instrumentation.test.utils.PortUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -12,7 +13,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.rocketmq.broker.BrokerController; import org.apache.rocketmq.common.BrokerConfig; @@ -37,13 +37,6 @@ public class IntegrationTestBase { protected static final List NAMESRV_CONTROLLERS = new ArrayList<>(); protected static final int COMMIT_LOG_SIZE = 1024 * 1024 * 100; protected static final int INDEX_NUM = 1000; - private static final AtomicInteger port = new AtomicInteger(40000); - - public static synchronized int nextPort() { - return port.addAndGet(random.nextInt(10) + 10); - } - - protected static final Random random = new Random(); private static String createTempDir() { String path = null; @@ -77,7 +70,9 @@ public class IntegrationTestBase { namesrvConfig.setKvConfigPath(kvConfigPath.toString()); namesrvConfig.setConfigStorePath(namesrvPath.toString()); - nameServerNettyServerConfig.setListenPort(nextPort()); + // find 3 consecutive open ports and use the last one of them + // rocketmq will also bind to given port - 2 + nameServerNettyServerConfig.setListenPort(PortUtils.findOpenPorts(3) + 2); NamesrvController namesrvController = new NamesrvController(namesrvConfig, nameServerNettyServerConfig); try { @@ -113,8 +108,8 @@ public class IntegrationTestBase { MessageStoreConfig storeConfig, BrokerConfig brokerConfig) { NettyServerConfig nettyServerConfig = new NettyServerConfig(); NettyClientConfig nettyClientConfig = new NettyClientConfig(); - nettyServerConfig.setListenPort(nextPort()); - storeConfig.setHaListenPort(nextPort()); + nettyServerConfig.setListenPort(PortUtils.findOpenPort()); + storeConfig.setHaListenPort(PortUtils.findOpenPort()); BrokerController brokerController = new BrokerController(brokerConfig, nettyServerConfig, nettyClientConfig, storeConfig); try { diff --git a/instrumentation/spark-2.3/javaagent/src/test/groovy/SparkJavaBasedTest.groovy b/instrumentation/spark-2.3/javaagent/src/test/groovy/SparkJavaBasedTest.groovy index a3a01eeeb9..45d1a0ca72 100644 --- a/instrumentation/spark-2.3/javaagent/src/test/groovy/SparkJavaBasedTest.groovy +++ b/instrumentation/spark-2.3/javaagent/src/test/groovy/SparkJavaBasedTest.groovy @@ -22,7 +22,7 @@ class SparkJavaBasedTest extends AgentInstrumentationSpecification { OkHttpClient client = OkHttpUtils.client() def setupSpec() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() TestSparkJavaApplication.initSpark(port) } diff --git a/instrumentation/vertx-reactive-3.5/javaagent/src/test/groovy/VertxReactivePropagationTest.groovy b/instrumentation/vertx-reactive-3.5/javaagent/src/test/groovy/VertxReactivePropagationTest.groovy index 6fabe9fc55..f05df1612b 100644 --- a/instrumentation/vertx-reactive-3.5/javaagent/src/test/groovy/VertxReactivePropagationTest.groovy +++ b/instrumentation/vertx-reactive-3.5/javaagent/src/test/groovy/VertxReactivePropagationTest.groovy @@ -28,7 +28,7 @@ class VertxReactivePropagationTest extends AgentInstrumentationSpecification { Vertx server def setupSpec() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() server = VertxReactiveWebServer.start(port) } diff --git a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTestTrait.groovy b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTestTrait.groovy index 5365a66dfa..27e09d1528 100644 --- a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTestTrait.groovy +++ b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTestTrait.groovy @@ -40,7 +40,7 @@ trait HttpServerTestTrait implements RetryOnAddressAlreadyInUseTrait { } def setupSpecUnderRetry() { - port = PortUtils.randomOpenPort() + port = PortUtils.findOpenPort() address = buildAddress() server = startServer(port) println getClass().name + " http server started at: http://localhost:$port" + getContextPath() diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortAllocator.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortAllocator.java new file mode 100644 index 0000000000..90f0cf2651 --- /dev/null +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortAllocator.java @@ -0,0 +1,129 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.test.utils; + +import java.io.Closeable; +import java.io.IOException; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class for finding open ports that test servers can bind. Allocator splits allocation range + * to chunks and binds to the first port in chunk to claim it. If first port of chunk is already in + * use allocator assumes that some other process has already claimed that chunk and moves to next + * chunk. This should let us as run tests in parallel without them interfering with each other. + */ +class PortAllocator { + + static final int CHUNK_SIZE = 100; + static final int RANGE_MIN = 11000; + // end of allocator port range, should be below ephemeral port range + static final int RANGE_MAX = 32768; + + private final PortBinder portBinder; + private final List sockets = new ArrayList<>(); + // next candidate port + private int next = RANGE_MIN; + private int nextChunkStart = RANGE_MIN; + + PortAllocator() { + this(PortBinder.INSTANCE); + } + + PortAllocator(PortBinder portBinder) { + this.portBinder = portBinder; + + Runtime.getRuntime() + .addShutdownHook( + new Thread( + () -> { + for (Closeable socket : sockets) { + try { + socket.close(); + } catch (IOException ignored) { + } + } + })); + } + + /** Find open port. */ + int getPort() { + return getPorts(1); + } + + /** Find consecutive range of open ports, returning the first one in the range. */ + synchronized int getPorts(int count) { + // as we bind to first port in each chunk the max amount of + // consecutive ports that we can find is CHUNK_SIZE - 1 + if (count < 1 || count >= CHUNK_SIZE) { + throw new IllegalStateException("Invalid count " + count); + } + while (next + count - 1 <= RANGE_MAX) { + // if current chunk doesn't have enough ports move to next chunk + if (next + count - 1 >= nextChunkStart) { + reserveNextChunk(); + } + // find requested amount of consecutive ports + while (next + count - 1 < nextChunkStart && next + count - 1 <= RANGE_MAX) { + // result is the lowest port in consecutive range + int result = next; + for (int i = 0; i < count; i++) { + int port = next; + next++; + if (!portBinder.canBind(port)) { + // someone has allocated a port in our port range, ignore it and try with + // the next port + break; + } else if (i == count - 1) { + return result; + } + } + } + } + // give up when port range is exhausted + throw new IllegalStateException("Failed to find suitable port"); + } + + private void reserveNextChunk() { + while (nextChunkStart < RANGE_MAX) { + // reserve a chunk, if binding to first port of chunk fails + // move to next chunk + Closeable serverSocket = portBinder.bind(nextChunkStart); + if (serverSocket != null) { + sockets.add(serverSocket); + next = nextChunkStart + 1; + nextChunkStart += CHUNK_SIZE; + return; + } + nextChunkStart += CHUNK_SIZE; + } + // give up when port range is exhausted + throw new IllegalStateException("Failed to reserve suitable port range"); + } + + static class PortBinder { + static PortBinder INSTANCE = new PortBinder(); + + Closeable bind(int port) { + try { + return new ServerSocket(port); + } catch (IOException exception) { + return null; + } + } + + boolean canBind(int port) { + try { + ServerSocket socket = new ServerSocket(port); + socket.close(); + return true; + } catch (IOException exception) { + return false; + } + } + } +} diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortUtils.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortUtils.java index c899c02b63..f0a6ea1dfb 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortUtils.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/test/utils/PortUtils.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.test.utils; import java.io.IOException; -import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.TimeUnit; @@ -14,18 +13,16 @@ public class PortUtils { public static int UNUSABLE_PORT = 61; - /** Open up a random, reusable port. */ - public static int randomOpenPort() { - ServerSocket socket; - try { - socket = new ServerSocket(0); - socket.setReuseAddress(true); - socket.close(); - return socket.getLocalPort(); - } catch (IOException ioe) { - ioe.printStackTrace(); - return -1; - } + private static final PortAllocator portAllocator = new PortAllocator(); + + /** Find consecutive open ports, returning the first one in the range. */ + public static int findOpenPorts(int count) { + return portAllocator.getPorts(count); + } + + /** Find open port. */ + public static int findOpenPort() { + return portAllocator.getPort(); } private static boolean isPortOpen(int port) { diff --git a/testing-common/src/test/java/io/opentelemetry/instrumentation/test/utils/PortAllocatorTest.java b/testing-common/src/test/java/io/opentelemetry/instrumentation/test/utils/PortAllocatorTest.java new file mode 100644 index 0000000000..5b870f5ff7 --- /dev/null +++ b/testing-common/src/test/java/io/opentelemetry/instrumentation/test/utils/PortAllocatorTest.java @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.test.utils; + +import java.io.Closeable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PortAllocatorTest { + + @Test + public void testSimple() { + PortAllocator portAllocator = getPortAllocator((port) -> true); + int next = PortAllocator.RANGE_MIN + 1; + for (int i = 0; i < 1000; i++) { + Assertions.assertEquals(next, portAllocator.getPort()); + next++; + if (next % PortAllocator.CHUNK_SIZE == 0) { + next++; + } + } + Assertions.assertEquals(next, portAllocator.getPorts(10)); + Assertions.assertEquals(12101, portAllocator.getPorts(PortAllocator.CHUNK_SIZE - 1)); + try { + Assertions.assertEquals(next, portAllocator.getPorts(PortAllocator.CHUNK_SIZE + 1)); + Assertions.fail("should not be able to allocate more than PORT_RANGE_STEP consecutive ports"); + } catch (IllegalStateException ignored) { + } + } + + @Test + public void testEven() { + PortAllocator portAllocator = getPortAllocator((port) -> port % 2 == 0); + int next = PortAllocator.RANGE_MIN + 2; + for (int i = 0; i < 1000; i++) { + Assertions.assertEquals(next, portAllocator.getPort()); + next += 2; + if (next % PortAllocator.CHUNK_SIZE == 0) { + next += 2; + } + } + try { + Assertions.assertEquals(next, portAllocator.getPorts(2)); + Assertions.fail("should not be able to allocate consecutive ports"); + } catch (IllegalStateException ignored) { + } + } + + private static PortAllocator getPortAllocator(PortTest portTest) { + return new PortAllocator(new TestPortBinder(portTest)); + } + + private interface PortTest { + boolean test(int port); + } + + private static class TestPortBinder extends PortAllocator.PortBinder { + private final PortTest portTest; + + TestPortBinder(PortTest portTest) { + this.portTest = portTest; + } + + @Override + Closeable bind(int port) { + if (canBind(port)) { + return () -> {}; + } + return null; + } + + @Override + boolean canBind(int port) { + return portTest.test(port); + } + } +}