You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polaris.apache.org by sn...@apache.org on 2026/08/20 09:30:10 UTC

(polaris) branch main updated: Remove MinIO based tests and minio-testcontainer (#5192)

This is an automated email from the ASF dual-hosted git repository.

snazy 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 f0a1907718 Remove MinIO based tests and minio-testcontainer (#5192)
f0a1907718 is described below

commit f0a1907718a826586b0481e05bb28c9b6ee11d37
Author: Robert Stupp <sn...@snazy.de>
AuthorDate: Thu Aug 20 11:30:05 2026 +0200

    Remove MinIO based tests and minio-testcontainer (#5192)
    
    Minio is no longer maintained. The independently added Floci based tests exercise the same test cases, so removing Minio based tests and the related testcontainer appears appropriate.
---
 LICENSE                                            |   4 -
 README.md                                          |   2 +-
 bom/build.gradle.kts                               |   1 -
 gradle/projects.main.properties                    |   1 -
 integration-tests/build.gradle.kts                 |   1 -
 runtime/service/build.gradle.kts                   |   1 -
 .../service/it/PolarisRestCatalogMinIOIT.java      |  94 ----
 .../service/it/RestCatalogMinIOSpecialIT.java      | 594 ---------------------
 .../minio-testcontainer/build.gradle.kts           |  42 --
 .../java/org/apache/polaris/test/minio/Minio.java  |  46 --
 .../org/apache/polaris/test/minio/MinioAccess.java |  68 ---
 .../test/minio/MinioConditionExtension.java        |  46 --
 .../apache/polaris/test/minio/MinioContainer.java  | 276 ----------
 .../apache/polaris/test/minio/MinioExtension.java  | 120 -----
 .../polaris/test/minio/MinioTestResource.java      |  65 ---
 .../polaris/test/minio/Dockerfile-minio-version    |  22 -
 16 files changed, 1 insertion(+), 1382 deletions(-)

diff --git a/LICENSE b/LICENSE
index f876e29e58..239dc6dadb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -326,10 +326,6 @@ This product includes code from Project Nessie.
 * tools/config-docs/generator/src/test/java/tests/smallrye/SomeEnum.java
 * tools/config-docs/generator/src/test/java/tests/smallrye/VeryNested.java
 * tools/container-spec-helper/src/main/java/org/apache/polaris/containerspec/ContainerSpecHelper.java
-* tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/Minio.java
-* tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioAccess.java
-* tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioContainer.java
-* tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioExtension.java
 * tools/testcontainers/rustfs-testcontainer/src/main/java/org/apache/polaris/test/rustfs/Rustfs.java
 * tools/testcontainers/rustfs-testcontainer/src/main/java/org/apache/polaris/test/rustfs/RustfsAccess.java
 * tools/testcontainers/rustfs-testcontainer/src/main/java/org/apache/polaris/test/rustfs/RustfsContainer.java
diff --git a/README.md b/README.md
index 2adc791807..d4fd14f3d7 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ The repository is organized into the following groups of Gradle modules. Each le
   - `polaris-bom`, `polaris-build-logic`, `polaris-version` - BOM, shared build logic, versioning
   - `polaris-immutables`, `polaris-misc-types`, `polaris-container-spec-helper` - shared utilities
   - `polaris-floci-aws-testcontainer`, `polaris-floci-az-testcontainer`, `polaris-floci-gcp-testcontainer`,
-    `polaris-minio-testcontainer`, `polaris-rustfs-testcontainer`, `polaris-hms-testcontainer` - test containers
+    `polaris-rustfs-testcontainer`, `polaris-hms-testcontainer` - test containers
   - `polaris-config-docs-{annotations,generator,site}` - reference-doc generation
   - `aggregated-license-report` - aggregated license report
 - **Tests**
diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts
index ee9b2a4bda..05808f668b 100644
--- a/bom/build.gradle.kts
+++ b/bom/build.gradle.kts
@@ -36,7 +36,6 @@ dependencies {
     api(project(":polaris-floci-az-testcontainer"))
     api(project(":polaris-floci-gcp-testcontainer"))
     api(project(":polaris-keycloak-testcontainer"))
-    api(project(":polaris-minio-testcontainer"))
     api(project(":polaris-rustfs-testcontainer"))
     api(project(":polaris-immutables"))
     api(project(":polaris-misc-types"))
diff --git a/gradle/projects.main.properties b/gradle/projects.main.properties
index f691d5782a..8d62143cbc 100644
--- a/gradle/projects.main.properties
+++ b/gradle/projects.main.properties
@@ -41,7 +41,6 @@ polaris-floci-aws-testcontainer=tools/testcontainers/floci-aws
 polaris-floci-az-testcontainer=tools/testcontainers/floci-az
 polaris-floci-gcp-testcontainer=tools/testcontainers/floci-gcp
 polaris-keycloak-testcontainer=tools/testcontainers/keycloak
-polaris-minio-testcontainer=tools/testcontainers/minio-testcontainer
 polaris-rustfs-testcontainer=tools/testcontainers/rustfs-testcontainer
 polaris-hms-testcontainer=tools/testcontainers/hms-testcontainer
 polaris-version=tools/version
diff --git a/integration-tests/build.gradle.kts b/integration-tests/build.gradle.kts
index 7d8e2c3d89..451884c81d 100644
--- a/integration-tests/build.gradle.kts
+++ b/integration-tests/build.gradle.kts
@@ -81,7 +81,6 @@ dependencies {
   implementation(libs.hawkular.agent.prometheus.scraper)
   implementation(libs.s3mock.testcontainers)
   implementation(project(":polaris-runtime-test-common"))
-  implementation(project(":polaris-minio-testcontainer"))
   implementation(project(":polaris-rustfs-testcontainer"))
   implementation(project(":polaris-hms-testcontainer"))
 }
diff --git a/runtime/service/build.gradle.kts b/runtime/service/build.gradle.kts
index e85068a982..f9d588399e 100644
--- a/runtime/service/build.gradle.kts
+++ b/runtime/service/build.gradle.kts
@@ -134,7 +134,6 @@ dependencies {
   testImplementation(project(":polaris-api-management-model"))
   testImplementation(project(":polaris-relational-jdbc"))
 
-  testImplementation(project(":polaris-minio-testcontainer"))
   testImplementation(project(":polaris-rustfs-testcontainer"))
 
   testImplementation("org.apache.iceberg:iceberg-api:${libs.versions.iceberg.get()}:tests")
diff --git a/runtime/service/src/intTest/java/org/apache/polaris/service/it/PolarisRestCatalogMinIOIT.java b/runtime/service/src/intTest/java/org/apache/polaris/service/it/PolarisRestCatalogMinIOIT.java
deleted file mode 100644
index 50d7b8e811..0000000000
--- a/runtime/service/src/intTest/java/org/apache/polaris/service/it/PolarisRestCatalogMinIOIT.java
+++ /dev/null
@@ -1,94 +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.it;
-
-import static org.apache.polaris.test.commons.MinioRustProfile.ACCESS_KEY;
-import static org.apache.polaris.test.commons.MinioRustProfile.SECRET_KEY;
-
-import com.google.common.collect.ImmutableMap;
-import io.quarkus.test.common.QuarkusTestResource;
-import io.quarkus.test.common.ResourceArg;
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-import io.quarkus.test.junit.TestProfile;
-import java.util.List;
-import java.util.Map;
-import org.apache.iceberg.aws.s3.S3FileIOProperties;
-import org.apache.polaris.core.admin.model.AwsStorageConfigInfo;
-import org.apache.polaris.core.admin.model.StorageConfigInfo;
-import org.apache.polaris.service.it.env.RestCatalogConfig;
-import org.apache.polaris.service.it.ext.PolarisIntegrationTestExtension;
-import org.apache.polaris.service.it.test.PolarisRestCatalogIntegrationBase;
-import org.apache.polaris.test.commons.MinioRustProfile;
-import org.apache.polaris.test.minio.Minio;
-import org.apache.polaris.test.minio.MinioAccess;
-import org.apache.polaris.test.minio.MinioConditionExtension;
-import org.apache.polaris.test.minio.MinioTestResource;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-@QuarkusIntegrationTest
-@TestProfile(MinioRustProfile.class)
-@QuarkusTestResource(
-    value = MinioTestResource.class,
-    initArgs = {
-      @ResourceArg(name = "accessKey", value = ACCESS_KEY),
-      @ResourceArg(name = "secretKey", value = SECRET_KEY)
-    })
-@ExtendWith(MinioConditionExtension.class)
-@ExtendWith(PolarisIntegrationTestExtension.class)
-@RestCatalogConfig({"header.X-Iceberg-Access-Delegation", "vended-credentials"})
-public class PolarisRestCatalogMinIOIT extends PolarisRestCatalogIntegrationBase {
-
-  protected static final String BUCKET_URI_PREFIX = "/minio-test-polaris";
-
-  @Minio static MinioAccess minioAccess;
-
-  private static Map<String, String> s3Properties;
-
-  @BeforeEach
-  void setup() {
-    s3Properties =
-        Map.of(
-            S3FileIOProperties.ENDPOINT,
-            minioAccess.s3endpoint(),
-            S3FileIOProperties.PATH_STYLE_ACCESS,
-            "true",
-            S3FileIOProperties.ACCESS_KEY_ID,
-            ACCESS_KEY,
-            S3FileIOProperties.SECRET_ACCESS_KEY,
-            SECRET_KEY);
-  }
-
-  @Override
-  protected ImmutableMap.Builder<String, String> clientFileIOProperties() {
-    return super.clientFileIOProperties().putAll(s3Properties);
-  }
-
-  @Override
-  protected StorageConfigInfo getStorageConfigInfo() {
-    AwsStorageConfigInfo.Builder storageConfig =
-        AwsStorageConfigInfo.builder()
-            .setStorageType(StorageConfigInfo.StorageTypeEnum.S3)
-            .setPathStyleAccess(true)
-            .setEndpoint(minioAccess.s3endpoint())
-            .setAllowedLocations(List.of(minioAccess.s3BucketUri(BUCKET_URI_PREFIX).toString()));
-
-    return storageConfig.build();
-  }
-}
diff --git a/runtime/service/src/intTest/java/org/apache/polaris/service/it/RestCatalogMinIOSpecialIT.java b/runtime/service/src/intTest/java/org/apache/polaris/service/it/RestCatalogMinIOSpecialIT.java
deleted file mode 100644
index 7dda278b3a..0000000000
--- a/runtime/service/src/intTest/java/org/apache/polaris/service/it/RestCatalogMinIOSpecialIT.java
+++ /dev/null
@@ -1,594 +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.it;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.iceberg.CatalogProperties.TABLE_DEFAULT_PREFIX;
-import static org.apache.iceberg.aws.AwsClientProperties.REFRESH_CREDENTIALS_ENDPOINT;
-import static org.apache.iceberg.aws.s3.S3FileIOProperties.ACCESS_KEY_ID;
-import static org.apache.iceberg.aws.s3.S3FileIOProperties.ENDPOINT;
-import static org.apache.iceberg.aws.s3.S3FileIOProperties.SECRET_ACCESS_KEY;
-import static org.apache.iceberg.types.Types.NestedField.optional;
-import static org.apache.iceberg.types.Types.NestedField.required;
-import static org.apache.polaris.core.storage.StorageAccessProperty.AWS_KEY_ID;
-import static org.apache.polaris.core.storage.StorageAccessProperty.AWS_SECRET_KEY;
-import static org.apache.polaris.service.catalog.AccessDelegationMode.VENDED_CREDENTIALS;
-import static org.apache.polaris.service.it.env.PolarisClient.polarisClient;
-import static org.apache.polaris.test.commons.MinioRustProfile.ACCESS_KEY;
-import static org.apache.polaris.test.commons.MinioRustProfile.SECRET_KEY;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-import com.google.common.collect.ImmutableMap;
-import io.quarkus.test.common.QuarkusTestResource;
-import io.quarkus.test.common.ResourceArg;
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-import io.quarkus.test.junit.TestProfile;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import org.apache.iceberg.DataFile;
-import org.apache.iceberg.DataFiles;
-import org.apache.iceberg.FileFormat;
-import org.apache.iceberg.HasTableOperations;
-import org.apache.iceberg.PartitionSpec;
-import org.apache.iceberg.Schema;
-import org.apache.iceberg.Table;
-import org.apache.iceberg.TableOperations;
-import org.apache.iceberg.catalog.TableIdentifier;
-import org.apache.iceberg.io.FileIO;
-import org.apache.iceberg.io.OutputFile;
-import org.apache.iceberg.io.PositionOutputStream;
-import org.apache.iceberg.rest.RESTCatalog;
-import org.apache.iceberg.rest.auth.OAuth2Properties;
-import org.apache.iceberg.rest.responses.LoadTableResponse;
-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.CatalogProperties;
-import org.apache.polaris.core.admin.model.PolarisCatalog;
-import org.apache.polaris.core.admin.model.PrincipalWithCredentials;
-import org.apache.polaris.core.admin.model.StorageConfigInfo;
-import org.apache.polaris.service.catalog.AccessDelegationMode;
-import org.apache.polaris.service.it.env.CatalogApi;
-import org.apache.polaris.service.it.env.ClientCredentials;
-import org.apache.polaris.service.it.env.ManagementApi;
-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.test.commons.MinioRustProfile;
-import org.apache.polaris.test.minio.Minio;
-import org.apache.polaris.test.minio.MinioAccess;
-import org.apache.polaris.test.minio.MinioConditionExtension;
-import org.apache.polaris.test.minio.MinioTestResource;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInfo;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.CsvSource;
-import org.junit.jupiter.params.provider.ValueSource;
-import software.amazon.awssdk.services.s3.S3Client;
-import software.amazon.awssdk.services.s3.model.GetObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-
-/**
- * These tests complement {@link PolarisRestCatalogMinIOIT} to validate client-side access to MinIO
- * storage via {@code FileIO} instances configured from catalog's {@code loadTable} responses with
- * some S3-specific options.
- */
-@QuarkusIntegrationTest
-@TestProfile(MinioRustProfile.class)
-@QuarkusTestResource(
-    value = MinioTestResource.class,
-    initArgs = {
-      @ResourceArg(name = "accessKey", value = ACCESS_KEY),
-      @ResourceArg(name = "secretKey", value = SECRET_KEY)
-    })
-@ExtendWith(MinioConditionExtension.class)
-@ExtendWith(PolarisIntegrationTestExtension.class)
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class RestCatalogMinIOSpecialIT {
-
-  private static final String BUCKET_URI_PREFIX = "/minio-test";
-  private static final String TEST_REGION = "us-west-2";
-  private static final String TEST_ROLE_ARN = "arn:aws:iam::000000000000:role/polaris-access-role";
-  private static String adminToken;
-
-  private static final Schema SCHEMA =
-      new Schema(
-          required(1, "id", Types.IntegerType.get(), "doc"),
-          optional(2, "data", Types.StringType.get()));
-
-  @Minio static MinioAccess minioAccess;
-
-  private static PolarisApiEndpoints endpoints;
-  private static PolarisClient client;
-  private static ManagementApi managementApi;
-  private static URI storageBase;
-  private static String endpoint;
-  private static S3Client s3Client;
-
-  private CatalogApi catalogApi;
-  private String principalRoleName;
-  private PrincipalWithCredentials principalCredentials;
-  private String catalogName;
-
-  @BeforeAll
-  void setup(PolarisApiEndpoints apiEndpoints, ClientCredentials credentials) {
-    endpoints = apiEndpoints;
-    s3Client = minioAccess.s3Client();
-    client = polarisClient(endpoints);
-    adminToken = client.obtainToken(credentials);
-    managementApi = client.managementApi(adminToken);
-    storageBase = minioAccess.s3BucketUri(BUCKET_URI_PREFIX);
-    endpoint = minioAccess.s3endpoint();
-  }
-
-  @AfterAll
-  void close() throws Exception {
-    client.close();
-  }
-
-  @BeforeEach
-  public void before(TestInfo testInfo) {
-    String principalName = client.newEntityName("test-user");
-    principalRoleName = client.newEntityName("test-admin");
-    principalCredentials = managementApi.createPrincipalWithRole(principalName, principalRoleName);
-
-    String principalToken = client.obtainToken(principalCredentials);
-    catalogApi = client.catalogApi(principalToken);
-
-    catalogName = client.newEntityName(testInfo.getTestMethod().orElseThrow().getName());
-  }
-
-  private RESTCatalog createCatalog(
-      Optional<String> endpoint,
-      Optional<String> stsEndpoint,
-      boolean pathStyleAccess,
-      Optional<AccessDelegationMode> delegationMode,
-      boolean stsEnabled) {
-    return createCatalog(
-        endpoint,
-        stsEndpoint,
-        pathStyleAccess,
-        Optional.empty(),
-        delegationMode,
-        stsEnabled,
-        Optional.empty(),
-        Optional.empty(),
-        Optional.empty());
-  }
-
-  private RESTCatalog createCatalog(
-      Optional<String> endpoint,
-      Optional<String> stsEndpoint,
-      boolean pathStyleAccess,
-      Optional<String> endpointInternal,
-      Optional<AccessDelegationMode> delegationMode,
-      boolean stsEnabled) {
-    return createCatalog(
-        endpoint,
-        stsEndpoint,
-        pathStyleAccess,
-        endpointInternal,
-        delegationMode,
-        stsEnabled,
-        Optional.empty(),
-        Optional.empty(),
-        Optional.empty());
-  }
-
-  private RESTCatalog createCatalog(
-      Optional<String> endpoint,
-      Optional<String> stsEndpoint,
-      boolean pathStyleAccess,
-      Optional<String> endpointInternal,
-      Optional<AccessDelegationMode> delegationMode,
-      boolean stsEnabled,
-      Optional<String> region,
-      Optional<String> roleArn,
-      Optional<Boolean> kmsUnavailable) {
-    AwsStorageConfigInfo.Builder storageConfig =
-        AwsStorageConfigInfo.builder()
-            .setStorageType(StorageConfigInfo.StorageTypeEnum.S3)
-            .setPathStyleAccess(pathStyleAccess)
-            .setStsUnavailable(!stsEnabled)
-            .setAllowedLocations(List.of(storageBase.toString() + "/" + catalogName));
-
-    endpoint.ifPresent(storageConfig::setEndpoint);
-    stsEndpoint.ifPresent(storageConfig::setStsEndpoint);
-    endpointInternal.ifPresent(storageConfig::setEndpointInternal);
-    region.ifPresent(storageConfig::setRegion);
-    roleArn.ifPresent(storageConfig::setRoleArn);
-    kmsUnavailable.ifPresent(storageConfig::setKmsUnavailable);
-
-    CatalogProperties.Builder catalogProps =
-        CatalogProperties.builder(storageBase.toString() + "/" + catalogName);
-    if (!stsEnabled) {
-      catalogProps.addProperty(TABLE_DEFAULT_PREFIX + AWS_KEY_ID.getPropertyName(), ACCESS_KEY);
-      catalogProps.addProperty(TABLE_DEFAULT_PREFIX + AWS_SECRET_KEY.getPropertyName(), SECRET_KEY);
-    }
-    Catalog catalog =
-        PolarisCatalog.builder()
-            .setType(Catalog.TypeEnum.INTERNAL)
-            .setName(catalogName)
-            .setStorageConfigInfo(storageConfig.build())
-            .setProperties(catalogProps.build())
-            .build();
-
-    managementApi.createCatalog(principalRoleName, catalog);
-
-    String authToken = client.obtainToken(principalCredentials);
-    RESTCatalog restCatalog = new RESTCatalog();
-
-    ImmutableMap.Builder<String, String> propertiesBuilder =
-        ImmutableMap.<String, String>builder()
-            .put(
-                org.apache.iceberg.CatalogProperties.URI, endpoints.catalogApiEndpoint().toString())
-            .put(OAuth2Properties.TOKEN, authToken)
-            .put("warehouse", catalogName)
-            .putAll(endpoints.extraHeaders("header."));
-
-    delegationMode.ifPresent(
-        dm -> propertiesBuilder.put("header.X-Iceberg-Access-Delegation", dm.protocolValue()));
-
-    if (delegationMode.isEmpty()) {
-      // Use local credentials on the client side
-      propertiesBuilder.put("s3.access-key-id", ACCESS_KEY);
-      propertiesBuilder.put("s3.secret-access-key", SECRET_KEY);
-    }
-
-    restCatalog.initialize("polaris", propertiesBuilder.buildKeepingLast());
-    return restCatalog;
-  }
-
-  @AfterEach
-  public void cleanUp() {
-    client.cleanUp(adminToken);
-  }
-
-  @ParameterizedTest
-  @CsvSource("true,  true,")
-  @CsvSource("false, true,")
-  @CsvSource("true,  false,")
-  @CsvSource("false, false,")
-  public void testCreateTable(boolean pathStyle, boolean stsEnabled) throws IOException {
-    LoadTableResponse response = doTestCreateTable(pathStyle, Optional.empty(), stsEnabled);
-    assertThat(response.config()).doesNotContainKey(SECRET_ACCESS_KEY);
-    assertThat(response.config()).doesNotContainKey(ACCESS_KEY_ID);
-    assertThat(response.config()).doesNotContainKey(REFRESH_CREDENTIALS_ENDPOINT);
-    assertThat(response.credentials()).isEmpty();
-  }
-
-  @ParameterizedTest
-  @ValueSource(booleans = {true, false})
-  public void testCreateTableVendedCredentials(boolean pathStyle) throws IOException {
-    LoadTableResponse response =
-        doTestCreateTable(pathStyle, Optional.of(VENDED_CREDENTIALS), true);
-    assertThat(response.config())
-        .containsEntry(
-            REFRESH_CREDENTIALS_ENDPOINT,
-            "v1/" + catalogName + "/namespaces/test-ns/tables/t1/credentials");
-    assertThat(response.credentials()).hasSize(1);
-  }
-
-  @ParameterizedTest
-  @CsvSource({
-    "false, false",
-    "true,  false",
-    "false, true",
-  })
-  public void testCreateTableVendedCredentialsWithPartialAwsShapePasses(
-      boolean includeRegion, boolean includeRoleArn) throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of(endpoint),
-            Optional.of(endpoint),
-            true,
-            Optional.empty(),
-            Optional.of(VENDED_CREDENTIALS),
-            true,
-            includeRegion ? Optional.of(TEST_REGION) : Optional.empty(),
-            includeRoleArn ? Optional.of(TEST_ROLE_ARN) : Optional.empty(),
-            Optional.of(false))) {
-      TableIdentifier id = createTableAndVerifyMetadata(restCatalog);
-      try {
-        assertLoadTableWithVendedCredentialsSucceeds(id);
-      } finally {
-        catalogApi.dropTable(catalogName, id);
-      }
-    }
-  }
-
-  @Test
-  public void testCreateTableVendedCredentialsWithFullAwsShapeAndKmsEnabledFails()
-      throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of(endpoint),
-            Optional.of(endpoint),
-            true,
-            Optional.empty(),
-            Optional.of(VENDED_CREDENTIALS),
-            true,
-            Optional.of(TEST_REGION),
-            Optional.of(TEST_ROLE_ARN),
-            Optional.of(false))) {
-      TableIdentifier id = createTableAndVerifyMetadata(restCatalog);
-      try {
-        assertLoadTableWithVendedCredentialsFailsWithKmsError(id);
-      } finally {
-        catalogApi.dropTable(catalogName, id);
-      }
-    }
-  }
-
-  @Test
-  public void testCreateTableVendedCredentialsWithAwsShapeAndKmsUnavailablePasses()
-      throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of(endpoint),
-            Optional.of(endpoint),
-            true,
-            Optional.empty(),
-            Optional.of(VENDED_CREDENTIALS),
-            true,
-            Optional.of(TEST_REGION),
-            Optional.of(TEST_ROLE_ARN),
-            Optional.of(true))) {
-      TableIdentifier id = createTableAndVerifyMetadata(restCatalog);
-      try {
-        assertLoadTableWithVendedCredentialsSucceeds(id);
-      } finally {
-        catalogApi.dropTable(catalogName, id);
-      }
-    }
-  }
-
-  private void assertLoadTableWithVendedCredentialsFailsWithKmsError(TableIdentifier id) {
-    assertThatThrownBy(
-            () ->
-                catalogApi.loadTable(
-                    catalogName,
-                    id,
-                    "ALL",
-                    Map.of("X-Iceberg-Access-Delegation", VENDED_CREDENTIALS.protocolValue())))
-        .hasMessageContaining("invalid resource")
-        .hasMessageContaining("arn:aws:kms:us-west-2:000000000000:key/*");
-  }
-
-  private void assertLoadTableWithVendedCredentialsSucceeds(TableIdentifier id) {
-    LoadTableResponse response =
-        catalogApi.loadTable(
-            catalogName,
-            id,
-            "ALL",
-            Map.of("X-Iceberg-Access-Delegation", VENDED_CREDENTIALS.protocolValue()));
-    assertThat(response.config())
-        .containsEntry(
-            REFRESH_CREDENTIALS_ENDPOINT,
-            "v1/" + catalogName + "/namespaces/test-ns/tables/t1/credentials");
-    assertThat(response.credentials()).hasSize(1);
-  }
-
-  private LoadTableResponse doTestCreateTable(
-      boolean pathStyle, Optional<AccessDelegationMode> dm, boolean stsEnabled) throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(Optional.of(endpoint), Optional.empty(), pathStyle, dm, stsEnabled)) {
-      LoadTableResponse loadTableResponse = doTestCreateTable(restCatalog, dm);
-      if (pathStyle) {
-        assertThat(loadTableResponse.config())
-            .containsEntry("s3.path-style-access", Boolean.TRUE.toString());
-      }
-      return loadTableResponse;
-    }
-  }
-
-  @Test
-  public void testInternalEndpoints() throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of("http://s3.example.com"),
-            Optional.of(endpoint),
-            false,
-            Optional.of(endpoint),
-            Optional.empty(),
-            true)) {
-      StorageConfigInfo storageConfig =
-          managementApi.getCatalog(catalogName).getStorageConfigInfo();
-      assertThat((AwsStorageConfigInfo) storageConfig)
-          .extracting(
-              AwsStorageConfigInfo::getEndpoint,
-              AwsStorageConfigInfo::getStsEndpoint,
-              AwsStorageConfigInfo::getEndpointInternal,
-              AwsStorageConfigInfo::getPathStyleAccess)
-          .containsExactly("http://s3.example.com", endpoint, endpoint, false);
-      LoadTableResponse loadTableResponse = doTestCreateTable(restCatalog, Optional.empty());
-      assertThat(loadTableResponse.config()).containsEntry(ENDPOINT, "http://s3.example.com");
-    }
-  }
-
-  @Test
-  public void testCreateTableFailureWithCredentialVendingWithoutSts() throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of(endpoint),
-            Optional.of("http://sts.example.com"), // not called
-            false,
-            Optional.of(VENDED_CREDENTIALS),
-            false)) {
-      StorageConfigInfo storageConfig =
-          managementApi.getCatalog(catalogName).getStorageConfigInfo();
-      assertThat((AwsStorageConfigInfo) storageConfig)
-          .extracting(
-              AwsStorageConfigInfo::getEndpoint,
-              AwsStorageConfigInfo::getStsEndpoint,
-              AwsStorageConfigInfo::getEndpointInternal,
-              AwsStorageConfigInfo::getPathStyleAccess,
-              AwsStorageConfigInfo::getStsUnavailable)
-          .containsExactly(endpoint, "http://sts.example.com", null, false, true);
-
-      catalogApi.createNamespace(catalogName, "test-ns");
-      TableIdentifier id = TableIdentifier.of("test-ns", "t2");
-      // Credential vending is not supported without STS
-      assertThatThrownBy(() -> restCatalog.createTable(id, SCHEMA))
-          .hasMessageContaining("but no credentials are available")
-          .hasMessageContaining(id.toString());
-    }
-  }
-
-  @Test
-  public void testLoadTableFailureWithCredentialVendingWithoutSts() throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of(endpoint),
-            Optional.of("http://sts.example.com"), // not called
-            false,
-            Optional.empty(),
-            false)) {
-
-      catalogApi.createNamespace(catalogName, "test-ns");
-      TableIdentifier id = TableIdentifier.of("test-ns", "t3");
-      restCatalog.createTable(id, SCHEMA);
-
-      // Credential vending is not supported without STS
-      assertThatThrownBy(
-              () ->
-                  catalogApi.loadTable(
-                      catalogName,
-                      id,
-                      "ALL",
-                      Map.of("X-Iceberg-Access-Delegation", VENDED_CREDENTIALS.protocolValue())))
-          .hasMessageContaining("but no credentials are available")
-          .hasMessageContaining(id.toString());
-    }
-  }
-
-  public LoadTableResponse doTestCreateTable(
-      RESTCatalog restCatalog, Optional<AccessDelegationMode> dm) {
-    TableIdentifier id = createTableAndVerifyMetadata(restCatalog);
-    assertThat(restCatalog.tableExists(id)).isTrue();
-
-    try {
-      LoadTableResponse loadTableResponse =
-          catalogApi.loadTable(
-              catalogName,
-              id,
-              "ALL",
-              dm.map(v -> Map.of("X-Iceberg-Access-Delegation", v.protocolValue()))
-                  .orElse(Map.of()));
-
-      assertThat(loadTableResponse.config()).containsKey(ENDPOINT);
-      return loadTableResponse;
-    } finally {
-      if (restCatalog.tableExists(id)) {
-        restCatalog.dropTable(id);
-        assertThat(restCatalog.tableExists(id)).isFalse();
-      }
-    }
-  }
-
-  private TableIdentifier createTableAndVerifyMetadata(RESTCatalog restCatalog) {
-    catalogApi.createNamespace(catalogName, "test-ns");
-    TableIdentifier id = TableIdentifier.of("test-ns", "t1");
-    Table table = restCatalog.createTable(id, SCHEMA);
-    assertThat(table).isNotNull();
-
-    TableOperations ops = ((HasTableOperations) table).operations();
-    URI location = URI.create(ops.current().metadataFileLocation());
-
-    GetObjectResponse response =
-        s3Client
-            .getObject(
-                GetObjectRequest.builder()
-                    .bucket(location.getAuthority())
-                    .key(location.getPath().substring(1)) // drop leading slash
-                    .build())
-            .response();
-    assertThat(response.contentLength()).isGreaterThan(0);
-    return id;
-  }
-
-  @ParameterizedTest
-  @CsvSource("true,  true,")
-  @CsvSource("false, true,")
-  @CsvSource("true,  false,")
-  @CsvSource("false, false,")
-  @CsvSource("true,  true,  VENDED_CREDENTIALS")
-  @CsvSource("false, true,  VENDED_CREDENTIALS")
-  public void testAppendFiles(
-      boolean pathStyle, boolean stsEnabled, AccessDelegationMode delegationMode)
-      throws IOException {
-    try (RESTCatalog restCatalog =
-        createCatalog(
-            Optional.of(endpoint),
-            Optional.of(endpoint),
-            pathStyle,
-            Optional.ofNullable(delegationMode),
-            stsEnabled)) {
-      catalogApi.createNamespace(catalogName, "test-ns");
-      TableIdentifier id = TableIdentifier.of("test-ns", "t1");
-      Table table = restCatalog.createTable(id, SCHEMA);
-      assertThat(table).isNotNull();
-
-      @SuppressWarnings("resource")
-      FileIO io = table.io();
-
-      URI loc =
-          URI.create(
-              table
-                  .locationProvider()
-                  .newDataLocation(
-                      String.format(
-                          "test-file-%s-%s-%s.txt", pathStyle, delegationMode, stsEnabled)));
-      OutputFile f1 = io.newOutputFile(loc.toString());
-      try (PositionOutputStream os = f1.create()) {
-        os.write("Hello World".getBytes(UTF_8));
-      }
-
-      DataFile df =
-          DataFiles.builder(PartitionSpec.unpartitioned())
-              .withPath(f1.location())
-              .withFormat(FileFormat.PARQUET) // bogus value
-              .withFileSizeInBytes(4)
-              .withRecordCount(1)
-              .build();
-
-      table.newAppend().appendFile(df).commit();
-
-      try (InputStream is =
-          s3Client.getObject(
-              GetObjectRequest.builder()
-                  .bucket(loc.getAuthority())
-                  .key(loc.getPath().substring(1)) // drop leading slash
-                  .build())) {
-        assertThat(new String(is.readAllBytes(), UTF_8)).isEqualTo("Hello World");
-      }
-    }
-  }
-}
diff --git a/tools/testcontainers/minio-testcontainer/build.gradle.kts b/tools/testcontainers/minio-testcontainer/build.gradle.kts
deleted file mode 100644
index 8a558aa891..0000000000
--- a/tools/testcontainers/minio-testcontainer/build.gradle.kts
+++ /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.
- */
-
-plugins {
-  id("org.kordamp.gradle.jandex")
-  id("polaris-server")
-}
-
-dependencies {
-  api(platform(libs.testcontainers.bom))
-  api("org.testcontainers:testcontainers")
-
-  api(platform(libs.awssdk.bom))
-  api("software.amazon.awssdk:s3")
-  api("software.amazon.awssdk:kms")
-
-  implementation(project(":polaris-container-spec-helper"))
-  implementation("software.amazon.awssdk:url-connection-client")
-  implementation(libs.guava)
-
-  compileOnly(platform(libs.junit.bom))
-  compileOnly("org.junit.jupiter:junit-jupiter-api")
-
-  compileOnly(platform(libs.quarkus.bom))
-  compileOnly("io.quarkus:quarkus-test-common")
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/Minio.java b/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/Minio.java
deleted file mode 100644
index f5ad582ad7..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/Minio.java
+++ /dev/null
@@ -1,46 +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.test.minio;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-// CODE_COPIED_TO_POLARIS from Project Nessie 0.104.2
-@Target({ElementType.FIELD, ElementType.PARAMETER})
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-public @interface Minio {
-  /** Optional, use this access key instead of a random one. */
-  String accessKey() default DEFAULT;
-
-  /** Optional, use this secret key instead of a random one. */
-  String secretKey() default DEFAULT;
-
-  /** Optional, use this bucket instead of a random one. */
-  String bucket() default DEFAULT;
-
-  /** Optional, use this region. */
-  String region() default DEFAULT;
-
-  String DEFAULT = "minio_default_value__";
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioAccess.java b/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioAccess.java
deleted file mode 100644
index 86e0a68f44..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioAccess.java
+++ /dev/null
@@ -1,68 +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.test.minio;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.Optional;
-import software.amazon.awssdk.core.sync.RequestBody;
-import software.amazon.awssdk.services.s3.S3Client;
-
-/**
- * Provides access to Minio via a preconfigured S3 client and providing the by default randomized
- * bucket and access/secret keys.
- *
- * <p>Annotate JUnit test instance or static fields or method parameters of this type with {@link
- * Minio}.
- */
-// CODE_COPIED_TO_POLARIS from Project Nessie 0.104.2
-public interface MinioAccess {
-
-  /** Host and port, separated by '{@code :}'. */
-  String hostPort();
-
-  String accessKey();
-
-  String secretKey();
-
-  String bucket();
-
-  Optional<String> region();
-
-  /** HTTP protocol endpoint. */
-  String s3endpoint();
-
-  S3Client s3Client();
-
-  /** Properties needed by Apache Iceberg to access this instance. */
-  Map<String, String> icebergProperties();
-
-  /** Properties needed by Apache Hadoop to access this instance. */
-  Map<String, String> hadoopConfig();
-
-  /** S3 scheme URI including the bucket to access the given path. */
-  URI s3BucketUri(String path);
-
-  /** Convenience method to put an object into S3. */
-  @SuppressWarnings("resource")
-  default void s3put(String key, RequestBody body) {
-    s3Client().putObject(b -> b.bucket(bucket()).key(key), body);
-  }
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioConditionExtension.java b/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioConditionExtension.java
deleted file mode 100644
index fbb96539dd..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioConditionExtension.java
+++ /dev/null
@@ -1,46 +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.test.minio;
-
-import static java.lang.String.format;
-import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled;
-import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled;
-
-import org.junit.jupiter.api.condition.OS;
-import org.junit.jupiter.api.extension.ConditionEvaluationResult;
-import org.junit.jupiter.api.extension.ExecutionCondition;
-import org.junit.jupiter.api.extension.ExtensionContext;
-
-/** JUnit extension that gates whether the Minio container can be run on the current platform. */
-public class MinioConditionExtension implements ExecutionCondition {
-  @Override
-  public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
-    if (OS.current() == OS.LINUX) {
-      return enabled("Running on Linux");
-    }
-    if (OS.current() == OS.MAC
-        && System.getenv("CI_MAC") == null
-        && MinioContainer.canRunOnMacOs()) {
-      // Disable tests on GitHub Actions
-      return enabled("Running on macOS locally");
-    }
-    return disabled(format("Disabled on %s", OS.current().name()));
-  }
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioContainer.java b/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioContainer.java
deleted file mode 100644
index 9da81d008d..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioContainer.java
+++ /dev/null
@@ -1,276 +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.test.minio;
-
-import com.google.common.base.Preconditions;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import org.apache.polaris.containerspec.ContainerSpecHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.output.Slf4jLogConsumer;
-import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
-import org.testcontainers.utility.Base58;
-import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
-import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
-import software.amazon.awssdk.regions.Region;
-import software.amazon.awssdk.services.s3.S3Client;
-import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
-
-// CODE_COPIED_TO_POLARIS from Project Nessie 0.104.2
-public final class MinioContainer extends GenericContainer<MinioContainer>
-    implements MinioAccess, AutoCloseable {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(MinioContainer.class);
-
-  private static final int DEFAULT_PORT = 9000;
-
-  private static final String MINIO_ACCESS_KEY = "MINIO_ROOT_USER";
-  private static final String MINIO_SECRET_KEY = "MINIO_ROOT_PASSWORD";
-  private static final String MINIO_DOMAIN = "MINIO_DOMAIN";
-
-  private static final String DEFAULT_STORAGE_DIRECTORY = "/data";
-  private static final String HEALTH_ENDPOINT = "/minio/health/ready";
-  private static final String MINIO_DOMAIN_NAME;
-
-  /**
-   * Domain must start with "s3" in order to be recognized as an S3 endpoint by the AWS SDK with
-   * virtual-host-style addressing. The bucket name is expected to be the first part of the domain
-   * name, e.g. "bucket.s3.127-0-0-1.nip.io".
-   */
-  private static final String MINIO_DOMAIN_NIP = "s3.127-0-0-1.nip.io";
-
-  /**
-   * Whether random bucket names cannot be used. Randomized bucket names can only be used when
-   * either `*.localhost` (on Linux) or `*.s3.127-0-0-1.nip.io` (on macOS, if DNS rebind protection
-   * is not active) can be resolved. Otherwise we have to use a fixed bucket name and users have to
-   * configure that in `/etc/hosts`.
-   */
-  private static final String FIXED_BUCKET_NAME;
-
-  static boolean canRunOnMacOs() {
-    return MINIO_DOMAIN_NAME.equals(MINIO_DOMAIN_NIP);
-  }
-
-  static {
-    String name;
-    String fixedBucketName = null;
-    if (System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("linux")) {
-      name = "localhost";
-    } else {
-      try {
-        InetAddress ignored = InetAddress.getByName(MINIO_DOMAIN_NIP);
-        name = MINIO_DOMAIN_NIP;
-      } catch (UnknownHostException x) {
-        LOGGER.warn(
-            "Could not resolve '{}', falling back to 'localhost'. "
-                + "This usually happens when your router or DNS provider is unable to resolve the nip.io addresses.",
-            MINIO_DOMAIN_NIP);
-        name = "localhost";
-        fixedBucketName = "miniobucket";
-        validateBucketHost(fixedBucketName);
-      }
-    }
-    MINIO_DOMAIN_NAME = name;
-    FIXED_BUCKET_NAME = fixedBucketName;
-  }
-
-  /** Validates the bucket host name, on non-Linux, if necessary. */
-  private static String validateBucketHost(String bucketName) {
-    if (FIXED_BUCKET_NAME != null) {
-      String test = bucketName + ".localhost";
-      try {
-        InetAddress ignored = InetAddress.getByName(test);
-      } catch (UnknownHostException e) {
-        LOGGER.warn(
-            "Could not resolve '{}',\n  Please add the line \n    '127.0.0.1   {}'\n  to your local '/etc/hosts' file.\n  Tests are expected to fail unless name resolution works.",
-            test,
-            test);
-      }
-    }
-    return bucketName;
-  }
-
-  private final String accessKey;
-  private final String secretKey;
-  private final String bucket;
-
-  private String hostPort;
-  private String s3endpoint;
-  private S3Client s3;
-  private Optional<String> region;
-
-  @SuppressWarnings("unused")
-  public MinioContainer() {
-    this(null, null, null, null, null);
-  }
-
-  @SuppressWarnings("resource")
-  public MinioContainer(
-      String image, String accessKey, String secretKey, String bucket, String region) {
-    super(
-        ContainerSpecHelper.containerSpecHelper("minio", MinioContainer.class)
-            .dockerImageName(image));
-    withNetworkAliases(randomString("minio"));
-    withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(MinioContainer.class)));
-    addExposedPort(DEFAULT_PORT);
-    this.accessKey = accessKey != null ? accessKey : randomString("access");
-    this.secretKey = secretKey != null ? secretKey : randomString("secret");
-    this.bucket =
-        bucket != null
-            ? validateBucketHost(bucket)
-            : (FIXED_BUCKET_NAME != null ? FIXED_BUCKET_NAME : randomString("bucket"));
-    this.region = Optional.ofNullable(region);
-    withEnv(MINIO_ACCESS_KEY, this.accessKey);
-    withEnv(MINIO_SECRET_KEY, this.secretKey);
-    // S3 SDK encodes bucket names in host names - need to tell Minio which domain to use
-    withEnv(MINIO_DOMAIN, MINIO_DOMAIN_NAME);
-    withCommand("server", DEFAULT_STORAGE_DIRECTORY);
-    setWaitStrategy(
-        new HttpWaitStrategy()
-            .forPort(DEFAULT_PORT)
-            .forPath(HEALTH_ENDPOINT)
-            .withStartupTimeout(Duration.ofMinutes(2)));
-  }
-
-  public MinioContainer withRegion(String region) {
-    this.region = Optional.of(region);
-    return this;
-  }
-
-  private static String randomString(String prefix) {
-    return prefix + "-" + Base58.randomString(6).toLowerCase(Locale.ROOT);
-  }
-
-  @Override
-  public String hostPort() {
-    Preconditions.checkState(hostPort != null, "Container not yet started");
-    return hostPort;
-  }
-
-  @Override
-  public String accessKey() {
-    return accessKey;
-  }
-
-  @Override
-  public String secretKey() {
-    return secretKey;
-  }
-
-  @Override
-  public String bucket() {
-    return bucket;
-  }
-
-  @Override
-  public Optional<String> region() {
-    return region;
-  }
-
-  @Override
-  public String s3endpoint() {
-    Preconditions.checkState(s3endpoint != null, "Container not yet started");
-    return s3endpoint;
-  }
-
-  @Override
-  public S3Client s3Client() {
-    Preconditions.checkState(s3 != null, "Container not yet started");
-    return s3;
-  }
-
-  @Override
-  public Map<String, String> icebergProperties() {
-    Map<String, String> props = new HashMap<>();
-    props.put("s3.access-key-id", accessKey());
-    props.put("s3.secret-access-key", secretKey());
-    props.put("s3.endpoint", s3endpoint());
-    props.put("http-client.type", "urlconnection");
-    region().ifPresent(r -> props.put("client.region", r));
-    return props;
-  }
-
-  @Override
-  public Map<String, String> hadoopConfig() {
-    Map<String, String> r = new HashMap<>();
-    r.put("fs.s3.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem");
-    r.put("fs.s3a.access.key", accessKey());
-    r.put("fs.s3a.secret.key", secretKey());
-    r.put("fs.s3a.endpoint", s3endpoint());
-    return r;
-  }
-
-  @Override
-  public URI s3BucketUri(String path) {
-    return s3BucketUri("s3", path);
-  }
-
-  public URI s3BucketUri(String scheme, String path) {
-    Preconditions.checkState(bucket != null, "Container not yet started");
-    return URI.create(String.format("%s://%s/", scheme, bucket)).resolve(path);
-  }
-
-  @Override
-  public void start() {
-    super.start();
-
-    this.hostPort = MINIO_DOMAIN_NAME + ":" + getMappedPort(DEFAULT_PORT);
-    this.s3endpoint = String.format("http://%s/", hostPort);
-
-    this.s3 = createS3Client();
-    this.s3.createBucket(CreateBucketRequest.builder().bucket(bucket()).build());
-  }
-
-  @Override
-  public void close() {
-    stop();
-  }
-
-  @Override
-  public void stop() {
-    try {
-      if (s3 != null) {
-        s3.close();
-      }
-    } finally {
-      s3 = null;
-      super.stop();
-    }
-  }
-
-  private S3Client createS3Client() {
-    return S3Client.builder()
-        .httpClientBuilder(UrlConnectionHttpClient.builder())
-        .applyMutation(builder -> builder.endpointOverride(URI.create(s3endpoint())))
-        .applyMutation(builder -> region.ifPresent(r -> builder.region(Region.of(r))))
-        .credentialsProvider(
-            StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey(), secretKey())))
-        .build();
-  }
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioExtension.java b/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioExtension.java
deleted file mode 100644
index e30e60685f..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioExtension.java
+++ /dev/null
@@ -1,120 +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.test.minio;
-
-import static org.junit.platform.commons.util.AnnotationUtils.findAnnotatedFields;
-import static org.junit.platform.commons.util.ReflectionUtils.makeAccessible;
-
-import java.lang.reflect.Field;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.ParameterContext;
-import org.junit.jupiter.api.extension.ParameterResolutionException;
-import org.junit.jupiter.api.extension.ParameterResolver;
-import org.junit.platform.commons.util.AnnotationUtils;
-import org.junit.platform.commons.util.ExceptionUtils;
-import org.junit.platform.commons.util.ReflectionUtils;
-
-/**
- * JUnit extension that provides a Minio container configured with a single bucket.
- *
- * <p>Provides instances of {@link MinioAccess} via instance or static fields or parameters
- * annotated with {@link Minio}.
- */
-// CODE_COPIED_TO_POLARIS from Project Nessie 0.104.2
-public class MinioExtension extends MinioConditionExtension
-    implements BeforeAllCallback, BeforeEachCallback, ParameterResolver {
-  private static final ExtensionContext.Namespace NAMESPACE =
-      ExtensionContext.Namespace.create(MinioExtension.class);
-
-  @Override
-  public void beforeAll(ExtensionContext context) {
-    Class<?> testClass = context.getRequiredTestClass();
-
-    findAnnotatedFields(testClass, Minio.class, ReflectionUtils::isStatic)
-        .forEach(field -> injectField(context, field));
-  }
-
-  @Override
-  public void beforeEach(ExtensionContext context) {
-    Class<?> testClass = context.getRequiredTestClass();
-
-    findAnnotatedFields(testClass, Minio.class, ReflectionUtils::isNotStatic)
-        .forEach(field -> injectField(context, field));
-  }
-
-  private void injectField(ExtensionContext context, Field field) {
-    try {
-      Minio minio =
-          AnnotationUtils.findAnnotation(field, Minio.class)
-              .orElseThrow(IllegalStateException::new);
-
-      MinioAccess container =
-          context
-              .getStore(NAMESPACE)
-              .computeIfAbsent(field.toString(), x -> createContainer(minio), MinioAccess.class);
-
-      makeAccessible(field).set(context.getTestInstance().orElse(null), container);
-    } catch (Throwable t) {
-      ExceptionUtils.throwAsUncheckedException(t);
-    }
-  }
-
-  @Override
-  public boolean supportsParameter(
-      ParameterContext parameterContext, ExtensionContext extensionContext)
-      throws ParameterResolutionException {
-    if (parameterContext.findAnnotation(Minio.class).isEmpty()) {
-      return false;
-    }
-    return parameterContext.getParameter().getType().isAssignableFrom(MinioAccess.class);
-  }
-
-  @Override
-  public Object resolveParameter(
-      ParameterContext parameterContext, ExtensionContext extensionContext)
-      throws ParameterResolutionException {
-    return extensionContext
-        .getStore(NAMESPACE)
-        .computeIfAbsent(
-            MinioExtension.class.getName() + '#' + parameterContext.getParameter().getName(),
-            k -> {
-              Minio minio = parameterContext.findAnnotation(Minio.class).get();
-              return createContainer(minio);
-            },
-            MinioAccess.class);
-  }
-
-  private MinioAccess createContainer(Minio minio) {
-    String accessKey = nonDefault(minio.accessKey());
-    String secretKey = nonDefault(minio.secretKey());
-    String bucket = nonDefault(minio.bucket());
-    String region = nonDefault(minio.region());
-    MinioContainer container =
-        new MinioContainer(null, accessKey, secretKey, bucket, region).withStartupAttempts(5);
-    container.start();
-    return container;
-  }
-
-  private static String nonDefault(String s) {
-    return s.equals(Minio.DEFAULT) ? null : s;
-  }
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioTestResource.java b/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioTestResource.java
deleted file mode 100644
index df2d26d683..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/java/org/apache/polaris/test/minio/MinioTestResource.java
+++ /dev/null
@@ -1,65 +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.test.minio;
-
-import static java.util.Objects.requireNonNull;
-
-import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
-import java.util.Map;
-
-public class MinioTestResource implements QuarkusTestResourceLifecycleManager {
-
-  private Map<String, String> initArgs = Map.of();
-  private MinioContainer container;
-
-  @Override
-  public void init(Map<String, String> initArgs) {
-    this.initArgs = Map.copyOf(initArgs);
-  }
-
-  @Override
-  public Map<String, String> start() {
-    var accessKey = initArgs.get("accessKey");
-    var secretKey = initArgs.get("secretKey");
-    var bucket = initArgs.get("bucket");
-    var region = initArgs.get("region");
-    this.container =
-        new MinioContainer(null, accessKey, secretKey, bucket, region).withStartupAttempts(5);
-    this.container.start();
-    return Map.of();
-  }
-
-  @Override
-  public void stop() {
-    if (container != null) {
-      try {
-        container.close();
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-  }
-
-  @Override
-  public void inject(TestInjector testInjector) {
-    MinioAccess minioAccess = requireNonNull(container, "Minio not started");
-    testInjector.injectIntoFields(minioAccess, field -> field.isAnnotationPresent(Minio.class));
-  }
-}
diff --git a/tools/testcontainers/minio-testcontainer/src/main/resources/org/apache/polaris/test/minio/Dockerfile-minio-version b/tools/testcontainers/minio-testcontainer/src/main/resources/org/apache/polaris/test/minio/Dockerfile-minio-version
deleted file mode 100644
index 69552d3ab9..0000000000
--- a/tools/testcontainers/minio-testcontainer/src/main/resources/org/apache/polaris/test/minio/Dockerfile-minio-version
+++ /dev/null
@@ -1,22 +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.
-#
-
-# Dockerfile to provide the image name and tag to a test.
-# Version is managed by Renovate - do not edit.
-FROM quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z