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 67350690681 Add more test cases on ExportStorageNodesExecutorTest 
(#38007)
67350690681 is described below

commit 6735069068101f8a2df7a46166f3b2cc1e9c2863
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Feb 11 18:15:41 2026 +0800

    Add more test cases on ExportStorageNodesExecutorTest (#38007)
---
 AGENTS.md                                          |  4 +-
 .../export/ExportStorageNodesExecutorTest.java     | 80 +++++++++++++++++-----
 2 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md
index 035278cdb1c..b14093cf1fe 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -90,8 +90,8 @@ Dangerous operation detected! Operation type: [specific 
action] Scope of impact:
 - **Risk gate:** if any action fits the Dangerous Operation Checklist, pause 
and use the confirmation template before proceeding.
 - **Planning rules:** use Sequential Thinking with 3-10 actionable steps (no 
single-step plans) via the plan tool for non-trivial tasks; convert all hard 
requirements (SPI usage, mocking rules, coverage/test naming, forbidden APIs) 
into a checklist inside the plan and do not code until each item is addressed 
or explicitly waived.
 - **Execution discipline:** inspect existing code before edits; keep changes 
minimal; default to mocks and SPI loaders; keep variable declarations near 
first use and mark retained values `final`; inline single-use locals by default 
unless reuse/readability justifies retention; delete dead code and avoid 
placeholders/TODOs.
-- **Post-task self-check (before replying):** confirm all instructions were 
honored; verify no placeholders/unused code; ensure Checkstyle/Spotless gates 
for touched modules are satisfied or explain why not run and what to run; list 
commands with exit codes; call out risks and follow-ups.
-- **Final response template:** include intent/why, changed files with paths, 
rationale per file/section, commands run (with exit codes), verification 
status, and remaining risks/next actions (if tests skipped, state reason and 
the exact command to run).
+- **Post-task self-check (before replying):** confirm all instructions were 
honored; verify no placeholders/unused code; ensure Checkstyle/Spotless gates 
for touched modules are satisfied or explain why not run and what to run; list 
commands with exit codes; call out risks and follow-ups; complete all 
applicable checks before replying and do not rely on users to find missed rule 
violations.
+- **Final response template:** include intent/why, changed files with paths, 
rationale per file/section, commands run (with exit codes), verification 
status, and remaining risks/next actions (if tests skipped, state reason and 
the exact command to run); include a concise self-check result statement 
confirming final clean status after fixes.
 
 ## Coverage & Branch Checklist
 - When coverage targets are declared (including 100%), list every branch/path 
with its planned test before coding.
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/export/ExportStorageNodesExecutorTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/export/ExportStorageNodesExecutorTest.java
index 9613e4c5b34..d0f230d1acb 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/export/ExportStorageNodesExecutorTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/export/ExportStorageNodesExecutorTest.java
@@ -21,6 +21,7 @@ import lombok.SneakyThrows;
 import org.apache.shardingsphere.authority.rule.AuthorityRule;
 import 
org.apache.shardingsphere.authority.rule.builder.DefaultAuthorityRuleConfigurationBuilder;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.distsql.handler.engine.query.DistSQLQueryExecutor;
 import 
org.apache.shardingsphere.distsql.statement.type.ral.queryable.export.ExportStorageNodesStatement;
 import 
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
@@ -47,6 +48,7 @@ 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.api.extension.ExtendWith;
+import org.junit.jupiter.api.io.TempDir;
 import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
@@ -58,7 +60,9 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -78,24 +82,37 @@ import static org.mockito.Mockito.when;
 @MockitoSettings(strictness = Strictness.LENIENT)
 class ExportStorageNodesExecutorTest {
     
+    private final ExportStorageNodesExecutor executor = 
(ExportStorageNodesExecutor) 
TypedSPILoader.getService(DistSQLQueryExecutor.class, 
ExportStorageNodesStatement.class);
+    
+    @TempDir
+    private Path tempDir;
+    
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private ShardingSphereDatabase database;
     
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ShardingSphereDatabase emptyDatabase;
+    
     @BeforeEach
     void setUp() {
-        
when(database.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "FIXTURE"));
+        DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+        when(database.getProtocolType()).thenReturn(databaseType);
+        when(emptyDatabase.getProtocolType()).thenReturn(databaseType);
+    }
+    
+    @Test
+    void assertGetColumnNames() {
+        assertThat(executor.getColumnNames(new 
ExportStorageNodesStatement(null, null)), is(Arrays.asList("id", "create_time", 
"storage_nodes")));
     }
     
     @Test
     void assertExecuteWithWrongDatabaseName() {
-        ExportStorageNodesStatement sqlStatement = new 
ExportStorageNodesStatement("foo", null);
-        assertThrows(IllegalArgumentException.class, () -> new 
ExportStorageNodesExecutor().getRows(sqlStatement, mockEmptyContextManager()));
+        assertThrows(IllegalArgumentException.class, () -> 
executor.getRows(new ExportStorageNodesStatement("foo", null), 
mockEmptyContextManager()));
     }
     
     @Test
     void assertExecuteWithEmptyMetaData() {
-        ExportStorageNodesStatement sqlStatement = new 
ExportStorageNodesStatement(null, null);
-        Collection<LocalDataQueryResultRow> actual = new 
ExportStorageNodesExecutor().getRows(sqlStatement, mockEmptyContextManager());
+        Collection<LocalDataQueryResultRow> actual = executor.getRows(new 
ExportStorageNodesStatement(null, null), mockEmptyContextManager());
         assertThat(actual.size(), is(1));
         LocalDataQueryResultRow row = actual.iterator().next();
         assertThat(row.getCell(3), is("{\"storage_nodes\":{}}"));
@@ -105,19 +122,15 @@ class ExportStorageNodesExecutorTest {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
         ShardingSphereMetaData metaData = new ShardingSphereMetaData(
                 Collections.emptyList(), new 
ResourceMetaData(Collections.emptyMap()), new 
RuleMetaData(Collections.emptyList()), new ConfigurationProperties(new 
Properties()));
-        MetaDataContexts metaDataContexts = new MetaDataContexts(metaData, new 
ShardingSphereStatistics());
-        when(result.getMetaDataContexts()).thenReturn(metaDataContexts);
+        when(result.getMetaDataContexts()).thenReturn(new 
MetaDataContexts(metaData, new ShardingSphereStatistics()));
         
when(result.getAllDatabaseNames()).thenReturn(Collections.singleton("empty_metadata"));
         return result;
     }
     
     @Test
     void assertExecute() {
-        when(database.getName()).thenReturn("normal_db");
-        Map<String, StorageUnit> storageUnits = createStorageUnits();
-        
when(database.getResourceMetaData().getStorageUnits()).thenReturn(storageUnits);
-        
when(database.getRuleMetaData().getConfigurations()).thenReturn(Collections.singleton(createShardingRuleConfiguration()));
-        Collection<LocalDataQueryResultRow> actual = new 
ExportStorageNodesExecutor().getRows(new ExportStorageNodesStatement(null, 
null), mockContextManager());
+        prepareNormalDatabase();
+        Collection<LocalDataQueryResultRow> actual = executor.getRows(new 
ExportStorageNodesStatement(null, null), mockContextManager(database));
         assertThat(actual.size(), is(1));
         LocalDataQueryResultRow row = actual.iterator().next();
         assertThat(row.getCell(3), is(loadExpectedRow()));
@@ -125,19 +138,50 @@ class ExportStorageNodesExecutorTest {
     
     @Test
     void assertExecuteWithDatabaseName() {
+        prepareNormalDatabase();
+        Collection<LocalDataQueryResultRow> actual = executor.getRows(new 
ExportStorageNodesStatement("normal_db", null), mockContextManager(database));
+        assertThat(actual.size(), is(1));
+        LocalDataQueryResultRow row = actual.iterator().next();
+        assertThat(row.getCell(3), is(loadExpectedRow()));
+    }
+    
+    @Test
+    void assertExecuteWithFilePath() throws IOException {
+        prepareNormalDatabase();
+        ContextManager contextManager = mockContextManager(database);
+        
when(contextManager.getComputeNodeInstanceContext().getInstance().getMetaData().getId()).thenReturn("file_id");
+        Path tempFile = tempDir.resolve("export-storage-nodes.json");
+        Collection<LocalDataQueryResultRow> actual = executor.getRows(new 
ExportStorageNodesStatement(null, tempFile.toString()), contextManager);
+        assertThat(actual.size(), is(1));
+        LocalDataQueryResultRow row = actual.iterator().next();
+        assertThat(row.getCell(1), is("file_id"));
+        assertThat(row.getCell(3), is(String.format("Successfully exported 
to:'%s'", tempFile)));
+        assertThat(new String(Files.readAllBytes(tempFile)), 
is(loadExpectedRow()));
+    }
+    
+    @Test
+    void assertExecuteWithEmptyStorageNodeDatabase() {
+        prepareNormalDatabase();
+        when(emptyDatabase.getName()).thenReturn("empty_db");
+        
when(emptyDatabase.getResourceMetaData().getAllInstanceDataSourceNames()).thenReturn(Collections.emptySet());
+        
when(emptyDatabase.getResourceMetaData().getStorageUnits()).thenReturn(Collections.emptyMap());
+        Collection<LocalDataQueryResultRow> actual = executor.getRows(new 
ExportStorageNodesStatement(null, null), mockContextManager(emptyDatabase, 
database));
+        assertThat(actual.size(), is(1));
+        LocalDataQueryResultRow row = actual.iterator().next();
+        assertThat(row.getCell(3), is(loadExpectedRow()));
+    }
+    
+    private void prepareNormalDatabase() {
         when(database.getName()).thenReturn("normal_db");
         Map<String, StorageUnit> storageUnits = createStorageUnits();
+        
when(database.getResourceMetaData().getAllInstanceDataSourceNames()).thenReturn(storageUnits.keySet());
         
when(database.getResourceMetaData().getStorageUnits()).thenReturn(storageUnits);
         
when(database.getRuleMetaData().getConfigurations()).thenReturn(Collections.singleton(createShardingRuleConfiguration()));
-        Collection<LocalDataQueryResultRow> actual = new 
ExportStorageNodesExecutor().getRows(new 
ExportStorageNodesStatement("normal_db", null), mockContextManager());
-        assertThat(actual.size(), is(1));
-        LocalDataQueryResultRow row = actual.iterator().next();
-        assertThat(row.getCell(3), is(loadExpectedRow()));
     }
     
-    private ContextManager mockContextManager() {
+    private ContextManager mockContextManager(final ShardingSphereDatabase... 
databases) {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
-        ShardingSphereMetaData metaData = new 
ShardingSphereMetaData(Collections.singleton(database),
+        ShardingSphereMetaData metaData = new 
ShardingSphereMetaData(Arrays.asList(databases),
                 new ResourceMetaData(Collections.emptyMap()),
                 new RuleMetaData(Collections.singleton(new AuthorityRule(new 
DefaultAuthorityRuleConfigurationBuilder().build()))),
                 new ConfigurationProperties(PropertiesBuilder.build(new 
Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), "true"))));

Reply via email to