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)

Reply via email to