Skip to content

HDDS-16084. Add ErrorProne to Ozone CI - #11056

Open
ivandika3 wants to merge 26 commits into
apache:masterfrom
ivandika3:HDDS-16084
Open

HDDS-16084. Add ErrorProne to Ozone CI#11056
ivandika3 wants to merge 26 commits into
apache:masterfrom
ivandika3:HDDS-16084

Conversation

@ivandika3

@ivandika3 ivandika3 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

ErrorProne is a well-known static analysis tool used in other ASF projects such as Celeborn, Druid, HBase, Solr, and Beam to catch common Java coding errors. It is lightweight compared with fbinfer (HDDS-15560).

This patch adds an ErrorProne CI check that fails when it finds any ERROR-severity bug patterns (https://errorprone.info/bugpatterns). All ErrorProne diagnostics are retained in diagnostics.txt; summary.txt contains only ERROR diagnostics or an explicit fallback for a non-diagnostic Maven failure, which is what the CI summary presents.

This patch also fixes all current ERROR-severity bug patterns in Ozone. The fixes are split into multiple commits. I have attached errorprone-error-fixes.md for the bug patterns and the possible risks. This caught real defects in CompactionDag and no-op assertions.

Behavior fixes included

  • CompactionDag pruning now removes pruned SST entries from compactionNodeMap; previously Map#remove received a node instead of its file-name key and therefore did nothing.
  • The valueOf(name()) conversions remove ordinal coupling. They are behavior-preserving for the currently matching protocol/error-code names; parity tests guard future enum additions, with the SCM security protocol’s two explicit historical exceptions covered separately.

WARNING diagnostics are intentionally not fixed in this patch; they can be handled by follow-up work. The ErrorProne ThreadSafe annotation is also deferred so it can be coordinated with fbinfer HDDS-15560.

Note for reviewer:

  • The possible risk is at the ProtobufBufferOrdinal rule (https://errorprone.info/bugpattern/ProtocolBufferOrdinal), but the current ResultCodes.valueOf(protoStatus.name()) mapping is covered by enum name-parity tests.
  • If we merge this, ongoing PRs may need to merge master because ErrorProne can reject existing code in their commits.

Generated by: GPT 5.6 Sol

What is the link to the Apache JIRA

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

How was this patch tested?

CI (Clean CI: https://github.com/ivandika3/ozone/actions/runs/32216855338).

@ivandika3
ivandika3 requested a review from Tejaskriya August 19, 2026 01:54
@ivandika3 ivandika3 changed the title HDDS-16084. Add ErrorProne into Ozone verification pipeline HDDS-16084. Add ErrorProne into Ozone CI Aug 19, 2026
@ivandika3 ivandika3 changed the title HDDS-16084. Add ErrorProne into Ozone CI HDDS-16084. Add ErrorProne to Ozone CI Aug 19, 2026
@ivandika3 ivandika3 added test build Pull request that modifies the build process labels Aug 19, 2026
@ivandika3
ivandika3 requested a review from smengcl August 19, 2026 09:44
@ivandika3 ivandika3 self-assigned this Aug 19, 2026
@ivandika3
ivandika3 requested a review from adoroszlai August 19, 2026 10:24
@ivandika3
ivandika3 marked this pull request as ready for review August 19, 2026 16:06

@rich7420 rich7420 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.

The ErrorProne gate looks well-built and CI is green. One thing: a few "cleanup" fixes are actually behavior changes / real bug fixes bundled in a lint PR worth a test and a description note. Two comments beloww

omKeyLocationInfoGroup.getLocationList()
.stream().map(omKeyLocationInfo -> pipelines.add(
omKeyLocationInfo.getPipeline())));
omKeyInfo.getKeyLocationVersions().forEach(omKeyLocationInfoGroup ->

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.

Not a test-lint fix — getPipelines() returned empty before (the old stream().map(...add...) was never consumed), so this actually changes what Recon reports. Please add a test for a non-empty pipeline list and call the behavior fix out in the description instead of under "Fix tests".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review, added a test for this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added the non-empty pipeline regression test and updated the PR description under “Behavior fixes included” to explicitly call out the changed /api/v1/containers payload.

if (resp.getStatus() != OK) {
throw new OMException(resp.getMessage(),
ResultCodes.values()[resp.getStatus().ordinal()]);
ResultCodes.valueOf(resp.getStatus().name()));

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.

valueOf(name()) is the right pattern, but this changes error-code translation for any status where the Status and ResultCodes ordinals differ. Is this an intended behavior fix? If so, a small test (a status past the first divergence) + a note in the description would help.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

error-code translation for any status where the Status and ResultCodes ordinals differ

I'm not sure I follow this, this patch does not use Status ordinal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Verified this is behavior-preserving for the current enums: TestResultCodes asserts equal sizes, name parity, and valueOf(name()) conversion for every value. I also clarified the removal of ordinal coupling in the PR description.

@rich7420

Copy link
Copy Markdown
Contributor

@ivandika3 thanks for the patch!

@smengcl smengcl 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.

Thanks @ivandika3 for the addition.

Comment thread hadoop-ozone/dev-support/checks/errorprone.sh Outdated
Comment thread hadoop-ozone/dev-support/checks/errorprone.sh Outdated
ivandika3 and others added 6 commits August 24, 2026 18:20
Co-authored-by: Siyao Meng <50227127+smengcl@users.noreply.github.com>
# Conflicts:
#	hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneClientRetriesOnExceptions.java
#	hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/ReconContainerMetadataManagerImpl.java
# Conflicts:
#	hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneClientRetriesOnExceptions.java
#	hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMClientRequestWithUserInfo.java

@peterxcli peterxcli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice work — adding Error Prone is clearly worth it, and the ERROR-level fixes catch several genuine bugs (CompactionDag, ReconContainerMetadataManagerImpl, the dropped includeNonStandardContainers row in ContainerBalancerConfiguration.toString(), and a good number of no-op assertions).

I went through the whole diff. Things I verified and am happy with:

  • The -Perrorprone profile really does apply to default-compile as well as default-testCompile — I ran mvn -Perrorprone -X -pl hadoop-hdds/config -am test-compile locally and confirmed combine.children="append" merges the Error Prone args with the existing -AartifactId=${project.artifactId} arg rather than replacing it. Error Prone diagnostics are emitted for both main and test sources.
  • SCMException.ResultCodes and OMException.ResultCodes: the values()[ordinal()] -> valueOf(name()) conversions are safe, because TestSCMExceptionResultCodes and TestResultCodes both assert equal enum length and exact name equality. SCMSecretKeyException.ErrorCode also matches the proto exactly. On your ProtocolBufferOrdinal note in the description — agreed, those three are fine; the fourth one is the odd one out (inline comment below).
  • SCM_ROOT_CA_PREFIX is SCM_ROOT_CA + "@" with no format specifier, so dropping String.format(...) is a no-op and now matches HASecurityUtils#initializeSecurity (SCM_ROOT_CA_PREFIX + hostname).
  • OmRangerSyncArgs.newServiceVersion is a primitive long, so the removed Objects.requireNonNull could never fire.
  • DelegatingProperties#contains -> containsValue: Hashtable#contains already has value semantics, so this is behaviour-preserving and just removes the confusion.
  • BucketEndpoint / VolumeEndpoint: both keep the @Inject constructor that assigns the field, so removing the redundant field annotation is safe.
  • ContainerBalancerConfiguration#toString: I counted — 17 %-50s %X%n rows = 34 conversions against 34 arguments after the patch. Correct.
  • TestECBlockInputStream: 5000 * ONEMB overflowed int to ~904 MB; 5000L restores the intended "very large block", and hasSufficientLocations() still holds.
  • TestReconContainerManager: State.{UNHEALTHY,INVALID,DELETED}.getNumber() = 5/6/7 vs ordinals 4/5/6, so the container IDs shift to 125/126/127 — no collision with the other IDs used in that class.
  • The errorprone check is wired correctly (#checks:basic marker, check_needs_bats picks up .bats$), and the check took ~10.5 min in your run, comfortably inside the 30-minute job timeout.

Seven things I'd like your thoughts on, left as inline comments. Only the first is something I'd consider blocking; the rest are follow-ups or nits.

  1. errorprone.sh bypasses _post_process.sh, so a Maven failure that isn't an Error Prone ERROR reports failures=0 with a misleading summary.
  2. The CompactionDag prune fix is a real behaviour change with no regression test.
  3. SCMSecurityProtocolProtos.Status -> SCMSecurityException.ErrorCode is the one name mapping with no parity test, and it already has a name with no counterpart.
  4. TestHSync now asserts hasSize() on a table scanned across the whole shared MiniOzoneCluster.
  5. The ReconContainerMetadataManagerImpl fix changes a public Recon REST payload — worth a release note.
  6. TestRocksDiffUtils drops a map entry rather than de-duplicating it.
  7. Two @SuppressWarnings without a justification comment.

On your merge-order note: agreed, this will need master merged into in-flight PRs, and it might be worth landing the CI plumbing and the ERROR fixes as separate commits on master so a revert of one doesn't drag the other along.

Comment thread hadoop-ozone/dev-support/checks/errorprone.sh Outdated

@peterxcli peterxcli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ivandika3 Thanks for the update, other LGTM.

Comment thread hadoop-ozone/dev-support/checks/errorprone.sh Outdated
ReconOMMetadataManager omMetadataManager = mock(ReconOMMetadataManager.class);
Table<String, OmKeyInfo> keyTable = mock(Table.class);
when(omMetadataManager.getKeyTable(BucketLayout.LEGACY)).thenReturn(keyTable);
when(keyTable.getSkipCache(key1)).thenReturn(new OmKeyInfo.Builder()

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.

getSkipCache() reads persisted OM rows, whose OmKeyInfo codec omits pipeline data via getProtobuf(true, ...). This mock bypasses that codec, so current OM rows still produce an empty pipeline list. Please test through the real table and source the pipeline from data that is actually retained.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. The mocked getSkipCache() bypassed OM metadata serialization. Persisted OmKeyInfo omits pipeline information, so a real table cannot supply pipelines on this path. I reverted the pipeline population change and its mock-only test rather than asserting behavior that does not exist in production.

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.

thanks for the update

DIAGNOSTIC_FILE="$REPORT_DIR/diagnostics.txt"
OUTPUT_LOG=$(mktemp)

MAVEN_OPTIONS='-B -fae --no-transfer-progress -Perrorprone -DskipDocs -DskipRecon -DskipShade'

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.

Please cover ozonefs-hadoop2 and ozonefs-hadoop3: -DskipShade removes both from this reactor, so this check still passes with an Error Prone ERROR in those sources. Hadoop2 copied sources also match the global -XepExcludedPaths exclusion.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed. The check no longer sets -DskipShade, so the build-with-ozonefs profile includes both OzoneFS compatibility modules. The excluded-path regex now keeps ozonefs-hadoop2/target/generated-sources/java in scope while continuing to exclude other generated sources.

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.

thanks for the update

Comment thread .github/ci.md Outdated
- bats: [Checks](../hadoop-ozone/dev-support/checks/bats.sh) bash scripts, (using the [Bash Automated Testing System](https://github.com/bats-core/bats-core#bats-core-bash-automated-testing-system-2018))
- checkstyle: [Runs](../hadoop-ozone/dev-support/checks/checkstyle.sh) 'mvn checkstyle' plugin to confirm Java source abides by Ozone coding conventions
- docs: [Builds](../hadoop-ozone/dev-support/checks/docs.sh) website with [Hugo](https://gohugo.io/)
- errorprone: [Runs](../hadoop-ozone/dev-support/checks/errorprone.sh) Error Prone static analysis during Java compilation. The check reports all warning and error diagnostics in `summary.txt` and fails for errors.

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.

nit: please update this to match errorprone.sh: all diagnostics go to diagnostics.txt, while summary.txt contains only ERROR/fallback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Pull request that modifies the build process test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants