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

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f8210e8c06 Add more test cases on PluginLifecycleServiceManagerTest 
(#37710)
8f8210e8c06 is described below

commit 8f8210e8c06fd57e48ccf04a73d8b9789ecb662a
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Jan 11 23:41:27 2026 +0800

    Add more test cases on PluginLifecycleServiceManagerTest (#37710)
---
 agent/core/pom.xml                                 |  7 ++
 .../plugin/PluginLifecycleServiceManagerTest.java  | 99 ++++++++++++++++++----
 2 files changed, 89 insertions(+), 17 deletions(-)

diff --git a/agent/core/pom.xml b/agent/core/pom.xml
index 28e1ab93feb..fb9c2bae117 100644
--- a/agent/core/pom.xml
+++ b/agent/core/pom.xml
@@ -37,6 +37,13 @@
             <version>${project.version}</version>
         </dependency>
         
+        <dependency>
+            <groupId>org.apache.shardingsphere</groupId>
+            <artifactId>shardingsphere-test-infra-framework</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        
         <dependency>
             <groupId>net.bytebuddy</groupId>
             <artifactId>byte-buddy</artifactId>
diff --git 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/plugin/PluginLifecycleServiceManagerTest.java
 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/plugin/PluginLifecycleServiceManagerTest.java
index e02d115ba7d..7070802b7d8 100644
--- 
a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/plugin/PluginLifecycleServiceManagerTest.java
+++ 
b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/plugin/PluginLifecycleServiceManagerTest.java
@@ -17,43 +17,108 @@
 
 package org.apache.shardingsphere.agent.core.plugin;
 
-import net.bytebuddy.dynamic.loading.MultipleParentClassLoader;
 import org.apache.shardingsphere.agent.api.PluginConfiguration;
+import org.apache.shardingsphere.agent.core.spi.AgentServiceLoader;
+import org.apache.shardingsphere.agent.spi.PluginLifecycleService;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.internal.configuration.plugins.Plugins;
 
-import java.net.MalformedURLException;
+import java.io.IOException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.net.URLStreamHandlerFactory;
-import java.nio.file.Paths;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.jar.JarFile;
 
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
 
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings({AgentServiceLoader.class, Runtime.class})
 class PluginLifecycleServiceManagerTest {
     
+    @BeforeEach
+    void resetStartedFlag() throws ReflectiveOperationException {
+        AtomicBoolean startedFlag = (AtomicBoolean) 
Plugins.getMemberAccessor().get(PluginLifecycleServiceManager.class.getDeclaredField("STARTED_FLAG"),
 PluginLifecycleServiceManager.class);
+        startedFlag.set(false);
+    }
+    
     @Test
-    void assertInitPluginLifecycleService() {
-        assertDoesNotThrow(() -> 
PluginLifecycleServiceManager.init(Collections.emptyMap(), 
Collections.emptyList(), new 
MultipleParentClassLoader(Collections.emptyList()), true));
+    void assertInitStartsPluginAndClosesJars() throws IOException {
+        Runtime runtime = mock(Runtime.class);
+        when(Runtime.getRuntime()).thenReturn(runtime);
+        PluginLifecycleService pluginLifecycleService = 
mock(PluginLifecycleService.class);
+        when(pluginLifecycleService.getType()).thenReturn("test");
+        mockAgentServiceLoader(pluginLifecycleService);
+        Map<String, PluginConfiguration> pluginConfigs = 
Collections.singletonMap("test", new PluginConfiguration("localhost", 3307, 
"pwd", new Properties()));
+        JarFile jarFile = mock(JarFile.class);
+        JarFile errorJarFile = mock(JarFile.class);
+        doThrow(IOException.class).when(errorJarFile).close();
+        ArgumentCaptor<Thread> shutdownHookCaptor = 
ArgumentCaptor.forClass(Thread.class);
+        ClassLoader expectedClassLoader = 
Thread.currentThread().getContextClassLoader();
+        ClassLoader pluginClassLoader = new URLClassLoader(new URL[0], 
expectedClassLoader);
+        PluginLifecycleServiceManager.init(pluginConfigs, 
Arrays.asList(jarFile, errorJarFile), pluginClassLoader, true);
+        assertThat(Thread.currentThread().getContextClassLoader(), 
is(expectedClassLoader));
+        verify(runtime).addShutdownHook(shutdownHookCaptor.capture());
+        shutdownHookCaptor.getValue().run();
+        verify(pluginLifecycleService).start(pluginConfigs.get("test"), true);
+        verify(pluginLifecycleService).close();
+        verify(jarFile).close();
+        verify(errorJarFile).close();
     }
     
     @Test
-    void assertInitPluginLifecycleServiceWithMap() {
-        Map<String, PluginConfiguration> pluginConfigs = 
Collections.singletonMap("Key", new PluginConfiguration("localhost", 8080, 
"random", new Properties()));
-        assertDoesNotThrow(() -> 
PluginLifecycleServiceManager.init(pluginConfigs, Collections.emptyList(), new 
MultipleParentClassLoader(Collections.emptyList()), true));
+    void assertInitWhenAlreadyStarted() throws ReflectiveOperationException {
+        AtomicBoolean startedFlag = (AtomicBoolean) 
Plugins.getMemberAccessor().get(PluginLifecycleServiceManager.class.getDeclaredField("STARTED_FLAG"),
 PluginLifecycleServiceManager.class);
+        startedFlag.set(true);
+        AgentServiceLoader<PluginLifecycleService> serviceLoader = 
AgentServiceLoader.getServiceLoader(PluginLifecycleService.class);
+        PluginLifecycleServiceManager.init(Collections.emptyMap(), 
Collections.emptyList(), new URLClassLoader(new URL[0]), true);
+        assertTrue(startedFlag.get());
+        verifyNoInteractions(serviceLoader);
     }
     
     @Test
-    void assertInitPluginLifecycleServiceWithMockHandler() throws 
MalformedURLException {
-        URLStreamHandlerFactory urlStreamHandlerFactory = 
mock(URLStreamHandlerFactory.class);
-        URLClassLoader urlClassLoader = new URLClassLoader(new 
URL[]{Paths.get(System.getProperty("java.io.tmpdir"), 
"test.txt").toUri().toURL()},
-                new MultipleParentClassLoader(Collections.emptyList()), 
urlStreamHandlerFactory);
-        PluginLifecycleServiceManager.init(Collections.emptyMap(), 
Collections.emptyList(), urlClassLoader, true);
-        verify(urlStreamHandlerFactory).createURLStreamHandler(anyString());
+    void assertInitWithoutMatchingService() {
+        PluginLifecycleService pluginLifecycleService = 
mock(PluginLifecycleService.class);
+        when(pluginLifecycleService.getType()).thenReturn("mismatch");
+        mockAgentServiceLoader(pluginLifecycleService);
+        PluginLifecycleServiceManager.init(Collections.singletonMap("test", 
new PluginConfiguration("127.0.0.1", 8080, "foo", new Properties())),
+                Collections.emptyList(), new URLClassLoader(new URL[0]), 
false);
+        verify(pluginLifecycleService, 
never()).start(any(PluginConfiguration.class), anyBoolean());
+    }
+    
+    @Test
+    void assertInitStartWithException() {
+        PluginLifecycleService pluginLifecycleService = 
mock(PluginLifecycleService.class);
+        when(pluginLifecycleService.getType()).thenReturn("test");
+        
doThrow(IllegalStateException.class).when(pluginLifecycleService).start(any(PluginConfiguration.class),
 anyBoolean());
+        mockAgentServiceLoader(pluginLifecycleService);
+        PluginConfiguration pluginConfig = new PluginConfiguration("0.0.0.0", 
9000, "bar", new Properties());
+        PluginLifecycleServiceManager.init(Collections.singletonMap("test", 
pluginConfig), Collections.emptyList(), new URLClassLoader(new URL[0]), true);
+        verify(pluginLifecycleService).start(pluginConfig, true);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void mockAgentServiceLoader(final PluginLifecycleService 
pluginLifecycleService) {
+        AgentServiceLoader<PluginLifecycleService> agentServiceLoader = 
mock(AgentServiceLoader.class);
+        
when(agentServiceLoader.getServices()).thenReturn(Collections.singleton(pluginLifecycleService));
+        
when(AgentServiceLoader.getServiceLoader(PluginLifecycleService.class)).thenReturn(agentServiceLoader);
     }
 }

Reply via email to