fix: stablize listing methods in MultipartManifest implementation
Description
This PR fixes some flaky tests found with NonDex, which explores non-determinism in tests. These tests can fail under different JVMs, hash seeds, etc.
The flaky tests:
- MultipartObjectAssemblerTest.addParts_withChecksum_allSuccessful_commit
- MultipartObjectAssemblerTest.addParts_allSuccessful_withRetryConfiguration_commit
- MultipartObjectAssemblerTest.addParts_allSuccessful_commit
- MultipartTransferManagerTest.awaitCompletion
Root Cause
MultipartManifestImpl stores parts in a HashMap, and listing methods such as listCompletedParts, listFailedParts iterate over parts. Since HashMap does not preserve any iteration order, the returned part lists are nondeterministic. However, multipart upload semantics process parts in ascending part number order. This mismatch caused flaky behavior when tests implicitly depend on ordered output.
Fix
Following the semantics of part numbers, we can use TreeMap to preserve the parts' order using the keys, with negligible overhead introduced.
Failure Reproduction
- Java version:
openjdk 21.0.8 2025-07-15 OpenJDK Runtime Environment (build 21.0.8+9-Ubuntu-0ubuntu124.04.1) OpenJDK 64-Bit Server VM (build 21.0.8+9-Ubuntu-0ubuntu124.04.1, mixed mode, sharing) - OS version:
Ubuntu 24.04.3 LTS
Build with the main branch and run tests with NonDex to observe the failure, for example:
mvn edu.illinois:nondex-maven-plugin:2.2.1:nondex -pl bmc-objectstorage/bmc-objectstorage-extensions \
-Dtest=MultipartObjectAssemblerTest -DnondexRuns=10 \
-Djacoco.skip -Drat.skip -Dpmd.skip -Denforcer.skip