Skip to content

HDDS-16077. Add a Testcontainers module for Ozone - #10966

Open
rich7420 wants to merge 4 commits into
apache:masterfrom
rich7420:HDDS-16077
Open

HDDS-16077. Add a Testcontainers module for Ozone#10966
rich7420 wants to merge 4 commits into
apache:masterfrom
rich7420:HDDS-16077

Conversation

@rich7420

@rich7420 rich7420 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

The goal of this task is to provide a Testcontainers module, so JVM projects can start a single-node Ozone with S3 Gateway in integration tests, the same way they use the MinIO or LocalStack modules. Ozone has no Testcontainers module yet (org.testcontainers is not used anywhere in the repo). Motivated by the container-based test-framework interest (e.g. Trino) raised on HDDS-14893.

Scope=>
New published module ozone-testcontainers under hadoop-ozone.
An OzoneContainer (extends GenericContainer) that runs single-node Ozone with S3 Gateway by wrapping the all-in-one image (apache/ozone:-all-in-one, from HDDS-14452 / ozone-docker#49).
Accessors mirroring the MinIO/LocalStack modules: getS3Endpoint(), getAccessKey(), getSecretKey(), getRegion().
Wait strategy on the S3 Gateway port (9878); a smoke test doing S3 create/put/get with AWS SDK v2 (path-style + static credentials), skipped when Docker is unavailable.

A Note here=>
uses the all-in-one image today; a cleaner ozone local run based image (HDDS-15087) would be a future improvement, not a blocker.

Scope boundaries (intentional for this incubating, S3-focused first version)=>
S3-only: only the S3 Gateway port (9878) is exposed, so tests reach Ozone through the S3 API, the same shape as the MinIO/LocalStack modules. Reaching OM over RPC (ofs:// / OzoneClient) would need exposing the OM port plus an accessor, and secure/Kerberos mode is not covered yet. Both are reasonable follow-ups rather than blockers for this first version.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-16077

How was this patch tested?

https://github.com/rich7420/ozone/actions/runs/31161526340

Add ozone-testcontainers, a Testcontainers module so JVM integration tests can
start a single-node Ozone with S3 Gateway the same way they use the MinIO or
LocalStack modules.

OzoneContainer wraps the all-in-one image (apache/ozone:2.2.0-all-in-one, from
HDDS-14452 / ozone-docker#49) and exposes getS3Endpoint()/getAccessKey()/
getSecretKey()/getRegion(). Its wait strategy waits for the S3 Gateway port and
then runs "ozone admin safemode wait" inside the container, so the cluster is
ready for S3 operations as soon as start() returns. A smoke test drives
create/put/get with the AWS SDK v2 (path-style, static credentials) and is
skipped when Docker is unavailable.

Notes:
- Uses the all-in-one image today; an "ozone local run" based image (HDDS-15087)
  would be a future improvement, not a blocker.
- testcontainers and aws-sdk versions are declared in the module for now.

Relates to HDDS-14893.
…ainer

OzoneContainer extends GenericContainer (which defines equals) and adds
credential/region fields, so spotbugs flags EQ_DOESNT_OVERRIDE_EQUALS. A
Testcontainers container is an identity object, not a value object, so
equals() is intentionally not overridden; exclude the warning via the
module findbugs filter rather than add the spotbugs-annotations dependency.
Copilot AI lite review requested due to automatic review settings August 7, 2026 12:21
@rich7420 rich7420 changed the title Hdds 16077 HDDS-16077. Add a Testcontainers module for Ozone Aug 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new ozone-testcontainers Maven module that provides a Testcontainers OzoneContainer wrapper for running a single-node Ozone + S3 Gateway (via the all-in-one Docker image) and documents how to use it from JVM integration tests.

Changes:

  • Adds ozone-testcontainers to the hadoop-ozone reactor and introduces the new module with its dependencies.
  • Implements OzoneContainer (extends GenericContainer) with S3 endpoint/credential accessors and a readiness wait strategy (listening port + SCM safemode wait).
  • Adds a Docker-gated smoke test using AWS SDK v2, plus user-facing README and site documentation.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
hadoop-ozone/pom.xml Adds ozone-testcontainers to the hadoop-ozone multi-module build.
hadoop-ozone/ozone-testcontainers/pom.xml New module POM with Testcontainers + AWS SDK v2 test dependencies and SpotBugs config.
hadoop-ozone/ozone-testcontainers/src/main/java/org/apache/ozone/testcontainers/OzoneContainer.java Implements the Testcontainers wrapper and readiness strategy.
hadoop-ozone/ozone-testcontainers/src/main/java/org/apache/ozone/testcontainers/package-info.java Package-level documentation for the new module.
hadoop-ozone/ozone-testcontainers/src/test/java/org/apache/ozone/testcontainers/TestOzoneContainer.java Smoke test that starts the container and performs S3 create/put/get using AWS SDK v2.
hadoop-ozone/ozone-testcontainers/README.md Module README describing purpose, status, and how to run locally.
hadoop-ozone/ozone-testcontainers/dev-support/findbugsExcludeFile.xml SpotBugs suppression for EQ_DOESNT_OVERRIDE_EQUALS on OzoneContainer.
hadoop-hdds/docs/content/tools/Testcontainers.md Adds website documentation for using ozone-testcontainers.
Suppressed comments (1)

hadoop-ozone/ozone-testcontainers/pom.xml:73

  • <optional>true</optional> on a test-scoped dependency has no effect on the published artifact and is misleading. Remove it to keep the POM consistent with other Ozone test modules.
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>apache-client</artifactId>
      <scope>test</scope>
      <optional>true</optional>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +64 to +68
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
Comment on lines +49 to +71
S3Client s3 = S3Client.builder()
.endpointOverride(URI.create(ozone.getS3Endpoint()))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(ozone.getAccessKey(), ozone.getSecretKey())))
.region(Region.of(ozone.getRegion()))
.forcePathStyle(true)
.build();

String bucket = "test-bucket";
String key = "hello.txt";
String body = "hello ozone";

// The container is ready (out of safe mode) after start(), so no retry.
s3.createBucket(b -> b.bucket(bucket));
s3.putObject(b -> b.bucket(bucket).key(key), RequestBody.fromString(body));

ResponseBytes<GetObjectResponse> got =
s3.getObjectAsBytes(b -> b.bucket(bucket).key(key));

assertEquals(body, got.asUtf8String());
assertTrue(s3.listBuckets().buckets().stream()
.anyMatch(b -> b.name().equals(bucket)));
}
Comment on lines +47 to +57
S3Client s3 = S3Client.builder()
.endpointOverride(URI.create(ozone.getS3Endpoint()))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(ozone.getAccessKey(), ozone.getSecretKey())))
.region(Region.of(ozone.getRegion()))
.forcePathStyle(true)
.build();

s3.createBucket(b -> b.bucket("my-bucket"));
// ... put / get / list objects
}
@rich7420
rich7420 marked this pull request as draft August 7, 2026 14:21
…imple

- Wrap the S3Client in try-with-resources in the test and the docs example so
  it does not leak HTTP resources/threads.
- Remove slf4j-simple: the module already inherits slf4j-reload4j (test scope)
  from the parent, so adding it produced a second SLF4J binding.
@rich7420
rich7420 marked this pull request as ready for review August 7, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants