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 07122499b9a Add more test cases on SingleTableDataNodeLoaderTest
(#38078)
07122499b9a is described below
commit 07122499b9a5ada8638437b0af303d2199c425e6
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Feb 18 12:03:03 2026 +0800
Add more test cases on SingleTableDataNodeLoaderTest (#38078)
* Add more test cases on SingleTableDataNodeLoaderTest
* Add more test cases on SingleTableDataNodeLoaderTest
* Add more test cases on SingleTableDataNodeLoaderTest
* Add more test cases on SingleTableDataNodeLoaderTest
* Add more test cases on SingleTableDataNodeLoaderTest
* Add more test cases on SingleTableDataNodeLoaderTest
* Add more test cases on SingleTableDataNodeLoaderTest
---
.../single/datanode/SingleTableDataNodeLoader.java | 4 +-
.../datanode/SingleTableDataNodeLoaderTest.java | 182 +++++++++++++++------
2 files changed, 131 insertions(+), 55 deletions(-)
diff --git
a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
index 912f0a7b1d0..052b4f4ccd7 100644
---
a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
+++
b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
@@ -133,7 +133,7 @@ public final class SingleTableDataNodeLoader {
continue;
}
Map<String, Collection<String>> configuredTablesForDataSource =
configuredTableMap.get(each.getDataSourceName());
- if (null == configuredTablesForDataSource ||
configuredTablesForDataSource.isEmpty()) {
+ if (null == configuredTablesForDataSource) {
continue;
}
if
(configuredTablesForDataSource.containsKey(SingleTableConstants.ASTERISK)) {
@@ -141,7 +141,7 @@ public final class SingleTableDataNodeLoader {
continue;
}
Collection<String> configuredTablesForSchema =
configuredTablesForDataSource.get(each.getSchemaName());
- if (null == configuredTablesForSchema ||
configuredTablesForSchema.isEmpty()) {
+ if (null == configuredTablesForSchema) {
continue;
}
if
(configuredTablesForSchema.contains(SingleTableConstants.ASTERISK) ||
configuredTablesForSchema.contains(each.getTableName().toLowerCase())) {
diff --git
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
index fd6cfdfc9d6..8e8b04f07b7 100644
---
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
+++
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
@@ -23,9 +23,16 @@ import
org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
import
org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.single.exception.SingleTablesLoadingException;
+import org.apache.shardingsphere.single.util.SingleTableLoadUtils;
import org.apache.shardingsphere.test.infra.fixture.jdbc.MockedDataSource;
import org.junit.jupiter.api.BeforeEach;
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 org.mockito.Answers;
+import org.mockito.MockedStatic;
import javax.sql.DataSource;
import java.sql.Connection;
@@ -35,32 +42,26 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeSet;
import java.util.stream.Collectors;
+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.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
class SingleTableDataNodeLoaderTest {
- private static final String TABLE_TYPE = "TABLE";
-
- private static final String PARTITIONED_TABLE_TYPE = "PARTITIONED TABLE";
-
- private static final String VIEW_TYPE = "VIEW";
-
- private static final String SYSTEM_TABLE_TYPE = "SYSTEM TABLE";
-
- private static final String SYSTEM_VIEW_TYPE = "SYSTEM VIEW";
-
- private static final String TABLE_NAME = "TABLE_NAME";
-
private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
private Map<String, DataSource> dataSourceMap;
@@ -68,15 +69,15 @@ class SingleTableDataNodeLoaderTest {
@BeforeEach
void setUp() throws SQLException {
dataSourceMap = new LinkedHashMap<>(2, 1F);
- dataSourceMap.put("ds0", mockDataSource("ds0",
Arrays.asList("employee", "dept", "salary")));
- dataSourceMap.put("ds1", mockDataSource("ds1",
Arrays.asList("student", "teacher", "class", "salary")));
+ dataSourceMap.put("foo_ds", mockDataSource("foo_ds",
Arrays.asList("foo_tbl1", "foo_tbl2")));
+ dataSourceMap.put("bar_ds", mockDataSource("bar_ds",
Arrays.asList("bar_tbl1", "bar_tbl2")));
}
private DataSource mockDataSource(final String dataSourceName, final
List<String> tableNames) throws SQLException {
Connection connection = mock(Connection.class, RETURNS_DEEP_STUBS);
when(connection.getCatalog()).thenReturn(dataSourceName);
ResultSet resultSet = mockResultSet(tableNames);
- when(connection.getMetaData().getTables(dataSourceName, null, null,
new String[]{TABLE_TYPE, PARTITIONED_TABLE_TYPE, VIEW_TYPE, SYSTEM_TABLE_TYPE,
SYSTEM_VIEW_TYPE})).thenReturn(resultSet);
+ when(connection.getMetaData().getTables(dataSourceName, null, null,
new String[]{"TABLE", "PARTITIONED TABLE", "VIEW", "SYSTEM TABLE", "SYSTEM
VIEW"})).thenReturn(resultSet);
when(connection.getMetaData().getURL()).thenReturn("jdbc:mock://127.0.0.1/foo_ds");
return new MockedDataSource(connection);
}
@@ -88,53 +89,128 @@ class SingleTableDataNodeLoaderTest {
Collection<Boolean> remainNextResults =
remainTableNames.stream().map(each -> true).collect(Collectors.toList());
remainNextResults.add(false);
when(result.next()).thenReturn(true, remainNextResults.toArray(new
Boolean[tableNames.size()]));
- when(result.getString(TABLE_NAME)).thenReturn(firstTableName,
remainTableNames.toArray(new String[tableNames.size() - 1]));
+ when(result.getString("TABLE_NAME")).thenReturn(firstTableName,
remainTableNames.toArray(new String[tableNames.size() - 1]));
return result;
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("loadWithConfiguredTableExpressionArguments")
+ void assertLoadWithConfiguredTableExpressions(final String name, final
Collection<ShardingSphereRule> builtRules,
+ final Collection<String>
configuredTables, final Map<String, Collection<String>>
expectedTableDataSources) {
+ Map<String, Collection<DataNode>> actual =
SingleTableDataNodeLoader.load("foo_db", databaseType, dataSourceMap,
builtRules, configuredTables);
+ assertThat(new TreeSet<>(actual.keySet()), is(new
TreeSet<>(expectedTableDataSources.keySet())));
+ assertTableDataSources(actual, expectedTableDataSources);
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("loadWithConfiguredTableMapRuleArguments")
+ void assertLoadWithConfiguredTableMapRules(final String name, final
Collection<String> splitTables,
+ final Collection<DataNode>
configuredDataNodes, final Map<String, Collection<String>>
expectedTableDataSources) {
+ try (MockedStatic<SingleTableLoadUtils> mockedSingleTableLoadUtils =
mockStatic(SingleTableLoadUtils.class, Answers.CALLS_REAL_METHODS)) {
+ mockedSingleTableLoadUtils.when(() ->
SingleTableLoadUtils.splitTableLines(Collections.singleton("foo_ds.foo_tbl2"))).thenReturn(splitTables);
+ mockedSingleTableLoadUtils.when(() ->
SingleTableLoadUtils.convertToDataNodes("foo_db", databaseType,
splitTables)).thenReturn(configuredDataNodes);
+ Map<String, Collection<DataNode>> actual =
SingleTableDataNodeLoader.load("foo_db", databaseType, dataSourceMap,
Collections.emptyList(), Collections.singleton("foo_ds.foo_tbl2"));
+ assertThat(new TreeSet<>(actual.keySet()), is(new
TreeSet<>(expectedTableDataSources.keySet())));
+ assertTableDataSources(actual, expectedTableDataSources);
+ }
+ }
+
+ private void assertTableDataSources(final Map<String,
Collection<DataNode>> actual, final Map<String, Collection<String>>
expectedTableDataSources) {
+ for (Entry<String, Collection<String>> entry :
expectedTableDataSources.entrySet()) {
+ Collection<String> actualDataSourceNames =
actual.get(entry.getKey()).stream().map(DataNode::getDataSourceName).collect(Collectors.toCollection(TreeSet::new));
+ assertThat(actualDataSourceNames, is(new
TreeSet<>(entry.getValue())));
+ }
+ }
+
@Test
- void assertLoad() {
- ShardingSphereRule builtRule = mock(ShardingSphereRule.class);
- TableMapperRuleAttribute ruleAttribute =
mock(TableMapperRuleAttribute.class, RETURNS_DEEP_STUBS);
-
when(ruleAttribute.getDistributedTableNames()).thenReturn(Arrays.asList("salary",
"employee", "student"));
- when(builtRule.getAttributes()).thenReturn(new
RuleAttributes(ruleAttribute));
+ void assertLoadWithFeatureRequiredSingleTables() {
Map<String, Collection<DataNode>> actual =
SingleTableDataNodeLoader.load(
- "foo_db", databaseType, dataSourceMap,
Collections.singleton(builtRule), Collections.singleton("*.*"));
- assertFalse(actual.containsKey("employee"));
- assertFalse(actual.containsKey("salary"));
- assertFalse(actual.containsKey("student"));
- assertTrue(actual.containsKey("dept"));
- assertTrue(actual.containsKey("teacher"));
- assertTrue(actual.containsKey("class"));
- assertThat(actual.get("dept").iterator().next().getDataSourceName(),
is("ds0"));
-
assertThat(actual.get("teacher").iterator().next().getDataSourceName(),
is("ds1"));
- assertThat(actual.get("class").iterator().next().getDataSourceName(),
is("ds1"));
+ "foo_db", databaseType, dataSourceMap,
Collections.singleton(createRule(Collections.emptyList(),
Collections.singleton("foo_tbl1"))), Collections.singleton("foo_ds.foo_tbl2"));
+ assertTrue(actual.containsKey("foo_tbl1"));
+ assertTrue(actual.containsKey("foo_tbl2"));
+ assertFalse(actual.containsKey("bar_tbl1"));
+
assertThat(actual.get("foo_tbl1").iterator().next().getDataSourceName(),
is("foo_ds"));
+
assertThat(actual.get("foo_tbl2").iterator().next().getDataSourceName(),
is("foo_ds"));
+ }
+
+ @Test
+ void assertLoadWithEmptyConfiguredTablesAndFeatureRequiredSingleTables() {
+ assertTrue(SingleTableDataNodeLoader.load(
+ "foo_db", databaseType, dataSourceMap,
Collections.singleton(createRule(Collections.emptyList(),
Collections.singleton("foo_tbl1"))), Collections.emptyList()).isEmpty());
+ }
+
+ @Test
+ void assertLoadWithDataSourceMap() {
+ Map<String, Collection<DataNode>> actual =
SingleTableDataNodeLoader.load("foo_db", dataSourceMap,
Collections.singleton("foo_tbl2"));
+ assertThat(new TreeSet<>(actual.keySet()), is(new
TreeSet<>(Arrays.asList("foo_tbl1", "bar_tbl1", "bar_tbl2"))));
+ assertThat(new
TreeSet<>(actual.get("bar_tbl1").stream().map(DataNode::getDataSourceName).collect(Collectors.toList())),
is(new TreeSet<>(Collections.singleton("bar_ds"))));
}
@Test
- void assertLoadWithConflictTables() {
- Map<String, Collection<DataNode>> actual =
SingleTableDataNodeLoader.load("foo_db", databaseType, dataSourceMap,
Collections.emptyList(), Collections.singleton("*.*.*"));
- assertTrue(actual.containsKey("employee"));
- assertTrue(actual.containsKey("salary"));
- assertTrue(actual.containsKey("student"));
- assertTrue(actual.containsKey("dept"));
- assertTrue(actual.containsKey("teacher"));
- assertTrue(actual.containsKey("class"));
-
assertThat(actual.get("employee").iterator().next().getDataSourceName(),
is("ds0"));
- assertThat(actual.get("salary").iterator().next().getDataSourceName(),
is("ds0"));
-
assertThat(actual.get("student").iterator().next().getDataSourceName(),
is("ds1"));
- assertThat(actual.get("dept").iterator().next().getDataSourceName(),
is("ds0"));
-
assertThat(actual.get("teacher").iterator().next().getDataSourceName(),
is("ds1"));
- assertThat(actual.get("class").iterator().next().getDataSourceName(),
is("ds1"));
+ void assertLoadSchemaTableNames() {
+ Map<String, Collection<String>> actual =
SingleTableDataNodeLoader.loadSchemaTableNames("foo_db", databaseType,
dataSourceMap.get("foo_ds"), "foo_ds", Collections.singleton("foo_tbl2"));
+ assertThat(new TreeSet<>(actual.keySet()), is(new
TreeSet<>(Collections.singleton("foo_db"))));
+ assertThat(new TreeSet<>(actual.get("foo_db")), is(new
TreeSet<>(Collections.singleton("foo_tbl1"))));
}
@Test
- void assertLoadWithEmptyConfiguredTables() {
- ShardingSphereRule builtRule = mock(ShardingSphereRule.class);
- TableMapperRuleAttribute ruleAttribute =
mock(TableMapperRuleAttribute.class, RETURNS_DEEP_STUBS);
-
when(ruleAttribute.getDistributedTableNames()).thenReturn(Arrays.asList("salary",
"employee", "student"));
- when(builtRule.getAttributes()).thenReturn(new
RuleAttributes(ruleAttribute));
- Map<String, Collection<DataNode>> actual =
SingleTableDataNodeLoader.load("foo_db", databaseType, dataSourceMap,
Collections.singleton(builtRule), Collections.emptyList());
- assertTrue(actual.isEmpty());
+ void assertLoadSchemaTableNamesWithSQLException() throws SQLException {
+ SQLException expected = new SQLException("mocked_ex");
+ DataSource dataSource = mock(DataSource.class);
+ when(dataSource.getConnection()).thenThrow(expected);
+ SingleTablesLoadingException actual =
assertThrows(SingleTablesLoadingException.class,
+ () -> SingleTableDataNodeLoader.loadSchemaTableNames("foo_db",
databaseType, dataSource, "foo_ds", Collections.emptyList()));
+ assertThat(actual.getCause(), is(expected));
+ }
+
+ private static Stream<Arguments>
loadWithConfiguredTableExpressionArguments() {
+ Map<String, Collection<String>> excludedTablesExpectedDataSources =
new LinkedHashMap<>(2, 1F);
+ excludedTablesExpectedDataSources.put("foo_tbl2",
Collections.singleton("foo_ds"));
+ excludedTablesExpectedDataSources.put("bar_tbl2",
Collections.singleton("bar_ds"));
+ Map<String, Collection<String>> allSchemaTablesExpectedDataSources =
new LinkedHashMap<>(4, 1F);
+ allSchemaTablesExpectedDataSources.put("foo_tbl1",
Collections.singleton("foo_ds"));
+ allSchemaTablesExpectedDataSources.put("foo_tbl2",
Collections.singleton("foo_ds"));
+ allSchemaTablesExpectedDataSources.put("bar_tbl1",
Collections.singleton("bar_ds"));
+ allSchemaTablesExpectedDataSources.put("bar_tbl2",
Collections.singleton("bar_ds"));
+ return Stream.of(
+ Arguments.arguments("empty configured tables",
Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()),
+ Arguments.arguments("all tables with excluded tables",
Collections.singleton(createRule(Arrays.asList("foo_tbl1", "bar_tbl1",
"unused_tbl"), Collections.emptyList())),
+ Collections.singleton("*.*"),
createExpectedTableDataSources(excludedTablesExpectedDataSources)),
+ Arguments.arguments("all schema tables",
Collections.emptyList(), Collections.singleton("*.*.*"),
createExpectedTableDataSources(allSchemaTablesExpectedDataSources)));
+ }
+
+ private static ShardingSphereRule createRule(final Collection<String>
distributedTableNames, final Collection<String> enhancedTableNames) {
+ ShardingSphereRule result = mock(ShardingSphereRule.class);
+ TableMapperRuleAttribute ruleAttribute =
mock(TableMapperRuleAttribute.class);
+
when(ruleAttribute.getDistributedTableNames()).thenReturn(distributedTableNames);
+
when(ruleAttribute.getActualTableNames()).thenReturn(Collections.emptyList());
+
when(ruleAttribute.getEnhancedTableNames()).thenReturn(enhancedTableNames);
+ when(result.getAttributes()).thenReturn(new
RuleAttributes(ruleAttribute));
+ return result;
+ }
+
+ private static Stream<Arguments> loadWithConfiguredTableMapRuleArguments()
{
+ Map<String, Collection<String>> wildcardExpectedDataSources = new
LinkedHashMap<>(2, 1F);
+ wildcardExpectedDataSources.put("foo_tbl1",
Collections.singleton("foo_ds"));
+ wildcardExpectedDataSources.put("foo_tbl2",
Collections.singleton("foo_ds"));
+ return Stream.of(
+ Arguments.arguments("configured data source not found", new
LinkedHashSet<>(Collections.singleton("other_ds.foo_tbl2")),
+ Collections.singleton(new DataNode("other_ds",
"foo_db", "foo_tbl2")), Collections.emptyMap()),
+ Arguments.arguments("configured wildcard schema", new
LinkedHashSet<>(Collections.singleton("foo_ds.foo_tbl2")),
+ Collections.singleton(new DataNode("foo_ds", "*",
"foo_tbl2")),
+
createExpectedTableDataSources(wildcardExpectedDataSources)),
+ Arguments.arguments("configured schema not matched", new
LinkedHashSet<>(Collections.singleton("foo_ds.foo_tbl2")),
+ Collections.singleton(new DataNode("foo_ds",
"other_schema", "foo_tbl2")), Collections.emptyMap()),
+ Arguments.arguments("configured table wildcard", new
LinkedHashSet<>(Collections.singleton("foo_ds.foo_tbl2")),
+ Collections.singleton(new DataNode("foo_ds", "foo_db",
"*")),
+
createExpectedTableDataSources(wildcardExpectedDataSources)));
+ }
+
+ private static Map<String, Collection<String>>
createExpectedTableDataSources(final Map<String, Collection<String>>
tableDataSources) {
+ Map<String, Collection<String>> result = new
LinkedHashMap<>(tableDataSources.size(), 1F);
+ for (Entry<String, Collection<String>> each :
tableDataSources.entrySet()) {
+ result.put(each.getKey(), new LinkedHashSet<>(each.getValue()));
+ }
+ return result;
}
}