This is an automated email from the ASF dual-hosted git repository.
dimas 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 438d06cf7 test(integration): refactor
PolarisRestCatalogIntegrationTest to run against any cloud provider (#1934)
438d06cf7 is described below
commit 438d06cf77169d56050948fe46a3763bb59e8c76
Author: Sushant Raikar <[email protected]>
AuthorDate: Fri Jun 27 14:18:13 2025 -0700
test(integration): refactor PolarisRestCatalogIntegrationTest to run
against any cloud provider (#1934)
* Make Catalog Integration Test suite cloud native
---
LICENSE | 2 +-
.../test/PolarisRestCatalogAwsIntegrationTest.java | 49 +++++++++++++
.../PolarisRestCatalogAzureIntegrationTest.java | 45 ++++++++++++
.../PolarisRestCatalogFileIntegrationTest.java | 59 ++++++++++++++++
.../test/PolarisRestCatalogGcpIntegrationTest.java | 46 ++++++++++++
...java => PolarisRestCatalogIntegrationBase.java} | 82 +++++++++++-----------
.../src/main/resources/META-INF/LICENSE | 2 +-
runtime/service/README-quarkus.md | 24 +++++++
...CatalogIT.java => QuarkusRestCatalogAwsIT.java} | 4 +-
...talogIT.java => QuarkusRestCatalogAzureIT.java} | 4 +-
...atalogIT.java => QuarkusRestCatalogFileIT.java} | 4 +-
...CatalogIT.java => QuarkusRestCatalogGcpIT.java} | 4 +-
.../it/relational/jdbc/JdbcRestCatalogIT.java | 4 +-
... => QuarkusRestCatalogFileIntegrationTest.java} | 6 +-
.../QuarkusRestCatalogViewAwsIntegrationTest.java | 52 --------------
...QuarkusRestCatalogViewAzureIntegrationTest.java | 51 --------------
.../QuarkusRestCatalogViewGcpIntegrationTest.java | 50 -------------
17 files changed, 279 insertions(+), 209 deletions(-)
diff --git a/LICENSE b/LICENSE
index 93cc39a5c..4330ca154 100644
--- a/LICENSE
+++ b/LICENSE
@@ -217,7 +217,7 @@ This product includes code from Apache Iceberg.
* spec/iceberg-rest-catalog-open-api.yaml
* spec/polaris-catalog-apis/oauth-tokens-api.yaml
-*
integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
+*
integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
*
service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
*
service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/CatalogHandlerUtils.java
*
plugins/spark/v3.5/spark/src/main/java/org/apache/polaris/spark/PolarisRESTCatalog.java
diff --git
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogAwsIntegrationTest.java
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogAwsIntegrationTest.java
new file mode 100644
index 000000000..11abab685
--- /dev/null
+++
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogAwsIntegrationTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.it.test;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+import org.apache.polaris.core.admin.model.AwsStorageConfigInfo;
+import org.apache.polaris.core.admin.model.StorageConfigInfo;
+import org.assertj.core.util.Strings;
+
+/** Runs PolarisRestCatalogIntegrationBase test on AWS. */
+public class PolarisRestCatalogAwsIntegrationTest extends
PolarisRestCatalogIntegrationBase {
+ public static final String ROLE_ARN =
+ Optional.ofNullable(System.getenv("INTEGRATION_TEST_ROLE_ARN"))
+ .or(() ->
Optional.ofNullable(System.getenv("INTEGRATION_TEST_S3_ROLE_ARN")))
+ .orElse("arn:aws:iam::123456789012:role/my-role");
+ public static final String BASE_LOCATION =
System.getenv("INTEGRATION_TEST_S3_PATH");
+
+ @Override
+ protected StorageConfigInfo getStorageConfigInfo() {
+ return AwsStorageConfigInfo.builder()
+ .setRoleArn(ROLE_ARN)
+ .setStorageType(StorageConfigInfo.StorageTypeEnum.S3)
+ .setAllowedLocations(List.of(BASE_LOCATION))
+ .build();
+ }
+
+ @Override
+ protected boolean shouldSkip() {
+ return Stream.of(BASE_LOCATION, ROLE_ARN).anyMatch(Strings::isNullOrEmpty);
+ }
+}
diff --git
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogAzureIntegrationTest.java
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogAzureIntegrationTest.java
new file mode 100644
index 000000000..8453b5617
--- /dev/null
+++
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogAzureIntegrationTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.it.test;
+
+import java.util.List;
+import java.util.stream.Stream;
+import org.apache.polaris.core.admin.model.AzureStorageConfigInfo;
+import org.apache.polaris.core.admin.model.StorageConfigInfo;
+import org.assertj.core.util.Strings;
+
+/** Runs PolarisRestCatalogIntegrationBase test on Azure. */
+public class PolarisRestCatalogAzureIntegrationTest extends
PolarisRestCatalogIntegrationBase {
+ public static final String TENANT_ID =
System.getenv("INTEGRATION_TEST_AZURE_TENANT_ID");
+ public static final String BASE_LOCATION =
System.getenv("INTEGRATION_TEST_AZURE_PATH");
+
+ @Override
+ protected StorageConfigInfo getStorageConfigInfo() {
+ return AzureStorageConfigInfo.builder()
+ .setTenantId(TENANT_ID)
+ .setStorageType(StorageConfigInfo.StorageTypeEnum.AZURE)
+ .setAllowedLocations(List.of(BASE_LOCATION))
+ .build();
+ }
+
+ @Override
+ protected boolean shouldSkip() {
+ return Stream.of(BASE_LOCATION,
TENANT_ID).anyMatch(Strings::isNullOrEmpty);
+ }
+}
diff --git
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogFileIntegrationTest.java
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogFileIntegrationTest.java
new file mode 100644
index 000000000..3cd2face1
--- /dev/null
+++
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogFileIntegrationTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.it.test;
+
+import java.net.URI;
+import java.nio.file.Path;
+import java.util.List;
+import org.apache.polaris.core.admin.model.FileStorageConfigInfo;
+import org.apache.polaris.core.admin.model.StorageConfigInfo;
+import org.apache.polaris.service.it.env.IntegrationTestsHelper;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.io.TempDir;
+
+/** Runs PolarisRestCatalogIntegrationBase test on the local filesystem. */
+public class PolarisRestCatalogFileIntegrationTest extends
PolarisRestCatalogIntegrationBase {
+
+ public static String baseLocation;
+
+ @BeforeAll
+ static void setup(@TempDir Path tempDir) {
+ URI tempDirURI = IntegrationTestsHelper.getTemporaryDirectory(tempDir);
+ baseLocation = stripTrailingSlash(tempDirURI.toString());
+ }
+
+ @Override
+ protected StorageConfigInfo getStorageConfigInfo() {
+ return FileStorageConfigInfo.builder()
+ .setStorageType(StorageConfigInfo.StorageTypeEnum.FILE)
+ .setAllowedLocations(List.of(baseLocation, "file://"))
+ .build();
+ }
+
+ @Override
+ protected boolean shouldSkip() {
+ return false;
+ }
+
+ private static String stripTrailingSlash(String uri) {
+ return uri.endsWith("/") && uri.length() > "file:///".length()
+ ? uri.substring(0, uri.length() - 1)
+ : uri;
+ }
+}
diff --git
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogGcpIntegrationTest.java
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogGcpIntegrationTest.java
new file mode 100644
index 000000000..92dd96973
--- /dev/null
+++
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogGcpIntegrationTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.it.test;
+
+import java.util.List;
+import java.util.stream.Stream;
+import org.apache.polaris.core.admin.model.GcpStorageConfigInfo;
+import org.apache.polaris.core.admin.model.StorageConfigInfo;
+import org.assertj.core.util.Strings;
+
+/** Runs PolarisRestCatalogIntegrationBase test on GCP. */
+public class PolarisRestCatalogGcpIntegrationTest extends
PolarisRestCatalogIntegrationBase {
+ public static final String SERVICE_ACCOUNT =
+ System.getenv("INTEGRATION_TEST_GCS_SERVICE_ACCOUNT");
+ public static final String BASE_LOCATION =
System.getenv("INTEGRATION_TEST_GCS_PATH");
+
+ @Override
+ protected StorageConfigInfo getStorageConfigInfo() {
+ return GcpStorageConfigInfo.builder()
+ .setGcsServiceAccount(SERVICE_ACCOUNT)
+ .setStorageType(StorageConfigInfo.StorageTypeEnum.GCS)
+ .setAllowedLocations(List.of(BASE_LOCATION))
+ .build();
+ }
+
+ @Override
+ protected boolean shouldSkip() {
+ return Stream.of(BASE_LOCATION,
SERVICE_ACCOUNT).anyMatch(Strings::isNullOrEmpty);
+ }
+}
diff --git
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
similarity index 96%
rename from
integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
rename to
integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
index a999ab9fe..cd62cb1ff 100644
---
a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
+++
b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
@@ -35,7 +35,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.net.URI;
-import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -68,12 +67,10 @@ import org.apache.iceberg.rest.RESTUtil;
import org.apache.iceberg.rest.requests.CreateTableRequest;
import org.apache.iceberg.rest.responses.ErrorResponse;
import org.apache.iceberg.types.Types;
-import org.apache.polaris.core.admin.model.AwsStorageConfigInfo;
import org.apache.polaris.core.admin.model.Catalog;
import org.apache.polaris.core.admin.model.CatalogGrant;
import org.apache.polaris.core.admin.model.CatalogPrivilege;
import org.apache.polaris.core.admin.model.CatalogProperties;
-import org.apache.polaris.core.admin.model.FileStorageConfigInfo;
import org.apache.polaris.core.admin.model.GrantResource;
import org.apache.polaris.core.admin.model.GrantResources;
import org.apache.polaris.core.admin.model.NamespaceGrant;
@@ -92,7 +89,6 @@ import org.apache.polaris.service.it.env.CatalogApi;
import org.apache.polaris.service.it.env.ClientCredentials;
import org.apache.polaris.service.it.env.GenericTableApi;
import org.apache.polaris.service.it.env.IcebergHelper;
-import org.apache.polaris.service.it.env.IntegrationTestsHelper;
import org.apache.polaris.service.it.env.ManagementApi;
import org.apache.polaris.service.it.env.PolarisApiEndpoints;
import org.apache.polaris.service.it.env.PolarisClient;
@@ -110,7 +106,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.jupiter.api.io.TempDir;
/**
* Import the full core Iceberg catalog tests by hitting the REST service via
the RESTCatalog
@@ -124,15 +119,15 @@ import org.junit.jupiter.api.io.TempDir;
* CODE_COPIED_TO_POLARIS From Apache Iceberg Version: 1.7.1
*/
@ExtendWith(PolarisIntegrationTestExtension.class)
-public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog> {
- private static final String TEST_ROLE_ARN =
- Optional.ofNullable(System.getenv("INTEGRATION_TEST_ROLE_ARN"))
- .orElse("arn:aws:iam::123456789012:role/my-role");
-
- private static URI s3BucketBase;
- private static URI externalCatalogBase;
-
+public abstract class PolarisRestCatalogIntegrationBase extends
CatalogTests<RESTCatalog> {
protected static final String VIEW_QUERY = "select * from ns1.layer1_table";
+ // subpath shouldn't start with a slash, as it is appended to the base URI
+ private static final String CATALOG_LOCATION_SUBPATH =
+
Optional.ofNullable(System.getenv("INTEGRATION_TEST_CATALOG_LOCATION_SUBPATH"))
+ .orElse("path/to/data");
+ private static final String EXTERNAL_CATALOG_LOCATION_SUBPATH =
+
Optional.ofNullable(System.getenv("INTEGRATION_TEST_EXTERNAL_CATALOG_LOCATION_SUBPATH"))
+ .orElse("external-catalog");
private static ClientCredentials adminCredentials;
private static PolarisApiEndpoints endpoints;
private static PolarisClient client;
@@ -144,9 +139,8 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
private RESTCatalog restCatalog;
private String currentCatalogName;
private Map<String, String> restCatalogConfig;
-
- private final String catalogBaseLocation =
- s3BucketBase + "/" + System.getenv("USER") + "/path/to/data";
+ private URI externalCatalogBase;
+ private String catalogBaseLocation;
private static final Map<String, String> DEFAULT_REST_CATALOG_CONFIG =
Map.of(
@@ -181,16 +175,26 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
String[] value() default {};
}
+ /**
+ * Get the storage configuration information for the catalog.
+ *
+ * @return StorageConfigInfo instance containing the storage configuration
+ */
+ protected abstract StorageConfigInfo getStorageConfigInfo();
+
+ /**
+ * Determine whether the test should be skipped based on the environment or
configuration.
+ *
+ * @return true if the test should be skipped, false otherwise
+ */
+ protected abstract boolean shouldSkip();
+
@BeforeAll
- static void setup(
- PolarisApiEndpoints apiEndpoints, ClientCredentials credentials,
@TempDir Path tempDir) {
+ static void setup(PolarisApiEndpoints apiEndpoints, ClientCredentials
credentials) {
adminCredentials = credentials;
endpoints = apiEndpoints;
client = polarisClient(endpoints);
managementApi = client.managementApi(credentials);
- URI testRootUri = IntegrationTestsHelper.getTemporaryDirectory(tempDir);
- s3BucketBase = testRootUri.resolve("my-bucket");
- externalCatalogBase = testRootUri.resolve("external-catalog");
}
static {
@@ -204,6 +208,7 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
@BeforeEach
public void before(TestInfo testInfo) {
+ Assumptions.assumeThat(shouldSkip()).isFalse();
String principalName = client.newEntityName("snowman-rest");
String principalRoleName = client.newEntityName("rest-admin");
principalCredentials =
managementApi.createPrincipalWithRole(principalName, principalRoleName);
@@ -213,14 +218,13 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
Method method = testInfo.getTestMethod().orElseThrow();
currentCatalogName = client.newEntityName(method.getName());
- AwsStorageConfigInfo awsConfigModel =
- AwsStorageConfigInfo.builder()
- .setRoleArn(TEST_ROLE_ARN)
- .setExternalId("externalId")
- .setUserArn("a:user:arn")
- .setStorageType(StorageConfigInfo.StorageTypeEnum.S3)
- .setAllowedLocations(List.of("s3://my-old-bucket/path/to/data"))
- .build();
+ StorageConfigInfo storageConfig = getStorageConfigInfo();
+ URI testRuntimeURI =
URI.create(storageConfig.getAllowedLocations().getFirst());
+ catalogBaseLocation = testRuntimeURI + "/" + CATALOG_LOCATION_SUBPATH;
+ externalCatalogBase =
+ URI.create(
+ testRuntimeURI + "/" + EXTERNAL_CATALOG_LOCATION_SUBPATH + "/" +
method.getName());
+
Optional<CatalogConfig> catalogConfig =
Optional.ofNullable(method.getAnnotation(CatalogConfig.class));
@@ -232,7 +236,7 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
}
catalogPropsBuilder.addProperty(
FeatureConfiguration.DROP_WITH_PURGE_ENABLED.catalogConfig(), "true");
- if (!s3BucketBase.getScheme().equals("file")) {
+ if (!testRuntimeURI.getScheme().equals("file")) {
catalogPropsBuilder.addProperty(
CatalogEntity.REPLACE_NEW_LOCATION_PREFIX_WITH_CATALOG_DEFAULT_KEY,
"file:");
}
@@ -241,11 +245,7 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
.setType(catalogConfig.map(CatalogConfig::value).orElse(Catalog.TypeEnum.INTERNAL))
.setName(currentCatalogName)
.setProperties(catalogPropsBuilder.build())
- .setStorageConfigInfo(
- s3BucketBase.getScheme().equals("file")
- ? new FileStorageConfigInfo(
- StorageConfigInfo.StorageTypeEnum.FILE,
List.of("file://"))
- : awsConfigModel)
+ .setStorageConfigInfo(storageConfig)
.build();
managementApi.createCatalog(principalRoleName, catalog);
@@ -701,12 +701,12 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
TableMetadata.newTableMetadata(
new Schema(List.of(Types.NestedField.required(1, "col1", new
Types.StringType()))),
PartitionSpec.unpartitioned(),
- "file:///tmp/ns1/my_table",
+ externalCatalogBase + "/ns1/my_table",
Map.of());
try (ResolvingFileIO resolvingFileIO = new ResolvingFileIO()) {
resolvingFileIO.initialize(Map.of());
resolvingFileIO.setConf(new Configuration());
- String fileLocation =
"file:///tmp/ns1/my_table/metadata/v1.metadata.json";
+ String fileLocation = externalCatalogBase +
"/ns1/my_table/metadata/v1.metadata.json";
TableMetadataParser.write(tableMetadata,
resolvingFileIO.newOutputFile(fileLocation));
restCatalog.registerTable(TableIdentifier.of(ns1, "my_table_etagged"),
fileLocation);
Invocation invocation =
@@ -745,12 +745,12 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
TableMetadata.newTableMetadata(
new Schema(List.of(Types.NestedField.required(1, "col1", new
Types.StringType()))),
PartitionSpec.unpartitioned(),
- "file:///tmp/ns1/my_table",
+ externalCatalogBase + "/ns1/my_table",
Map.of());
try (ResolvingFileIO resolvingFileIO = new ResolvingFileIO()) {
resolvingFileIO.initialize(Map.of());
resolvingFileIO.setConf(new Configuration());
- String fileLocation =
"file:///tmp/ns1/my_table/metadata/v1.metadata.json";
+ String fileLocation = externalCatalogBase +
"/ns1/my_table/metadata/v1.metadata.json";
TableMetadataParser.write(tableMetadata,
resolvingFileIO.newOutputFile(fileLocation));
Invocation registerInvocation =
@@ -788,12 +788,12 @@ public class PolarisRestCatalogIntegrationTest extends
CatalogTests<RESTCatalog>
TableMetadata.newTableMetadata(
new Schema(List.of(Types.NestedField.required(1, "col1", new
Types.StringType()))),
PartitionSpec.unpartitioned(),
- "file:///tmp/ns1/my_table",
+ externalCatalogBase + "/ns1/my_table",
Map.of());
try (ResolvingFileIO resolvingFileIO = new ResolvingFileIO()) {
resolvingFileIO.initialize(Map.of());
resolvingFileIO.setConf(new Configuration());
- String fileLocation =
"file:///tmp/ns1/my_table/metadata/v1.metadata.json";
+ String fileLocation = externalCatalogBase +
"/ns1/my_table/metadata/v1.metadata.json";
TableMetadataParser.write(tableMetadata,
resolvingFileIO.newOutputFile(fileLocation));
Invocation createInvocation =
diff --git a/integration-tests/src/main/resources/META-INF/LICENSE
b/integration-tests/src/main/resources/META-INF/LICENSE
index be81989a6..30ac2d34f 100644
--- a/integration-tests/src/main/resources/META-INF/LICENSE
+++ b/integration-tests/src/main/resources/META-INF/LICENSE
@@ -204,7 +204,7 @@
This product includes code from Apache Iceberg.
-*
integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
+*
integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationBase.java
Copyright: Copyright 2017-2025 The Apache Software Foundation
Home page: https://iceberg.apache.org
diff --git a/runtime/service/README-quarkus.md
b/runtime/service/README-quarkus.md
index cf303aa10..0a42c319d 100644
--- a/runtime/service/README-quarkus.md
+++ b/runtime/service/README-quarkus.md
@@ -79,6 +79,30 @@ configuration property).
You can find more details here: https://quarkus.io/guides/config
+# Integration tests
+Integration tests from the :polaris-tests module can be run against a local
Polaris Quarkus instance
+for each supported cloud storage. Set the appropriate environment variables
for your target cloud,
+then run the tests as shown below.
+
+For S3:
+```shell
+export INTEGRATION_TEST_S3_PATH="s3://bucket/subpath"
+export INTEGRATION_TEST_S3_ROLE_ARN="your-role-arn"
+./gradlew :polaris-runtime-service:intTest
+```
+For Azure:
+```shell
+export INTEGRATION_TEST_AZURE_PATH="abfss://bucket/subpath"
+export INTEGRATION_TEST_AZURE_TENANT_ID="your-tenant-id"
+./gradlew :polaris-runtime-service:intTest
+```
+For GCS:
+```shell
+export INTEGRATION_TEST_GCS_PATH="gs://bucket/subpath"
+export INTEGRATION_TEST_GCS_SERVICE_ACCOUNT="your-service-account"
+./gradlew :polaris-runtime-service:intTest
+```
+
# TODO
* Modify `CallContext` and remove all usages of `ThreadLocal`, replace with
proper context propagation.
diff --git
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogAwsIT.java
similarity index 84%
copy from
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
copy to
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogAwsIT.java
index 5d214d188..b0b423ad3 100644
---
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
+++
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogAwsIT.java
@@ -19,7 +19,7 @@
package org.apache.polaris.service.quarkus.it;
import io.quarkus.test.junit.QuarkusIntegrationTest;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationTest;
+import org.apache.polaris.service.it.test.PolarisRestCatalogAwsIntegrationTest;
@QuarkusIntegrationTest
-public class QuarkusRestCatalogIT extends PolarisRestCatalogIntegrationTest {}
+public class QuarkusRestCatalogAwsIT extends
PolarisRestCatalogAwsIntegrationTest {}
diff --git
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogAzureIT.java
similarity index 84%
copy from
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
copy to
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogAzureIT.java
index 5d214d188..6a829122d 100644
---
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
+++
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogAzureIT.java
@@ -19,7 +19,7 @@
package org.apache.polaris.service.quarkus.it;
import io.quarkus.test.junit.QuarkusIntegrationTest;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationTest;
+import
org.apache.polaris.service.it.test.PolarisRestCatalogAzureIntegrationTest;
@QuarkusIntegrationTest
-public class QuarkusRestCatalogIT extends PolarisRestCatalogIntegrationTest {}
+public class QuarkusRestCatalogAzureIT extends
PolarisRestCatalogAzureIntegrationTest {}
diff --git
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogFileIT.java
similarity index 84%
copy from
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
copy to
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogFileIT.java
index 5d214d188..cd1905a0a 100644
---
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
+++
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogFileIT.java
@@ -19,7 +19,7 @@
package org.apache.polaris.service.quarkus.it;
import io.quarkus.test.junit.QuarkusIntegrationTest;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationTest;
+import
org.apache.polaris.service.it.test.PolarisRestCatalogFileIntegrationTest;
@QuarkusIntegrationTest
-public class QuarkusRestCatalogIT extends PolarisRestCatalogIntegrationTest {}
+public class QuarkusRestCatalogFileIT extends
PolarisRestCatalogFileIntegrationTest {}
diff --git
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogGcpIT.java
similarity index 84%
rename from
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
rename to
runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogGcpIT.java
index 5d214d188..ceccad902 100644
---
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIT.java
+++
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogGcpIT.java
@@ -19,7 +19,7 @@
package org.apache.polaris.service.quarkus.it;
import io.quarkus.test.junit.QuarkusIntegrationTest;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationTest;
+import org.apache.polaris.service.it.test.PolarisRestCatalogGcpIntegrationTest;
@QuarkusIntegrationTest
-public class QuarkusRestCatalogIT extends PolarisRestCatalogIntegrationTest {}
+public class QuarkusRestCatalogGcpIT extends
PolarisRestCatalogGcpIntegrationTest {}
diff --git
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/relational/jdbc/JdbcRestCatalogIT.java
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/relational/jdbc/JdbcRestCatalogIT.java
index 59b35fe91..c7192437f 100644
---
a/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/relational/jdbc/JdbcRestCatalogIT.java
+++
b/runtime/service/src/intTest/java/org/apache/polaris/service/quarkus/it/relational/jdbc/JdbcRestCatalogIT.java
@@ -20,9 +20,9 @@ package org.apache.polaris.service.quarkus.it.relational.jdbc;
import io.quarkus.test.junit.QuarkusIntegrationTest;
import io.quarkus.test.junit.TestProfile;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationTest;
+import
org.apache.polaris.service.it.test.PolarisRestCatalogFileIntegrationTest;
import org.apache.polaris.test.commons.RelationalJdbcProfile;
@TestProfile(RelationalJdbcProfile.class)
@QuarkusIntegrationTest
-public class JdbcRestCatalogIT extends PolarisRestCatalogIntegrationTest {}
+public class JdbcRestCatalogIT extends PolarisRestCatalogFileIntegrationTest {}
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIntegrationTest.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogFileIntegrationTest.java
similarity index 86%
rename from
runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIntegrationTest.java
rename to
runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogFileIntegrationTest.java
index b2ddd79b0..126ab23f8 100644
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogIntegrationTest.java
+++
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogFileIntegrationTest.java
@@ -22,11 +22,11 @@ import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.QuarkusTestProfile;
import io.quarkus.test.junit.TestProfile;
import java.util.Map;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationTest;
+import
org.apache.polaris.service.it.test.PolarisRestCatalogFileIntegrationTest;
@QuarkusTest
-@TestProfile(QuarkusRestCatalogIntegrationTest.Profile.class)
-public class QuarkusRestCatalogIntegrationTest extends
PolarisRestCatalogIntegrationTest {
+@TestProfile(QuarkusRestCatalogFileIntegrationTest.Profile.class)
+public class QuarkusRestCatalogFileIntegrationTest extends
PolarisRestCatalogFileIntegrationTest {
public static class Profile implements QuarkusTestProfile {
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewAwsIntegrationTest.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewAwsIntegrationTest.java
deleted file mode 100644
index 16380c24d..000000000
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewAwsIntegrationTest.java
+++ /dev/null
@@ -1,52 +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.quarkus.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.quarkus.test.junit.QuarkusTestProfile;
-import io.quarkus.test.junit.TestProfile;
-import java.lang.reflect.Field;
-import java.nio.file.Path;
-import java.util.Map;
-import org.apache.iceberg.view.ViewCatalogTests;
-import
org.apache.polaris.service.it.test.PolarisRestCatalogViewAwsIntegrationTest;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.io.TempDir;
-
-@QuarkusTest
-@TestProfile(QuarkusRestCatalogViewAwsIntegrationTest.Profile.class)
-public class QuarkusRestCatalogViewAwsIntegrationTest
- extends PolarisRestCatalogViewAwsIntegrationTest {
-
- public static class Profile implements QuarkusTestProfile {
-
- @Override
- public Map<String, String> getConfigOverrides() {
- return Map.of("polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
"[\"S3\"]");
- }
- }
-
- @BeforeEach
- public void setUpTempDir(@TempDir Path tempDir) throws Exception {
- // see https://github.com/quarkusio/quarkus/issues/13261
- Field field = ViewCatalogTests.class.getDeclaredField("tempDir");
- field.setAccessible(true);
- field.set(this, tempDir);
- }
-}
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewAzureIntegrationTest.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewAzureIntegrationTest.java
deleted file mode 100644
index 49ff842b7..000000000
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewAzureIntegrationTest.java
+++ /dev/null
@@ -1,51 +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.quarkus.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.quarkus.test.junit.QuarkusTestProfile;
-import io.quarkus.test.junit.TestProfile;
-import java.lang.reflect.Field;
-import java.nio.file.Path;
-import java.util.Map;
-import org.apache.iceberg.view.ViewCatalogTests;
-import
org.apache.polaris.service.it.test.PolarisRestCatalogViewAzureIntegrationTest;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.io.TempDir;
-
-@QuarkusTest
-@TestProfile(QuarkusRestCatalogViewAzureIntegrationTest.Profile.class)
-public class QuarkusRestCatalogViewAzureIntegrationTest
- extends PolarisRestCatalogViewAzureIntegrationTest {
- public static class Profile implements QuarkusTestProfile {
-
- @Override
- public Map<String, String> getConfigOverrides() {
- return Map.of("polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
"[\"AZURE\"]");
- }
- }
-
- @BeforeEach
- public void setUpTempDir(@TempDir Path tempDir) throws Exception {
- // see https://github.com/quarkusio/quarkus/issues/13261
- Field field = ViewCatalogTests.class.getDeclaredField("tempDir");
- field.setAccessible(true);
- field.set(this, tempDir);
- }
-}
diff --git
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewGcpIntegrationTest.java
b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewGcpIntegrationTest.java
deleted file mode 100644
index ef04d745e..000000000
---
a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/it/QuarkusRestCatalogViewGcpIntegrationTest.java
+++ /dev/null
@@ -1,50 +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.quarkus.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.quarkus.test.junit.QuarkusTestProfile;
-import java.lang.reflect.Field;
-import java.nio.file.Path;
-import java.util.Map;
-import org.apache.iceberg.view.ViewCatalogTests;
-import
org.apache.polaris.service.it.test.PolarisRestCatalogViewGcpIntegrationTest;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.io.TempDir;
-
-@QuarkusTest
-public class QuarkusRestCatalogViewGcpIntegrationTest
- extends PolarisRestCatalogViewGcpIntegrationTest {
-
- public static class Profile implements QuarkusTestProfile {
-
- @Override
- public Map<String, String> getConfigOverrides() {
- return Map.of("polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
"[\"GCS\"]");
- }
- }
-
- @BeforeEach
- public void setUpTempDir(@TempDir Path tempDir) throws Exception {
- // see https://github.com/quarkusio/quarkus/issues/13261
- Field field = ViewCatalogTests.class.getDeclaredField("tempDir");
- field.setAccessible(true);
- field.set(this, tempDir);
- }
-}