You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polaris.apache.org by ad...@apache.org on 2026/06/23 11:58:27 UTC
(polaris) branch main updated: Remove TestEnvironmentExtension (#4841)
This is an automated email from the ASF dual-hosted git repository.
adutra pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new e6edacff11 Remove TestEnvironmentExtension (#4841)
e6edacff11 is described below
commit e6edacff111af6ec022020aebe5d8f5e24361f1a
Author: Alexandre Dutra <ad...@apache.org>
AuthorDate: Tue Jun 23 13:58:22 2026 +0200
Remove TestEnvironmentExtension (#4841)
This extension was introduced in the early stages of Polaris. Its main purpose was to expose the management port to some tests.
We now have a better option for achieving this with the `ServerManager` SPI and various `RestApi` clients.
This PR removes that extension and replaces it with a new `MetricsApi extends RestApi` class. The `Server` interface now exposes a new `managementUri()` method.
---
integration-tests/build.gradle.kts | 1 +
.../env/{Server.java => PlatformApiEndpoints.java} | 40 +++++-----
.../polaris/service/it/env/PlatformMetricsApi.java | 18 +++--
.../service/it/env/PolarisApiEndpoints.java | 22 ++++--
.../polaris/service/it/env/PolarisClient.java | 39 +++++++++-
.../org/apache/polaris/service/it/env/RestApi.java | 12 ++-
.../org/apache/polaris/service/it/env/Server.java | 13 ++++
.../it/ext/PolarisIntegrationTestExtension.java | 13 ++++
.../service/it/env/PlatformApiEndpointsTest.java | 52 +++++++++++++
.../service/it/env/PolarisApiEndpointsTest.java | 64 +++++++++++++--
.../src/main/resources/application-it.properties | 4 +-
.../src/main/resources/application-test.properties | 5 ++
.../src/main/resources/application.properties | 2 -
.../polaris/service/metrics/MetricsTestBase.java | 32 ++++----
.../service/ratelimiter/RateLimiterFilterTest.java | 38 ++++-----
.../test/DefaultTestEnvironmentResolver.java | 39 ----------
.../polaris/service/test/TestEnvironment.java | 42 ----------
.../service/test/TestEnvironmentExtension.java | 91 ----------------------
.../service/test/TestEnvironmentResolver.java | 26 -------
.../apache/polaris/service/it/ServerManager.java | 29 +++++--
20 files changed, 290 insertions(+), 292 deletions(-)
diff --git a/integration-tests/build.gradle.kts b/integration-tests/build.gradle.kts
index 518000c8a8..edb4f7185c 100644
--- a/integration-tests/build.gradle.kts
+++ b/integration-tests/build.gradle.kts
@@ -78,6 +78,7 @@ dependencies {
implementation(libs.assertj.core)
implementation(libs.mockito.core)
implementation(libs.awaitility)
+ implementation(libs.hawkular.agent.prometheus.scraper)
implementation(libs.s3mock.testcontainers)
implementation(project(":polaris-runtime-test-common"))
implementation(project(":polaris-minio-testcontainer"))
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PlatformApiEndpoints.java
similarity index 51%
copy from integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java
copy to integration-tests/src/main/java/org/apache/polaris/service/it/env/PlatformApiEndpoints.java
index fea53d8917..8f6cd35eb2 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PlatformApiEndpoints.java
@@ -18,37 +18,33 @@
*/
package org.apache.polaris.service.it.env;
+import static org.apache.polaris.service.it.env.PolarisApiEndpoints.appendPath;
+
+import java.io.Serializable;
import java.net.URI;
-import java.util.Map;
/**
- * This is a holder for access information to a particular Polaris Server. Test cases may use only
- * the provided admin credentials or create new principals.
+ * Endpoints exposed by the server's management interface.
+ *
+ * <p>These endpoints are platform-dependent and may not be always available. This class assumes
+ * that Polaris is running on a Quarkus platform, and adopts its naming conventions. It may not work
+ * well on other platforms.
*/
-public interface Server extends AutoCloseable {
+public final class PlatformApiEndpoints implements Serializable {
- String DEFAULT_REALM_HEADER = "Polaris-Realm";
- String DEFAULT_REALM_ID = "POLARIS";
+ private final URI metricsApiEndpoint;
+ private final URI healthApiEndpoint;
- default String realmId() {
- return DEFAULT_REALM_ID;
+ public PlatformApiEndpoints(URI managementUri) {
+ this.metricsApiEndpoint = appendPath(managementUri, "metrics");
+ this.healthApiEndpoint = appendPath(managementUri, "health");
}
- default String realmHeaderName() {
- return DEFAULT_REALM_HEADER;
+ public URI metricsApiEndpoint() {
+ return metricsApiEndpoint;
}
- default Map<String, String> headers() {
- return Map.of(realmHeaderName(), realmId());
+ public URI healthApiEndpoint() {
+ return healthApiEndpoint;
}
-
- /**
- * The base URI to all Polaris APIs (e.g. the common base of the Iceberg REST API endpoints and
- * Polaris Management API endpoints).
- *
- * @see PolarisApiEndpoints
- */
- URI baseUri();
-
- ClientPrincipal adminCredentials();
}
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/test/TestMetricsUtil.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PlatformMetricsApi.java
similarity index 81%
rename from runtime/service/src/test/java/org/apache/polaris/service/test/TestMetricsUtil.java
rename to integration-tests/src/main/java/org/apache/polaris/service/it/env/PlatformMetricsApi.java
index 088cdd4f7a..9e64ed18de 100644
--- a/runtime/service/src/test/java/org/apache/polaris/service/test/TestMetricsUtil.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PlatformMetricsApi.java
@@ -16,12 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.polaris.service.test;
+package org.apache.polaris.service.it.env;
-import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.Assertions.assertThat;
import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@@ -33,12 +32,15 @@ import org.hawkular.agent.prometheus.text.TextPrometheusMetricsProcessor;
import org.hawkular.agent.prometheus.types.MetricFamily;
import org.hawkular.agent.prometheus.walkers.CollectorPrometheusMetricsWalker;
-/** Utils for working with metrics in tests */
-public class TestMetricsUtil {
+public class PlatformMetricsApi extends RestApi {
- public static Map<String, MetricFamily> fetchMetrics(URI baseManagementUri) {
- try (Client client = ClientBuilder.newBuilder().build();
- Response response = client.target(baseManagementUri.resolve("q/metrics")).request().get()) {
+ PlatformMetricsApi(Client client, URI metricsApiEndpoint) {
+ super(client, metricsApiEndpoint, "text/plain");
+ }
+
+ /** Fetches all Prometheus metric families from {@code q/metrics}. */
+ public Map<String, MetricFamily> fetchMetrics() {
+ try (Response response = request().get()) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
String body = response.readEntity(String.class);
InputStream inputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisApiEndpoints.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisApiEndpoints.java
index 78e62bcd29..109f4089d9 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisApiEndpoints.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisApiEndpoints.java
@@ -30,26 +30,24 @@ import java.util.stream.Collectors;
*/
public final class PolarisApiEndpoints implements Serializable {
- private final URI baseUri;
+ private final URI catalogApiEndpoint;
+ private final URI managementApiEndpoint;
private final String realmId;
private final Map<String, String> headers;
- public PolarisApiEndpoints(URI baseUri, String realmId, String realmHeaderName) {
- this(baseUri, realmId, Map.of(realmHeaderName, realmId));
- }
-
public PolarisApiEndpoints(URI baseUri, String realmId, Map<String, String> headers) {
- this.baseUri = baseUri;
+ this.catalogApiEndpoint = appendPath(baseUri, "api/catalog");
+ this.managementApiEndpoint = appendPath(baseUri, "api/management");
this.realmId = realmId;
this.headers = headers;
}
public URI catalogApiEndpoint() {
- return baseUri.resolve(baseUri.getRawPath() + "/api/catalog").normalize();
+ return catalogApiEndpoint;
}
public URI managementApiEndpoint() {
- return baseUri.resolve(baseUri.getRawPath() + "/api/management").normalize();
+ return managementApiEndpoint;
}
public String realmId() {
@@ -65,4 +63,12 @@ public final class PolarisApiEndpoints implements Serializable {
.map(e -> Map.entry(keyPrefix + e.getKey(), e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
+
+ static URI appendPath(URI base, String path) {
+ String baseStr = base.toString();
+ if (baseStr.endsWith("/")) {
+ baseStr = baseStr.substring(0, baseStr.length() - 1);
+ }
+ return URI.create(baseStr + "/" + path).normalize();
+ }
}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java
index 2a5c31eeab..ac0ec018aa 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java
@@ -33,14 +33,18 @@ import java.util.Random;
import org.apache.iceberg.rest.RESTSerializers;
import org.apache.polaris.core.admin.model.PrincipalWithCredentials;
import org.apache.polaris.service.it.ext.PolarisServerManager;
+import org.jspecify.annotations.Nullable;
/**
- * This is a holder for the heavy-weight HTTP client for accessing Polaris APIs. This class provides
- * method for constructing light-weight API wrappers for Iceberg REST and Polaris Management API
- * that reuse the same shared HTTP client.
+ * This is a holder for the heavy-weight HTTP client for accessing Polaris APIs, and optionally,
+ * platform APIs (such as metrics or health endpoints).
+ *
+ * <p>This class provides methods for constructing light-weight API wrappers for Iceberg REST APis,
+ * Polaris Management APIs, and platform APIs that reuse the same shared HTTP client.
*/
public final class PolarisClient implements AutoCloseable {
private final PolarisApiEndpoints endpoints;
+ private final @Nullable PlatformApiEndpoints platformEndpoints;
private final Client client;
// Use an alphanumeric ID for widest compatibility in HTTP and SQL.
// Use MAX_RADIX for shorter output.
@@ -48,15 +52,35 @@ public final class PolarisClient implements AutoCloseable {
Long.toString(Math.abs(new Random().nextLong()), Character.MAX_RADIX);
private PolarisClient(PolarisApiEndpoints endpoints) {
- this.endpoints = endpoints;
+ this(endpoints, null);
+ }
+ private PolarisClient(
+ PolarisApiEndpoints endpoints, @Nullable PlatformApiEndpoints platformEndpoints) {
+ this.endpoints = endpoints;
+ this.platformEndpoints = platformEndpoints;
this.client = polarisServerManager().createClient();
}
+ /**
+ * Builds a {@link PolarisClient} for the given {@link PolarisApiEndpoints}. The returned client
+ * cannot access platform endpoints; use {@link #polarisClient(PolarisApiEndpoints,
+ * PlatformApiEndpoints)} if platform endpoints are required by the test.
+ */
public static PolarisClient polarisClient(PolarisApiEndpoints endpoints) {
return new PolarisClient(endpoints);
}
+ /**
+ * Builds a {@link PolarisClient} for the given {@link PolarisApiEndpoints} and {@link
+ * PlatformApiEndpoints}. The returned client can access both Polaris APIs and platform endpoints
+ * (e.g. metrics or health endpoints).
+ */
+ public static PolarisClient polarisClient(
+ PolarisApiEndpoints endpoints, PlatformApiEndpoints platformEndpoints) {
+ return new PolarisClient(endpoints, platformEndpoints);
+ }
+
/**
* Utility method that creates an {@link ObjectMapper} sufficient for (de-)serializing client-side
* payloads for Iceberg REST and Polaris Management APIs.
@@ -103,6 +127,13 @@ public final class PolarisClient implements AutoCloseable {
return new PolicyApi(client, endpoints, authToken, endpoints.catalogApiEndpoint());
}
+ public PlatformMetricsApi platformMetricsApi() {
+ if (platformEndpoints == null) {
+ throw new IllegalStateException("Platform endpoints are not available");
+ }
+ return new PlatformMetricsApi(client, platformEndpoints.metricsApiEndpoint());
+ }
+
/** Requests an access token from the Polaris server for the given principal. */
public String obtainToken(PrincipalWithCredentials credentials) {
return obtainToken(new ClientPrincipal(credentials));
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/env/RestApi.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/RestApi.java
index 13964af0ac..c295586d1d 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/env/RestApi.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/RestApi.java
@@ -28,10 +28,20 @@ import java.util.Map;
public class RestApi {
private final Client client;
private final URI uri;
+ private final String contentType;
RestApi(Client client, URI uri) {
+ this(client, uri, "application/json");
+ }
+
+ RestApi(Client client, URI uri, String contentType) {
this.client = client;
this.uri = uri;
+ this.contentType = contentType;
+ }
+
+ public Invocation.Builder request() {
+ return client.target(uri).request(contentType);
}
public Invocation.Builder request(String path) {
@@ -59,7 +69,7 @@ public class RestApi {
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
target = target.queryParam(entry.getKey(), entry.getValue());
}
- Invocation.Builder request = target.request("application/json");
+ Invocation.Builder request = target.request(contentType);
headers.forEach(request::header);
return request;
}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java
index fea53d8917..911b3fec4a 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/Server.java
@@ -20,6 +20,7 @@ package org.apache.polaris.service.it.env;
import java.net.URI;
import java.util.Map;
+import java.util.Optional;
/**
* This is a holder for access information to a particular Polaris Server. Test cases may use only
@@ -50,5 +51,17 @@ public interface Server extends AutoCloseable {
*/
URI baseUri();
+ /**
+ * The base URI for the platform management interface (exposing metrics and health checks). Not to
+ * be confused with the Polaris Management API. This URI includes the management interface root
+ * path, usually {@code /q} on Quarkus platforms.
+ *
+ * <p>The management URI is sometimes unavailable, e.g. in the case of a @QuarkusIntegrationTest;
+ * in such cases this method returns empty.
+ */
+ default Optional<URI> managementUri() {
+ return Optional.empty();
+ }
+
ClientPrincipal adminCredentials();
}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java
index f3abce39f9..ad377f409c 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java
@@ -20,8 +20,10 @@ package org.apache.polaris.service.it.ext;
import static org.apache.polaris.service.it.ext.PolarisServerManagerLoader.polarisServerManager;
+import java.util.Optional;
import org.apache.polaris.service.it.env.ClientCredentials;
import org.apache.polaris.service.it.env.ClientPrincipal;
+import org.apache.polaris.service.it.env.PlatformApiEndpoints;
import org.apache.polaris.service.it.env.PolarisApiEndpoints;
import org.apache.polaris.service.it.env.Server;
import org.junit.jupiter.api.extension.ExtensionContext;
@@ -45,6 +47,7 @@ public class PolarisIntegrationTestExtension implements ParameterResolver {
throws ParameterResolutionException {
Class<?> type = parameterContext.getParameter().getType();
return type.isAssignableFrom(PolarisApiEndpoints.class)
+ || type.isAssignableFrom(PlatformApiEndpoints.class)
|| type.isAssignableFrom(ClientPrincipal.class)
|| type.isAssignableFrom(ClientCredentials.class);
}
@@ -57,6 +60,10 @@ public class PolarisIntegrationTestExtension implements ParameterResolver {
Class<?> type = parameterContext.getParameter().getType();
if (type.isAssignableFrom(PolarisApiEndpoints.class)) {
return env.endpoints();
+ } else if (type.isAssignableFrom(PlatformApiEndpoints.class)) {
+ return env.quarkusEndpoints()
+ .orElseThrow(
+ () -> new IllegalStateException("Quarkus management endpoint is not available"));
} else if (type.isAssignableFrom(ClientPrincipal.class)) {
return env.server.adminCredentials();
} else if (type.isAssignableFrom(ClientCredentials.class)) {
@@ -88,17 +95,23 @@ public class PolarisIntegrationTestExtension implements ParameterResolver {
private static class Env implements AutoCloseable {
private final Server server;
private final PolarisApiEndpoints endpoints;
+ private final Optional<PlatformApiEndpoints> platformEndpoints;
private Env(Server server) {
this.server = server;
this.endpoints =
new PolarisApiEndpoints(server.baseUri(), server.realmId(), server.headers());
+ this.platformEndpoints = server.managementUri().map(PlatformApiEndpoints::new);
}
PolarisApiEndpoints endpoints() {
return endpoints;
}
+ Optional<PlatformApiEndpoints> quarkusEndpoints() {
+ return platformEndpoints;
+ }
+
@Override
public void close() throws Exception {
server.close();
diff --git a/integration-tests/src/test/java/org/apache/polaris/service/it/env/PlatformApiEndpointsTest.java b/integration-tests/src/test/java/org/apache/polaris/service/it/env/PlatformApiEndpointsTest.java
new file mode 100644
index 0000000000..407424a778
--- /dev/null
+++ b/integration-tests/src/test/java/org/apache/polaris/service/it/env/PlatformApiEndpointsTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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
+ *
+ * https://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.polaris.service.it.env;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.net.URI;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+public class PlatformApiEndpointsTest {
+
+ @ParameterizedTest
+ @CsvSource({
+ "https://example.com , https://example.com/metrics",
+ "https://example.com/ , https://example.com/metrics",
+ "https://example.com/polaris , https://example.com/polaris/metrics",
+ "https://example.com/polaris/ , https://example.com/polaris/metrics"
+ })
+ void testQuarkusMetricsApiEndpoint(URI baseUri, URI expectedUri) {
+ PlatformApiEndpoints endpoints = new PlatformApiEndpoints(baseUri);
+ assertThat(endpoints.metricsApiEndpoint()).isEqualTo(expectedUri);
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "https://example.com , https://example.com/health",
+ "https://example.com/ , https://example.com/health",
+ "https://example.com/polaris , https://example.com/polaris/health",
+ "https://example.com/polaris/ , https://example.com/polaris/health"
+ })
+ void testQuarkusHealthApiEndpoint(URI baseUri, URI expectedUri) {
+ PlatformApiEndpoints endpoints = new PlatformApiEndpoints(baseUri);
+ assertThat(endpoints.healthApiEndpoint()).isEqualTo(expectedUri);
+ }
+}
diff --git a/integration-tests/src/test/java/org/apache/polaris/service/it/env/PolarisApiEndpointsTest.java b/integration-tests/src/test/java/org/apache/polaris/service/it/env/PolarisApiEndpointsTest.java
index 1ba9d9db5d..3b1b3d0285 100644
--- a/integration-tests/src/test/java/org/apache/polaris/service/it/env/PolarisApiEndpointsTest.java
+++ b/integration-tests/src/test/java/org/apache/polaris/service/it/env/PolarisApiEndpointsTest.java
@@ -7,7 +7,7 @@
* "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
+ * https://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
@@ -18,19 +18,67 @@
*/
package org.apache.polaris.service.it.env;
+import static org.assertj.core.api.Assertions.assertThat;
+
import java.net.URI;
-import org.junit.jupiter.api.Assertions;
+import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
/** Unit tests for PolarisApiEndpoints */
public class PolarisApiEndpointsTest {
+
+ @ParameterizedTest
+ @CsvSource({
+ "https://example.com , https://example.com/api/catalog",
+ "https://example.com/ , https://example.com/api/catalog",
+ "https://example.com/polaris , https://example.com/polaris/api/catalog",
+ "https://example.com/polaris/ , https://example.com/polaris/api/catalog"
+ })
+ void testCatalogApiEndpoint(URI baseUri, URI expectedUri) {
+ PolarisApiEndpoints endpoints = new PolarisApiEndpoints(baseUri, "realm1", Map.of());
+ assertThat(endpoints.catalogApiEndpoint()).isEqualTo(expectedUri);
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "https://example.com , https://example.com/api/management",
+ "https://example.com/ , https://example.com/api/management",
+ "https://example.com/polaris , https://example.com/polaris/api/management",
+ "https://example.com/polaris/ , https://example.com/polaris/api/management"
+ })
+ void testManagementApiEndpoint(URI baseUri, URI expectedUri) {
+ PolarisApiEndpoints endpoints = new PolarisApiEndpoints(baseUri, "realm1", Map.of());
+ assertThat(endpoints.managementApiEndpoint()).isEqualTo(expectedUri);
+ }
+
+ @Test
+ void testRealmId() {
+ PolarisApiEndpoints endpoints =
+ new PolarisApiEndpoints(URI.create("https://example.com/irrelevant"), "realm1", Map.of());
+ assertThat(endpoints.realmId()).isEqualTo("realm1");
+ }
+
+ @Test
+ void testExtraHeaders() {
+ PolarisApiEndpoints endpoints =
+ new PolarisApiEndpoints(
+ URI.create("https://example.com/irrelevant"),
+ "realm1",
+ Map.of("key1", "value1", "key2", "value2"));
+ assertThat(endpoints.extraHeaders())
+ .containsOnly(Map.entry("key1", "value1"), Map.entry("key2", "value2"));
+ }
+
@Test
- void testEndpointRespectsPathPrefix() {
+ void testExtraHeadersPrefix() {
PolarisApiEndpoints endpoints =
- new PolarisApiEndpoints(URI.create("http://myserver.com/polaris"), "", "Polaris-Realm");
- Assertions.assertEquals(
- "http://myserver.com/polaris/api/catalog", endpoints.catalogApiEndpoint().toString());
- Assertions.assertEquals(
- "http://myserver.com/polaris/api/management", endpoints.managementApiEndpoint().toString());
+ new PolarisApiEndpoints(
+ URI.create("https://example.com/irrelevant"),
+ "realm1",
+ Map.of("key1", "value1", "key2", "value2"));
+ assertThat(endpoints.extraHeaders("prefix."))
+ .containsOnly(Map.entry("prefix.key1", "value1"), Map.entry("prefix.key2", "value2"));
}
}
diff --git a/runtime/defaults/src/main/resources/application-it.properties b/runtime/defaults/src/main/resources/application-it.properties
index 108a9585b9..df2d901463 100644
--- a/runtime/defaults/src/main/resources/application-it.properties
+++ b/runtime/defaults/src/main/resources/application-it.properties
@@ -21,8 +21,10 @@
# Note: Quarkus integration tests cannot use QuarkusTestProfile.
quarkus.http.limits.max-body-size=1000000
-quarkus.http.port=0
+# For integration tests, we must *override* the HTTP and management ports themselves to zero;
+# modifying the test-ports has no effect in these tests.
+quarkus.http.port=0
quarkus.management.port=0
# polaris.persistence.type=jdbc
diff --git a/runtime/defaults/src/main/resources/application-test.properties b/runtime/defaults/src/main/resources/application-test.properties
index 4f31702e27..c8d2d1672d 100644
--- a/runtime/defaults/src/main/resources/application-test.properties
+++ b/runtime/defaults/src/main/resources/application-test.properties
@@ -20,6 +20,11 @@
# Configuration common to ALL unit tests (executed with "test" profile – Gradle "test" tasks).
# Per-test specific configuration should use QuarkusTestProfile
+# For unit tests, the default HTTP and management *test-ports* (8081 and 9001 respectively) must be
+# overridden to zero, so that Quarkus will automatically select an available port.
+quarkus.http.test-port=0
+quarkus.management.test-port=0
+
quarkus.datasource.devservices.enabled=false
quarkus.keycloak.devservices.enabled=false
quarkus.mongodb.devservices.enabled=false
diff --git a/runtime/defaults/src/main/resources/application.properties b/runtime/defaults/src/main/resources/application.properties
index 6fe3b9ad63..626c6beb40 100644
--- a/runtime/defaults/src/main/resources/application.properties
+++ b/runtime/defaults/src/main/resources/application.properties
@@ -66,7 +66,6 @@ quarkus.http.cors.enabled=false
#quarkus.http.cors.access-control-allow-credentials=true
quarkus.http.port=8181
-quarkus.http.test-port=0
quarkus.log.level=INFO
quarkus.log.console.enabled=true
@@ -88,7 +87,6 @@ quarkus.log.file.rotation.max-backup-index=14
# quarkus.log.category."org.apache.iceberg.rest".level=INFO
quarkus.management.port=8182
-quarkus.management.test-port=0
# OIDC settings. These settings are required only when using external authentication providers.
# See https://quarkus.io/guides/security-oidc-configuration-properties-reference
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/metrics/MetricsTestBase.java b/runtime/service/src/test/java/org/apache/polaris/service/metrics/MetricsTestBase.java
index a04fc7d04c..28b2e4782d 100644
--- a/runtime/service/src/test/java/org/apache/polaris/service/metrics/MetricsTestBase.java
+++ b/runtime/service/src/test/java/org/apache/polaris/service/metrics/MetricsTestBase.java
@@ -28,13 +28,12 @@ import java.time.Duration;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.polaris.service.it.env.ClientPrincipal;
+import org.apache.polaris.service.it.env.PlatformApiEndpoints;
+import org.apache.polaris.service.it.env.PlatformMetricsApi;
import org.apache.polaris.service.it.env.PolarisApiEndpoints;
import org.apache.polaris.service.it.env.PolarisClient;
import org.apache.polaris.service.it.ext.PolarisIntegrationTestExtension;
import org.apache.polaris.service.ratelimiter.MockRateLimiter;
-import org.apache.polaris.service.test.TestEnvironment;
-import org.apache.polaris.service.test.TestEnvironmentExtension;
-import org.apache.polaris.service.test.TestMetricsUtil;
import org.awaitility.Awaitility;
import org.hawkular.agent.prometheus.types.MetricFamily;
import org.hawkular.agent.prometheus.types.Summary;
@@ -47,7 +46,6 @@ import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-@ExtendWith(TestEnvironmentExtension.class)
@ExtendWith(PolarisIntegrationTestExtension.class)
public abstract class MetricsTestBase {
@@ -58,20 +56,22 @@ public abstract class MetricsTestBase {
@Inject MeterRegistry registry;
@Inject MetricsConfiguration metricsConfiguration;
- private TestEnvironment testEnv;
- private PolarisApiEndpoints endpoints;
+ private PlatformMetricsApi platformMetricsApi;
+ private PolarisApiEndpoints polarisEndpoints;
private PolarisClient client;
private ClientPrincipal principal;
private String adminToken;
@BeforeAll
public void setUp(
- TestEnvironment testEnv, PolarisApiEndpoints endpoints, ClientPrincipal principal) {
+ PolarisApiEndpoints polarisEndpoints,
+ PlatformApiEndpoints quarkusEndpoints,
+ ClientPrincipal principal) {
MockRateLimiter.allowProceed = true;
- this.testEnv = testEnv;
- this.endpoints = endpoints;
+ this.polarisEndpoints = polarisEndpoints;
this.principal = principal;
- client = PolarisClient.polarisClient(this.endpoints);
+ client = PolarisClient.polarisClient(polarisEndpoints, quarkusEndpoints);
+ platformMetricsApi = client.platformMetricsApi();
adminToken = client.obtainToken(principal.credentials());
}
@@ -93,7 +93,7 @@ public abstract class MetricsTestBase {
.atMost(Duration.ofMinutes(2))
.untilAsserted(
() -> {
- value.set(TestMetricsUtil.fetchMetrics(testEnv.baseManagementUri()));
+ value.set(platformMetricsApi.fetchMetrics());
assertThat(value.get()).containsKey(API_METRIC_NAME);
assertThat(value.get()).containsKey(HTTP_METRIC_NAME);
});
@@ -115,7 +115,7 @@ public abstract class MetricsTestBase {
Map.entry(
"realm_id",
metricsConfiguration.realmIdTag().enableInApiMetrics()
- ? endpoints.realmId()
+ ? polarisEndpoints.realmId()
: ""),
Map.entry(
"principal",
@@ -144,7 +144,8 @@ public abstract class MetricsTestBase {
Map.entry("status", "200"),
Map.entry("uri", "/api/management/v1/principals/{principalName}"));
if (metricsConfiguration.realmIdTag().enableInHttpMetrics()) {
- assertThat(metric.getLabels()).containsEntry("realm_id", endpoints.realmId());
+ assertThat(metric.getLabels())
+ .containsEntry("realm_id", polarisEndpoints.realmId());
} else {
assertThat(metric.getLabels()).doesNotContainKey("realm_id");
}
@@ -170,7 +171,7 @@ public abstract class MetricsTestBase {
Map.entry(
"realm_id",
metricsConfiguration.realmIdTag().enableInApiMetrics()
- ? endpoints.realmId()
+ ? polarisEndpoints.realmId()
: ""),
Map.entry(
"principal",
@@ -198,7 +199,8 @@ public abstract class MetricsTestBase {
Map.entry("status", "404"),
Map.entry("uri", "/api/management/v1/principals/{principalName}"));
if (metricsConfiguration.realmIdTag().enableInHttpMetrics()) {
- assertThat(metric.getLabels()).containsEntry("realm_id", endpoints.realmId());
+ assertThat(metric.getLabels())
+ .containsEntry("realm_id", polarisEndpoints.realmId());
} else {
assertThat(metric.getLabels()).doesNotContainKey("realm_id");
}
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/ratelimiter/RateLimiterFilterTest.java b/runtime/service/src/test/java/org/apache/polaris/service/ratelimiter/RateLimiterFilterTest.java
index 9322a9159b..a7e7d766ec 100644
--- a/runtime/service/src/test/java/org/apache/polaris/service/ratelimiter/RateLimiterFilterTest.java
+++ b/runtime/service/src/test/java/org/apache/polaris/service/ratelimiter/RateLimiterFilterTest.java
@@ -43,13 +43,12 @@ import org.apache.polaris.service.events.PolarisEvent;
import org.apache.polaris.service.events.PolarisEventType;
import org.apache.polaris.service.events.listeners.TestPolarisEventListener;
import org.apache.polaris.service.it.env.ClientCredentials;
+import org.apache.polaris.service.it.env.PlatformApiEndpoints;
+import org.apache.polaris.service.it.env.PlatformMetricsApi;
import org.apache.polaris.service.it.env.PolarisApiEndpoints;
import org.apache.polaris.service.it.env.PolarisClient;
import org.apache.polaris.service.it.ext.PolarisIntegrationTestExtension;
import org.apache.polaris.service.ratelimiter.RateLimiterFilterTest.Profile;
-import org.apache.polaris.service.test.TestEnvironment;
-import org.apache.polaris.service.test.TestEnvironmentExtension;
-import org.apache.polaris.service.test.TestMetricsUtil;
import org.hawkular.agent.prometheus.types.MetricFamily;
import org.hawkular.agent.prometheus.types.Summary;
import org.junit.jupiter.api.AfterAll;
@@ -64,7 +63,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
@QuarkusTest
@TestInstance(Lifecycle.PER_CLASS)
@TestProfile(Profile.class)
-@ExtendWith(TestEnvironmentExtension.class)
@ExtendWith(PolarisIntegrationTestExtension.class)
public class RateLimiterFilterTest {
@@ -97,18 +95,20 @@ public class RateLimiterFilterTest {
@Identifier("test")
TestPolarisEventListener polarisEventListener;
- private TestEnvironment testEnv;
- private PolarisApiEndpoints endpoints;
+ private PlatformMetricsApi platformMetricsApi;
+ private PolarisApiEndpoints polarisEndpoints;
private PolarisClient client;
private String adminToken;
@BeforeAll
public void setUp(
- TestEnvironment testEnv, PolarisApiEndpoints endpoints, ClientCredentials credentials) {
+ PolarisApiEndpoints polarisEndpoints,
+ PlatformApiEndpoints quarkusEndpoints,
+ ClientCredentials credentials) {
MockRateLimiter.allowProceed = true;
- this.testEnv = testEnv;
- this.endpoints = endpoints;
- client = PolarisClient.polarisClient(endpoints);
+ this.polarisEndpoints = polarisEndpoints;
+ client = PolarisClient.polarisClient(polarisEndpoints, quarkusEndpoints);
+ platformMetricsApi = client.platformMetricsApi();
adminToken = client.obtainToken(credentials);
}
@@ -128,7 +128,8 @@ public class RateLimiterFilterTest {
@Test
public void testRateLimiter() {
- Consumer<Status> requestAsserter = constructRequestAsserter(testEnv, adminToken, "POLARIS");
+ Consumer<Status> requestAsserter =
+ constructRequestAsserter(polarisEndpoints, adminToken, "POLARIS");
for (int i = 0; i < 3; i++) {
MockRateLimiter.allowProceed = true;
@@ -139,7 +140,8 @@ public class RateLimiterFilterTest {
// Ensure that a different realm identifier gets a separate limit
MockRateLimiter.allowProceed = true;
- Consumer<Status> requestAsserter2 = constructRequestAsserter(testEnv, adminToken, "POLARIS2");
+ Consumer<Status> requestAsserter2 =
+ constructRequestAsserter(polarisEndpoints, adminToken, "POLARIS2");
requestAsserter2.accept(Status.OK);
}
@@ -161,7 +163,7 @@ public class RateLimiterFilterTest {
@Test
public void testMetricsAreEmittedWhenRateLimiting() {
Consumer<Status> requestAsserter =
- constructRequestAsserter(testEnv, adminToken, endpoints.realmId());
+ constructRequestAsserter(polarisEndpoints, adminToken, polarisEndpoints.realmId());
for (int i = 0; i < 3; i++) {
MockRateLimiter.allowProceed = true;
@@ -177,7 +179,7 @@ public class RateLimiterFilterTest {
// http_server_requests_seconds_count{application="Polaris",environment="prod",method="GET",outcome="CLIENT_ERROR",realm_id="org_apache_polaris_service_ratelimiter_RateLimiterFilterTest",status="429",uri="/api/management/v1/principal-roles"} 1.0
// polaris_principal_roles_listPrincipalRoles_seconds_count{application="Polaris",class="org.apache.polaris.service.admin.api.PolarisPrincipalRolesApi",environment="prod",exception="none",method="listPrincipalRoles"} 50.0
- Map<String, MetricFamily> metrics = TestMetricsUtil.fetchMetrics(testEnv.baseManagementUri());
+ Map<String, MetricFamily> metrics = platformMetricsApi.fetchMetrics();
assertThat(metrics)
.isNotEmpty()
@@ -191,7 +193,7 @@ public class RateLimiterFilterTest {
.contains(
Map.entry("application", "Polaris"),
Map.entry("environment", "prod"),
- Map.entry("realm_id", endpoints.realmId()),
+ Map.entry("realm_id", polarisEndpoints.realmId()),
Map.entry("method", "GET"),
Map.entry("outcome", "CLIENT_ERROR"),
Map.entry("status", String.valueOf(Status.TOO_MANY_REQUESTS.getStatusCode())),
@@ -209,7 +211,7 @@ public class RateLimiterFilterTest {
.contains(
Map.entry("application", "Polaris"),
Map.entry("environment", "prod"),
- Map.entry("realm_id", endpoints.realmId()),
+ Map.entry("realm_id", polarisEndpoints.realmId()),
Map.entry(
"class", "org.apache.polaris.service.admin.api.PolarisPrincipalRolesApi"),
Map.entry("exception", "none"),
@@ -227,12 +229,12 @@ public class RateLimiterFilterTest {
* whether the rate limiter intervenes.
*/
private static Consumer<Status> constructRequestAsserter(
- TestEnvironment testEnv, String adminToken, String realm) {
+ PolarisApiEndpoints endpoints, String adminToken, String realm) {
return (Status status) -> {
try (Client client = ClientBuilder.newBuilder().build();
Response response =
client
- .target(String.format("%s/api/management/v1/principal-roles", testEnv.baseUri()))
+ .target(String.format("%s/v1/principal-roles", endpoints.managementApiEndpoint()))
.request("application/json")
.header("Authorization", "Bearer " + adminToken)
.header("Polaris-Realm", realm)
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/test/DefaultTestEnvironmentResolver.java b/runtime/service/src/test/java/org/apache/polaris/service/test/DefaultTestEnvironmentResolver.java
deleted file mode 100644
index fc9686a9d1..0000000000
--- a/runtime/service/src/test/java/org/apache/polaris/service/test/DefaultTestEnvironmentResolver.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.polaris.service.test;
-
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.junit.jupiter.api.extension.ExtensionContext;
-
-public class DefaultTestEnvironmentResolver implements TestEnvironmentResolver {
-
- /** Resolves the TestEnvironment to point to the local Quarkus Application instance. */
- @Override
- public TestEnvironment resolveTestEnvironment(ExtensionContext extensionContext) {
- var quarkusManagementPort =
- ConfigProvider.getConfig().getConfigValue("quarkus.management.port");
- var localManagementPort = Integer.parseInt(quarkusManagementPort.getValue());
- var quarkusHttpPort = ConfigProvider.getConfig().getConfigValue("quarkus.http.port");
- var localPort = Integer.parseInt(quarkusHttpPort.getValue());
-
- return new TestEnvironment(
- String.format("http://localhost:%d/", localPort),
- String.format("http://localhost:%d/", localManagementPort));
- }
-}
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironment.java b/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironment.java
deleted file mode 100644
index 705c40605a..0000000000
--- a/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironment.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.polaris.service.test;
-
-import java.net.URI;
-import java.util.UUID;
-
-/**
- * Defines the test environment that a test should run in.
- *
- * @param baseUri The base URL that requests should target, for example {@code
- * http://localhost:8181}
- * @param baseManagementUri The base URL that requests should target for the management interface,
- * for example {@code http://localhost:8182}
- * @param testId An ID unique to this test. This can be used to prefix resource names, such as
- * catalog names, to prevent collision.
- */
-public record TestEnvironment(URI baseUri, URI baseManagementUri, String testId) {
-
- public TestEnvironment(String baseUri, String baseManagementUri) {
- this(
- URI.create(baseUri),
- URI.create(baseManagementUri),
- UUID.randomUUID().toString().replace("-", ""));
- }
-}
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironmentExtension.java b/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironmentExtension.java
deleted file mode 100644
index 011d85282c..0000000000
--- a/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironmentExtension.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.polaris.service.test;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Optional;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-
-/**
- * JUnit test extension that determines the TestEnvironment. Falls back to targeting the local
- * Dropwizard instance.
- */
-public class TestEnvironmentExtension implements ParameterResolver {
- /**
- * Environment variable that specifies the test environment resolver. This should be a class name.
- * If this is not set, falls back to DropwizardTestEnvironmentResolver.
- */
- public static final String ENV_TEST_ENVIRONMENT_RESOLVER_IMPL =
- "INTEGRATION_TEST_ENVIRONMENT_RESOLVER_IMPL";
-
- private static final String ENV_PROPERTY_KEY = "testenvironment";
-
- public static TestEnvironment getEnv(ExtensionContext extensionContext)
- throws IllegalAccessException {
- // This must be cached because the TestEnvironment has a randomly generated ID
- return extensionContext
- .getStore(Namespace.create(extensionContext.getRequiredTestClass()))
- .computeIfAbsent(
- ENV_PROPERTY_KEY,
- (k) -> getTestEnvironmentResolver().resolveTestEnvironment(extensionContext),
- TestEnvironment.class);
- }
-
- @Override
- public boolean supportsParameter(
- ParameterContext parameterContext, ExtensionContext extensionContext)
- throws ParameterResolutionException {
- return parameterContext.getParameter().getType().equals(TestEnvironment.class);
- }
-
- @Override
- public Object resolveParameter(
- ParameterContext parameterContext, ExtensionContext extensionContext)
- throws ParameterResolutionException {
- try {
- return getEnv(extensionContext);
- } catch (IllegalAccessException e) {
- throw new ParameterResolutionException(e.getMessage());
- }
- }
-
- private static TestEnvironmentResolver getTestEnvironmentResolver() {
- String impl =
- Optional.ofNullable(System.getenv(ENV_TEST_ENVIRONMENT_RESOLVER_IMPL))
- .orElse(DefaultTestEnvironmentResolver.class.getName());
-
- try {
- return (TestEnvironmentResolver) (Class.forName(impl).getDeclaredConstructor().newInstance());
- } catch (InstantiationException
- | IllegalAccessException
- | IllegalArgumentException
- | InvocationTargetException
- | ClassNotFoundException
- | NoSuchMethodException e) {
- throw new IllegalArgumentException(
- String.format(
- "Failed to initialize TestEnvironmentResolver using implementation %s.", impl),
- e);
- }
- }
-}
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironmentResolver.java b/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironmentResolver.java
deleted file mode 100644
index 7064fbabde..0000000000
--- a/runtime/service/src/test/java/org/apache/polaris/service/test/TestEnvironmentResolver.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.polaris.service.test;
-
-import org.junit.jupiter.api.extension.ExtensionContext;
-
-/** Interface for determining the test environment that tests should run in */
-public interface TestEnvironmentResolver {
- TestEnvironment resolveTestEnvironment(ExtensionContext extensionContext);
-}
diff --git a/runtime/service/src/testFixtures/java/org/apache/polaris/service/it/ServerManager.java b/runtime/service/src/testFixtures/java/org/apache/polaris/service/it/ServerManager.java
index 4f1849c098..dbe8d8cb9d 100644
--- a/runtime/service/src/testFixtures/java/org/apache/polaris/service/it/ServerManager.java
+++ b/runtime/service/src/testFixtures/java/org/apache/polaris/service/it/ServerManager.java
@@ -18,9 +18,12 @@
*/
package org.apache.polaris.service.it;
-import io.quarkus.test.common.ListeningAddress;
+import io.quarkus.test.common.http.TestHTTPResourceManager;
+import io.quarkus.test.config.ConfigInjector;
import io.quarkus.test.config.ValueRegistryInjector;
+import io.quarkus.value.registry.ValueRegistry;
import java.net.URI;
+import java.util.Optional;
import org.apache.polaris.service.it.env.ClientCredentials;
import org.apache.polaris.service.it.env.ClientPrincipal;
import org.apache.polaris.service.it.env.Server;
@@ -29,13 +32,30 @@ import org.junit.jupiter.api.extension.ExtensionContext;
public class ServerManager implements PolarisServerManager {
+ private static final ValueRegistry.RuntimeKey<Integer> MANAGEMENT_PORT =
+ ValueRegistry.RuntimeKey.intKey("quarkus.management.port");
+
@Override
public Server serverForContext(ExtensionContext context) {
return new Server() {
@Override
public URI baseUri() {
- return URI.create(String.format("http://localhost:%d", getQuarkusTestPort(context)));
+ var registry = ValueRegistryInjector.get(context);
+ var config = ConfigInjector.get(context);
+ return URI.create(TestHTTPResourceManager.testUrl(registry, config));
+ }
+
+ @Override
+ public Optional<URI> managementUri() {
+ var registry = ValueRegistryInjector.get(context);
+ var config = ConfigInjector.get(context);
+ // Probe whether the actual port to use has been registered. If not, the management
+ // interface is not available, and we are likely in a @QuarkusIntegrationTest.
+ int dynamicPort = registry.getOrDefault(MANAGEMENT_PORT, -1);
+ return dynamicPort == -1
+ ? Optional.empty()
+ : Optional.of(URI.create(TestHTTPResourceManager.testManagementUrl(registry, config)));
}
@Override
@@ -51,9 +71,4 @@ public class ServerManager implements PolarisServerManager {
}
};
}
-
- private static int getQuarkusTestPort(ExtensionContext context) {
- var registry = ValueRegistryInjector.get(context);
- return registry.get(ListeningAddress.HTTP_PORT);
- }
}