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

jimin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new ac99e5bebe test: add UT for namingserver module (#7330)
ac99e5bebe is described below

commit ac99e5bebe0db8f75763c2e2c0c874df3f2dbb0c
Author: Soyan <523420...@qq.com>
AuthorDate: Thu May 8 14:42:26 2025 +0800

    test: add UT for namingserver module (#7330)
---
 changes/en-us/2.x.md                               |   3 +-
 changes/zh-cn/2.x.md                               |   3 +-
 .../namingserver/ClusterWatcherManagerTest.java    | 199 ++++++++++++
 .../seata/namingserver/NamingControllerTest.java   | 166 +++++++++-
 .../seata/namingserver/NamingEntityTest.java       | 206 ++++++++++++
 .../seata/namingserver/NamingManagerTest.java      | 354 +++++++++++++++++++++
 6 files changed, 913 insertions(+), 18 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index bc4c9ced24..85e55f0f94 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -60,7 +60,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#7287](https://github.com/apache/incubator-seata/pull/7287)] Refactored 
testGetErrorMsgWithValidCodeReturnsExpectedMsg to use parameterized unit testing
 - [[#7294](https://github.com/apache/incubator-seata/pull/7294)] improved test 
testGetInsertParamsValue in SqlServerInsertRecognizerTest by splitting and 
parameterizing
 - [[#7295](https://github.com/apache/incubator-seata/pull/7295)] updated 3 
tests in StringUtilsTest to use parameterized unit testing
-
+- [[#7205](https://github.com/apache/incubator-seata/issues/7205)] add UT for 
namingserver module
 ### refactor:
 
 - [[#7315](https://github.com/apache/incubator-seata/pull/7315)] Refactor log 
testing to use ListAppender for more accurate and efficient log capture
@@ -80,5 +80,6 @@ Thanks to these contributors for their code commits. Please 
report an unintended
 - [xingfudeshi](https://github.com/xingfudeshi)
 - [wjwang00](https://github.com/wjwang00)
 - [YongGoose](https://github.com/YongGoose)
+- [JisoLya](https://github.com/JisoLya)
 
 Also, we receive many valuable issues, questions and advices from our 
community. Thanks for you all.
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 8fe36aa33e..af54100470 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -59,7 +59,7 @@
 - [[#7287](https://github.com/apache/incubator-seata/pull/7287)] 重构了 CodeTest 
中的 testGetErrorMsgWithValidCodeReturnsExpectedMsg 测试,以简化并使用参数化单元测试。
 - [[#7294](https://github.com/apache/incubator-seata/pull/7294)] 重构了 
SqlServerInsertRecognizerTest 中的 testGetInsertParamsValue 测试,通过拆分并使用参数化单元测试进行改进
 - [[#7295](https://github.com/apache/incubator-seata/pull/7295)] 重构了 
StringUtilsTest 中的 3 个测试,改为使用参数化单元测试
-
+- [[#7205](https://github.com/apache/incubator-seata/issues/7205)] 为 
namingserver module 添加单元测试
 ### refactor:
 
 - [[#7315](https://github.com/apache/incubator-seata/pull/7315)] 
重构日志测试,使用ListAppender实现更准确高效的日志捕获
@@ -79,5 +79,6 @@
 - [xingfudeshi](https://github.com/xingfudeshi)
 - [wjwang00](https://github.com/wjwang00)
 - [YongGoose](https://github.com/YongGoose)
+- [JisoLya](https://github.com/JisoLya)
 
 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。
diff --git 
a/namingserver/src/test/java/org/apache/seata/namingserver/ClusterWatcherManagerTest.java
 
b/namingserver/src/test/java/org/apache/seata/namingserver/ClusterWatcherManagerTest.java
new file mode 100644
index 0000000000..f0844aa13b
--- /dev/null
+++ 
b/namingserver/src/test/java/org/apache/seata/namingserver/ClusterWatcherManagerTest.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.seata.namingserver;
+
+
+import org.apache.seata.namingserver.listener.ClusterChangeEvent;
+import org.apache.seata.namingserver.listener.Watcher;
+import org.apache.seata.namingserver.manager.ClusterWatcherManager;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+
+@SpringBootTest
+public class ClusterWatcherManagerTest {
+
+    private ClusterWatcherManager clusterWatcherManager;
+
+    @Mock
+    private AsyncContext asyncContext;
+
+    @Mock
+    private HttpServletResponse response;
+
+    @Mock
+    private HttpServletRequest request;
+
+    private final String TEST_GROUP = "testGroup";
+    private final int TEST_TIMEOUT = 5000;
+    private final Long TEST_TERM = 1000L;
+    private final String TEST_CLIENT_ENDPOINT = "127.0.0.1";
+
+    @BeforeEach
+    void setUp() {
+        clusterWatcherManager = new ClusterWatcherManager();
+        Mockito.when(asyncContext.getResponse()).thenReturn(response);
+        Mockito.when(asyncContext.getRequest()).thenReturn(request);
+        Mockito.when(request.getRemoteAddr()).thenReturn(TEST_CLIENT_ENDPOINT);
+
+        Map<String, Queue<Watcher<?>>> watchers = (Map<String, 
Queue<Watcher<?>>>) ReflectionTestUtils.getField(clusterWatcherManager, 
"WATCHERS");
+        Map<String, Long> groupUpdateTime = (Map<String, Long>) 
ReflectionTestUtils.getField(clusterWatcherManager, "GROUP_UPDATE_TIME");
+
+        watchers.clear();
+        groupUpdateTime.clear();
+    }
+
+    @Test
+    void testInit() {
+        clusterWatcherManager.init();
+        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = 
(ScheduledThreadPoolExecutor) ReflectionTestUtils
+                .getField(clusterWatcherManager, 
"scheduledThreadPoolExecutor");
+
+        assertNotNull(scheduledThreadPoolExecutor);
+        assertFalse(scheduledThreadPoolExecutor.isShutdown());
+    }
+
+    @Test
+    void testRegistryNewWatcher() {
+        Watcher<AsyncContext> watcher = new Watcher<>(TEST_GROUP, 
asyncContext, TEST_TIMEOUT, TEST_TERM, TEST_CLIENT_ENDPOINT);
+        clusterWatcherManager.registryWatcher(watcher);
+
+        Map<String, Queue<Watcher<?>>> watchers = (Map<String, 
Queue<Watcher<?>>>) ReflectionTestUtils.getField(clusterWatcherManager, 
"WATCHERS");
+
+        assertNotNull(watchers);
+        assertTrue(watchers.containsKey(TEST_GROUP));
+        assertEquals(1, watchers.get(TEST_GROUP).size());
+        assertFalse(watcher.isDone());
+    }
+
+    @Test
+    void testRegistryWatcherOldTerm() {
+        Map<String, Long> groupUpdateTime = (Map<String, Long>) 
ReflectionTestUtils.getField(clusterWatcherManager, "GROUP_UPDATE_TIME");
+        groupUpdateTime.put(TEST_GROUP, TEST_TERM + 10);
+
+        Watcher<AsyncContext> watcher = new Watcher<>(TEST_GROUP, 
asyncContext, TEST_TIMEOUT, TEST_TERM, TEST_CLIENT_ENDPOINT);
+        clusterWatcherManager.registryWatcher(watcher);
+
+        Mockito.verify(response).setStatus(HttpServletResponse.SC_OK);
+        Mockito.verify(asyncContext).complete();
+        assertTrue(watcher.isDone());
+
+        Map<String, Queue<Watcher<?>>> watchers = (Map<String, 
Queue<Watcher<?>>>) ReflectionTestUtils.getField(clusterWatcherManager, 
"WATCHERS");
+
+        assertFalse(watchers.containsKey(TEST_GROUP));
+        assertNull(watchers.get(TEST_GROUP));
+    }
+
+    @Test
+    void testOnEventChange() {
+        Watcher<AsyncContext> watcher = new Watcher<>(TEST_GROUP, 
asyncContext, TEST_TIMEOUT, TEST_TERM, TEST_CLIENT_ENDPOINT);
+        clusterWatcherManager.registryWatcher(watcher);
+        Map<String, Queue<Watcher<?>>> watchers = (Map<String, 
Queue<Watcher<?>>>) ReflectionTestUtils.getField(clusterWatcherManager, 
"WATCHERS");
+        Map<String, Long> updateTime = (Map<String, Long>) 
ReflectionTestUtils.getField(clusterWatcherManager, "GROUP_UPDATE_TIME");
+
+        assertNotNull(watchers);
+        assertNotNull(updateTime);
+
+        ClusterChangeEvent zeroTermEvent = new ClusterChangeEvent(this, 
TEST_GROUP, 0);
+        clusterWatcherManager.onChangeEvent(zeroTermEvent);
+
+        assertEquals(0, updateTime.size());
+        assertFalse(watcher.isDone());
+        assertTrue(watchers.containsKey(TEST_GROUP));
+        assertNotNull(watchers.get(TEST_GROUP));
+        assertEquals(1, watchers.get(TEST_GROUP).size());
+
+        ClusterChangeEvent event = new ClusterChangeEvent(this, TEST_GROUP, 
TEST_TERM + 1);
+        clusterWatcherManager.onChangeEvent(event);
+
+        Mockito.verify(response).setStatus(HttpServletResponse.SC_OK);
+        Mockito.verify(asyncContext).complete();
+
+        assertEquals(1, updateTime.size());
+        assertEquals(TEST_TERM + 1, updateTime.get(TEST_GROUP));
+        assertTrue(watcher.isDone());
+        assertFalse(watchers.containsKey(TEST_GROUP));
+        assertNull(watchers.get(TEST_GROUP));
+    }
+
+    @Test
+    void testGetWatcherIpList() {
+        Watcher<AsyncContext> watcher1 = new Watcher<>(TEST_GROUP, 
asyncContext, TEST_TIMEOUT, TEST_TERM, "127.0.0.1");
+        Watcher<AsyncContext> watcher2 = new Watcher<>(TEST_GROUP, 
asyncContext, TEST_TIMEOUT, TEST_TERM, "127.0.0.1");
+        Watcher<AsyncContext> watcher3 = new Watcher<>(TEST_GROUP, 
asyncContext, TEST_TIMEOUT, TEST_TERM, "192.168.1.1");
+
+        clusterWatcherManager.registryWatcher(watcher1);
+        clusterWatcherManager.registryWatcher(watcher2);
+        clusterWatcherManager.registryWatcher(watcher3);
+        List<String> watcherIpList = 
clusterWatcherManager.getWatcherIpList(TEST_GROUP);
+
+        assertNotNull(watcherIpList);
+        assertEquals(2, watcherIpList.size());
+        assertTrue(watcherIpList.contains("127.0.0.1"));
+        assertTrue(watcherIpList.contains("192.168.1.1"));
+    }
+
+    @Test
+    void testGetWatchVGroupList() {
+        Watcher<AsyncContext> watcher1 = new Watcher<>("VGroup1", 
asyncContext, TEST_TIMEOUT, TEST_TERM, "127.0.0.1");
+        Watcher<AsyncContext> watcher2 = new Watcher<>("VGroup1", 
asyncContext, TEST_TIMEOUT, TEST_TERM, "127.0.0.2");
+        Watcher<AsyncContext> watcher3 = new Watcher<>("VGroup2", 
asyncContext, TEST_TIMEOUT, TEST_TERM, "192.168.1.1");
+
+        clusterWatcherManager.registryWatcher(watcher1);
+        clusterWatcherManager.registryWatcher(watcher2);
+        clusterWatcherManager.registryWatcher(watcher3);
+
+        List<String> watchVGroupList = 
clusterWatcherManager.getWatchVGroupList();
+
+        assertNotNull(watchVGroupList);
+        assertEquals(2, watchVGroupList.size());
+        assertTrue(watchVGroupList.contains("VGroup1"));
+        assertTrue(watchVGroupList.contains("VGroup2"));
+    }
+
+    @Test
+    void testGetTermByvGroup() {
+        Map<String, Long> groupUpdateTime = (Map<String, Long>) 
ReflectionTestUtils.getField(clusterWatcherManager, "GROUP_UPDATE_TIME");
+
+        assertNotNull(groupUpdateTime);
+
+        groupUpdateTime.put(TEST_GROUP, TEST_TERM);
+        Long term1 = clusterWatcherManager.getTermByvGroup(TEST_GROUP);
+        Long term2 = clusterWatcherManager.getTermByvGroup("NotExist");
+
+        assertEquals(TEST_TERM, term1);
+        assertEquals(0L, term2);
+    }
+}
diff --git 
a/namingserver/src/test/java/org/apache/seata/namingserver/NamingControllerTest.java
 
b/namingserver/src/test/java/org/apache/seata/namingserver/NamingControllerTest.java
index eb8666b383..f9468252ce 100644
--- 
a/namingserver/src/test/java/org/apache/seata/namingserver/NamingControllerTest.java
+++ 
b/namingserver/src/test/java/org/apache/seata/namingserver/NamingControllerTest.java
@@ -21,14 +21,19 @@ import org.apache.seata.common.metadata.Node;
 import org.apache.seata.common.metadata.namingserver.MetaResponse;
 import org.apache.seata.common.metadata.namingserver.NamingServerNode;
 import org.apache.seata.common.metadata.namingserver.Unit;
+import org.apache.seata.common.result.Result;
 import org.apache.seata.namingserver.controller.NamingController;
+import org.apache.seata.namingserver.manager.NamingManager;
 import org.junit.jupiter.api.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -62,8 +67,8 @@ class NamingControllerTest {
         node.setTransaction(new Node.Endpoint("127.0.0.1", 8091, "netty"));
         node.setControl(new Node.Endpoint("127.0.0.1", 7091, "http"));
         Map<String, Object> meatadata = node.getMetadata();
-        Map<String,Object> vGroups = new HashMap<>();
-        vGroups.put(vGroup,unitName);
+        Map<String, Object> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
         meatadata.put(CONSTANT_GROUP, vGroups);
         namingController.registerInstance(namespace, clusterName, unitName, 
node);
         namingController.changeGroup(namespace, clusterName, unitName, vGroup);
@@ -93,17 +98,17 @@ class NamingControllerTest {
         node.setTransaction(new Node.Endpoint("127.0.0.1", 8092, "netty"));
         node.setControl(new Node.Endpoint("127.0.0.1", 7092, "http"));
         Map<String, Object> meatadata = node.getMetadata();
-        Map<String,Object> vGroups = new HashMap<>();
-        vGroups.put(vGroup,unitName);
+        Map<String, Object> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
         meatadata.put(CONSTANT_GROUP, vGroups);
         namingController.registerInstance(namespace, clusterName, unitName, 
node);
         NamingServerNode node2 = new NamingServerNode();
         node2.setTransaction(new Node.Endpoint("127.0.0.1", 8093, "netty"));
         node2.setControl(new Node.Endpoint("127.0.0.1", 7093, "http"));
         Map<String, Object> meatadata2 = node2.getMetadata();
-        Map<String,Object> vGroups2 = new HashMap<>();
+        Map<String, Object> vGroups2 = new HashMap<>();
         String unitName2 = UUID.randomUUID().toString();
-        vGroups2.put(UUID.randomUUID().toString(),unitName2);
+        vGroups2.put(UUID.randomUUID().toString(), unitName2);
         meatadata2.put(CONSTANT_GROUP, vGroups2);
         namingController.registerInstance(namespace, 
UUID.randomUUID().toString(), unitName2, node2);
         MetaResponse metaResponse = namingController.discovery(vGroup, 
namespace);
@@ -136,8 +141,8 @@ class NamingControllerTest {
         node.setTransaction(new Node.Endpoint("127.0.0.1", 8094, "netty"));
         node.setControl(new Node.Endpoint("127.0.0.1", 7094, "http"));
         Map<String, Object> meatadata = node.getMetadata();
-        Map<String,Object> vGroups = new HashMap<>();
-        vGroups.put(vGroup,unitName);
+        Map<String, Object> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
         meatadata.put(CONSTANT_GROUP, vGroups);
         namingController.registerInstance(namespace, clusterName, unitName, 
node);
         //namingController.changeGroup(namespace, clusterName, vGroup, vGroup);
@@ -172,15 +177,15 @@ class NamingControllerTest {
         node.setTransaction(new Node.Endpoint("127.0.0.1", 8095, "netty"));
         node.setControl(new Node.Endpoint("127.0.0.1", 7095, "http"));
         Map<String, Object> meatadata = node.getMetadata();
-        Map<String,Object> vGroups = new HashMap<>();
-        vGroups.put(vGroup,unitName);
+        Map<String, Object> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
         meatadata.put(CONSTANT_GROUP, vGroups);
         NamingServerNode node2 = new NamingServerNode();
         String unitName2 = String.valueOf(UUID.randomUUID());
         node2.setTransaction(new Node.Endpoint("127.0.0.1", 8096, "netty"));
         node2.setControl(new Node.Endpoint("127.0.0.1", 7096, "http"));
         vGroups = new HashMap<>();
-        vGroups.put(vGroup,unitName2);
+        vGroups.put(vGroup, unitName2);
         node2.getMetadata().put(CONSTANT_GROUP, vGroups);
         namingController.registerInstance(namespace, clusterName, unitName, 
node);
         namingController.registerInstance(namespace, clusterName, unitName2, 
node2);
@@ -216,20 +221,20 @@ class NamingControllerTest {
         node.setTransaction(new Node.Endpoint("127.0.0.1", 8097, "netty"));
         node.setControl(new Node.Endpoint("127.0.0.1", 7097, "http"));
         Map<String, Object> meatadata = node.getMetadata();
-        Map<String,Object> vGroups = new HashMap<>();
-        vGroups.put(vGroup,unitName);
+        Map<String, Object> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
         meatadata.put(CONSTANT_GROUP, vGroups);
         namingController.registerInstance(namespace, clusterName, unitName, 
node);
         NamingServerNode node2 = new NamingServerNode();
         node2.setTransaction(new Node.Endpoint("127.0.0.1", 8098, "netty"));
         node2.setControl(new Node.Endpoint("127.0.0.1", 7098, "http"));
         Map<String, Object> meatadata2 = node2.getMetadata();
-        Map<String,Object> vGroups2 = new HashMap<>();
+        Map<String, Object> vGroups2 = new HashMap<>();
         String unitName2 = UUID.randomUUID().toString();
-        vGroups2.put(vGroup,unitName2);
+        vGroups2.put(vGroup, unitName2);
         meatadata2.put(CONSTANT_GROUP, vGroups2);
         namingController.registerInstance(namespace, clusterName, unitName2, 
node2);
-        Thread thread = new Thread(()->{
+        Thread thread = new Thread(() -> {
             for (int i = 0; i < 5; i++) {
                 try {
                     TimeUnit.SECONDS.sleep(5);
@@ -262,4 +267,133 @@ class NamingControllerTest {
         assertEquals(8097, node1.getTransaction().getPort());
     }
 
+    @Test
+    void testRegisterInstanceReturnMessageSuccess() {
+        String clusterName = "cluster6";
+        String namespace = "public6";
+        String vGroup = "testRegisterInstanceReturnMessage";
+        String unitName = String.valueOf(UUID.randomUUID());
+        NamingServerNode node = new NamingServerNode();
+        node.setTransaction(new Node.Endpoint("127.0.0.1", 8094, "netty"));
+        node.setControl(new Node.Endpoint("127.0.0.1", 7094, "http"));
+        Map<String, Object> meatadata = node.getMetadata();
+        Map<String, Object> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        meatadata.put(CONSTANT_GROUP, vGroups);
+        Result<String> result = namingController.registerInstance(namespace, 
clusterName, unitName, node);
+        assertNotNull(result);
+        assertEquals("200", result.getCode());
+        assertEquals("node has registered successfully!", result.getMessage());
+        namingController.unregisterInstance(namespace, clusterName, unitName, 
node);
+    }
+
+    @Test
+    void testRegisterInstanceReturnMessageFailure() {
+        String clusterName = "cluster7";
+        String namespace = "public7";
+        String unitName = String.valueOf(UUID.randomUUID());
+        NamingServerNode invalidNode = new NamingServerNode();
+        Result<String> result = namingController.registerInstance(namespace, 
clusterName, unitName, invalidNode);
+        assertNotNull(result);
+        assertEquals("500", result.getCode());
+        assertEquals("node registered unsuccessfully!", result.getMessage());
+    }
+
+    @Test
+    void testBatchRegisterInstanceMessageSuccess() {
+        String clusterName = "cluster8";
+        String namespace = "public8";
+        String unitName = String.valueOf(UUID.randomUUID());
+        NamingServerNode node1 = new NamingServerNode();
+        node1.setTransaction(new Node.Endpoint("127.0.0.1", 8097, "netty"));
+        node1.setControl(new Node.Endpoint("127.0.0.1", 7097, "http"));
+        node1.setUnit(unitName);
+        NamingServerNode node2 = new NamingServerNode();
+        node2.setTransaction(new Node.Endpoint("127.0.0.1", 8098, "netty"));
+        node2.setControl(new Node.Endpoint("127.0.0.1", 7098, "http"));
+        node2.setUnit(unitName);
+        ArrayList<NamingServerNode> nodeList = new ArrayList<>();
+        nodeList.add(node1);
+        nodeList.add(node2);
+        Result<String> result = 
namingController.batchRegisterInstance(namespace, clusterName, nodeList);
+        assertNotNull(result);
+        assertEquals("200", result.getCode());
+        assertEquals("node has registered successfully!", result.getMessage());
+    }
+
+    @Test
+    void testBatchRegisterInstanceMessageFailure() {
+        String clusterName = "cluster9";
+        String namespace = "public9";
+        String unitName = String.valueOf(UUID.randomUUID());
+        NamingServerNode node1 = new NamingServerNode();
+        node1.setTransaction(new Node.Endpoint("127.0.0.1", 8097, "netty"));
+        node1.setControl(new Node.Endpoint("127.0.0.1", 7097, "http"));
+        node1.setUnit(unitName);
+        NamingServerNode invalidNode = new NamingServerNode();
+        ArrayList<NamingServerNode> nodeList = new ArrayList<>();
+        nodeList.add(node1);
+        nodeList.add(invalidNode);
+        Result<String> result = 
namingController.batchRegisterInstance(namespace, clusterName, nodeList);
+        assertNotNull(result);
+        assertEquals("500", result.getCode());
+        assertEquals("node registered unsuccessfully!", result.getMessage());
+    }
+
+    @Test
+    void testAddGroupMessageSuccess() {
+        String namespace = "public10";
+        String clusterName = "cluster10";
+        String unitName = String.valueOf(UUID.randomUUID());
+        String vGroup = "testAddGroupMessageSuccess";
+        NamingManager mockNamingManager = Mockito.mock(NamingManager.class);
+        Result<String> expectedResult = new Result<>("200", "add vGroup 
successfully!");
+        Mockito.when(mockNamingManager.createGroup(namespace, vGroup, 
clusterName, unitName)).thenReturn(expectedResult);
+        try {
+            Field field = 
NamingController.class.getDeclaredField("namingManager");
+            field.setAccessible(true);
+            NamingManager originalNamingManager = (NamingManager) 
field.get(namingController);
+            field.set(namingController, mockNamingManager);
+            try {
+                Result<String> result = namingController.addGroup(namespace, 
clusterName, unitName, vGroup);
+                assertNotNull(result);
+                assertEquals("200", result.getCode());
+                assertEquals("change vGroup " + vGroup + "to cluster " + 
clusterName + " successfully!", result.getMessage());
+                Mockito.verify(mockNamingManager).createGroup(namespace, 
vGroup, clusterName, unitName);
+            } finally {
+                field.set(namingController, originalNamingManager);
+            }
+        } catch (Exception e) {
+            fail("Test failed due to exception: " + e.getMessage());
+        }
+    }
+
+    @Test
+    void testAddGroupMessageFailure() {
+        String namespace = "public11";
+        String clusterName = "cluster11";
+        String unitName = String.valueOf(UUID.randomUUID());
+        String vGroup = "testAddGroupMessageFailure";
+        NamingManager mockNamingManager = Mockito.mock(NamingManager.class);
+        Result<String> expectedResult = new Result<>("500", "add vGroup in new 
cluster failed");
+        Mockito.when(mockNamingManager.createGroup(namespace, vGroup, 
clusterName, unitName)).thenReturn(expectedResult);
+        try {
+            Field field = 
NamingController.class.getDeclaredField("namingManager");
+            field.setAccessible(true);
+            NamingManager originalNamingManager = (NamingManager) 
field.get(namingController);
+            field.set(namingController, mockNamingManager);
+            try {
+                Result<String> result = namingController.addGroup(namespace, 
clusterName, unitName, vGroup);
+                assertNotNull(result);
+                assertEquals("500", result.getCode());
+                assertEquals("add vGroup in new cluster failed", 
result.getMessage());
+                Mockito.verify(mockNamingManager).createGroup(namespace, 
vGroup, clusterName, unitName);
+            } finally {
+                field.set(namingController, originalNamingManager);
+            }
+        } catch (Exception e) {
+            fail("Test failed due to exception: " + e.getMessage());
+        }
+    }
+
 }
\ No newline at end of file
diff --git 
a/namingserver/src/test/java/org/apache/seata/namingserver/NamingEntityTest.java
 
b/namingserver/src/test/java/org/apache/seata/namingserver/NamingEntityTest.java
new file mode 100644
index 0000000000..08c988fc5f
--- /dev/null
+++ 
b/namingserver/src/test/java/org/apache/seata/namingserver/NamingEntityTest.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.seata.namingserver;
+
+import org.apache.seata.common.metadata.namingserver.Unit;
+import org.apache.seata.namingserver.entity.bo.ClusterBO;
+import org.apache.seata.namingserver.entity.pojo.ClusterData;
+import org.apache.seata.namingserver.entity.vo.NamespaceVO;
+import org.apache.seata.namingserver.entity.vo.monitor.ClusterVO;
+import org.apache.seata.namingserver.entity.vo.monitor.WatcherVO;
+import org.apache.seata.namingserver.listener.Watcher;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+@SpringBootTest
+class NamingEntityTest {
+
+    @Test
+    void testClusterBO() {
+        HashSet<String> unitNames1 = new HashSet<>();
+        unitNames1.add("testClusterBO1");
+        unitNames1.add("testClusterBO2");
+        ClusterBO clusterBO = new ClusterBO(unitNames1);
+        assertNotNull(clusterBO);
+        Set<String> actualUnitNames = clusterBO.getUnitNames();
+        assertEquals(unitNames1.size(), actualUnitNames.size());
+        unitNames1.forEach(unit -> assertTrue(actualUnitNames.contains(unit)));
+        actualUnitNames.forEach(unit -> assertTrue(unitNames1.contains(unit)));
+
+        HashSet<String> unitNames2 = new HashSet<>();
+        unitNames2.add("testClusterBO3");
+        clusterBO.setUnitNames(unitNames2);
+        Set<String> afterSetter = clusterBO.getUnitNames();
+        assertEquals(unitNames2.size(), afterSetter.size());
+        unitNames2.forEach(unit -> assertTrue(afterSetter.contains(unit)));
+        afterSetter.forEach(unit -> assertTrue(unitNames2.contains(unit)));
+    }
+
+    @Test
+    void testNamespaceVO() {
+        NamespaceVO namespaceVO = new NamespaceVO();
+        assertNotNull(namespaceVO);
+        assertNotNull(namespaceVO.getClusters());
+        assertNotNull(namespaceVO.getVgroups());
+
+        ArrayList<String> vGroups = new ArrayList<>();
+        ArrayList<String> clusters = new ArrayList<>();
+        vGroups.add("testVGroup1");
+        vGroups.add("testVGroup2");
+        clusters.add("testCluster1");
+        clusters.add("testCluster2");
+
+        namespaceVO.setVgroups(vGroups);
+        namespaceVO.setClusters(clusters);
+
+        assertEquals(namespaceVO.getVgroups().size(), vGroups.size());
+        assertEquals(namespaceVO.getClusters().size(), clusters.size());
+        vGroups.forEach(unit -> 
assertTrue(namespaceVO.getVgroups().contains(unit)));
+        clusters.forEach(unit -> 
assertTrue(namespaceVO.getClusters().contains(unit)));
+    }
+
+    @Test
+    void testDefaultConstructorClusterVO() {
+        ClusterVO clusterVO = new ClusterVO();
+        assertNotNull(clusterVO);
+        assertNotNull(clusterVO.getUnitData());
+        assertNotNull(clusterVO.getvGroupMapping());
+        assertEquals(0, clusterVO.getUnitData().size());
+        assertEquals(0, clusterVO.getvGroupMapping().size());
+    }
+
+    @Test
+    void testParamConstructorClusterVO() {
+        String clusterName = "testCluster";
+        String clusterType = "testClusterType";
+        ArrayList<Unit> unitData = new ArrayList<>();
+        ClusterVO clusterVO = new ClusterVO(clusterName, clusterType, 
unitData);
+
+        assertNotNull(clusterVO);
+        assertNotNull(clusterVO.getUnitData());
+        assertNotNull(clusterVO.getvGroupMapping());
+        assertEquals(0, clusterVO.getUnitData().size());
+        assertEquals(0, clusterVO.getvGroupMapping().size());
+        assertEquals(clusterName, clusterVO.getClusterName());
+        assertEquals(clusterType, clusterVO.getClusterType());
+    }
+
+    @Test
+    void testSetvGroupMappingClusterVO() {
+        ClusterVO clusterVO = new ClusterVO();
+        assertNotNull(clusterVO);
+        assertNotNull(clusterVO.getvGroupMapping());
+        assertEquals(0, clusterVO.getvGroupMapping().size());
+
+        ArrayList<String> vGroupMapping = new ArrayList<>();
+        vGroupMapping.add("testVGroupMapping1");
+        clusterVO.setvGroupMapping(vGroupMapping);
+        assertEquals(1, clusterVO.getvGroupMapping().size());
+        vGroupMapping.forEach(unit -> 
assertTrue(clusterVO.getvGroupMapping().contains(unit)));
+    }
+
+    @Test
+    void testConvertFromClusterData() {
+        ClusterData clusterData = new ClusterData();
+        clusterData.setClusterName("testCluster");
+        clusterData.setClusterType("testClusterType");
+        clusterData.getUnitData().put("test", new Unit());
+
+        ClusterVO clusterVO = ClusterVO.convertFromClusterData(clusterData);
+
+        assertNotNull(clusterVO);
+        assertNotNull(clusterVO.getUnitData());
+        assertNotNull(clusterVO.getvGroupMapping());
+        assertEquals(1, clusterVO.getUnitData().size());
+        assertEquals(0, clusterVO.getvGroupMapping().size());
+        assertEquals("testCluster", clusterVO.getClusterName());
+        assertEquals("testClusterType", clusterVO.getClusterType());
+    }
+
+    @Test
+    void testAddMapping() {
+        ClusterVO clusterVO = new ClusterVO();
+        clusterVO.getvGroupMapping().add("testVGroupMapping1");
+
+        clusterVO.addMapping("testVGroupMapping1");
+        assertEquals(1, clusterVO.getvGroupMapping().size());
+
+        clusterVO.addMapping("testVGroupMapping2");
+        assertEquals(2, clusterVO.getvGroupMapping().size());
+    }
+
+    @Test
+    void testWatchVO() {
+        WatcherVO watcherVO1 = new WatcherVO();
+        ArrayList<String> watcherIP1 = new ArrayList<>();
+        watcherVO1.setvGroup("testWatcher1");
+        watcherVO1.setWatcherIp(watcherIP1);
+        assertNotNull(watcherVO1);
+        assertNotNull(watcherVO1.getWatcherIp());
+        assertEquals("testWatcher1", watcherVO1.getvGroup());
+        assertEquals(0, watcherVO1.getWatcherIp().size());
+
+        String vGroup = "testWatch";
+        ArrayList<String> watcherIP2 = new ArrayList<>();
+        watcherIP2.add("127.0.0.1");
+        WatcherVO watcherVO2 = new WatcherVO(vGroup, watcherIP2);
+        assertNotNull(watcherVO2);
+        assertNotNull(watcherVO2.getWatcherIp());
+        assertEquals("testWatch", watcherVO2.getvGroup());
+        assertEquals(1, watcherVO2.getWatcherIp().size());
+        watcherIP2.forEach(unit -> 
assertTrue(watcherVO2.getWatcherIp().contains(unit)));
+    }
+
+    @Test
+    void testWatcher() {
+        String group = "testWatcher";
+        String asyncContext = "testAsyncContext";
+        int timeout = 10;
+        long term = new Random().nextLong();
+        String clientEndpoint = "127.0.0.1";
+        Watcher<String> watcher = new Watcher<>(group, asyncContext, timeout, 
term, clientEndpoint);
+
+        assertNotNull(watcher);
+        assertEquals(group, watcher.getGroup());
+        assertEquals(asyncContext, watcher.getAsyncContext());
+        assertEquals(term, watcher.getTerm());
+        assertEquals(clientEndpoint, watcher.getClientEndpoint());
+        assertEquals("http", watcher.getProtocol());
+        assertFalse(watcher.isDone());
+
+        watcher.setTerm(100);
+        watcher.setAsyncContext("newAsyncContext");
+        watcher.setClientEndpoint("127.0.0.2");
+        watcher.setProtocol("gRPC");
+        watcher.setDone(true);
+        assertEquals(100, watcher.getTerm());
+        assertEquals("newAsyncContext", watcher.getAsyncContext());
+        assertEquals("127.0.0.2", watcher.getClientEndpoint());
+        assertEquals("gRPC", watcher.getProtocol());
+        assertTrue(watcher.isDone());
+    }
+}
diff --git 
a/namingserver/src/test/java/org/apache/seata/namingserver/NamingManagerTest.java
 
b/namingserver/src/test/java/org/apache/seata/namingserver/NamingManagerTest.java
new file mode 100644
index 0000000000..188201b544
--- /dev/null
+++ 
b/namingserver/src/test/java/org/apache/seata/namingserver/NamingManagerTest.java
@@ -0,0 +1,354 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.seata.namingserver;
+
+import org.apache.http.StatusLine;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.seata.common.metadata.Cluster;
+import org.apache.seata.common.metadata.ClusterRole;
+import org.apache.seata.common.metadata.Node;
+import org.apache.seata.common.metadata.namingserver.NamingServerNode;
+import org.apache.seata.common.metadata.namingserver.Unit;
+import org.apache.seata.common.result.Result;
+import org.apache.seata.common.util.HttpClientUtil;
+import org.apache.seata.namingserver.entity.vo.monitor.ClusterVO;
+import org.apache.seata.namingserver.listener.ClusterChangeEvent;
+import org.apache.seata.namingserver.manager.NamingManager;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.UUID;
+import java.util.Arrays;
+
+import static org.apache.seata.common.NamingServerConstants.CONSTANT_GROUP;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.anyInt;
+
+@SpringBootTest
+class NamingManagerTest {
+
+    private NamingManager namingManager;
+
+    @Mock
+    private ApplicationContext applicationContext;
+
+    @Mock
+    private CloseableHttpResponse httpResponse;
+
+    @Mock
+    private StatusLine statusLine;
+
+    private MockedStatic<HttpClientUtil> mockedHttpClientUtil;
+
+    @BeforeEach
+    void setUp() {
+        namingManager = new NamingManager();
+        ReflectionTestUtils.setField(namingManager, "applicationContext", 
applicationContext);
+        ReflectionTestUtils.setField(namingManager, "heartbeatTimeThreshold", 
500000);
+        ReflectionTestUtils.setField(namingManager, 
"heartbeatCheckTimePeriod", 10000000);
+
+        Mockito.when(httpResponse.getStatusLine()).thenReturn(statusLine);
+        mockedHttpClientUtil = Mockito.mockStatic(HttpClientUtil.class);
+        mockedHttpClientUtil.when(() -> HttpClientUtil.doGet(anyString(), 
anyMap(), anyMap(), anyInt())).thenReturn(httpResponse);
+
+        namingManager.init();
+    }
+
+    private NamingServerNode createTestNode(String host, int port, String 
unitName) {
+        NamingServerNode node = new NamingServerNode();
+        node.setTransaction(new Node.Endpoint(host, port, "netty"));
+        node.setControl(new Node.Endpoint(host, port + 1000, "http"));
+        node.setUnit(unitName);
+        node.setRole(ClusterRole.LEADER);
+        node.setTerm(1L);
+        Map<String, Object> metadata = new HashMap<>();
+        metadata.put("cluster-type", "default");
+        node.setMetadata(metadata);
+        return node;
+    }
+
+    @AfterEach
+    void tearDown() {
+        if (mockedHttpClientUtil != null) {
+            mockedHttpClientUtil.close();
+        }
+    }
+
+    @Test
+    void testRegisterInstance() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8080, unitName);
+        boolean result = namingManager.registerInstance(node, namespace, 
clusterName, unitName);
+
+        assertTrue(result);
+
+        List<Node> instances = namingManager.getInstances(namespace, 
clusterName);
+        assertEquals(1, instances.size());
+        assertEquals("127.0.0.1", instances.get(0).getTransaction().getHost());
+        assertEquals(8080, instances.get(0).getTransaction().getPort());
+    }
+
+    @Test
+    void testRegisterInstances() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+
+        NamingServerNode node1 = createTestNode("127.0.0.1", 8001, unitName);
+        NamingServerNode node2 = createTestNode("127.0.0.1", 8002, unitName);
+        List<NamingServerNode> nodeList = Arrays.asList(node1, node2);
+
+        boolean result = namingManager.registerInstances(nodeList, namespace, 
clusterName);
+
+        assertTrue(result);
+        assertEquals(2, namingManager.getInstances(namespace, 
clusterName).size());
+    }
+
+    @Test
+    void testUnregisterInstance() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8080, unitName);
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        List<Node> instances = namingManager.getInstances(namespace, 
clusterName);
+        assertEquals(1, instances.size());
+
+        boolean result = namingManager.unregisterInstance(namespace, 
clusterName, unitName, node);
+
+        assertTrue(result);
+        assertTrue(namingManager.getInstances(namespace, 
clusterName).isEmpty());
+        Mockito.verify(applicationContext, 
Mockito.times(2)).publishEvent(any(ClusterChangeEvent.class));
+    }
+
+    @Test
+    void testGetClusterListByVgroup() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8080, unitName);
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        List<Cluster> clusterListByVgroup = 
namingManager.getClusterListByVgroup(vGroup, namespace);
+
+        assertNotNull(clusterListByVgroup);
+        assertEquals(1, clusterListByVgroup.size());
+        assertEquals(clusterName, clusterListByVgroup.get(0).getClusterName());
+
+        List<Cluster> notExist = 
namingManager.getClusterListByVgroup("NotExist-vGroup", namespace);
+        assertEquals(0, notExist.size());
+    }
+
+    @Test
+    void testInstanceHeartBeatCheck() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8080, unitName);
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        List<Node> instances = namingManager.getInstances(namespace, 
clusterName);
+        assertEquals(1, instances.size());
+
+        ReflectionTestUtils.setField(namingManager, "heartbeatTimeThreshold", 
10);
+        try {
+            Thread.sleep(100L);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        namingManager.instanceHeartBeatCheck();
+
+        List<Node> afterHeartBeat = namingManager.getInstances(namespace, 
clusterName);
+        assertEquals(0, afterHeartBeat.size());
+        Mockito.verify(applicationContext, 
Mockito.times(2)).publishEvent(any(ClusterChangeEvent.class));
+    }
+
+    @Test
+    void testCreateGroup() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8080, unitName);
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        Mockito.when(statusLine.getStatusCode()).thenReturn(200);
+        Result<String> result = namingManager.createGroup(namespace, vGroup, 
clusterName, unitName);
+        assertTrue(result.isSuccess());
+        assertEquals("200", result.getCode());
+        assertEquals("add vGroup successfully!", result.getMessage());
+
+        mockedHttpClientUtil.verify(() -> HttpClientUtil.doGet(anyString(), 
anyMap(), anyMap(), anyInt()), Mockito.times(1));
+    }
+
+    @Test
+    void testCreateGroupNoInstance() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        namingManager.registerInstance(null, namespace, clusterName, unitName);
+        Result<String> result = namingManager.createGroup(namespace, vGroup, 
clusterName, unitName);
+
+        assertFalse(result.isSuccess());
+        assertEquals("301", result.getCode());
+        assertEquals("no instance in cluster:" + clusterName, 
result.getMessage());
+    }
+
+    @Test
+    void testAddGroup() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8080, unitName);
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        boolean result = namingManager.addGroup(namespace, vGroup, 
clusterName, unitName);
+        assertTrue(result);
+
+        boolean result1 = namingManager.addGroup(namespace, vGroup, 
clusterName, unitName);
+        assertFalse(result1);
+    }
+
+    @Test
+    void testRemoveGroup() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8000, unitName);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        Unit unit = new Unit();
+        unit.setUnitName(unitName);
+        List<NamingServerNode> nodeList = new ArrayList<>();
+        nodeList.add(node);
+        unit.setNamingInstanceList(nodeList);
+
+        Mockito.when(httpResponse.getStatusLine()).thenReturn(statusLine);
+        Mockito.when(statusLine.getStatusCode()).thenReturn(200);
+
+
+        mockedHttpClientUtil.when(() -> HttpClientUtil.doGet(anyString(), 
anyMap(), anyMap(), anyInt()))
+                .thenReturn(httpResponse);
+
+        Result<String> result = namingManager.removeGroup(unit, vGroup, 
clusterName, namespace, unitName);
+
+        assertTrue(result.isSuccess());
+        assertEquals("200", result.getCode());
+        assertEquals("remove group in old cluster successfully!", 
result.getMessage());
+
+        mockedHttpClientUtil.verify(() -> HttpClientUtil.doGet(
+                anyString(), anyMap(), anyMap(), anyInt()), Mockito.times(1));
+
+    }
+
+    @Test
+    void testMonitorCluster() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        List<ClusterVO> emptyResult = 
namingManager.monitorCluster("empty-namespace");
+        assertTrue(emptyResult.isEmpty());
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8001, unitName);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        List<ClusterVO> resultWithoutMapping = 
namingManager.monitorCluster(namespace);
+        assertFalse(resultWithoutMapping.isEmpty());
+        assertEquals(1, resultWithoutMapping.size());
+        ClusterVO clusterVO = resultWithoutMapping.get(0);
+        assertEquals(clusterName, clusterVO.getClusterName());
+        assertTrue(clusterVO.getvGroupMapping().isEmpty());
+
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        List<ClusterVO> resultWithMapping = 
namingManager.monitorCluster(namespace);
+        assertFalse(resultWithMapping.get(0).getvGroupMapping().isEmpty());
+        
assertTrue(resultWithMapping.get(0).getvGroupMapping().contains(vGroup));
+    }
+
+    @Test
+    void testNotifyClusterChange() {
+        String namespace = "test-namespace";
+        String clusterName = "test-cluster";
+        String unitName = UUID.randomUUID().toString();
+        String vGroup = "test-vGroup";
+
+        NamingServerNode node = createTestNode("127.0.0.1", 8000, unitName);
+        Map<String, String> vGroups = new HashMap<>();
+        vGroups.put(vGroup, unitName);
+        node.getMetadata().put(CONSTANT_GROUP, vGroups);
+        namingManager.registerInstance(node, namespace, clusterName, unitName);
+
+        namingManager.notifyClusterChange(vGroup, namespace, clusterName, 
unitName, 1000L);
+
+        Mockito.verify(applicationContext, 
Mockito.times(2)).publishEvent(any(ClusterChangeEvent.class));
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org

Reply via email to