You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by zi...@apache.org on 2025/04/10 02:52:28 UTC

(pulsar) branch master updated: [fix][test] Fix UnfinishedStubbing issue in AuthZTests (#24165)

This is an automated email from the ASF dual-hosted git repository.

zixuan 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 e8be56d0c08 [fix][test] Fix UnfinishedStubbing issue in AuthZTests (#24165)
e8be56d0c08 is described below

commit e8be56d0c08dec07d291af48c00a5bd5e04c5ade
Author: Lari Hotari <lh...@users.noreply.github.com>
AuthorDate: Thu Apr 10 05:52:22 2025 +0300

    [fix][test] Fix UnfinishedStubbing issue in AuthZTests (#24165)
---
 .../org/apache/pulsar/broker/admin/AuthZTest.java  | 54 +++++++++++++++-------
 .../pulsar/broker/admin/NamespaceAuthZTest.java    | 46 ++++++++++++------
 .../admin/TransactionAndSchemaAuthZTest.java       | 18 --------
 3 files changed, 70 insertions(+), 48 deletions(-)

diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AuthZTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AuthZTest.java
index 3816b9a7a7e..d09ffe268d1 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AuthZTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AuthZTest.java
@@ -18,22 +18,25 @@
  */
 package org.apache.pulsar.broker.admin;
 
+import static org.mockito.Mockito.doReturn;
 import io.jsonwebtoken.Jwts;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
 import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.pulsar.broker.BrokerTestUtil;
 import org.apache.pulsar.broker.authorization.AuthorizationService;
 import org.apache.pulsar.client.admin.PulsarAdmin;
 import org.apache.pulsar.common.policies.data.NamespaceOperation;
 import org.apache.pulsar.common.policies.data.TopicOperation;
 import org.apache.pulsar.security.MockedPulsarStandalone;
 import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicBoolean;
-import static org.mockito.Mockito.doReturn;
 
-public class AuthZTest extends MockedPulsarStandalone {
+public abstract class AuthZTest extends MockedPulsarStandalone {
 
     protected PulsarAdmin superUserAdmin;
 
@@ -47,6 +50,9 @@ public class AuthZTest extends MockedPulsarStandalone {
     protected static final String TENANT_ADMIN_TOKEN = Jwts.builder()
             .claim("sub", TENANT_ADMIN_SUBJECT).signWith(SECRET_KEY).compact();
 
+    private volatile Consumer<InvocationOnMock> allowTopicOperationAsyncHandler;
+    private volatile Consumer<InvocationOnMock> allowNamespaceOperationAsyncHandler;
+
     @Override
     public void close() throws Exception {
         if (superUserAdmin != null) {
@@ -65,48 +71,62 @@ public class AuthZTest extends MockedPulsarStandalone {
     @BeforeMethod(alwaysRun = true)
     public void before() throws IllegalAccessException {
         orignalAuthorizationService = getPulsarService().getBrokerService().getAuthorizationService();
-        authorizationService = Mockito.spy(orignalAuthorizationService);
+        authorizationService = BrokerTestUtil.spyWithoutRecordingInvocations(orignalAuthorizationService);
         FieldUtils.writeField(getPulsarService().getBrokerService(), "authorizationService",
                 authorizationService, true);
+        Mockito.doAnswer(invocationOnMock -> {
+            Consumer<InvocationOnMock> localAllowTopicOperationAsyncHandler =
+                    allowTopicOperationAsyncHandler;
+            if (localAllowTopicOperationAsyncHandler != null) {
+                localAllowTopicOperationAsyncHandler.accept(invocationOnMock);
+            }
+            return invocationOnMock.callRealMethod();
+        }).when(authorizationService).allowTopicOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any());
+        doReturn(true)
+                .when(authorizationService).isValidOriginalPrincipal(Mockito.any(), Mockito.any(), Mockito.any());
+        Mockito.doAnswer(invocationOnMock -> {
+            Consumer<InvocationOnMock> localAllowNamespaceOperationAsyncHandler =
+                    allowNamespaceOperationAsyncHandler;
+            if (localAllowNamespaceOperationAsyncHandler != null) {
+                localAllowNamespaceOperationAsyncHandler.accept(invocationOnMock);
+            }
+            return invocationOnMock.callRealMethod();
+        }).when(authorizationService).allowNamespaceOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any());
     }
 
     @AfterMethod(alwaysRun = true)
     public void after() throws IllegalAccessException {
         FieldUtils.writeField(getPulsarService().getBrokerService(), "authorizationService",
                 orignalAuthorizationService, true);
+        allowNamespaceOperationAsyncHandler = null;
+        allowTopicOperationAsyncHandler = null;
     }
 
     protected AtomicBoolean setAuthorizationTopicOperationChecker(String role, Object operation) {
         AtomicBoolean execFlag = new AtomicBoolean(false);
         if (operation instanceof TopicOperation) {
-            Mockito.doAnswer(invocationOnMock -> {
+            allowTopicOperationAsyncHandler = invocationOnMock -> {
                 String role_ = invocationOnMock.getArgument(2);
                 if (role.equals(role_)) {
                     TopicOperation operation_ = invocationOnMock.getArgument(1);
                     Assert.assertEquals(operation_, operation);
                 }
                 execFlag.set(true);
-                return invocationOnMock.callRealMethod();
-            }).when(authorizationService).allowTopicOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
-                    Mockito.any(), Mockito.any());
+            };
         } else if (operation instanceof NamespaceOperation) {
-            doReturn(true)
-                    .when(authorizationService).isValidOriginalPrincipal(Mockito.any(), Mockito.any(), Mockito.any());
-            Mockito.doAnswer(invocationOnMock -> {
+            allowNamespaceOperationAsyncHandler = invocationOnMock -> {
                 String role_ = invocationOnMock.getArgument(2);
                 if (role.equals(role_)) {
                     TopicOperation operation_ = invocationOnMock.getArgument(1);
                     Assert.assertEquals(operation_, operation);
                 }
                 execFlag.set(true);
-                return invocationOnMock.callRealMethod();
-            }).when(authorizationService).allowNamespaceOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
-                    Mockito.any(), Mockito.any());
+            };
         } else {
             throw new IllegalArgumentException("");
         }
-
-
         return execFlag;
     }
 
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespaceAuthZTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespaceAuthZTest.java
index 66e13ef59f0..8a9e38d166f 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespaceAuthZTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespaceAuthZTest.java
@@ -36,10 +36,12 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
 import lombok.Cleanup;
 import lombok.SneakyThrows;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.pulsar.broker.BrokerTestUtil;
 import org.apache.pulsar.broker.authorization.AuthorizationService;
 import org.apache.pulsar.broker.service.Topic;
 import org.apache.pulsar.client.admin.PulsarAdmin;
@@ -96,6 +98,9 @@ public class NamespaceAuthZTest extends MockedPulsarStandalone {
     private static final String TENANT_ADMIN_TOKEN = Jwts.builder()
             .claim("sub", TENANT_ADMIN_SUBJECT).signWith(SECRET_KEY).compact();
 
+    private volatile Consumer<InvocationOnMock> allowNamespacePolicyOperationAsyncHandler;
+    private volatile Consumer<InvocationOnMock> allowNamespaceOperationAsyncHandler;
+
     @SneakyThrows
     @BeforeClass
     public void setup() {
@@ -118,9 +123,28 @@ public class NamespaceAuthZTest extends MockedPulsarStandalone {
                 .authentication(new AuthenticationToken(TENANT_ADMIN_TOKEN))
                 .build();
         this.pulsarClient = super.getPulsarService().getClient();
-        this.authorizationService = Mockito.spy(getPulsarService().getBrokerService().getAuthorizationService());
+        this.authorizationService = BrokerTestUtil.spyWithoutRecordingInvocations(
+                getPulsarService().getBrokerService().getAuthorizationService());
         FieldUtils.writeField(getPulsarService().getBrokerService(), "authorizationService",
                 authorizationService, true);
+        Mockito.doAnswer(invocationOnMock -> {
+            Consumer<InvocationOnMock> localAllowNamespacePolicyOperationAsyncHandler =
+                    allowNamespacePolicyOperationAsyncHandler;
+            if (localAllowNamespacePolicyOperationAsyncHandler != null) {
+                localAllowNamespacePolicyOperationAsyncHandler.accept(invocationOnMock);
+            }
+            return invocationOnMock.callRealMethod();
+        }).when(authorizationService).allowNamespacePolicyOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
+                Mockito.any(), Mockito.any());
+        Mockito.doAnswer(invocationOnMock -> {
+            Consumer<InvocationOnMock> localAllowNamespaceOperationAsyncHandler =
+                    allowNamespaceOperationAsyncHandler;
+            if (localAllowNamespaceOperationAsyncHandler != null) {
+                localAllowNamespaceOperationAsyncHandler.accept(invocationOnMock);
+            }
+            return invocationOnMock.callRealMethod();
+        }).when(authorizationService).allowNamespaceOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
+                Mockito.any());
     }
 
 
@@ -144,33 +168,31 @@ public class NamespaceAuthZTest extends MockedPulsarStandalone {
     public void after() throws Exception {
         deleteNamespaceWithRetry("public/default", true, superUserAdmin);
         superUserAdmin.namespaces().createNamespace("public/default");
+        allowNamespacePolicyOperationAsyncHandler = null;
+        allowNamespaceOperationAsyncHandler = null;
     }
 
     private AtomicBoolean setAuthorizationOperationChecker(String role, NamespaceOperation operation) {
         AtomicBoolean execFlag = new AtomicBoolean(false);
-        Mockito.doAnswer(invocationOnMock -> {
+        allowNamespaceOperationAsyncHandler = invocationOnMock -> {
             String role_ = invocationOnMock.getArgument(2);
             if (role.equals(role_)) {
                 NamespaceOperation operation_ = invocationOnMock.getArgument(1);
                 Assert.assertEquals(operation_, operation);
             }
             execFlag.set(true);
-            return invocationOnMock.callRealMethod();
-        }).when(authorizationService).allowNamespaceOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
-                Mockito.any());
-         return execFlag;
+        };
+        return execFlag;
     }
 
     private void clearAuthorizationOperationChecker() {
-        Mockito.doAnswer(InvocationOnMock::callRealMethod).when(authorizationService)
-                .allowNamespaceOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
-                        Mockito.any());
+        allowNamespaceOperationAsyncHandler = null;
     }
 
     private AtomicBoolean setAuthorizationPolicyOperationChecker(String role, Object policyName, Object operation) {
         AtomicBoolean execFlag = new AtomicBoolean(false);
         if (operation instanceof PolicyOperation) {
-            Mockito.doAnswer(invocationOnMock -> {
+            allowNamespacePolicyOperationAsyncHandler = invocationOnMock -> {
                 String role_ = invocationOnMock.getArgument(3);
                 if (role.equals(role_)) {
                     PolicyName policyName_ = invocationOnMock.getArgument(1);
@@ -179,9 +201,7 @@ public class NamespaceAuthZTest extends MockedPulsarStandalone {
                     assertEquals(policyName_, policyName);
                 }
                 execFlag.set(true);
-                return invocationOnMock.callRealMethod();
-            }).when(authorizationService).allowNamespacePolicyOperationAsync(Mockito.any(), Mockito.any(), Mockito.any(),
-                    Mockito.any(), Mockito.any());
+            };
         } else {
             throw new IllegalArgumentException("");
         }
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/TransactionAndSchemaAuthZTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/TransactionAndSchemaAuthZTest.java
index f52d6dae9bb..deaa7c237ff 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/TransactionAndSchemaAuthZTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/TransactionAndSchemaAuthZTest.java
@@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import lombok.Cleanup;
 import lombok.SneakyThrows;
-import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.pulsar.client.admin.PulsarAdmin;
 import org.apache.pulsar.client.admin.PulsarAdminException;
 import org.apache.pulsar.client.api.Consumer;
@@ -43,12 +42,9 @@ import org.apache.pulsar.common.policies.data.TopicOperation;
 import org.apache.pulsar.common.schema.SchemaInfo;
 import org.apache.pulsar.common.schema.SchemaType;
 import org.apache.pulsar.metadata.api.MetadataStoreException;
-import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
@@ -85,20 +81,6 @@ public class TransactionAndSchemaAuthZTest extends AuthZTest {
         close();
     }
 
-    @BeforeMethod
-    public void before() throws IllegalAccessException {
-        orignalAuthorizationService = getPulsarService().getBrokerService().getAuthorizationService();
-        authorizationService = Mockito.spy(orignalAuthorizationService);
-        FieldUtils.writeField(getPulsarService().getBrokerService(), "authorizationService",
-                authorizationService, true);
-    }
-
-    @AfterMethod
-    public void after() throws IllegalAccessException {
-        FieldUtils.writeField(getPulsarService().getBrokerService(), "authorizationService",
-                orignalAuthorizationService, true);
-    }
-
     protected void createTransactionCoordinatorAssign(int numPartitionsOfTC) throws MetadataStoreException {
         getPulsarService().getPulsarResources()
                 .getNamespaceResources()