From d4d17a87106557026d98570f7573d6bb13c4ff76 Mon Sep 17 00:00:00 2001 From: teleivo Date: Fri, 25 Sep 2026 10:23:51 +0200 Subject: [PATCH 1/2] chore: replace MinIO with SeaweedFS in tests [2.41] Backport of #25373. quay.io/minio/minio now returns 401 on pull, breaking the S3-backed integration tests and the e2e compose setup. Use SeaweedFS with only its S3 gateway enabled instead. Adapted to 2.41: the branch configures the S3 store through MinIOConfiguration/MinIOConfigurationProvider rather than a JUnit extension; they are renamed to S3Configuration/S3ConfigurationProvider and start a SeaweedFS container. (cherry picked from commit f642b56859db6630206e80e23a659687f4b41c1e) --- dhis-2/dhis-support/dhis-support-test/pom.xml | 4 -- ...onfiguration.java => S3Configuration.java} | 8 +-- ...ider.java => S3ConfigurationProvider.java} | 54 +++++++++++-------- .../dhis-test-e2e/config/dhis2_home/dhis.conf | 2 +- dhis-2/dhis-test-e2e/docker-compose.yml | 18 +++---- ...erMinIOTest.java => AppManagerS3Test.java} | 12 ++--- dhis-2/pom.xml | 5 -- 7 files changed, 52 insertions(+), 51 deletions(-) rename dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/{MinIOConfiguration.java => S3Configuration.java} (88%) rename dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/{MinIOConfigurationProvider.java => S3ConfigurationProvider.java} (54%) rename dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/{AppManagerMinIOTest.java => AppManagerS3Test.java} (96%) diff --git a/dhis-2/dhis-support/dhis-support-test/pom.xml b/dhis-2/dhis-support/dhis-support-test/pom.xml index f027f3beab61..a2c740229309 100644 --- a/dhis-2/dhis-support/dhis-support-test/pom.xml +++ b/dhis-2/dhis-support/dhis-support-test/pom.xml @@ -115,10 +115,6 @@ org.testcontainers postgresql - - org.testcontainers - minio - org.postgresql postgresql diff --git a/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/MinIOConfiguration.java b/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/S3Configuration.java similarity index 88% rename from dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/MinIOConfiguration.java rename to dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/S3Configuration.java index 26cf109d0555..e14c373bb234 100644 --- a/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/MinIOConfiguration.java +++ b/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/S3Configuration.java @@ -32,16 +32,16 @@ import org.springframework.context.annotation.Configuration; /** - * Use this configuration for tests relying on MinIO storage running in a Docker container. e.g. add - * to test class like `@ContextConfiguration(classes = {MinIODhisConfiguration.class})` + * Use this configuration for tests relying on S3 storage running in a Docker container. e.g. add to + * test class like `@ContextConfiguration(classes = {S3Configuration.class})` * * @author david mackessy */ @Configuration -public class MinIOConfiguration { +public class S3Configuration { @Bean public DhisConfigurationProvider dhisConfigurationProvider() { - return new MinIOConfigurationProvider( + return new S3ConfigurationProvider( new TestContainerPostgresConfig().dhisConfigurationProvider().getProperties()); } } diff --git a/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/MinIOConfigurationProvider.java b/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/S3ConfigurationProvider.java similarity index 54% rename from dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/MinIOConfigurationProvider.java rename to dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/S3ConfigurationProvider.java index fd11d9688fcb..57c77599a116 100644 --- a/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/MinIOConfigurationProvider.java +++ b/dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/config/S3ConfigurationProvider.java @@ -28,44 +28,54 @@ package org.hisp.dhis.config; import java.util.Properties; -import org.testcontainers.containers.MinIOContainer; -import org.testcontainers.utility.DockerImageName; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; /** - * Config provider for MinIO store usage. It extends the Postgres config to make use of that setup. + * Config provider for S3 store usage, backed by a SeaweedFS container with only its S3 gateway + * enabled. It extends the Postgres config to make use of that setup. * * @author david mackessy */ -public class MinIOConfigurationProvider extends PostgresDhisConfigurationProvider { +public class S3ConfigurationProvider extends PostgresDhisConfigurationProvider { + private static final String S3_ACCESS_KEY = "testuser"; + private static final String S3_SECRET_KEY = "testpassword"; + private static final int S3_PORT = 8333; + private static final String S3_URL; - private static final String MINIO_USER = "testuser"; - private static final String MINIO_PASSWORD = "testpassword"; - private static final MinIOContainer MIN_IO_CONTAINER; + private static final GenericContainer S3_CONTAINER; static { - // Docker Hub no longer serves minio/minio (404 / pull access denied). Official - // community images remain on quay.io; Testcontainers requires a compatible substitute. - MIN_IO_CONTAINER = - new MinIOContainer( - DockerImageName.parse("quay.io/minio/minio:RELEASE.2024-07-16T23-46-41Z") - .asCompatibleSubstituteFor("minio/minio")) - .withUserName(MINIO_USER) - .withPassword(MINIO_PASSWORD); - MIN_IO_CONTAINER.start(); - S3_URL = MIN_IO_CONTAINER.getS3URL(); + S3_CONTAINER = + new GenericContainer<>("chrislusf/seaweedfs:4.47") + .withCommand( + "server", + "-dir=/data", + "-s3", + "-s3.port.iceberg=0", + "-s3.port.lance=0", + "-master.telemetry=false") + // SeaweedFS registers these as the admin S3 identity. + .withEnv("AWS_ACCESS_KEY_ID", S3_ACCESS_KEY) + .withEnv("AWS_SECRET_ACCESS_KEY", S3_SECRET_KEY) + .withExposedPorts(S3_PORT) + .waitingFor(Wait.forHttp("/healthz").forPort(S3_PORT)); + S3_CONTAINER.start(); + S3_URL = "http://" + S3_CONTAINER.getHost() + ":" + S3_CONTAINER.getMappedPort(S3_PORT); } - public MinIOConfigurationProvider(Properties dhisConfig) { - setMinIOProperties(dhisConfig); + public S3ConfigurationProvider(Properties dhisConfig) { + setS3Properties(dhisConfig); } - public void setMinIOProperties(Properties properties) { + public void setS3Properties(Properties properties) { properties.put("filestore.provider", "s3"); properties.put("filestore.container", "dhis2"); properties.put("filestore.location", "eu-west-1"); properties.put("filestore.endpoint", S3_URL); - properties.put("filestore.identity", MINIO_USER); - properties.put("filestore.secret", MINIO_PASSWORD); + properties.put("filestore.identity", S3_ACCESS_KEY); + properties.put("filestore.secret", S3_SECRET_KEY); this.properties = properties; } } diff --git a/dhis-2/dhis-test-e2e/config/dhis2_home/dhis.conf b/dhis-2/dhis-test-e2e/config/dhis2_home/dhis.conf index 825a869f5ea8..a9a9afeb06fd 100644 --- a/dhis-2/dhis-test-e2e/config/dhis2_home/dhis.conf +++ b/dhis-2/dhis-test-e2e/config/dhis2_home/dhis.conf @@ -11,7 +11,7 @@ redis.host = redis filestore.provider = s3 filestore.container = dhis2 filestore.location = eu-west-1 -filestore.endpoint = http://minio:9000 +filestore.endpoint = http://s3:8333 filestore.identity = root filestore.secret = dhisdhis diff --git a/dhis-2/dhis-test-e2e/docker-compose.yml b/dhis-2/dhis-test-e2e/docker-compose.yml index fffd2550f732..aa367445cedf 100644 --- a/dhis-2/dhis-test-e2e/docker-compose.yml +++ b/dhis-2/dhis-test-e2e/docker-compose.yml @@ -16,7 +16,7 @@ services: condition: service_healthy redis: condition: service_started - minio: + s3: condition: service_healthy db: @@ -43,20 +43,20 @@ services: ports: - "6379" - minio: - image: quay.io/minio/minio - command: server /data --console-address ":9090" + s3: + image: chrislusf/seaweedfs:4.47 + command: server -dir=/data -s3 -s3.port.iceberg=0 -s3.port.lance=0 -master.telemetry=false ports: - - "9000" # minio API - - "9090" # minio UI + - "8333" # S3 API healthcheck: - test: [ "CMD", "mc", "ready", "local" ] + test: [ "CMD", "wget", "--quiet", "--spider", "http://127.0.0.1:8333/healthz" ] interval: 5s timeout: 5s retries: 5 environment: - MINIO_ROOT_USER: root - MINIO_ROOT_PASSWORD: dhisdhis + # SeaweedFS registers these as the admin S3 identity + AWS_ACCESS_KEY_ID: root + AWS_SECRET_ACCESS_KEY: dhisdhis selenium: image: "selenium/standalone-chrome:latest" diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/AppManagerMinIOTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/AppManagerS3Test.java similarity index 96% rename from dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/AppManagerMinIOTest.java rename to dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/AppManagerS3Test.java index ad07fe1528ea..591b772122ef 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/AppManagerMinIOTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/app/AppManagerS3Test.java @@ -41,7 +41,7 @@ import org.hisp.dhis.appmanager.ResourceResult.Redirect; import org.hisp.dhis.appmanager.ResourceResult.ResourceFound; import org.hisp.dhis.appmanager.ResourceResult.ResourceNotFound; -import org.hisp.dhis.config.MinIOConfiguration; +import org.hisp.dhis.config.S3Configuration; import org.hisp.dhis.test.integration.IntegrationTestBase; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -56,17 +56,17 @@ import org.springframework.test.context.ContextConfiguration; /** - * Test class configured for use cases when DHIS2 is configured to use MinIO storage. The default + * Test class configured for use cases when DHIS2 is configured to use S3 storage. The default * storage is the local filesystem. */ -@ContextConfiguration(classes = {MinIOConfiguration.class}) -class AppManagerMinIOTest extends IntegrationTestBase { +@ContextConfiguration(classes = {S3Configuration.class}) +class AppManagerS3Test extends IntegrationTestBase { @Autowired AppManager appManager; @Test - @DisplayName("Can install and then update an App using MinIO storage") - void canUpdateAppUsingMinIOStorageTest() throws IOException { + @DisplayName("Can install and then update an App using S3 storage") + void canUpdateAppUsingS3StorageTest() throws IOException { // install an app for the 1st time (version 1) AppStatus appStatus = appManager.installApp( diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index 4dffa6c2dcad..699df8f76d5a 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -1756,11 +1756,6 @@ jdbc ${testcontainers.version} - - org.testcontainers - minio - ${testcontainers.version} - From 539e86396954bc7036d6935ac47bbe880665d58c Mon Sep 17 00:00:00 2001 From: Morten Svanaes Date: Sun, 27 Sep 2026 00:50:04 +0800 Subject: [PATCH 2/2] chore: restore maven-surefire-plugin 3.5.6 [2.41] Surefire 3.6.0 switches groups/excludedGroups to JUnit 4 category filtering when junit:junit is on the test classpath (it comes in transitively via Testcontainers). The JUnit Platform tags are then ignored: the unit-test profile runs every integration test and the integration-test and integration-h2-test profiles run none. 2.42 and 2.43 stay on 3.5.6 for the same reason. --- dhis-2/pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index 699df8f76d5a..03f7b3f9fa49 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -219,7 +219,9 @@ 2.2 - 3.6.0 + + 3.5.6 3.15.0 3.6.4 3.5.0