This is an automated email from the ASF dual-hosted git repository.
lhotari pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new d4893d1b26a [fix][tests] Fix Mockito mocks memory leak (#17851)
d4893d1b26a is described below
commit d4893d1b26a128329c9fe66f86454dd2a15422aa
Author: Lari Hotari <[email protected]>
AuthorDate: Tue Sep 27 23:27:33 2022 +0300
[fix][tests] Fix Mockito mocks memory leak (#17851)
* Call cleanup method in finally block to ensure it's not skipped
* Clear invocations for the mocks that are left around without cleanup
* Cleanup PulsarService and PulsarAdmin mocks/spies in
MockedPulsarServiceBaseTest
* Don't record invocations at all for PulsarService and PulsarAdmin in
MockedPulsarServiceBaseTest
* Don't record invocations for spies by default
* Simplify reseting mocks
* Fix PersistentTopicTest
* Fix TokenExpirationProducerConsumerTest
* Fix SimpleLoadManagerImplTest
* Fix FilterEntryTest
---
.../pulsar/tests/MockitoCleanupListener.java | 13 +++++----
.../tests/MockitoThreadLocalStateCleaner.java | 19 +++++++++++++
.../org/apache/pulsar/broker/BrokerTestUtil.java | 33 ++++++++++++++++++++++
.../broker/auth/MockedPulsarServiceBaseTest.java | 22 +++++++++++----
.../loadbalance/SimpleLoadManagerImplTest.java | 4 +--
.../pulsar/broker/service/PersistentTopicTest.java | 13 +++++----
.../broker/service/ServerCnxAuthorizationTest.java | 26 ++++++++---------
.../broker/service/plugin/FilterEntryTest.java | 6 ++--
.../api/TokenExpirationProduceConsumerTest.java | 8 ++++++
.../client/impl/BrokerClientIntegrationTest.java | 8 ++++--
10 files changed, 115 insertions(+), 37 deletions(-)
diff --git
a/buildtools/src/main/java/org/apache/pulsar/tests/MockitoCleanupListener.java
b/buildtools/src/main/java/org/apache/pulsar/tests/MockitoCleanupListener.java
index 73fff1bb7e2..ff590c05bbc 100644
---
a/buildtools/src/main/java/org/apache/pulsar/tests/MockitoCleanupListener.java
+++
b/buildtools/src/main/java/org/apache/pulsar/tests/MockitoCleanupListener.java
@@ -38,11 +38,15 @@ public class MockitoCleanupListener extends
BetweenTestClassesListenerAdapter {
@Override
protected void onBetweenTestClasses(Class<?> endedTestClass, Class<?>
startedTestClass) {
if (MOCKITO_CLEANUP_ENABLED) {
- if (MockitoThreadLocalStateCleaner.INSTANCE.isEnabled()) {
- LOG.info("Cleaning up Mockito's
ThreadSafeMockingProgress.MOCKING_PROGRESS_PROVIDER thread local state.");
- MockitoThreadLocalStateCleaner.INSTANCE.cleanup();
+ try {
+ if (MockitoThreadLocalStateCleaner.INSTANCE.isEnabled()) {
+ LOG.info(
+ "Cleaning up Mockito's
ThreadSafeMockingProgress.MOCKING_PROGRESS_PROVIDER thread local state.");
+ MockitoThreadLocalStateCleaner.INSTANCE.cleanup();
+ }
+ } finally {
+ cleanupMockitoInline();
}
- cleanupMockitoInline();
}
}
@@ -54,5 +58,4 @@ public class MockitoCleanupListener extends
BetweenTestClassesListenerAdapter {
private void cleanupMockitoInline() {
Mockito.framework().clearInlineMocks();
}
-
}
diff --git
a/buildtools/src/main/java/org/apache/pulsar/tests/MockitoThreadLocalStateCleaner.java
b/buildtools/src/main/java/org/apache/pulsar/tests/MockitoThreadLocalStateCleaner.java
index 3c383fb1d92..4fe4ea7e0e2 100644
---
a/buildtools/src/main/java/org/apache/pulsar/tests/MockitoThreadLocalStateCleaner.java
+++
b/buildtools/src/main/java/org/apache/pulsar/tests/MockitoThreadLocalStateCleaner.java
@@ -23,6 +23,8 @@ import java.lang.reflect.InvocationTargetException;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
+import org.mockito.internal.stubbing.InvocationContainerImpl;
+import org.mockito.internal.util.MockUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,16 +74,33 @@ public final class MockitoThreadLocalStateCleaner {
LOG.warn("Invalid usage of Mockito detected on thread
{}."
+ " There is ongoing stubbing on mock
of class={} instance={}",
thread, mock.getClass().getName(), mock);
+ try {
+ clearInvocations(thread, mock);
+ } catch (Exception e) {
+ LOG.warn("Clearing invocations failed", e);
+ }
}
}
} catch (NoSuchMethodException | IllegalAccessException e) {
LOG.debug("Cannot call validateState on existing Mockito
ProgressProvider");
} catch (InvocationTargetException e) {
LOG.warn("Invalid usage of Mockito detected on thread {}",
thread, e.getCause());
+ } catch (Exception e) {
+ LOG.warn("Removing {} instance from thread {} failed",
mockingProgress.getClass().getName(), thread, e);
}
});
}
+ private static void clearInvocations(Thread thread, Object mock) {
+ InvocationContainerImpl invocationContainer =
MockUtil.getInvocationContainer(mock);
+ if (invocationContainer.hasInvocationForPotentialStubbing()) {
+ LOG.warn("Mock contains registered invocations that should be
cleared. thread {} class={} "
+ + "instance={}",
+ thread, mock.getClass().getName(), mock);
+ invocationContainer.clearInvocations();
+ }
+ }
+
public boolean isEnabled() {
return MOCKING_PROGRESS_PROVIDER != null;
}
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/BrokerTestUtil.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/BrokerTestUtil.java
index 224060c9d91..7d7a3ebd262 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/BrokerTestUtil.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/BrokerTestUtil.java
@@ -34,14 +34,47 @@ public class BrokerTestUtil {
* Creates a Mockito spy directly without an intermediate instance to spy.
* This is to address flaky test issue where a spy created with a given
instance fails with
* {@link org.mockito.exceptions.misusing.WrongTypeOfReturnValue}
exception.
+ * The spy is stub-only which does not record method invocations.
*
* @param classToSpy the class to spy
* @param args the constructor arguments to use when creating the spy
instance
* @return a spy of the provided class created with given constructor
arguments
*/
public static <T> T spyWithClassAndConstructorArgs(Class<T> classToSpy,
Object... args) {
+ return Mockito.mock(classToSpy, Mockito.withSettings()
+ .useConstructor(args)
+ .defaultAnswer(Mockito.CALLS_REAL_METHODS)
+ .stubOnly());
+ }
+
+ /**
+ * Creates a Mockito spy directly without an intermediate instance to spy.
+ * This is to address flaky test issue where a spy created with a given
instance fails with
+ * {@link org.mockito.exceptions.misusing.WrongTypeOfReturnValue}
exception.
+ * The spy records method invocations.
+ *
+ * @param classToSpy the class to spy
+ * @param args the constructor arguments to use when creating the spy
instance
+ * @return a spy of the provided class created with given constructor
arguments
+ */
+ public static <T> T
spyWithClassAndConstructorArgsRecordingInvocations(Class<T> classToSpy,
Object... args) {
return Mockito.mock(classToSpy, Mockito.withSettings()
.useConstructor(args)
.defaultAnswer(Mockito.CALLS_REAL_METHODS));
}
+
+ /**
+ * Create a Mockito spy that is stub-only which does not record method
invocations,
+ * thus saving memory but disallowing verification of invocations.
+ *
+ * @param object to spy on
+ * @return a spy of the real object
+ * @param <T> type of object
+ */
+ public static <T> T spyWithoutRecordingInvocations(T object) {
+ return Mockito.mock((Class<T>) object.getClass(),
Mockito.withSettings()
+ .spiedInstance(object)
+ .defaultAnswer(Mockito.CALLS_REAL_METHODS)
+ .stubOnly());
+ }
}
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/auth/MockedPulsarServiceBaseTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/auth/MockedPulsarServiceBaseTest.java
index d3eea7996a1..62fd69b3811 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/auth/MockedPulsarServiceBaseTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/auth/MockedPulsarServiceBaseTest.java
@@ -19,6 +19,7 @@
package org.apache.pulsar.broker.auth;
import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgs;
+import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithoutRecordingInvocations;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
@@ -47,6 +48,8 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.TimeoutHandler;
import org.apache.bookkeeper.client.BookKeeper;
import org.apache.bookkeeper.client.EnsemblePlacementPolicy;
import org.apache.bookkeeper.client.PulsarMockBookKeeper;
@@ -78,12 +81,11 @@ import org.apache.pulsar.tests.TestRetrySupport;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.MockZooKeeper;
import org.apache.zookeeper.data.ACL;
+import org.mockito.Mockito;
+import org.mockito.internal.util.MockUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.ws.rs.container.AsyncResponse;
-import javax.ws.rs.container.TimeoutHandler;
-
/**
* Base class for all tests that need a Pulsar instance without a ZK and BK
cluster.
*/
@@ -232,6 +234,9 @@ public abstract class MockedPulsarServiceBaseTest extends
TestRetrySupport {
// an NPE in shutdown, obscuring the real error
if (admin != null) {
admin.close();
+ if (MockUtil.isMock(admin)) {
+ Mockito.reset(admin);
+ }
admin = null;
}
if (pulsarClient != null) {
@@ -248,6 +253,7 @@ public abstract class MockedPulsarServiceBaseTest extends
TestRetrySupport {
resetConfig();
if (mockBookKeeper != null) {
mockBookKeeper.reallyShutdown();
+ Mockito.reset(mockBookKeeper);
mockBookKeeper = null;
}
if (mockZooKeeperGlobal != null) {
@@ -304,6 +310,9 @@ public abstract class MockedPulsarServiceBaseTest extends
TestRetrySupport {
// set shutdown timeout to 0 for forceful shutdown
pulsar.getConfiguration().setBrokerShutdownTimeoutMs(0L);
pulsar.close();
+ if (MockUtil.isMock(pulsar)) {
+ Mockito.reset(pulsar);
+ }
pulsar = null;
// Simulate cleanup of ephemeral nodes
//mockZooKeeper.delete("/loadbalance/brokers/localhost:" +
pulsar.getConfiguration().getWebServicePort(), -1);
@@ -320,12 +329,15 @@ public abstract class MockedPulsarServiceBaseTest extends
TestRetrySupport {
if (admin != null) {
admin.close();
+ if (MockUtil.isMock(admin)) {
+ Mockito.reset(admin);
+ }
}
PulsarAdminBuilder pulsarAdminBuilder =
PulsarAdmin.builder().serviceHttpUrl(brokerUrl != null
? brokerUrl.toString()
: brokerUrlTls.toString());
customizeNewPulsarAdminBuilder(pulsarAdminBuilder);
- admin = spy(pulsarAdminBuilder.build());
+ admin = spyWithoutRecordingInvocations(pulsarAdminBuilder.build());
}
protected void customizeNewPulsarAdminBuilder(PulsarAdminBuilder
pulsarAdminBuilder) {
@@ -338,7 +350,7 @@ public abstract class MockedPulsarServiceBaseTest extends
TestRetrySupport {
protected PulsarService
startBrokerWithoutAuthorization(ServiceConfiguration conf) throws Exception {
conf.setBrokerShutdownTimeoutMs(0L);
- PulsarService pulsar = spy(newPulsarService(conf));
+ PulsarService pulsar =
spyWithoutRecordingInvocations(newPulsarService(conf));
setupBrokerMocks(pulsar);
beforePulsarStartMocks(pulsar);
pulsar.start();
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/SimpleLoadManagerImplTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/SimpleLoadManagerImplTest.java
index 8ac7a94d208..9e17cf85155 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/SimpleLoadManagerImplTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/SimpleLoadManagerImplTest.java
@@ -18,7 +18,7 @@
*/
package org.apache.pulsar.broker.loadbalance;
-import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgs;
+import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgsRecordingInvocations;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -335,7 +335,7 @@ public class SimpleLoadManagerImplTest {
@Test(enabled = true)
public void testDoLoadShedding() throws Exception {
- SimpleLoadManagerImpl loadManager =
spyWithClassAndConstructorArgs(SimpleLoadManagerImpl.class, pulsar1);
+ SimpleLoadManagerImpl loadManager =
spyWithClassAndConstructorArgsRecordingInvocations(SimpleLoadManagerImpl.class,
pulsar1);
PulsarResourceDescription rd = new PulsarResourceDescription();
rd.put("memory", new ResourceUsage(1024, 4096));
rd.put("cpu", new ResourceUsage(10, 100));
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/PersistentTopicTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/PersistentTopicTest.java
index 1404ce7c798..2d8ff60fc27 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/PersistentTopicTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/PersistentTopicTest.java
@@ -19,6 +19,7 @@
package org.apache.pulsar.broker.service;
import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgs;
+import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgsRecordingInvocations;
import static
org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.createMockBookKeeper;
import static
org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.createMockZooKeeper;
import static
org.apache.pulsar.common.protocol.Commands.DEFAULT_CONSUMER_EPOCH;
@@ -230,7 +231,7 @@ public class PersistentTopicTest extends
MockedBookKeeperTestCase {
doReturn(brokerService).when(pulsar).getBrokerService();
});
// Mock serviceCnx.
- serverCnx = spyWithClassAndConstructorArgs(ServerCnx.class, pulsar);
+ serverCnx =
spyWithClassAndConstructorArgsRecordingInvocations(ServerCnx.class, pulsar);
doReturn(true).when(serverCnx).isActive();
doReturn(true).when(serverCnx).isWritable();
doReturn(new InetSocketAddress("localhost",
1234)).when(serverCnx).clientAddress();
@@ -369,7 +370,7 @@ public class PersistentTopicTest extends
MockedBookKeeperTestCase {
@Test
public void testDispatcherMultiConsumerReadFailed() throws Exception {
- PersistentTopic topic =
spyWithClassAndConstructorArgs(PersistentTopic.class, successTopicName,
ledgerMock, brokerService);
+ PersistentTopic topic =
spyWithClassAndConstructorArgsRecordingInvocations(PersistentTopic.class,
successTopicName, ledgerMock, brokerService);
ManagedCursor cursor = mock(ManagedCursor.class);
when(cursor.getName()).thenReturn("cursor");
Subscription subscription = mock(Subscription.class);
@@ -381,7 +382,7 @@ public class PersistentTopicTest extends
MockedBookKeeperTestCase {
@Test
public void testDispatcherSingleConsumerReadFailed() throws Exception {
- PersistentTopic topic =
spyWithClassAndConstructorArgs(PersistentTopic.class, successTopicName,
ledgerMock, brokerService);
+ PersistentTopic topic =
spyWithClassAndConstructorArgsRecordingInvocations(PersistentTopic.class,
successTopicName, ledgerMock, brokerService);
ManagedCursor cursor = mock(ManagedCursor.class);
when(cursor.getName()).thenReturn("cursor");
PersistentDispatcherSingleActiveConsumer dispatcher = new
PersistentDispatcherSingleActiveConsumer(cursor,
@@ -2105,13 +2106,13 @@ public class PersistentTopicTest extends
MockedBookKeeperTestCase {
.concurrencyLevel(1)
.build();
// This subscription is connected by consumer.
- PersistentSubscription nonDeletableSubscription1 =
spyWithClassAndConstructorArgs(PersistentSubscription.class, topic,
"nonDeletableSubscription1", cursorMock, false);
+ PersistentSubscription nonDeletableSubscription1 =
spyWithClassAndConstructorArgsRecordingInvocations(PersistentSubscription.class,
topic, "nonDeletableSubscription1", cursorMock, false);
subscriptions.put(nonDeletableSubscription1.getName(),
nonDeletableSubscription1);
// This subscription is not connected by consumer.
- PersistentSubscription deletableSubscription1 =
spyWithClassAndConstructorArgs(PersistentSubscription.class, topic,
"deletableSubscription1", cursorMock, false);
+ PersistentSubscription deletableSubscription1 =
spyWithClassAndConstructorArgsRecordingInvocations(PersistentSubscription.class,
topic, "deletableSubscription1", cursorMock, false);
subscriptions.put(deletableSubscription1.getName(),
deletableSubscription1);
// This subscription is replicated.
- PersistentSubscription nonDeletableSubscription2 =
spyWithClassAndConstructorArgs(PersistentSubscription.class, topic,
"nonDeletableSubscription2", cursorMock, true);
+ PersistentSubscription nonDeletableSubscription2 =
spyWithClassAndConstructorArgsRecordingInvocations(PersistentSubscription.class,
topic, "nonDeletableSubscription2", cursorMock, true);
subscriptions.put(nonDeletableSubscription2.getName(),
nonDeletableSubscription2);
Field field = topic.getClass().getDeclaredField("subscriptions");
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxAuthorizationTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxAuthorizationTest.java
index 6d108ce675d..c005b96d004 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxAuthorizationTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/ServerCnxAuthorizationTest.java
@@ -19,7 +19,7 @@
package org.apache.pulsar.broker.service;
-import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgs;
+import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgsRecordingInvocations;
import static
org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.createMockBookKeeper;
import static
org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest.createMockZooKeeper;
import static org.mockito.ArgumentMatchers.argThat;
@@ -41,7 +41,6 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
-import javax.crypto.SecretKey;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
@@ -50,6 +49,7 @@ import java.util.Collections;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
+import javax.crypto.SecretKey;
import org.apache.bookkeeper.common.util.OrderedExecutor;
import org.apache.bookkeeper.mledger.ManagedLedgerFactory;
import org.apache.pulsar.broker.PulsarService;
@@ -113,7 +113,7 @@ public class ServerCnxAuthorizationTest {
+ Base64.getEncoder().encodeToString(SECRET_KEY.getEncoded()));
svcConfig.setProperties(properties);
- pulsar = spyWithClassAndConstructorArgs(PulsarService.class,
svcConfig);
+ pulsar =
spyWithClassAndConstructorArgsRecordingInvocations(PulsarService.class,
svcConfig);
doReturn(new
DefaultSchemaRegistryService()).when(pulsar).getSchemaRegistryService();
doReturn(svcConfig).when(pulsar).getConfiguration();
@@ -135,21 +135,21 @@ public class ServerCnxAuthorizationTest {
doReturn(store).when(pulsar).getLocalMetadataStore();
doReturn(store).when(pulsar).getConfigurationMetadataStore();
- pulsarResources =
spyWithClassAndConstructorArgs(PulsarResources.class, store, store);
+ pulsarResources =
spyWithClassAndConstructorArgsRecordingInvocations(PulsarResources.class,
store, store);
PulsarServiceMockSupport.mockPulsarServiceProps(pulsar, () -> {
doReturn(pulsarResources).when(pulsar).getPulsarResources();
});
NamespaceResources namespaceResources =
- spyWithClassAndConstructorArgs(NamespaceResources.class,
store, store, 30);
+
spyWithClassAndConstructorArgsRecordingInvocations(NamespaceResources.class,
store, store, 30);
doReturn(namespaceResources).when(pulsarResources).getNamespaceResources();
- TenantResources tenantResources =
spyWithClassAndConstructorArgs(TenantResources.class, store, 30);
+ TenantResources tenantResources =
spyWithClassAndConstructorArgsRecordingInvocations(TenantResources.class,
store, 30);
doReturn(tenantResources).when(pulsarResources).getTenantResources();
doReturn(CompletableFuture.completedFuture(Optional.of(TenantInfo.builder().build()))).when(tenantResources)
.getTenantAsync("public");
- brokerService = spyWithClassAndConstructorArgs(BrokerService.class,
pulsar, eventLoopGroup);
+ brokerService =
spyWithClassAndConstructorArgsRecordingInvocations(BrokerService.class, pulsar,
eventLoopGroup);
BrokerInterceptor interceptor = mock(BrokerInterceptor.class);
doReturn(interceptor).when(brokerService).getInterceptor();
PulsarServiceMockSupport.mockPulsarServiceProps(pulsar, () -> {
@@ -162,7 +162,7 @@ public class ServerCnxAuthorizationTest {
public void testVerifyOriginalPrincipalWithAuthDataForwardedFromProxy()
throws Exception {
doReturn(true).when(svcConfig).isAuthenticateOriginalAuthData();
- ServerCnx serverCnx = spyWithClassAndConstructorArgs(ServerCnx.class,
pulsar);
+ ServerCnx serverCnx =
spyWithClassAndConstructorArgsRecordingInvocations(ServerCnx.class, pulsar);
ChannelHandlerContext channelHandlerContext =
mock(ChannelHandlerContext.class);
Channel channel = mock(Channel.class);
ChannelPipeline channelPipeline = mock(ChannelPipeline.class);
@@ -198,7 +198,7 @@ public class ServerCnxAuthorizationTest {
assertEquals(serverCnx.getAuthState().getAuthRole(), PROXY_PRINCIPAL);
AuthorizationService authorizationService =
- spyWithClassAndConstructorArgs(AuthorizationService.class,
svcConfig, pulsarResources);
+
spyWithClassAndConstructorArgsRecordingInvocations(AuthorizationService.class,
svcConfig, pulsarResources);
doReturn(authorizationService).when(brokerService).getAuthorizationService();
// lookup
@@ -268,7 +268,7 @@ public class ServerCnxAuthorizationTest {
public void testVerifyOriginalPrincipalWithoutAuthDataForwardedFromProxy()
throws Exception {
doReturn(false).when(svcConfig).isAuthenticateOriginalAuthData();
- ServerCnx serverCnx = spyWithClassAndConstructorArgs(ServerCnx.class,
pulsar);
+ ServerCnx serverCnx =
spyWithClassAndConstructorArgsRecordingInvocations(ServerCnx.class, pulsar);
ChannelHandlerContext channelHandlerContext =
mock(ChannelHandlerContext.class);
Channel channel = mock(Channel.class);
ChannelPipeline channelPipeline = mock(ChannelPipeline.class);
@@ -299,7 +299,7 @@ public class ServerCnxAuthorizationTest {
assertEquals(serverCnx.getAuthState().getAuthRole(), PROXY_PRINCIPAL);
AuthorizationService authorizationService =
- spyWithClassAndConstructorArgs(AuthorizationService.class,
svcConfig, pulsarResources);
+
spyWithClassAndConstructorArgsRecordingInvocations(AuthorizationService.class,
svcConfig, pulsarResources);
doReturn(authorizationService).when(brokerService).getAuthorizationService();
// lookup
@@ -360,7 +360,7 @@ public class ServerCnxAuthorizationTest {
@Test
public void testVerifyAuthRoleAndAuthDataFromDirectConnectionBroker()
throws Exception {
- ServerCnx serverCnx = spyWithClassAndConstructorArgs(ServerCnx.class,
pulsar);
+ ServerCnx serverCnx =
spyWithClassAndConstructorArgsRecordingInvocations(ServerCnx.class, pulsar);
ChannelHandlerContext channelHandlerContext =
mock(ChannelHandlerContext.class);
Channel channel = mock(Channel.class);
@@ -391,7 +391,7 @@ public class ServerCnxAuthorizationTest {
assertEquals(serverCnx.getAuthState().getAuthRole(), CLIENT_PRINCIPAL);
AuthorizationService authorizationService =
- spyWithClassAndConstructorArgs(AuthorizationService.class,
svcConfig, pulsarResources);
+
spyWithClassAndConstructorArgsRecordingInvocations(AuthorizationService.class,
svcConfig, pulsarResources);
doReturn(authorizationService).when(brokerService).getAuthorizationService();
// lookup
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/plugin/FilterEntryTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/plugin/FilterEntryTest.java
index a5f8b5ab38f..c10ab392da0 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/plugin/FilterEntryTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/plugin/FilterEntryTest.java
@@ -19,6 +19,7 @@
package org.apache.pulsar.broker.service.plugin;
import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgs;
+import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgsRecordingInvocations;
import static
org.apache.pulsar.client.api.SubscriptionInitialPosition.Earliest;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -36,7 +37,6 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
-
import lombok.extern.slf4j.Slf4j;
import org.apache.bookkeeper.mledger.Entry;
import org.apache.bookkeeper.mledger.impl.PositionImpl;
@@ -165,9 +165,9 @@ public class FilterEntryTest extends BrokerTestBase {
field.setAccessible(true);
NarClassLoader narClassLoader = mock(NarClassLoader.class);
EntryFilter filter1 = new EntryFilterTest();
- EntryFilterWithClassLoader loader1 =
spyWithClassAndConstructorArgs(EntryFilterWithClassLoader.class, filter1,
narClassLoader);
+ EntryFilterWithClassLoader loader1 =
spyWithClassAndConstructorArgsRecordingInvocations(EntryFilterWithClassLoader.class,
filter1, narClassLoader);
EntryFilter filter2 = new EntryFilter2Test();
- EntryFilterWithClassLoader loader2 =
spyWithClassAndConstructorArgs(EntryFilterWithClassLoader.class, filter2,
narClassLoader);
+ EntryFilterWithClassLoader loader2 =
spyWithClassAndConstructorArgsRecordingInvocations(EntryFilterWithClassLoader.class,
filter2, narClassLoader);
field.set(dispatcher, ImmutableList.of(loader1, loader2));
Producer<String> producer = pulsarClient.newProducer(Schema.STRING)
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/TokenExpirationProduceConsumerTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/TokenExpirationProduceConsumerTest.java
index 6b26d174042..520c8743cbe 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/TokenExpirationProduceConsumerTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/TokenExpirationProduceConsumerTest.java
@@ -36,6 +36,8 @@ import org.apache.pulsar.common.policies.data.AuthAction;
import org.apache.pulsar.common.policies.data.ClusterData;
import org.apache.pulsar.common.policies.data.TenantInfoImpl;
import org.awaitility.Awaitility;
+import org.mockito.Mockito;
+import org.mockito.internal.util.MockUtil;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -64,6 +66,12 @@ public class TokenExpirationProduceConsumerTest extends
TlsProducerConsumerBase
// Start Broker
super.init();
+ if (admin != null) {
+ admin.close();
+ if (MockUtil.isMock(admin)) {
+ Mockito.reset(admin);
+ }
+ }
admin = getAdmin(ADMIN_TOKEN);
admin.clusters().createCluster(configClusterName,
ClusterData.builder()
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/BrokerClientIntegrationTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/BrokerClientIntegrationTest.java
index 0039fc92cb8..a8c3d353e84 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/BrokerClientIntegrationTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/client/impl/BrokerClientIntegrationTest.java
@@ -20,7 +20,7 @@ package org.apache.pulsar.client.impl;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.UUID.randomUUID;
-import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgs;
+import static
org.apache.pulsar.broker.BrokerTestUtil.spyWithClassAndConstructorArgsRecordingInvocations;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
@@ -819,8 +819,10 @@ public class BrokerClientIntegrationTest extends
ProducerConsumerBase {
final String topicName = "persistent://my-property/my-ns/my-topic1";
ObjectMapper mapper = new ObjectMapper();
SchemaReader<TestMessageObject> reader =
- spyWithClassAndConstructorArgs(JacksonJsonReader.class,
mapper, TestMessageObject.class);
- SchemaWriter<TestMessageObject> writer =
spyWithClassAndConstructorArgs(JacksonJsonWriter.class, mapper);
+
spyWithClassAndConstructorArgsRecordingInvocations(JacksonJsonReader.class,
mapper,
+ TestMessageObject.class);
+ SchemaWriter<TestMessageObject> writer =
+
spyWithClassAndConstructorArgsRecordingInvocations(JacksonJsonWriter.class,
mapper);
SchemaDefinition<TestMessageObject> schemaDefinition = new
SchemaDefinitionBuilderImpl<TestMessageObject>()
.withPojo(TestMessageObject.class)