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);
+ }
+}