From 131e711995485a08e4038427ef33e6b31a83030e Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Tue, 2 Jun 2026 15:06:41 +0200 Subject: [PATCH 1/4] chore(ort-utils): Let the system pick an ephemeral port for testing This is safer than picking a random port which might be taken. Signed-off-by: Sebastian Schuberth --- .../funTest/kotlin/storage/HttpFileStorageFunTest.kt | 10 ++-------- .../src/funTest/kotlin/storage/S3FileStorageFunTest.kt | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt index 7d0033b69a07a..472681742dd03 100644 --- a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt @@ -35,14 +35,8 @@ import java.net.HttpURLConnection import java.net.InetAddress import java.net.InetSocketAddress -import kotlin.random.Random - -import org.apache.logging.log4j.kotlin.logger - class HttpFileStorageFunTest : WordSpec() { private val loopback = InetAddress.getLoopbackAddress() - private val port = Random.nextInt(1024, 49152) // See https://en.wikipedia.org/wiki/Registered_port. - .also { logger.debug { "Using port $it for HTTP server." } } private val handler = object : HttpHandler { val requests = mutableMapOf() @@ -69,12 +63,12 @@ class HttpFileStorageFunTest : WordSpec() { } // Start the local HTTP server with the system default value for queued incoming connections. - private val server = HttpServer.create(InetSocketAddress(loopback, port), 0).apply { + private val server = HttpServer.create(InetSocketAddress(loopback, 0), 0).apply { createContext("/", handler) start() } - private val storage = HttpFileStorage("http://${loopback.hostAddress}:$port") + private val storage = HttpFileStorage("http://${loopback.hostAddress}:${server.address.port}") override suspend fun afterEach(testCase: TestCase, result: TestResult) { handler.requests.clear() diff --git a/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt index 13ae534215422..eb56a96230375 100644 --- a/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt @@ -35,15 +35,9 @@ import java.net.HttpURLConnection import java.net.InetAddress import java.net.InetSocketAddress -import kotlin.random.Random - -import org.apache.logging.log4j.kotlin.logger - class S3FileStorageFunTest : WordSpec() { private val loopback = InetAddress.getLoopbackAddress() private val protocol = "http" - private val port = Random.nextInt(1024, 49152) // See https://en.wikipedia.org/wiki/Registered_port. - .also { logger.debug { "Using port $it for S3 Mock server." } } private val bucket = "ort-scan-results" @@ -95,7 +89,7 @@ class S3FileStorageFunTest : WordSpec() { } // Start a local HTTP server to mock S3 with the system default value for queued incoming connections. - private val server = HttpServer.create(InetSocketAddress(loopback, port), 0).apply { + private val server = HttpServer.create(InetSocketAddress(loopback, 0), 0).apply { createContext("/", handler) start() } @@ -105,7 +99,7 @@ class S3FileStorageFunTest : WordSpec() { awsRegion = "us-east-1", bucketName = bucket, compression = false, - customEndpoint = "$protocol://${loopback.hostAddress}:$port", + customEndpoint = "$protocol://${loopback.hostAddress}:${server.address.port}", secretAccessKey = "secret" ) From 285c364a0a8937c43738d464ee164f62ddf8a1e0 Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Tue, 2 Jun 2026 15:12:50 +0200 Subject: [PATCH 2/4] chore(ort-utils): Use a `ConcurrentHashMap` for requests in tests Be on the safe side for parallel put / get requests. Signed-off-by: Sebastian Schuberth --- utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt | 3 ++- utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt index 472681742dd03..dcd2c9c1b79ad 100644 --- a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt @@ -34,12 +34,13 @@ import java.io.IOException import java.net.HttpURLConnection import java.net.InetAddress import java.net.InetSocketAddress +import java.util.concurrent.ConcurrentHashMap class HttpFileStorageFunTest : WordSpec() { private val loopback = InetAddress.getLoopbackAddress() private val handler = object : HttpHandler { - val requests = mutableMapOf() + val requests = ConcurrentHashMap() override fun handle(exchange: HttpExchange) { when (exchange.requestMethod) { diff --git a/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt index eb56a96230375..ad716c51a0b5c 100644 --- a/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt @@ -34,6 +34,7 @@ import io.kotest.matchers.shouldBe import java.net.HttpURLConnection import java.net.InetAddress import java.net.InetSocketAddress +import java.util.concurrent.ConcurrentHashMap class S3FileStorageFunTest : WordSpec() { private val loopback = InetAddress.getLoopbackAddress() @@ -42,7 +43,7 @@ class S3FileStorageFunTest : WordSpec() { private val bucket = "ort-scan-results" private val handler = object : HttpHandler { - val requests = mutableMapOf() + val requests = ConcurrentHashMap() override fun handle(exchange: HttpExchange) { when (exchange.requestMethod) { From 00b0f3367b476adaa00737e7d07b682722df61c1 Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Tue, 2 Jun 2026 15:26:46 +0200 Subject: [PATCH 3/4] fix(ort-utils): Read the request body before responding in a test This is part of a `SocketTimeoutException` fix when running with Java 25 and aligns with [1]. [1]: https://github.com/oss-review-toolkit/ort/blob/b855fe74b32c14c2cf3a3a3943ab61e2dc17a125/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt#L61-L62 Signed-off-by: Sebastian Schuberth --- utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt index dcd2c9c1b79ad..55ca04ee2e042 100644 --- a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt @@ -45,8 +45,8 @@ class HttpFileStorageFunTest : WordSpec() { override fun handle(exchange: HttpExchange) { when (exchange.requestMethod) { "PUT" -> { - exchange.sendResponseHeaders(HttpURLConnection.HTTP_CREATED, 0) requests[exchange.requestURI.toString()] = exchange.requestBody.reader().use { it.readText() } + exchange.sendResponseHeaders(HttpURLConnection.HTTP_CREATED, 0) } "GET" -> { From 3793b13db7fc04073481be6bb965bbd5ed047ee5 Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Tue, 2 Jun 2026 15:31:56 +0200 Subject: [PATCH 4/4] fix(ort-utils): Set the body size to -1 when not sending any body in tests This is part of a `SocketTimeoutException` fix when running with Java 25. Signed-off-by: Sebastian Schuberth --- .../ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt | 4 ++-- utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt index 55ca04ee2e042..e8022d6bcee94 100644 --- a/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/HttpFileStorageFunTest.kt @@ -46,7 +46,7 @@ class HttpFileStorageFunTest : WordSpec() { when (exchange.requestMethod) { "PUT" -> { requests[exchange.requestURI.toString()] = exchange.requestBody.reader().use { it.readText() } - exchange.sendResponseHeaders(HttpURLConnection.HTTP_CREATED, 0) + exchange.sendResponseHeaders(HttpURLConnection.HTTP_CREATED, -1) } "GET" -> { @@ -55,7 +55,7 @@ class HttpFileStorageFunTest : WordSpec() { exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0) exchange.responseBody.writer().use { it.write(data) } } else { - exchange.sendResponseHeaders(HttpURLConnection.HTTP_NOT_FOUND, 0) + exchange.sendResponseHeaders(HttpURLConnection.HTTP_NOT_FOUND, -1) } } } diff --git a/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt b/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt index ad716c51a0b5c..9f493a46b69f7 100644 --- a/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt +++ b/utils/ort/src/funTest/kotlin/storage/S3FileStorageFunTest.kt @@ -60,7 +60,7 @@ class S3FileStorageFunTest : WordSpec() { "PUT" -> { val key = exchange.requestURI.toString().removePrefix("/$bucket/") requests[key] = exchange.requestBody.reader().use { it.readText() }.split('\n')[1].trimEnd() - exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0) + exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, -1) } "GET" -> {