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 3e49640e18a Add more test cases on 
readwritesplitting.distsql.handler.update package (#38262)
3e49640e18a is described below

commit 3e49640e18a974409848aa8668d23a4696952497
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Feb 28 12:12:15 2026 +0800

    Add more test cases on readwritesplitting.distsql.handler.update package 
(#38262)
---
 .../AlterReadwriteSplittingRuleExecutorTest.java   | 170 ++++++-------------
 ...riteSplittingStorageUnitStatusExecutorTest.java | 135 +++++++++++++++
 .../CreateReadwriteSplittingRuleExecutorTest.java  | 182 +++++++--------------
 .../DropReadwriteSplittingRuleExecutorTest.java    | 134 +++++++++------
 .../handler/update/UnusedAlgorithmFinderTest.java  |  56 +++++++
 5 files changed, 384 insertions(+), 293 deletions(-)

diff --git 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java
 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java
index ba63b5659a9..9b9b5cfa92f 100644
--- 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java
+++ 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleExecutorTest.java
@@ -17,20 +17,17 @@
 
 package org.apache.shardingsphere.readwritesplitting.distsql.handler.update;
 
+import 
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleDefinitionExecutor;
 import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
-import 
org.apache.shardingsphere.infra.algorithm.core.exception.InvalidAlgorithmConfigurationException;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
+import 
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
-import 
org.apache.shardingsphere.infra.spi.exception.ServiceProviderNotFoundException;
-import org.apache.shardingsphere.infra.util.props.PropertiesBuilder;
-import org.apache.shardingsphere.infra.util.props.PropertiesBuilder.Property;
+import 
org.apache.shardingsphere.infra.rule.attribute.datasource.DataSourceMapperRuleAttribute;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.readwritesplitting.config.ReadwriteSplittingRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.segment.ReadwriteSplittingRuleSegment;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.statement.AlterReadwriteSplittingRuleStatement;
-import 
org.apache.shardingsphere.readwritesplitting.exception.actual.DuplicateReadwriteSplittingActualDataSourceException;
 import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -42,12 +39,17 @@ import org.mockito.junit.jupiter.MockitoExtension;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.Properties;
 
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -60,143 +62,71 @@ class AlterReadwriteSplittingRuleExecutorTest {
     @Mock
     private ResourceMetaData resourceMetaData;
     
-    private final AlterReadwriteSplittingRuleExecutor executor = new 
AlterReadwriteSplittingRuleExecutor();
+    private final AlterReadwriteSplittingRuleExecutor executor = 
(AlterReadwriteSplittingRuleExecutor) TypedSPILoader.getService(
+            DatabaseRuleDefinitionExecutor.class, 
AlterReadwriteSplittingRuleStatement.class);
     
     @BeforeEach
     void setUp() {
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         executor.setDatabase(database);
     }
     
     @Test
-    void assertCheckSQLStatementWithoutToBeAlteredRules() {
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        when(rule.getConfiguration()).thenReturn(new 
ReadwriteSplittingRuleConfiguration(Collections.emptyList(), 
Collections.emptyMap()));
-        executor.setRule(rule);
-        assertThrows(MissingRequiredRuleException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement("TEST")));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithNotExistedDataSources() {
-        
when(resourceMetaData.getNotExistedDataSources(any())).thenReturn(Collections.singleton("read_ds_0"));
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        assertThrows(MissingRequiredStorageUnitsException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement("TEST")));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithoutToBeAlteredLoadBalancers() {
-        
when(database.getRuleMetaData().findRules(any())).thenReturn(Collections.emptyList());
-        executor.setDatabase(database);
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        assertThrows(ServiceProviderNotFoundException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement("INVALID_TYPE")));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithDuplicateWriteDataSourcesInStatement() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules());
-        executor.setRule(rule);
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatementWithDuplicateWriteDataSources("readwrite_ds_0",
 "readwrite_ds_1", "TEST")));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithDuplicateWriteDataSources() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules());
-        executor.setRule(rule);
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> executor.checkBeforeUpdate(
-                        createSQLStatement("readwrite_ds_0", "ds_write_1", 
Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties())));
+    void assertCheckBeforeUpdate() {
+        mockCheckBeforeUpdateDependencies();
+        setRule(createCurrentRuleConfiguration());
+        assertDoesNotThrow(() -> 
executor.checkBeforeUpdate(createSQLStatement(Arrays.asList("read_ds_0", 
"read_ds_1"), new Properties())));
     }
     
     @Test
-    void assertCheckSQLStatementWithDuplicateReadDataSourcesInStatement() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules());
-        executor.setRule(rule);
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatementWithDuplicateReadDataSources("readwrite_ds_0",
 "readwrite_ds_1", "TEST")));
+    void assertBuildToBeAlteredRuleConfiguration() {
+        ReadwriteSplittingRuleConfiguration actual = 
executor.buildToBeAlteredRuleConfiguration(createSQLStatement(Arrays.asList("read_ds_0",
 "read_ds_1"), new Properties()));
+        assertThat(actual.getDataSourceGroups().size(), is(1));
+        assertThat(actual.getLoadBalancers().size(), is(1));
+        
assertTrue(actual.getLoadBalancers().containsKey("readwrite_ds_RANDOM"));
     }
     
     @Test
-    void assertCheckSQLStatementWithDuplicateReadDataSources() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfigurationWithMultipleRules());
-        executor.setRule(rule);
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "write_ds_1", 
Arrays.asList("read_ds_0_0", "read_ds_0_1"), "TEST", new Properties())));
+    void assertBuildToBeDroppedRuleConfiguration() {
+        ReadwriteSplittingRuleConfiguration ruleConfig = 
createCurrentRuleConfiguration();
+        setRule(ruleConfig);
+        ReadwriteSplittingRuleConfiguration actual = 
executor.buildToBeDroppedRuleConfiguration(ruleConfig);
+        assertThat(actual.getDataSourceGroups().size(), is(0));
+        assertThat(actual.getLoadBalancers().size(), is(1));
+        assertTrue(actual.getLoadBalancers().containsKey("unused_lb"));
     }
     
     @Test
-    void assertCheckSQLStatementWithInvalidLoadBalancerProperties() {
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        assertThrows(InvalidAlgorithmConfigurationException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatement("readwrite_ds", "write_ds", 
Arrays.asList("read_ds_0", "read_ds_1"), "weight",
-                        PropertiesBuilder.build(new Property("read_ds_0", 
"5"), new Property("read_ds_2", "5")))));
+    void assertGetRuleClass() {
+        assertThat(executor.getRuleClass(), is(ReadwriteSplittingRule.class));
     }
     
-    private AlterReadwriteSplittingRuleStatement createSQLStatement(final 
String loadBalancerTypeName) {
-        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment("readwrite_ds", "write_ds", 
Arrays.asList("read_ds_0", "ds_read_ds_1"),
-                new AlgorithmSegment(loadBalancerTypeName, new Properties()));
+    private AlterReadwriteSplittingRuleStatement createSQLStatement(final 
Collection<String> readDataSources, final Properties props) {
+        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment("readwrite_ds", "write_ds", readDataSources, new 
AlgorithmSegment("RANDOM", props));
         AlterReadwriteSplittingRuleStatement result = new 
AlterReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment));
         result.buildAttributes();
         return result;
     }
     
-    private AlterReadwriteSplittingRuleStatement createSQLStatement(final 
String ruleName, final String writeDataSource, final Collection<String> 
readDataSources,
-                                                                    final 
String loadBalancerName, final Properties props) {
-        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, new 
AlgorithmSegment(loadBalancerName, props));
-        AlterReadwriteSplittingRuleStatement result = new 
AlterReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment));
-        result.buildAttributes();
-        return result;
-    }
-    
-    private AlterReadwriteSplittingRuleStatement 
createSQLStatementWithDuplicateWriteDataSources(final String ruleName0, final 
String ruleName1, final String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment0 = new 
ReadwriteSplittingRuleSegment(ruleName0, "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        ReadwriteSplittingRuleSegment ruleSegment1 = new 
ReadwriteSplittingRuleSegment(ruleName1, "write_ds", Arrays.asList("read_ds_2", 
"read_ds_3"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        AlterReadwriteSplittingRuleStatement result = new 
AlterReadwriteSplittingRuleStatement(Arrays.asList(ruleSegment0, ruleSegment1));
-        result.buildAttributes();
-        return result;
-    }
-    
-    private AlterReadwriteSplittingRuleStatement 
createSQLStatementWithDuplicateReadDataSources(final String ruleName0, final 
String ruleName1, final String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment0 = new 
ReadwriteSplittingRuleSegment(ruleName0, "write_ds_0", 
Arrays.asList("read_ds_0", "read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        ReadwriteSplittingRuleSegment ruleSegment1 = new 
ReadwriteSplittingRuleSegment(ruleName1, "write_ds_1", 
Arrays.asList("read_ds_0", "read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        AlterReadwriteSplittingRuleStatement result = new 
AlterReadwriteSplittingRuleStatement(Arrays.asList(ruleSegment0, ruleSegment1));
-        result.buildAttributes();
-        return result;
+    private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
+        ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig = new ReadwriteSplittingDataSourceGroupRuleConfiguration(
+                "readwrite_ds", "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"), "used_lb");
+        Map<String, AlgorithmConfiguration> loadBalancers = new HashMap<>(2, 
1F);
+        loadBalancers.put("used_lb", new AlgorithmConfiguration("RANDOM", new 
Properties()));
+        loadBalancers.put("unused_lb", new AlgorithmConfiguration("RANDOM", 
new Properties()));
+        return new ReadwriteSplittingRuleConfiguration(new 
LinkedList<>(Collections.singleton(dataSourceGroupConfig)), loadBalancers);
     }
     
-    private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
-        ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig =
-                new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("readwrite_ds", "ds_write", 
Arrays.asList("read_ds_0", "read_ds_1"), "TEST");
-        return new ReadwriteSplittingRuleConfiguration(new 
LinkedList<>(Collections.singleton(dataSourceGroupConfig)), 
Collections.emptyMap());
+    private void setRule(final ReadwriteSplittingRuleConfiguration ruleConfig) 
{
+        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
+        when(rule.getConfiguration()).thenReturn(ruleConfig);
+        executor.setRule(rule);
     }
     
-    private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfigurationWithMultipleRules() {
-        ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig0 =
-                new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("readwrite_ds_0", 
"ds_write_0", Arrays.asList("read_ds_0_0", "read_ds_0_1"), "TEST");
-        ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig1 =
-                new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("readwrite_ds_1", 
"ds_write_1", Arrays.asList("read_ds_1_0", "read_ds_1_1"), "TEST");
-        return new ReadwriteSplittingRuleConfiguration(new 
LinkedList<>(Arrays.asList(dataSourceGroupConfig0, dataSourceGroupConfig1)), 
Collections.emptyMap());
+    private void mockCheckBeforeUpdateDependencies() {
+        when(database.getName()).thenReturn("test_db");
+        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
+        
lenient().when(resourceMetaData.getStorageUnits()).thenReturn(Collections.emptyMap());
+        
when(resourceMetaData.getNotExistedDataSources(any())).thenReturn(Collections.emptySet());
+        
when(database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class)).thenReturn(Collections.emptyList());
     }
 }
diff --git 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingStorageUnitStatusExecutorTest.java
 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingStorageUnitStatusExecutorTest.java
new file mode 100644
index 00000000000..7d5c41276bc
--- /dev/null
+++ 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingStorageUnitStatusExecutorTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.shardingsphere.readwritesplitting.distsql.handler.update;
+
+import 
org.apache.shardingsphere.distsql.handler.engine.update.DistSQLUpdateExecutor;
+import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.InvalidStorageUnitStatusException;
+import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.infra.state.datasource.DataSourceState;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import 
org.apache.shardingsphere.mode.node.QualifiedDataSourceStatePersistService;
+import 
org.apache.shardingsphere.readwritesplitting.distsql.statement.AlterReadwriteSplittingStorageUnitStatusStatement;
+import 
org.apache.shardingsphere.readwritesplitting.exception.actual.ReadwriteSplittingActualDataSourceNotFoundException;
+import 
org.apache.shardingsphere.readwritesplitting.group.ReadwriteSplittingGroup;
+import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceGroupRule;
+import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.stream.Stream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class AlterReadwriteSplittingStorageUnitStatusExecutorTest {
+    
+    private final AlterReadwriteSplittingStorageUnitStatusExecutor executor = 
(AlterReadwriteSplittingStorageUnitStatusExecutor) TypedSPILoader.getService(
+            DistSQLUpdateExecutor.class, 
AlterReadwriteSplittingStorageUnitStatusStatement.class);
+    
+    @Mock
+    private ShardingSphereDatabase database;
+    
+    @Mock
+    private ReadwriteSplittingRule rule;
+    
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ContextManager contextManager;
+    
+    @BeforeEach
+    void setUp() {
+        executor.setDatabase(database);
+        executor.setRule(rule);
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("executeUpdateFailureArguments")
+    void assertExecuteUpdateWithInvalidStatus(final String name, final String 
configuredRuleName, final Collection<String> readDataSources,
+                                              final Collection<String> 
disabledDataSourceNames, final boolean enable, final Class<? extends Exception> 
expectedException) {
+        lenient().when(database.getName()).thenReturn("test_db");
+        setRuleGroup(configuredRuleName, readDataSources, 
disabledDataSourceNames);
+        assertThrows(expectedException, () -> executor.executeUpdate(new 
AlterReadwriteSplittingStorageUnitStatusStatement(null, "readwrite_group", 
"read_ds_0", enable), contextManager));
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("executeUpdateSuccessArguments")
+    void assertExecuteUpdate(final String name, final String 
statementRuleName, final String configuredRuleName,
+                             final boolean enable, final Collection<String> 
disabledDataSourceNames, final DataSourceState expectedState) {
+        when(database.getName()).thenReturn("test_db");
+        QualifiedDataSourceStatePersistService qualifiedDataSourceStateService 
= mock(QualifiedDataSourceStatePersistService.class);
+        
when(contextManager.getPersistServiceFacade().getQualifiedDataSourceStateService()).thenReturn(qualifiedDataSourceStateService);
+        setRuleGroup(configuredRuleName, Collections.singleton("read_ds_0"), 
disabledDataSourceNames);
+        assertDoesNotThrow(() -> executor.executeUpdate(new 
AlterReadwriteSplittingStorageUnitStatusStatement(null, statementRuleName, 
"read_ds_0", enable), contextManager));
+        verify(qualifiedDataSourceStateService).update("test_db", 
statementRuleName, "read_ds_0", expectedState);
+    }
+    
+    private void setRuleGroup(final String configuredRuleName, final 
Collection<String> readDataSources, final Collection<String> 
disabledDataSourceNames) {
+        if (null == configuredRuleName) {
+            
when(rule.getDataSourceRuleGroups()).thenReturn(Collections.emptyMap());
+            return;
+        }
+        ReadwriteSplittingDataSourceGroupRule dataSourceGroupRule = 
mock(ReadwriteSplittingDataSourceGroupRule.class);
+        when(dataSourceGroupRule.getName()).thenReturn(configuredRuleName);
+        ReadwriteSplittingGroup readwriteSplittingGroup = 
mock(ReadwriteSplittingGroup.class);
+        when(readwriteSplittingGroup.getReadDataSources()).thenReturn(new 
LinkedList<>(readDataSources));
+        
when(dataSourceGroupRule.getReadwriteSplittingGroup()).thenReturn(readwriteSplittingGroup);
+        
lenient().when(dataSourceGroupRule.getDisabledDataSourceNames()).thenReturn(Collections.unmodifiableCollection(disabledDataSourceNames));
+        
when(rule.getDataSourceRuleGroups()).thenReturn(Collections.singletonMap(configuredRuleName,
 dataSourceGroupRule));
+    }
+    
+    @Test
+    void assertGetRuleClass() {
+        assertThat(executor.getRuleClass(), is(ReadwriteSplittingRule.class));
+    }
+    
+    private static Stream<Arguments> executeUpdateFailureArguments() {
+        return Stream.of(
+                Arguments.of("missing readwrite-splitting rule", null, 
Collections.singleton("read_ds_0"), Collections.emptySet(), true, 
MissingRequiredRuleException.class),
+                Arguments.of("missing read storage unit", "readwrite_group", 
Collections.singleton("read_ds_1"), Collections.emptySet(), true,
+                        
ReadwriteSplittingActualDataSourceNotFoundException.class),
+                Arguments.of("enable storage unit that is not disabled", 
"readwrite_group", Collections.singleton("read_ds_0"), Collections.emptySet(), 
true,
+                        InvalidStorageUnitStatusException.class),
+                Arguments.of("disable storage unit that is already disabled", 
"readwrite_group", Collections.singleton("read_ds_0"), 
Collections.singleton("read_ds_0"), false,
+                        InvalidStorageUnitStatusException.class));
+    }
+    
+    private static Stream<Arguments> executeUpdateSuccessArguments() {
+        return Stream.of(
+                Arguments.of("enable storage unit", "readwrite_group", 
"readwrite_group", true, Collections.singleton("read_ds_0"), 
DataSourceState.ENABLED),
+                Arguments.of("disable storage unit", "readwrite_group", 
"readwrite_group", false, Collections.emptySet(), DataSourceState.DISABLED),
+                Arguments.of("match rule name case insensitively", 
"readwrite_group", "READWRITE_GROUP", true, Collections.singleton("read_ds_0"), 
DataSourceState.ENABLED));
+    }
+}
diff --git 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java
 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java
index f5d4814905e..1b9ab2435f1 100644
--- 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java
+++ 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleExecutorTest.java
@@ -17,47 +17,45 @@
 
 package org.apache.shardingsphere.readwritesplitting.distsql.handler.update;
 
+import 
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleDefinitionExecutor;
 import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
-import 
org.apache.shardingsphere.infra.algorithm.core.exception.InvalidAlgorithmConfigurationException;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.DuplicateRuleException;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.InvalidRuleConfigurationException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
 import 
org.apache.shardingsphere.infra.rule.attribute.datasource.DataSourceMapperRuleAttribute;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
-import org.apache.shardingsphere.infra.util.props.PropertiesBuilder;
-import org.apache.shardingsphere.infra.util.props.PropertiesBuilder.Property;
 import 
org.apache.shardingsphere.readwritesplitting.config.ReadwriteSplittingRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.segment.ReadwriteSplittingRuleSegment;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.statement.CreateReadwriteSplittingRuleStatement;
-import 
org.apache.shardingsphere.readwritesplitting.exception.actual.DuplicateReadwriteSplittingActualDataSourceException;
 import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
-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.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Answers;
 import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.Properties;
+import java.util.stream.Stream;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(AutoMockExtension.class)
-@StaticMockSettings(TypedSPILoader.class)
+@ExtendWith(MockitoExtension.class)
 class CreateReadwriteSplittingRuleExecutorTest {
     
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -66,153 +64,87 @@ class CreateReadwriteSplittingRuleExecutorTest {
     @Mock
     private ResourceMetaData resourceMetaData;
     
-    private final CreateReadwriteSplittingRuleExecutor executor = new 
CreateReadwriteSplittingRuleExecutor();
+    private final CreateReadwriteSplittingRuleExecutor executor = 
(CreateReadwriteSplittingRuleExecutor) TypedSPILoader.getService(
+            DatabaseRuleDefinitionExecutor.class, 
CreateReadwriteSplittingRuleStatement.class);
     
     @BeforeEach
     void setUp() {
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         executor.setDatabase(database);
     }
     
     @Test
-    void assertCheckSQLStatementWithDuplicateRuleNames() {
-        
when(resourceMetaData.getStorageUnits()).thenReturn(Collections.emptyMap());
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        assertThrows(DuplicateRuleException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement("TEST")));
+    void assertCheckBeforeUpdate() {
+        mockCheckBeforeUpdateDependencies(Collections.emptySet());
+        setRule(null);
+        assertDoesNotThrow(() -> 
executor.checkBeforeUpdate(createSQLStatement(false, 
Collections.singleton(createRuleSegment("readwrite_ds_1")))));
     }
     
     @Test
-    void assertCheckSQLStatementWithDuplicateDataSources() {
-        
when(resourceMetaData.getStorageUnits()).thenReturn(Collections.singletonMap("write_ds",
 null));
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        assertThrows(InvalidRuleConfigurationException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement("write_ds", "TEST")));
+    void assertBuildToBeCreatedRuleConfigurationWithoutIfNotExists() {
+        setRule(createCurrentRuleConfiguration());
+        ReadwriteSplittingRuleConfiguration actual = 
executor.buildToBeCreatedRuleConfiguration(createSQLStatement(false, 
Collections.singleton(createRuleSegment("readwrite_ds_1"))));
+        assertThat(actual.getDataSourceGroups().size(), is(1));
+        assertThat(actual.getLoadBalancers().size(), is(1));
     }
     
-    @Test
-    void assertCheckSQLStatementWithNotExistedDataSources() {
-        
when(resourceMetaData.getNotExistedDataSources(any())).thenReturn(Arrays.asList("read_ds_0",
 "read_ds_1"));
-        assertThrows(MissingRequiredStorageUnitsException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement("TEST")));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("buildToBeCreatedRuleConfigurationArguments")
+    void assertBuildToBeCreatedRuleConfigurationWithIfNotExists(final String 
name, final ReadwriteSplittingRuleConfiguration currentRuleConfig,
+                                                                final 
Collection<ReadwriteSplittingRuleSegment> ruleSegments, final int 
expectedGroupCount) {
+        setRule(currentRuleConfig);
+        
assertThat(executor.buildToBeCreatedRuleConfiguration(createSQLStatement(true, 
ruleSegments)).getDataSourceGroups().size(), is(expectedGroupCount));
     }
     
     @Test
-    void assertCheckSQLStatementWithDuplicateLogicDataSource() {
-        DataSourceMapperRuleAttribute ruleAttribute = 
mock(DataSourceMapperRuleAttribute.class);
-        
when(ruleAttribute.getDataSourceMapper()).thenReturn(Collections.singletonMap("duplicate_ds",
 Collections.singleton("ds_0")));
-        
when(database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class)).thenReturn(Collections.singleton(ruleAttribute));
-        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment("duplicate_ds", "write_ds_0", 
Arrays.asList("read_ds_0", "read_ds_1"),
-                new AlgorithmSegment(null, new Properties()));
-        executor.setDatabase(database);
-        assertThrows(InvalidRuleConfigurationException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement(false, ruleSegment)));
+    void assertGetRuleClass() {
+        assertThat(executor.getRuleClass(), is(ReadwriteSplittingRule.class));
     }
     
     @Test
-    void assertCheckSQLStatementWithDuplicateWriteDataSourcesInStatement() {
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatementWithDuplicateWriteDataSources("write_ds_0",
 "write_ds_1", "TEST")));
+    void assertCheckBeforeUpdateWithMissingStorageUnit() {
+        mockCheckBeforeUpdateDependencies(Collections.singleton("missing_ds"));
+        setRule(null);
+        assertThrows(MissingRequiredStorageUnitsException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement(false, 
Collections.singleton(createRuleSegment("readwrite_ds_1")))));
     }
     
-    @Test
-    void assertCheckSQLStatementWithDuplicateWriteDataSources() {
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "ds_write", 
Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties())));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithDuplicateReadDataSourcesInStatement() {
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatementWithDuplicateReadDataSources("write_ds_0",
 "write_ds_1", "TEST")));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithDuplicateReadDataSources() {
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
-        
assertThrows(DuplicateReadwriteSplittingActualDataSourceException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatement("readwrite_ds_1", "write_ds_1", 
Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties())));
-    }
-    
-    @Test
-    void assertCheckSQLStatementWithInvalidLoadBalancerProperties() {
-        assertThrows(InvalidAlgorithmConfigurationException.class,
-                () -> 
executor.checkBeforeUpdate(createSQLStatement("readwrite_group", "write_ds", 
Arrays.asList("read_ds_0", "read_ds_1"), "weight",
-                        PropertiesBuilder.build(new Property("read_ds_0", 
"5"), new Property("read_ds_2", "5")))));
+    private void mockCheckBeforeUpdateDependencies(final Collection<String> 
notExistedDataSources) {
+        when(database.getName()).thenReturn("test_db");
+        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
+        
when(resourceMetaData.getStorageUnits()).thenReturn(Collections.emptyMap());
+        
when(resourceMetaData.getNotExistedDataSources(any())).thenReturn(notExistedDataSources);
+        
when(database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class)).thenReturn(Collections.emptyList());
     }
     
-    @Test
-    void assertCheckSQLStatementWithIfNotExists() {
-        ReadwriteSplittingRuleSegment staticSegment = new 
ReadwriteSplittingRuleSegment("readwrite_ds_0", "write_ds_0", 
Arrays.asList("read_ds_2", "read_ds_3"),
-                new AlgorithmSegment(null, new Properties()));
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
+    private void setRule(final ReadwriteSplittingRuleConfiguration 
currentRuleConfig) {
+        ReadwriteSplittingRule rule = null == currentRuleConfig ? null : 
mock(ReadwriteSplittingRule.class);
+        if (null != rule) {
+            
lenient().when(rule.getConfiguration()).thenReturn(currentRuleConfig);
+        }
         executor.setRule(rule);
-        executor.checkBeforeUpdate(createSQLStatement(true, staticSegment));
-    }
-    
-    @Test
-    void assertUpdateSuccess() {
-        DataSourceMapperRuleAttribute ruleAttribute = 
mock(DataSourceMapperRuleAttribute.class, RETURNS_DEEP_STUBS);
-        
when(ruleAttribute.getDataSourceMapper()).thenReturn(Collections.singletonMap("ms_group",
 Collections.singleton("ds_0")));
-        
when(database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class)).thenReturn(Collections.singleton(ruleAttribute));
-        ReadwriteSplittingRuleSegment staticSegment = new 
ReadwriteSplittingRuleSegment(
-                "static_rule", "write_ds_0", Arrays.asList("read_ds_0", 
"read_ds_1"), new AlgorithmSegment("TEST", new Properties()));
-        CreateReadwriteSplittingRuleStatement sqlStatement = new 
CreateReadwriteSplittingRuleStatement(false, 
Collections.singleton(staticSegment));
-        sqlStatement.buildAttributes();
-        executor.setDatabase(database);
-        executor.checkBeforeUpdate(sqlStatement);
-        executor.setRule(mock(ReadwriteSplittingRule.class));
-        ReadwriteSplittingRuleConfiguration toBeCreatedRuleConfig = 
executor.buildToBeCreatedRuleConfiguration(sqlStatement);
-        assertThat(toBeCreatedRuleConfig.getDataSourceGroups().size(), is(1));
-        assertThat(toBeCreatedRuleConfig.getLoadBalancers().size(), is(1));
-    }
-    
-    private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
String loadBalancerName) {
-        return createSQLStatement(false, new 
ReadwriteSplittingRuleSegment("readwrite_ds_0", "write_ds", 
Arrays.asList("read_ds_0", "read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties())));
-    }
-    
-    private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
String ruleName, final String loadBalancerName) {
-        return createSQLStatement(false, new 
ReadwriteSplittingRuleSegment(ruleName, "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties())));
-    }
-    
-    private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
String ruleName, final String writeDataSource, final Collection<String> 
readDataSources,
-                                                                     final 
String loadBalancerName, final Properties props) {
-        return createSQLStatement(false, new 
ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, new 
AlgorithmSegment(loadBalancerName, props)));
     }
     
-    private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
boolean ifNotExists, final ReadwriteSplittingRuleSegment... ruleSegments) {
-        CreateReadwriteSplittingRuleStatement result = new 
CreateReadwriteSplittingRuleStatement(ifNotExists, Arrays.asList(ruleSegments));
+    private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
boolean ifNotExists, final Collection<ReadwriteSplittingRuleSegment> 
ruleSegments) {
+        CreateReadwriteSplittingRuleStatement result = new 
CreateReadwriteSplittingRuleStatement(ifNotExists, new 
LinkedList<>(ruleSegments));
         result.buildAttributes();
         return result;
     }
     
-    private CreateReadwriteSplittingRuleStatement 
createSQLStatementWithDuplicateWriteDataSources(final String ruleName0, final 
String ruleName1, final String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment0 = new 
ReadwriteSplittingRuleSegment(ruleName0, "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        ReadwriteSplittingRuleSegment ruleSegment1 = new 
ReadwriteSplittingRuleSegment(ruleName1, "write_ds", Arrays.asList("read_ds_2", 
"read_ds_3"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        return createSQLStatement(false, ruleSegment0, ruleSegment1);
+    private static Stream<Arguments> 
buildToBeCreatedRuleConfigurationArguments() {
+        return Stream.of(
+                Arguments.of("if not exists with null rule", null, new 
LinkedList<>(Collections.singleton(createRuleSegment("readwrite_ds_1"))), 1),
+                Arguments.of("if not exists removes duplicated rule", 
createCurrentRuleConfiguration(),
+                        new 
LinkedList<>(Collections.singleton(createRuleSegment("readwrite_ds_0"))), 0),
+                Arguments.of("if not exists keeps non duplicated rule", 
createCurrentRuleConfiguration(),
+                        new 
LinkedList<>(Collections.singleton(createRuleSegment("readwrite_ds_1"))), 1));
     }
     
-    private CreateReadwriteSplittingRuleStatement 
createSQLStatementWithDuplicateReadDataSources(final String ruleName0, final 
String ruleName1, final String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment0 = new 
ReadwriteSplittingRuleSegment(ruleName0, "write_ds_0", 
Arrays.asList("read_ds_0", "read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        ReadwriteSplittingRuleSegment ruleSegment1 = new 
ReadwriteSplittingRuleSegment(ruleName1, "write_ds_1", 
Arrays.asList("read_ds_0", "read_ds_1"),
-                new AlgorithmSegment(loadBalancerName, new Properties()));
-        return createSQLStatement(false, ruleSegment0, ruleSegment1);
+    private static ReadwriteSplittingRuleSegment createRuleSegment(final 
String ruleName) {
+        return new ReadwriteSplittingRuleSegment(ruleName, "write_ds", 
Arrays.asList("read_ds_0", "read_ds_1"), new AlgorithmSegment("RANDOM", new 
Properties()));
     }
     
-    private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
+    private static ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
         ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig = new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("readwrite_ds_0", "ds_write",
-                Arrays.asList("read_ds_0", "read_ds_1"), "TEST");
+                Arrays.asList("read_ds_0", "read_ds_1"), "RANDOM");
         return new ReadwriteSplittingRuleConfiguration(new 
LinkedList<>(Collections.singleton(dataSourceGroupConfig)), 
Collections.emptyMap());
     }
 }
diff --git 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleExecutorTest.java
 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleExecutorTest.java
index aaedff97c8f..1b87e307730 100644
--- 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleExecutorTest.java
+++ 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleExecutorTest.java
@@ -17,43 +17,52 @@
 
 package org.apache.shardingsphere.readwritesplitting.distsql.handler.update;
 
+import 
org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.database.DatabaseRuleDefinitionExecutor;
 import 
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
 import org.apache.shardingsphere.infra.datanode.DataNode;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.InUsedRuleException;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.MissingRequiredRuleException;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.RuleDefinitionException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
 import 
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
 import 
org.apache.shardingsphere.infra.rule.attribute.datasource.DataSourceMapperRuleAttribute;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.readwritesplitting.config.ReadwriteSplittingRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.statement.DropReadwriteSplittingRuleStatement;
 import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
+import org.apache.shardingsphere.single.rule.SingleRule;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Properties;
+import java.util.stream.Stream;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @ExtendWith(MockitoExtension.class)
 class DropReadwriteSplittingRuleExecutorTest {
     
-    private final DropReadwriteSplittingRuleExecutor executor = new 
DropReadwriteSplittingRuleExecutor();
+    private final DropReadwriteSplittingRuleExecutor executor = 
(DropReadwriteSplittingRuleExecutor) TypedSPILoader.getService(
+            DatabaseRuleDefinitionExecutor.class, 
DropReadwriteSplittingRuleStatement.class);
     
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private ShardingSphereDatabase database;
@@ -64,89 +73,118 @@ class DropReadwriteSplittingRuleExecutorTest {
     }
     
     @Test
-    void assertCheckSQLStatementWithoutToBeDroppedRule() throws 
RuleDefinitionException {
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        when(rule.getConfiguration()).thenReturn(new 
ReadwriteSplittingRuleConfiguration(Collections.emptyList(), 
Collections.emptyMap()));
-        executor.setRule(rule);
+    void assertCheckBeforeUpdateWithoutToBeDroppedRule() {
+        when(database.getName()).thenReturn("test_db");
+        setRule(new 
ReadwriteSplittingRuleConfiguration(Collections.emptyList(), 
Collections.emptyMap()));
         assertThrows(MissingRequiredRuleException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement()));
     }
     
     @Test
-    void assertCheckSQLStatementWithIfExists() throws RuleDefinitionException {
+    void assertCheckBeforeUpdateWithIfExists() {
         DropReadwriteSplittingRuleStatement sqlStatement = new 
DropReadwriteSplittingRuleStatement(true, 
Collections.singleton("readwrite_ds"));
         sqlStatement.buildAttributes();
-        executor.checkBeforeUpdate(sqlStatement);
+        assertDoesNotThrow(() -> executor.checkBeforeUpdate(sqlStatement));
     }
     
     @Test
-    void assertCheckSQLStatementWithInUsed() throws RuleDefinitionException {
+    void assertCheckBeforeUpdateWithInUsedRule() {
+        when(database.getName()).thenReturn("test_db");
         DataSourceMapperRuleAttribute dataSourceMapperRuleAttribute = 
mock(DataSourceMapperRuleAttribute.class);
-        
when(database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class)).thenReturn(Collections.singleton(dataSourceMapperRuleAttribute));
-        DataNodeRuleAttribute dataNodeRuleAttribute = 
mock(DataNodeRuleAttribute.class);
-        
when(dataNodeRuleAttribute.getAllDataNodes()).thenReturn(Collections.singletonMap("foo_ds",
 Collections.singleton(new DataNode("readwrite_ds.tbl"))));
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        when(rule.getAttributes()).thenReturn(new 
RuleAttributes(dataNodeRuleAttribute));
-        
when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(rule));
-        executor.setDatabase(database);
-        
when(rule.getConfiguration()).thenReturn(createCurrentRuleConfiguration());
-        executor.setRule(rule);
+        
when(dataSourceMapperRuleAttribute.getDataSourceMapper()).thenReturn(Collections.singletonMap("logic_tbl",
 Collections.singleton("readwrite_ds")));
+        ShardingSphereRule mapperRule = mock(ShardingSphereRule.class);
+        when(mapperRule.getAttributes()).thenReturn(new 
RuleAttributes(dataSourceMapperRuleAttribute));
+        
when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(mapperRule));
+        setRule(createCurrentRuleConfiguration());
         assertThrows(InUsedRuleException.class, () -> 
executor.checkBeforeUpdate(createSQLStatement()));
     }
     
     @Test
-    void assertBuildToBeDroppedRuleConfiguration() {
-        ReadwriteSplittingRuleConfiguration ruleConfig = 
createCurrentRuleConfiguration();
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        when(rule.getConfiguration()).thenReturn(ruleConfig);
-        executor.setRule(rule);
+    void assertCheckBeforeUpdateWithUnusedResources() {
+        ReadwriteSplittingRule readwriteRule = 
mock(ReadwriteSplittingRule.class);
+        when(readwriteRule.getAttributes()).thenReturn(new RuleAttributes());
+        DataSourceMapperRuleAttribute dataSourceMapperRuleAttribute = 
mock(DataSourceMapperRuleAttribute.class);
+        
when(dataSourceMapperRuleAttribute.getDataSourceMapper()).thenReturn(Collections.singletonMap("logic_tbl",
 Collections.singleton("foo_ds")));
+        ShardingSphereRule mapperRule = mock(ShardingSphereRule.class);
+        when(mapperRule.getAttributes()).thenReturn(new 
RuleAttributes(dataSourceMapperRuleAttribute));
+        ShardingSphereRule plainRule = mock(ShardingSphereRule.class);
+        when(plainRule.getAttributes()).thenReturn(new RuleAttributes());
+        DataNodeRuleAttribute dataNodeRuleAttribute = 
mock(DataNodeRuleAttribute.class);
+        
when(dataNodeRuleAttribute.getAllDataNodes()).thenReturn(Collections.singletonMap("bar_tbl",
 Collections.singleton(new DataNode("bar_ds.tbl"))));
+        ShardingSphereRule dataNodeRule = mock(ShardingSphereRule.class);
+        when(dataNodeRule.getAttributes()).thenReturn(new 
RuleAttributes(dataNodeRuleAttribute));
+        SingleRule singleRule = mock(SingleRule.class);
+        when(singleRule.getAttributes()).thenReturn(new RuleAttributes());
+        
when(database.getRuleMetaData().getRules()).thenReturn(Arrays.asList(readwriteRule,
 mapperRule, plainRule, dataNodeRule, singleRule));
+        setRule(createCurrentRuleConfiguration());
+        assertDoesNotThrow(() -> 
executor.checkBeforeUpdate(createSQLStatement()));
+    }
+    
+    private DropReadwriteSplittingRuleStatement createSQLStatement() {
+        DropReadwriteSplittingRuleStatement result = new 
DropReadwriteSplittingRuleStatement(false, 
Collections.singleton("readwrite_ds"));
+        result.buildAttributes();
+        return result;
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("buildToBeDroppedRuleConfigurationArguments")
+    void assertBuildToBeDroppedRuleConfiguration(final String name,
+                                                 final 
ReadwriteSplittingRuleConfiguration currentRuleConfig, final int 
expectedDataSourceGroupCount, final int expectedLoadBalancerCount) {
+        setRule(currentRuleConfig);
         ReadwriteSplittingRuleConfiguration actual = 
executor.buildToBeDroppedRuleConfiguration(createSQLStatement());
-        assertThat(actual.getDataSourceGroups().size(), is(1));
-        assertThat(actual.getLoadBalancers().size(), is(1));
+        assertThat(actual.getDataSourceGroups().size(), 
is(expectedDataSourceGroupCount));
+        assertThat(actual.getLoadBalancers().size(), 
is(expectedLoadBalancerCount));
     }
     
-    @Test
-    void assertBuildToBeDroppedRuleConfigurationWithInUsedLoadBalancer() {
-        ReadwriteSplittingRuleConfiguration ruleConfig = 
createMultipleCurrentRuleConfigurations();
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("hasAnyOneToBeDroppedArguments")
+    void assertHasAnyOneToBeDropped(final String name, final 
Collection<String> toBeDroppedNames, final boolean expected) {
+        setRule(createCurrentRuleConfiguration());
+        DropReadwriteSplittingRuleStatement sqlStatement = new 
DropReadwriteSplittingRuleStatement(false, toBeDroppedNames);
+        sqlStatement.buildAttributes();
+        boolean actual = executor.hasAnyOneToBeDropped(sqlStatement);
+        assertThat(actual, is(expected));
+    }
+    
+    private void setRule(final ReadwriteSplittingRuleConfiguration ruleConfig) 
{
         ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
         when(rule.getConfiguration()).thenReturn(ruleConfig);
         executor.setRule(rule);
-        ReadwriteSplittingRuleConfiguration actual = 
executor.buildToBeDroppedRuleConfiguration(createSQLStatement());
-        assertThat(actual.getDataSourceGroups().size(), is(1));
-        assertTrue(actual.getLoadBalancers().isEmpty());
     }
     
     @Test
-    void assertBuildToBeDroppedRuleConfigurationWithoutLoadBalancerName() {
-        ReadwriteSplittingRuleConfiguration ruleConfig = 
createCurrentRuleConfigurationWithoutLoadBalancerName();
-        ReadwriteSplittingRule rule = mock(ReadwriteSplittingRule.class);
-        when(rule.getConfiguration()).thenReturn(ruleConfig);
-        executor.setRule(rule);
-        ReadwriteSplittingRuleConfiguration actual = 
executor.buildToBeDroppedRuleConfiguration(createSQLStatement());
-        assertThat(actual.getDataSourceGroups().size(), is(1));
-        assertThat(actual.getLoadBalancers().size(), is(1));
+    void assertGetRuleClass() {
+        assertThat(executor.getRuleClass(), is(ReadwriteSplittingRule.class));
     }
     
-    private DropReadwriteSplittingRuleStatement createSQLStatement() {
-        DropReadwriteSplittingRuleStatement result = new 
DropReadwriteSplittingRuleStatement(false, 
Collections.singleton("readwrite_ds"));
-        result.buildAttributes();
-        return result;
+    private static Stream<Arguments> hasAnyOneToBeDroppedArguments() {
+        return Stream.of(
+                Arguments.of("contains dropped rule", 
Collections.singleton("readwrite_ds"), true),
+                Arguments.of("without dropped rule", 
Collections.singleton("other_ds"), false),
+                Arguments.of("intersected dropped rules", 
Arrays.asList("other_ds", "readwrite_ds"), true));
+    }
+    
+    private static Stream<Arguments> 
buildToBeDroppedRuleConfigurationArguments() {
+        return Stream.of(
+                Arguments.of("drop configuration with unused load balancer", 
createCurrentRuleConfiguration(), 1, 1),
+                Arguments.of("drop configuration without load balancer name", 
createCurrentRuleConfigurationWithoutLoadBalancerName(), 1, 1),
+                Arguments.of("drop configuration with in-used load balancer", 
createMultipleCurrentRuleConfigurations(), 1, 0));
     }
     
-    private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
+    private static ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
         ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig = new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("readwrite_ds",
                 "", Collections.emptyList(), "readwrite_ds");
         Map<String, AlgorithmConfiguration> loadBalancers = 
Collections.singletonMap("readwrite_ds", new AlgorithmConfiguration("TEST", new 
Properties()));
         return new ReadwriteSplittingRuleConfiguration(new 
LinkedList<>(Collections.singleton(dataSourceGroupConfig)), loadBalancers);
     }
     
-    private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfigurationWithoutLoadBalancerName() {
+    private static ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfigurationWithoutLoadBalancerName() {
         ReadwriteSplittingDataSourceGroupRuleConfiguration 
dataSourceGroupConfig = new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("readwrite_ds",
                 "", new LinkedList<>(), null);
         Map<String, AlgorithmConfiguration> loadBalancers = 
Collections.singletonMap("readwrite_ds", new AlgorithmConfiguration("TEST", new 
Properties()));
         return new ReadwriteSplittingRuleConfiguration(new 
LinkedList<>(Collections.singleton(dataSourceGroupConfig)), loadBalancers);
     }
     
-    private ReadwriteSplittingRuleConfiguration 
createMultipleCurrentRuleConfigurations() {
+    private static ReadwriteSplittingRuleConfiguration 
createMultipleCurrentRuleConfigurations() {
         ReadwriteSplittingDataSourceGroupRuleConfiguration 
fooDataSourceGroupConfig = new 
ReadwriteSplittingDataSourceGroupRuleConfiguration(
                 "foo_ds", "", new LinkedList<>(), "TEST");
         ReadwriteSplittingDataSourceGroupRuleConfiguration 
barDataSourceGroupConfig = new 
ReadwriteSplittingDataSourceGroupRuleConfiguration(
diff --git 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/UnusedAlgorithmFinderTest.java
 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/UnusedAlgorithmFinderTest.java
new file mode 100644
index 00000000000..f55a30d5146
--- /dev/null
+++ 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/UnusedAlgorithmFinderTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.shardingsphere.readwritesplitting.distsql.handler.update;
+
+import 
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
+import 
org.apache.shardingsphere.readwritesplitting.config.ReadwriteSplittingRuleConfiguration;
+import 
org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class UnusedAlgorithmFinderTest {
+    
+    @Test
+    void assertFindUnusedLoadBalancers() {
+        ReadwriteSplittingRuleConfiguration ruleConfig = 
createRuleConfiguration(Collections.singletonList("lb_0"), 
Arrays.asList("lb_0", "lb_1"));
+        assertThat(UnusedAlgorithmFinder.findUnusedLoadBalancers(ruleConfig), 
is(Collections.singleton("lb_1")));
+    }
+    
+    @Test
+    void assertFindUnusedLoadBalancersWithoutUnused() {
+        ReadwriteSplittingRuleConfiguration ruleConfig = 
createRuleConfiguration(Arrays.asList("lb_0", "lb_1"), Arrays.asList("lb_0", 
"lb_1"));
+        
assertTrue(UnusedAlgorithmFinder.findUnusedLoadBalancers(ruleConfig).isEmpty());
+    }
+    
+    private ReadwriteSplittingRuleConfiguration createRuleConfiguration(final 
Collection<String> usedLoadBalancers, final Collection<String> 
allLoadBalancers) {
+        Collection<ReadwriteSplittingDataSourceGroupRuleConfiguration> 
dataSourceGroups = usedLoadBalancers.stream()
+                .map(each -> new 
ReadwriteSplittingDataSourceGroupRuleConfiguration("group_" + each, "write_ds", 
Collections.singletonList("read_ds"), each)).collect(Collectors.toList());
+        Map<String, AlgorithmConfiguration> loadBalancers = 
allLoadBalancers.stream().collect(Collectors.toMap(each -> each, each -> new 
AlgorithmConfiguration("RANDOM", new Properties())));
+        return new ReadwriteSplittingRuleConfiguration(dataSourceGroups, 
loadBalancers);
+    }
+}

Reply via email to