Skip to content

Commit 0ee4312

Browse files
test: Add tests covering BlobStoreService operations [DHIS2-20648] (#23867)
* test: Add tests to cover blob store service * clean up javadocs and use awaitility * Rename tests and reuse MinIO container * Clean up * fix tests * revert test change * Use 1 container for minio tests n different classes
1 parent fb8b420 commit 0ee4312

8 files changed

Lines changed: 787 additions & 16 deletions

File tree

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/appmanager/JCloudsAppStorageService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ public void deleteApp(@Nonnull App app) {
338338
AppFolderName folder = app.appFolder();
339339
blobStore.deleteBlob(folder.resolve(MANIFEST_WEBAPP_FILENAME));
340340

341+
// TODO(DHIS2-20648) Once the replacement BlobStoreService implementation does recursive
342+
// deleteDirectory on every backend (see contract test), this branch can collapse to a
343+
// single blobStore.deleteDirectory(folder.asPrefix()) call.
341344
if (blobStore.isFilesystem()) {
342345
// Delete all files related to app (works for local filestore)
343346
blobStore.deleteDirectory(folder.asPrefix());

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/storage/BlobStoreService.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ void putBlob(
111111
* Recursively deletes all blobs whose key starts with {@code prefix}. On filesystem backends this
112112
* maps to a directory delete; on object-store backends it performs per-key deletion.
113113
*/
114+
// TODO(DHIS2-20648) The replacement implementation must honour this recursively for ALL
115+
// backends. The current jclouds-transient and jclouds-S3 paths are non-recursive (callers
116+
// work around it in JCloudsAppStorageService#deleteApp); see BlobStoreServiceContractTest's
117+
// supportsRecursiveDirectoryDelete capability hook — drop the false overrides once fixed.
114118
void deleteDirectory(BlobKeyPrefix prefix);
115119

116120
/**
@@ -121,8 +125,12 @@ void putBlob(
121125

122126
/**
123127
* Lists all blob keys whose key starts with {@code prefix} (recursive). May return an empty
124-
* iterable if no matching blobs exist.
128+
* iterable if no matching blobs exist. Returned keys identify real blobs only — synthetic
129+
* directory marker entries (values ending with {@code /}) must not be returned.
125130
*/
131+
// TODO(DHIS2-20648) The replacement implementation must filter directory markers. The current
132+
// jclouds-filesystem provider emits them; see BlobStoreServiceContractTest's
133+
// listKeysIncludesDirectoryMarkers capability hook — drop the true override once fixed.
126134
Iterable<BlobKey> listKeys(BlobKeyPrefix prefix);
127135

128136
/**

dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/test/junit/MinIOTestExtension.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,27 @@
3232
import java.util.Properties;
3333
import org.hisp.dhis.external.conf.DhisConfigurationProvider;
3434
import org.hisp.dhis.test.config.PostgresDhisConfigurationProvider;
35-
import org.junit.jupiter.api.extension.AfterAllCallback;
36-
import org.junit.jupiter.api.extension.ExtensionContext;
35+
import org.junit.jupiter.api.extension.Extension;
3736
import org.springframework.context.annotation.Bean;
3837
import org.testcontainers.containers.MinIOContainer;
3938

4039
/**
4140
* Use this configuration for tests relying on MinIO storage running in a Docker container. The
42-
* container is stopped after the tests in the class have completed. Just add to test class like
41+
* container is started once per JVM and shared across all test classes that use this extension;
42+
* Testcontainers' Ryuk reaper handles teardown on JVM exit. Just add to test class like
4343
*
4444
* <p>@ExtendWith(MinIOTestExtension.class)
4545
*
4646
* <p>@ContextConfiguration(classes = {MinIOConfig.class})
4747
*
48-
* <p>If there are many uses of this extension then it should be considered whether keeping the
49-
* container up for the entirety of the tests is more preferable, rather than starting/stopping
50-
* multiple containers.
51-
*
5248
* @author david mackessy
5349
*/
54-
public class MinIOTestExtension implements AfterAllCallback {
50+
public class MinIOTestExtension implements Extension {
51+
52+
public static final String MINIO_USER = "testuser";
53+
public static final String MINIO_PASSWORD = "testpassword";
5554

5655
private static final String S3_URL;
57-
private static final String MINIO_USER = "testuser";
58-
private static final String MINIO_PASSWORD = "testpassword";
5956
private static final MinIOContainer MIN_IO_CONTAINER;
6057

6158
static {
@@ -67,6 +64,13 @@ public class MinIOTestExtension implements AfterAllCallback {
6764
S3_URL = MIN_IO_CONTAINER.getS3URL();
6865
}
6966

67+
/**
68+
* Endpoint URL the running MinIO container is reachable on (e.g. {@code http://localhost:32812}).
69+
*/
70+
public static String s3Url() {
71+
return S3_URL;
72+
}
73+
7074
public static class DhisConfig {
7175
@Bean
7276
public DhisConfigurationProvider dhisConfigurationProvider() {
@@ -83,9 +87,4 @@ public DhisConfigurationProvider dhisConfigurationProvider() {
8387
return pgDhisConfig;
8488
}
8589
}
86-
87-
@Override
88-
public void afterAll(ExtensionContext context) {
89-
MIN_IO_CONTAINER.stop();
90-
}
9190
}

dhis-2/dhis-test-integration/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@
187187
<artifactId>dhis-support-test</artifactId>
188188
<scope>test</scope>
189189
</dependency>
190+
<dependency>
191+
<groupId>org.testcontainers</groupId>
192+
<artifactId>minio</artifactId>
193+
<scope>test</scope>
194+
</dependency>
190195
<dependency>
191196
<groupId>org.hisp.dhis.parser</groupId>
192197
<artifactId>dhis-antlr-expression-parser</artifactId>
@@ -393,6 +398,7 @@
393398
<ignoredUnusedDeclaredDependency>org.hisp.dhis:dhis-service-setting</ignoredUnusedDeclaredDependency>
394399
<ignoredUnusedDeclaredDependency>org.testcontainers:postgresql</ignoredUnusedDeclaredDependency>
395400
<ignoredUnusedDeclaredDependency>org.testcontainers:jdbc</ignoredUnusedDeclaredDependency>
401+
<ignoredUnusedDeclaredDependency>org.testcontainers:minio</ignoredUnusedDeclaredDependency>
396402
<!-- log4j-slf4j-impl is needed to log using slf4j see https://www.slf4j.org/codes.html#noProviders -->
397403
<ignoredUnusedDeclaredDependency>org.apache.logging.log4j:log4j-slf4j-impl</ignoredUnusedDeclaredDependency>
398404
<ignoredUnusedDeclaredDependency>org.hisp.dhis:dhis-service-audit-consumer</ignoredUnusedDeclaredDependency>

0 commit comments

Comments
 (0)