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 ab6e7fb4d04 Add more test cases on TableRefreshUtilsTest (#37199)
ab6e7fb4d04 is described below
commit ab6e7fb4d04499e3fb9ffb4f0c69cc22587e2a6c
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Nov 27 18:55:32 2025 +0800
Add more test cases on TableRefreshUtilsTest (#37199)
---
AGENTS.md | 2 +
.../refresher/util/TableRefreshUtilsTest.java | 76 +++++++++++++++++++++-
2 files changed, 75 insertions(+), 3 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index 0c2a3ba976e..69910ef099a 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -244,6 +244,8 @@ Always state which topology, registry, and engine versions
(e.g., MySQL 5.7 vs 8
- If a test already uses `@ExtendWith(AutoMockExtension.class)`, always
declare the needed static collaborators via `@StaticMockSettings` instead of
hand-written `mockStatic` blocks; justify any exception explicitly in the plan
before coding.
- When a binder under test instantiates another binder (e.g.,
`SelectStatementBinder`, `TableSegmentBinder`), prefer `mockConstruction` and
capture the injected context rather than reimplementing the constructor logic;
only skip this approach if the plan explains why it cannot work.
- Manage every static binder (`ColumnSegmentBinder`,
`ExpressionSegmentBinder`, etc.) via `@StaticMockSettings` to avoid ad-hoc
try-with-resources `mockStatic` blocks; if multiple static dependencies are
needed, list each one in the plan.
+- For identifier formatting or dialect-dependent logic, default to mocking
`DatabaseTypedSPILoader`/`TypedSPILoader` with scoped `MockedStatic` instead of
loading real database types, to avoid ClassCast issues and
environment-dependent casing.
+- Before adding coverage to a utility with multiple return paths, list every
branch (no rule, non-Single config, wildcard blocks, missing data node,
positive path, collection overload) and map each to a test; update the plan
whenever this checklist changes.
## Brevity & Signal
- Prefer tables/bullets over prose walls; cite file paths (`kernel/src/...`)
directly.
diff --git
a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/util/TableRefreshUtilsTest.java
b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/util/TableRefreshUtilsTest.java
index 2733c94095f..742da2fa239 100644
---
a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/util/TableRefreshUtilsTest.java
+++
b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/refresher/util/TableRefreshUtilsTest.java
@@ -18,6 +18,9 @@
package org.apache.shardingsphere.mode.metadata.refresher.util;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
+import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
+import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.IdentifierPatternType;
+import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.infra.datanode.DataNode;
@@ -34,6 +37,7 @@ import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.Iden
import
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
import java.util.Arrays;
import java.util.Collections;
@@ -49,16 +53,38 @@ import static org.mockito.Mockito.when;
@ExtendWith(AutoMockExtension.class)
class TableRefreshUtilsTest {
- private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+ private final DatabaseType fixtureDatabaseType =
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
@Test
void assertGetTableNameFormatsWithIdentifierPattern() {
- assertThat(TableRefreshUtils.getTableName(new
IdentifierValue("Foo_Table"), databaseType), is("Foo_Table"));
+ assertThat(TableRefreshUtils.getTableName(new
IdentifierValue("Foo_Table"), fixtureDatabaseType), is("Foo_Table"));
}
@Test
void assertGetTableNameWithQuotedIdentifierReturnsOriginal() {
- assertThat(TableRefreshUtils.getTableName(new
IdentifierValue("FooTable", QuoteCharacter.QUOTE), databaseType),
is("FooTable"));
+ assertThat(TableRefreshUtils.getTableName(new
IdentifierValue("FooTable", QuoteCharacter.QUOTE), fixtureDatabaseType),
is("FooTable"));
+ }
+
+ @Test
+ void assertGetTableNameFormatsUpperCase() {
+ DatabaseType upperCaseDatabaseType = mock(DatabaseType.class);
+ DialectDatabaseMetaData dialectDatabaseMetaData =
mock(DialectDatabaseMetaData.class);
+
when(dialectDatabaseMetaData.getIdentifierPatternType()).thenReturn(IdentifierPatternType.UPPER_CASE);
+ try (MockedStatic<DatabaseTypedSPILoader> mockedStatic =
org.mockito.Mockito.mockStatic(DatabaseTypedSPILoader.class)) {
+ mockedStatic.when(() ->
DatabaseTypedSPILoader.getService(DialectDatabaseMetaData.class,
upperCaseDatabaseType)).thenReturn(dialectDatabaseMetaData);
+ assertThat(TableRefreshUtils.getTableName(new
IdentifierValue("foo_table"), upperCaseDatabaseType), is("FOO_TABLE"));
+ }
+ }
+
+ @Test
+ void assertGetTableNameFormatsLowerCase() {
+ DatabaseType lowerCaseDatabaseType = mock(DatabaseType.class);
+ DialectDatabaseMetaData dialectDatabaseMetaData =
mock(DialectDatabaseMetaData.class);
+
when(dialectDatabaseMetaData.getIdentifierPatternType()).thenReturn(IdentifierPatternType.LOWER_CASE);
+ try (MockedStatic<DatabaseTypedSPILoader> mockedStatic =
org.mockito.Mockito.mockStatic(DatabaseTypedSPILoader.class)) {
+ mockedStatic.when(() ->
DatabaseTypedSPILoader.getService(DialectDatabaseMetaData.class,
lowerCaseDatabaseType)).thenReturn(dialectDatabaseMetaData);
+ assertThat(TableRefreshUtils.getTableName(new
IdentifierValue("Foo_Table"), lowerCaseDatabaseType), is("foo_table"));
+ }
}
@Test
@@ -108,6 +134,17 @@ class TableRefreshUtilsTest {
assertFalse(TableRefreshUtils.isNeedRefresh(new
RuleMetaData(Collections.singleton(rule)), "foo_schema", "foo_tbl"));
}
+ @Test
+ void assertIsNeedRefreshWhenAllSchemaTablesConfigured() {
+ MutableDataNodeRuleAttribute mutableDataNodeRuleAttribute =
mock(MutableDataNodeRuleAttribute.class);
+ SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration();
+
ruleConfig.setTables(Collections.singletonList(SingleTableConstants.ALL_SCHEMA_TABLES));
+ ShardingSphereRule rule = mock(ShardingSphereRule.class);
+ when(rule.getConfiguration()).thenReturn(ruleConfig);
+ when(rule.getAttributes()).thenReturn(new
RuleAttributes(mutableDataNodeRuleAttribute));
+ assertFalse(TableRefreshUtils.isNeedRefresh(new
RuleMetaData(Collections.singleton(rule)), "foo_schema", "foo_tbl"));
+ }
+
@Test
void assertIsNeedRefreshWhenTableDataNodeMissing() {
MutableDataNodeRuleAttribute mutableDataNodeRuleAttribute =
mock(MutableDataNodeRuleAttribute.class);
@@ -156,4 +193,37 @@ class TableRefreshUtilsTest {
when(rule.getAttributes()).thenReturn(new
RuleAttributes(mutableDataNodeRuleAttribute));
assertTrue(TableRefreshUtils.isNeedRefresh(new
RuleMetaData(Collections.singleton(rule)), "foo_schema",
Arrays.asList("bar_tbl", "foo_tbl")));
}
+
+ @Test
+ void assertIsNeedRefreshBlockedByDataSourceSchemaWildcard() {
+ MutableDataNodeRuleAttribute mutableDataNodeRuleAttribute =
mock(MutableDataNodeRuleAttribute.class);
+ DataNode dataNode = new DataNode("foo_ds", "foo_schema", "foo_tbl");
+ when(mutableDataNodeRuleAttribute.findTableDataNode("foo_schema",
"foo_tbl")).thenReturn(Optional.of(dataNode));
+ SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration();
+ ruleConfig.setTables(Collections.singletonList("foo_ds.*.*"));
+ ShardingSphereRule rule = mock(ShardingSphereRule.class);
+ when(rule.getConfiguration()).thenReturn(ruleConfig);
+ when(rule.getAttributes()).thenReturn(new
RuleAttributes(mutableDataNodeRuleAttribute));
+ assertFalse(TableRefreshUtils.isNeedRefresh(new
RuleMetaData(Collections.singleton(rule)), "foo_schema", "foo_tbl"));
+ }
+
+ @Test
+ void assertIsNeedRefreshBlockedBySchemaSpecificWildcard() {
+ MutableDataNodeRuleAttribute mutableDataNodeRuleAttribute =
mock(MutableDataNodeRuleAttribute.class);
+ DataNode dataNode = new DataNode("foo_ds", "foo_schema", "foo_tbl");
+ when(mutableDataNodeRuleAttribute.findTableDataNode("foo_schema",
"foo_tbl")).thenReturn(Optional.of(dataNode));
+ SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration();
+ ruleConfig.setTables(Collections.singletonList("foo_ds.foo_schema.*"));
+ ShardingSphereRule rule = mock(ShardingSphereRule.class);
+ when(rule.getConfiguration()).thenReturn(ruleConfig);
+ when(rule.getAttributes()).thenReturn(new
RuleAttributes(mutableDataNodeRuleAttribute));
+ assertFalse(TableRefreshUtils.isNeedRefresh(new
RuleMetaData(Collections.singleton(rule)), "foo_schema", "foo_tbl"));
+ }
+
+ @Test
+ void assertIsNeedRefreshWithTableCollectionWhenNoTableNeedsRefresh() {
+ ShardingSphereRule rule = mock(ShardingSphereRule.class);
+ when(rule.getAttributes()).thenReturn(new RuleAttributes());
+ assertFalse(TableRefreshUtils.isNeedRefresh(new
RuleMetaData(Collections.singleton(rule)), "foo_schema",
Arrays.asList("bar_tbl", "foo_tbl")));
+ }
}