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 dbb7c900ecc Add more test cases on SingleRouteEngineTest (#38085)
dbb7c900ecc is described below
commit dbb7c900ecc121d6bb7a252c77576d5153351d30
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Feb 18 20:16:32 2026 +0800
Add more test cases on SingleRouteEngineTest (#38085)
* Add more test cases on SingleRouteEngineTest
* Add more test cases on SingleRouteEngineTest
---
.../single/route/engine/SingleRouteEngineTest.java | 121 +++++++++++++++++----
1 file changed, 97 insertions(+), 24 deletions(-)
diff --git
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
index eb16e812df1..eb012d5dd0f 100644
---
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
+++
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.single.route.engine;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.database.exception.core.exception.syntax.table.TableExistsException;
import org.apache.shardingsphere.infra.datanode.DataNode;
+import
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.hint.HintValueContext;
import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable;
import org.apache.shardingsphere.infra.route.context.RouteContext;
@@ -30,32 +31,39 @@ import
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttri
import
org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.single.config.SingleRuleConfiguration;
+import org.apache.shardingsphere.single.exception.SingleTableNotFoundException;
import org.apache.shardingsphere.single.rule.SingleRule;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.DDLStatement;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import org.apache.shardingsphere.test.infra.fixture.jdbc.MockedDataSource;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+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.mock;
import static org.mockito.Mockito.when;
@@ -66,7 +74,7 @@ class SingleRouteEngineTest {
@Test
void assertRouteInSameDataSource() throws SQLException {
- SingleRouteEngine engine = new
SingleRouteEngine(mockQualifiedTables(), null, mock());
+ SingleRouteEngine engine = new SingleRouteEngine(Arrays.asList(new
QualifiedTable("foo_db", "t_order"), new QualifiedTable("foo_db",
"t_order_item")), null, mock());
SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(),
"foo_db", mock(), createDataSourceMap(), Collections.emptyList());
singleRule.getAttributes().getAttribute(DataNodeRuleAttribute.class).getAllDataNodes().put("t_order",
Collections.singleton(new DataNode("ds_0", "foo_db", "t_order")));
singleRule.getAttributes().getAttribute(DataNodeRuleAttribute.class).getAllDataNodes().put("t_order_item",
Collections.singleton(new DataNode("ds_0", "foo_db", "t_order_item")));
@@ -85,16 +93,13 @@ class SingleRouteEngineTest {
assertThat(tableMapper1.getLogicName(), is("t_order_item"));
}
- private Collection<QualifiedTable> mockQualifiedTables() {
- return Arrays.asList(new QualifiedTable("foo_db", "t_order"), new
QualifiedTable("foo_db", "t_order_item"));
- }
-
@Test
void assertRouteWithoutSingleRule() throws SQLException {
CreateTableStatement sqlStatement = new
CreateTableStatement(databaseType);
- SingleRouteEngine engine = new
SingleRouteEngine(mockQualifiedTables(), sqlStatement, mock());
+ SingleRouteEngine engine = new SingleRouteEngine(Arrays.asList(new
QualifiedTable("foo_db", "t_order"), new QualifiedTable("foo_db",
"t_order_item")), sqlStatement, mock());
SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(),
"foo_db", mock(), createDataSourceMap(), Collections.emptyList());
RouteContext routeContext = new RouteContext();
+ assertThat(routeContext.getOriginalDataNodes().size(), is(0));
engine.route(routeContext, singleRule);
List<RouteUnit> routeUnits = new
ArrayList<>(routeContext.getRouteUnits());
assertThat(routeContext.getRouteUnits().size(), is(1));
@@ -108,9 +113,10 @@ class SingleRouteEngineTest {
@Test
void assertRouteWithDefaultSingleRule() throws SQLException {
CreateTableStatement sqlStatement = new
CreateTableStatement(databaseType);
- SingleRouteEngine engine = new
SingleRouteEngine(mockQualifiedTables(), sqlStatement, mock());
+ SingleRouteEngine engine = new SingleRouteEngine(Arrays.asList(new
QualifiedTable("foo_db", "t_order"), new QualifiedTable("foo_db",
"t_order_item")), sqlStatement, mock());
SingleRule singleRule = new SingleRule(new
SingleRuleConfiguration(Collections.emptyList(), "ds_0"), "foo_db", mock(),
createDataSourceMap(), Collections.emptyList());
RouteContext routeContext = new RouteContext();
+ assertThat(routeContext.getRouteUnits().size(), is(0));
engine.route(routeContext, singleRule);
List<RouteUnit> routeUnits = new
ArrayList<>(routeContext.getRouteUnits());
assertThat(routeContext.getRouteUnits().size(), is(1));
@@ -122,6 +128,55 @@ class SingleRouteEngineTest {
assertThat(tableMapper0.getLogicName(), is("t_order"));
}
+ @Test
+ void assertRouteWithCombinedRouteContext() {
+ SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mock(SQLStatement.class), mock(HintValueContext.class));
+ RouteContext routeContext = new RouteContext();
+ routeContext.putRouteUnit(new RouteMapper("ds_0", "ds_0"),
Collections.singletonList(new RouteMapper("t_order", "t_order")));
+ routeContext.putRouteUnit(new RouteMapper("ds_1", "ds_1"),
Collections.singletonList(new RouteMapper("t_order", "t_order")));
+ engine.route(routeContext, mockSingleRuleWithTableDataNode(new
DataNode("ds_1", "foo_db", "t_order"), true));
+ List<RouteUnit> routeUnits = new
ArrayList<>(routeContext.getRouteUnits());
+ assertThat(routeUnits.size(), is(1));
+ assertThat(routeUnits.get(0).getDataSourceMapper().getActualName(),
is("ds_1"));
+ assertThat(routeUnits.get(0).getTableMappers().size(), is(1));
+ }
+
+ @Test
+ void assertRouteWithSelectStatementAndExistingRouteUnits() {
+ SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mock(SelectStatement.class), mock(HintValueContext.class));
+ RouteContext routeContext = new RouteContext();
+ routeContext.putRouteUnit(new RouteMapper("ds_0", "ds_0"),
Collections.singletonList(new RouteMapper("t_order", "t_order")));
+ engine.route(routeContext, mockSingleRuleWithTableDataNode(new
DataNode("ds_1", "foo_db", "t_order"), true));
+ assertThat(routeContext.getRouteUnits().size(), is(2));
+ }
+
+ @Test
+ void assertRouteWhenAllTablesNotInSameComputeNode() {
+ SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mock(SQLStatement.class), mock(HintValueContext.class));
+ RouteContext routeContext = new RouteContext();
+ routeContext.getOriginalDataNodes().add(Collections.singleton(new
DataNode("ds_0", "foo_db", "t_order")));
+ assertThrows(UnsupportedSQLOperationException.class, () ->
engine.route(routeContext, mockSingleRuleWithTableDataNode(new DataNode("ds_0",
"foo_db", "t_order"), false)));
+ }
+
+ @Test
+ void assertRouteWithNonCreateDDLStatement() {
+ SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mock(DDLStatement.class), mock(HintValueContext.class));
+ RouteContext routeContext = new RouteContext();
+ assertThat(routeContext.getRouteUnits().size(), is(0));
+ engine.route(routeContext, mockSingleRuleWithTableDataNode(new
DataNode("ds_0", "foo_db", "t_order")));
+ List<RouteUnit> routeUnits = new
ArrayList<>(routeContext.getRouteUnits());
+ assertThat(routeUnits.size(), is(1));
+ assertThat(routeUnits.get(0).getDataSourceMapper().getActualName(),
is("ds_0"));
+ }
+
+ @Test
+ void assertRouteWhenSingleTableNotFound() {
+ SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mock(SQLStatement.class), mock(HintValueContext.class));
+ RouteContext routeContext = new RouteContext();
+ assertThat(routeContext.getRouteUnits().size(), is(0));
+ assertThrows(SingleTableNotFoundException.class, () ->
engine.route(routeContext, mockSingleRuleWithoutTableDataNode()));
+ }
+
private Map<String, DataSource> createDataSourceMap() throws SQLException {
Map<String, DataSource> result = new HashMap<>(2, 1F);
Connection connection = mock(Connection.class, RETURNS_DEEP_STUBS);
@@ -131,31 +186,49 @@ class SingleRouteEngineTest {
return result;
}
- @Test
- void assertRouteDuplicateSingleTable() {
- SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mockStatement(false), mock(HintValueContext.class));
- assertThrows(TableExistsException.class, () -> engine.route(new
RouteContext(), mockSingleRule()));
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("routeDuplicateSingleTableArguments")
+ void assertRouteDuplicateSingleTable(final String name, final boolean
ifNotExists, final boolean skipMetadataValidate, final boolean
expectedToThrowException) {
+ CreateTableStatement createTableStatement =
mock(CreateTableStatement.class);
+ when(createTableStatement.isIfNotExists()).thenReturn(ifNotExists);
+ when(createTableStatement.getTable()).thenReturn(new
SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
+ HintValueContext hintValueContext = mock(HintValueContext.class);
+
when(hintValueContext.isSkipMetadataValidate()).thenReturn(skipMetadataValidate);
+ SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), createTableStatement, hintValueContext);
+ if (expectedToThrowException) {
+ assertThrows(TableExistsException.class, () -> engine.route(new
RouteContext(), mockSingleRuleWithTableDataNode(new DataNode("ds_0", "foo_db",
"t_order"))));
+ } else {
+ assertDoesNotThrow(() -> engine.route(new RouteContext(),
mockSingleRuleWithTableDataNode(new DataNode("ds_0", "foo_db", "t_order"))));
+ }
}
- @Test
- void assertRouteIfNotExistsDuplicateSingleTable() {
- SingleRouteEngine engine = new
SingleRouteEngine(Collections.singleton(new QualifiedTable("foo_db",
"t_order")), mockStatement(true), mock(HintValueContext.class));
- assertDoesNotThrow(() -> engine.route(new RouteContext(),
mockSingleRule()));
+ private static Stream<Arguments> routeDuplicateSingleTableArguments() {
+ return Stream.of(
+
Arguments.of("if-not-exists-disabled-and-metadata-check-enabled", false, false,
true),
+ Arguments.of("if-not-exists-enabled", true, false, false),
+ Arguments.of("skip-metadata-validate-enabled", false, true,
false));
+ }
+
+ private SingleRule mockSingleRuleWithTableDataNode(final DataNode
tableDataNode) {
+ SingleRule result = mock(SingleRule.class);
+ MutableDataNodeRuleAttribute ruleAttribute =
mock(MutableDataNodeRuleAttribute.class);
+ when(ruleAttribute.findTableDataNode("foo_db",
"t_order")).thenReturn(Optional.of(tableDataNode));
+ when(result.getAttributes()).thenReturn(new
RuleAttributes(ruleAttribute));
+ return result;
}
- private SQLStatement mockStatement(final boolean ifNotExists) {
- CreateTableStatement result = mock(CreateTableStatement.class);
- when(result.isIfNotExists()).thenReturn(ifNotExists);
- when(result.getTable()).thenReturn(new SimpleTableSegment(new
TableNameSegment(0, 0, new IdentifierValue("t_order"))));
+ private SingleRule mockSingleRuleWithTableDataNode(final DataNode
tableDataNode, final boolean allTablesInSameComputeNode) {
+ SingleRule result = mockSingleRuleWithTableDataNode(tableDataNode);
+ when(result.isAllTablesInSameComputeNode(any(),
any())).thenReturn(allTablesInSameComputeNode);
return result;
}
- private SingleRule mockSingleRule() {
+ private SingleRule mockSingleRuleWithoutTableDataNode() {
SingleRule result = mock(SingleRule.class);
- DataNode dataNode = mock(DataNode.class);
MutableDataNodeRuleAttribute ruleAttribute =
mock(MutableDataNodeRuleAttribute.class);
- when(ruleAttribute.findTableDataNode("foo_db",
"t_order")).thenReturn(Optional.of(dataNode));
+ when(ruleAttribute.findTableDataNode("foo_db",
"t_order")).thenReturn(Optional.empty());
when(result.getAttributes()).thenReturn(new
RuleAttributes(ruleAttribute));
+ when(result.isAllTablesInSameComputeNode(any(),
any())).thenReturn(true);
return result;
}
}