diff --git a/phoenix-core/src/it/java/org/apache/phoenix/rpc/UpdateCacheIT.java b/phoenix-core/src/it/java/org/apache/phoenix/rpc/UpdateCacheIT.java index 4de3304e6ee..1af5a3b5122 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/rpc/UpdateCacheIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/rpc/UpdateCacheIT.java @@ -40,8 +40,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.phoenix.end2end.NeedsOwnMiniClusterTest; import org.apache.phoenix.end2end.ParallelStatsDisabledIT; -import org.apache.phoenix.end2end.ParallelStatsDisabledTest; import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData; import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver; import org.apache.phoenix.query.ConnectionQueryServices; @@ -66,8 +66,24 @@ /** * Verifies the number of RPC calls from {@link MetaDataClient} updateCache() for transactional and * non-transactional tables. + * + *
Categorized as {@link NeedsOwnMiniClusterTest} so failsafe runs this class in its own forked + * JVM (reuseForks=false). The {@link #helpTestUpdateCache} helper wraps the JVM-singleton + * {@link ConnectionQueryServices} returned by {@code driver.getConnectionQueryServices(...)} in a + * Mockito spy. Because the Phoenix driver caches that CQS as a process-global singleton and the + * spy delegates to the real instance with {@code this} bound to the spy, every internal Phoenix + * call back through the services field is recorded in the spy's {@code InvocationContainerImpl}, + * holding strong references to all arguments. Under the {@code ParallelStatsDisabledTest} + * execution ({@code reuseForks=true}) this class previously ran in a fork that had already + * accumulated thousands of tests' worth of cached metadata, regions, and live ZK clients on the + * same singleton; combined with the spy's invocation-history retention, the fork was tipping over + * with {@code OutOfMemoryError: Java heap space} (5.8 GB heap dump from the ZK + * {@code main-SendThread}) on {@link #testUpdateCacheForNonTxnTable}. Running in its own JVM + * gives the test a fresh CQS singleton with no cross-test accumulation. This follows the same + * convention as {@code MetaDataEndPointIT} and other singleton-state-sensitive tests in this + * project. */ -@Category(ParallelStatsDisabledTest.class) +@Category(NeedsOwnMiniClusterTest.class) public class UpdateCacheIT extends ParallelStatsDisabledIT { private boolean isLastDDLTimestampValidationEnabled =