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 7cc2565a21e Add missing unit tests for TCL factory, SQL parser, admin 
handler, and export generator (#37492)
7cc2565a21e is described below

commit 7cc2565a21e1ec5481d647caa1334ff93b553792
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Dec 24 16:01:36 2025 +0800

    Add missing unit tests for TCL factory, SQL parser, admin handler, and 
export generator (#37492)
    
    * Add missing unit tests for TCL factory, SQL parser, admin handler, and 
export generator
    
    * Add missing unit tests for TCL factory, SQL parser, admin handler, and 
export generator
---
 .../handler/ProxySQLComQueryParserTest.java        | 107 ++++++++++++++
 ...atabaseAdminProxyBackendHandlerFactoryTest.java |  98 +++++++++++++
 .../LocalTCLProxyBackendHandlerFactoryTest.java    | 153 +++++++++++++++++++++
 .../util/DatabaseExportMetaDataGeneratorTest.java  | 123 +++++++++++++++++
 4 files changed, 481 insertions(+)

diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxySQLComQueryParserTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxySQLComQueryParserTest.java
new file mode 100644
index 00000000000..fdc8fe3a859
--- /dev/null
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxySQLComQueryParserTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.proxy.backend.handler;
+
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.parser.SQLParserEngine;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.parser.rule.SQLParserRule;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.EmptyStatement;
+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.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+
+import java.util.Collections;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+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(ProxyContext.class)
+class ProxySQLComQueryParserTest {
+    
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Mock
+    private ConnectionSession connectionSession;
+    
+    @Test
+    void assertParseEmptySQL() {
+        when(connectionSession.getUsedDatabaseName()).thenReturn(null);
+        SQLStatement actual = ProxySQLComQueryParser.parse("   ", 
databaseType, connectionSession);
+        assertThat(actual, isA(EmptyStatement.class));
+        assertThat(actual.getDatabaseType(), is(databaseType));
+    }
+    
+    @Test
+    void assertParseWithMissingDatabaseUseDefaultType() {
+        when(connectionSession.getUsedDatabaseName()).thenReturn("missing_db");
+        SQLParserEngine parserEngine = mock(SQLParserEngine.class);
+        SQLStatement expected = new SQLStatement(databaseType);
+        SQLParserRule parserRule = mockParserRule(parserEngine);
+        mockProxyContext(parserRule, false, null);
+        when(parserEngine.parse(anyString(), eq(false))).thenReturn(expected);
+        assertThat(ProxySQLComQueryParser.parse("select 1", databaseType, 
connectionSession), is(expected));
+    }
+    
+    @Test
+    void assertParseWithExistingDatabaseUseDatabaseProtocolType() {
+        DatabaseType protocolType = 
TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
+        when(connectionSession.getUsedDatabaseName()).thenReturn("logic_db");
+        SQLParserEngine parserEngine = mock(SQLParserEngine.class);
+        SQLStatement expected = new SQLStatement(protocolType);
+        SQLParserRule parserRule = mockParserRule(parserEngine);
+        mockProxyContext(parserRule, true, protocolType);
+        when(parserEngine.parse(anyString(), eq(false))).thenReturn(expected);
+        assertThat(ProxySQLComQueryParser.parse("select * from t_order", 
databaseType, connectionSession), is(expected));
+    }
+    
+    private SQLParserRule mockParserRule(final SQLParserEngine parserEngine) {
+        SQLParserRule result = mock(SQLParserRule.class);
+        
when(result.getSQLParserEngine(any(DatabaseType.class))).thenReturn(parserEngine);
+        return result;
+    }
+    
+    private void mockProxyContext(final SQLParserRule parserRule, final 
boolean containsDatabase, final DatabaseType protocolType) {
+        ContextManager contextManager = mock(ContextManager.class, 
RETURNS_DEEP_STUBS);
+        
when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new
 RuleMetaData(Collections.singleton(parserRule)));
+        
lenient().when(contextManager.getMetaDataContexts().getMetaData().containsDatabase("logic_db")).thenReturn(containsDatabase);
+        if (containsDatabase) {
+            ShardingSphereDatabase database = 
mock(ShardingSphereDatabase.class);
+            when(contextManager.getDatabase(anyString())).thenReturn(database);
+            when(database.getProtocolType()).thenReturn(protocolType);
+        }
+        
when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+    }
+}
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminProxyBackendHandlerFactoryTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminProxyBackendHandlerFactoryTest.java
new file mode 100644
index 00000000000..1a423f8df20
--- /dev/null
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminProxyBackendHandlerFactoryTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.proxy.backend.handler.admin;
+
+import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutorCreator;
+import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminQueryExecutor;
+import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminUpdateExecutor;
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
+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.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+
+import java.util.Collections;
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isA;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(AutoMockExtension.class)
+@StaticMockSettings({DatabaseTypedSPILoader.class, ProxyContext.class})
+class DatabaseAdminProxyBackendHandlerFactoryTest {
+    
+    private static final DatabaseType DATABASE_TYPE = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ConnectionSession connectionSession;
+    
+    @Mock
+    private SQLStatementContext sqlStatementContext;
+    
+    @Test
+    void assertNewInstanceWhenExecutorCreatorNotFound() {
+        
when(DatabaseTypedSPILoader.findService(DatabaseAdminExecutorCreator.class, 
DATABASE_TYPE)).thenReturn(Optional.empty());
+        
assertFalse(DatabaseAdminProxyBackendHandlerFactory.newInstance(DATABASE_TYPE, 
sqlStatementContext, connectionSession, "sql", 
Collections.emptyList()).isPresent());
+    }
+    
+    @Test
+    void assertNewInstanceWhenExecutorNotFound() {
+        DatabaseAdminExecutorCreator executorCreator = 
mock(DatabaseAdminExecutorCreator.class);
+        when(executorCreator.create(sqlStatementContext, "sql", "logic_db", 
Collections.emptyList())).thenReturn(Optional.empty());
+        
when(DatabaseTypedSPILoader.findService(DatabaseAdminExecutorCreator.class, 
DATABASE_TYPE)).thenReturn(Optional.of(executorCreator));
+        when(connectionSession.getUsedDatabaseName()).thenReturn("logic_db");
+        
assertFalse(DatabaseAdminProxyBackendHandlerFactory.newInstance(DATABASE_TYPE, 
sqlStatementContext, connectionSession, "sql", 
Collections.emptyList()).isPresent());
+    }
+    
+    @Test
+    void assertNewInstanceWhenCreateQueryBackendHandler() {
+        DatabaseAdminExecutorCreator executorCreator = 
mock(DatabaseAdminExecutorCreator.class);
+        
when(DatabaseTypedSPILoader.findService(DatabaseAdminExecutorCreator.class, 
DATABASE_TYPE)).thenReturn(Optional.of(executorCreator));
+        when(executorCreator.create(sqlStatementContext, "sql", "logic_db", 
Collections.emptyList())).thenReturn(Optional.of(mock(DatabaseAdminQueryExecutor.class)));
+        when(connectionSession.getUsedDatabaseName()).thenReturn("logic_db");
+        
when(ProxyContext.getInstance().getContextManager()).thenReturn(mock(ContextManager.class));
+        Optional<ProxyBackendHandler> actual = 
DatabaseAdminProxyBackendHandlerFactory.newInstance(DATABASE_TYPE, 
sqlStatementContext, connectionSession, "sql", Collections.emptyList());
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), 
isA(DatabaseAdminQueryProxyBackendHandler.class));
+    }
+    
+    @Test
+    void assertNewInstanceWhenCreateUpdateBackendHandler() {
+        DatabaseAdminExecutorCreator executorCreator = 
mock(DatabaseAdminExecutorCreator.class);
+        
when(DatabaseTypedSPILoader.findService(DatabaseAdminExecutorCreator.class, 
DATABASE_TYPE)).thenReturn(Optional.of(executorCreator));
+        when(connectionSession.getUsedDatabaseName()).thenReturn("logic_db");
+        when(executorCreator.create(sqlStatementContext, "sql", "logic_db", 
Collections.emptyList())).thenReturn(Optional.of(mock(DatabaseAdminUpdateExecutor.class)));
+        
when(ProxyContext.getInstance().getContextManager()).thenReturn(mock(ContextManager.class));
+        Optional<ProxyBackendHandler> actual = 
DatabaseAdminProxyBackendHandlerFactory.newInstance(DATABASE_TYPE, 
sqlStatementContext, connectionSession, "sql", Collections.emptyList());
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), 
isA(DatabaseAdminUpdateProxyBackendHandler.class));
+    }
+}
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/tcl/local/LocalTCLProxyBackendHandlerFactoryTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/tcl/local/LocalTCLProxyBackendHandlerFactoryTest.java
new file mode 100644
index 00000000000..41b0134587d
--- /dev/null
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/tcl/local/LocalTCLProxyBackendHandlerFactoryTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.proxy.backend.handler.tcl.local;
+
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
+import 
org.apache.shardingsphere.infra.session.connection.transaction.TransactionConnectionContext;
+import org.apache.shardingsphere.infra.session.query.QueryContext;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
+import 
org.apache.shardingsphere.proxy.backend.connector.DatabaseProxyConnector;
+import 
org.apache.shardingsphere.proxy.backend.connector.DatabaseProxyConnectorFactory;
+import 
org.apache.shardingsphere.proxy.backend.connector.ProxyDatabaseConnectionManager;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.BeginTransactionProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.CommitProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.ReleaseSavepointProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.RollbackProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.RollbackSavepointProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.SetAutoCommitProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.SetSavepointProxyBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.tcl.local.type.SetTransactionProxyBackendHandler;
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
+import 
org.apache.shardingsphere.proxy.backend.session.transaction.TransactionStatus;
+import 
org.apache.shardingsphere.sql.parser.statement.core.enums.OperationScope;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.BeginTransactionStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.CommitStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.ReleaseSavepointStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.RollbackStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.SavepointStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.SetAutoCommitStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.SetTransactionStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.tcl.TCLStatement;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
+import 
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockSettings;
+import org.apache.shardingsphere.transaction.rule.TransactionRule;
+import 
org.apache.shardingsphere.transaction.rule.builder.DefaultTransactionRuleConfigurationBuilder;
+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 java.util.Collections;
+import java.util.stream.Stream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
+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({DatabaseProxyConnectorFactory.class, ProxyContext.class})
+class LocalTCLProxyBackendHandlerFactoryTest {
+    
+    private static final DatabaseType DATABASE_TYPE = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private ConnectionSession connectionSession;
+    
+    @Mock
+    private ProxyDatabaseConnectionManager databaseConnectionManager;
+    
+    @BeforeEach
+    void setUp() {
+        
when(connectionSession.getDatabaseConnectionManager()).thenReturn(databaseConnectionManager);
+        
lenient().when(databaseConnectionManager.getConnectionSession()).thenReturn(connectionSession);
+        when(connectionSession.getProtocolType()).thenReturn(DATABASE_TYPE);
+        when(connectionSession.getTransactionStatus()).thenReturn(new 
TransactionStatus());
+        ConnectionContext connectionContext = mock(ConnectionContext.class);
+        
lenient().when(connectionContext.getTransactionContext()).thenReturn(new 
TransactionConnectionContext());
+        
when(connectionSession.getConnectionContext()).thenReturn(connectionContext);
+        ContextManager contextManager = mockContextManager();
+        
when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+    }
+    
+    private ContextManager mockContextManager() {
+        ContextManager result = mock(ContextManager.class);
+        MetaDataContexts metaDataContexts = mock(MetaDataContexts.class, 
RETURNS_DEEP_STUBS);
+        TransactionRule transactionRule = new TransactionRule(new 
DefaultTransactionRuleConfigurationBuilder().build(), Collections.emptyList());
+        RuleMetaData globalRuleMetaData = new 
RuleMetaData(Collections.singleton(transactionRule));
+        
lenient().when(metaDataContexts.getMetaData().getGlobalRuleMetaData()).thenReturn(globalRuleMetaData);
+        
lenient().when(result.getMetaDataContexts()).thenReturn(metaDataContexts);
+        return result;
+    }
+    
+    @Test
+    void assertNewInstanceReturnConnectorWhenNotMatched() {
+        TCLStatement sqlStatement = new SetTransactionStatement(DATABASE_TYPE, 
OperationScope.GLOBAL, null, null);
+        QueryContext queryContext = mockQueryContext(sqlStatement);
+        DatabaseProxyConnector expected = mock(DatabaseProxyConnector.class);
+        when(DatabaseProxyConnectorFactory.newInstance(queryContext, 
databaseConnectionManager, false)).thenReturn(expected);
+        
assertThat(LocalTCLProxyBackendHandlerFactory.newInstance(queryContext, 
connectionSession), is(expected));
+    }
+    
+    @Test
+    void assertNewInstanceReturnConnectorWhenUnknownStatement() {
+        TCLStatement sqlStatement = new TCLStatement(DATABASE_TYPE) {
+        };
+        QueryContext queryContext = mockQueryContext(sqlStatement);
+        DatabaseProxyConnector expected = mock(DatabaseProxyConnector.class);
+        when(DatabaseProxyConnectorFactory.newInstance(queryContext, 
databaseConnectionManager, false)).thenReturn(expected);
+        
assertThat(LocalTCLProxyBackendHandlerFactory.newInstance(queryContext, 
connectionSession), is(expected));
+    }
+    
+    @ParameterizedTest
+    @MethodSource("assertNewInstanceArguments")
+    void assertNewInstance(final TCLStatement sqlStatement, final Class<? 
extends ProxyBackendHandler> expectedClass) {
+        
assertThat(LocalTCLProxyBackendHandlerFactory.newInstance(mockQueryContext(sqlStatement),
 connectionSession), isA(expectedClass));
+    }
+    
+    private QueryContext mockQueryContext(final TCLStatement sqlStatement) {
+        QueryContext result = mock(QueryContext.class, RETURNS_DEEP_STUBS);
+        
when(result.getSqlStatementContext().getSqlStatement()).thenReturn(sqlStatement);
+        return result;
+    }
+    
+    private static Stream<Arguments> assertNewInstanceArguments() {
+        return Stream.of(
+                Arguments.of(new BeginTransactionStatement(DATABASE_TYPE), 
BeginTransactionProxyBackendHandler.class),
+                Arguments.of(new SetAutoCommitStatement(DATABASE_TYPE, false), 
SetAutoCommitProxyBackendHandler.class),
+                Arguments.of(new CommitStatement(DATABASE_TYPE), 
CommitProxyBackendHandler.class),
+                Arguments.of(new RollbackStatement(DATABASE_TYPE, "sp"), 
RollbackSavepointProxyBackendHandler.class),
+                Arguments.of(new RollbackStatement(DATABASE_TYPE), 
RollbackProxyBackendHandler.class),
+                Arguments.of(new SavepointStatement(DATABASE_TYPE, "sp"), 
SetSavepointProxyBackendHandler.class),
+                Arguments.of(new ReleaseSavepointStatement(DATABASE_TYPE, 
"sp"), ReleaseSavepointProxyBackendHandler.class),
+                Arguments.of(new SetTransactionStatement(DATABASE_TYPE, 
OperationScope.SESSION, null, null), SetTransactionProxyBackendHandler.class));
+    }
+}
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/util/DatabaseExportMetaDataGeneratorTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/util/DatabaseExportMetaDataGeneratorTest.java
new file mode 100644
index 00000000000..37447e3d302
--- /dev/null
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/util/DatabaseExportMetaDataGeneratorTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.proxy.backend.util;
+
+import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
+import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.synonym.ConnectionPropertySynonyms;
+import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.synonym.PoolPropertySynonyms;
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import 
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
+import 
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
+import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
+import org.apache.shardingsphere.single.config.SingleRuleConfiguration;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class DatabaseExportMetaDataGeneratorTest {
+    
+    @Test
+    void assertGenerateYAMLFormatWithoutDataSourcesOrRules() {
+        assertThat(new 
DatabaseExportMetaDataGenerator(mockEmptyDatabase()).generateYAMLFormat(), 
is("databaseName: empty_db" + System.lineSeparator()));
+    }
+    
+    private ShardingSphereDatabase mockEmptyDatabase() {
+        ShardingSphereDatabase result = mock(ShardingSphereDatabase.class);
+        when(result.getName()).thenReturn("empty_db");
+        ResourceMetaData resourceMetaData = mock(ResourceMetaData.class);
+        
when(resourceMetaData.getStorageUnits()).thenReturn(Collections.emptyMap());
+        when(result.getResourceMetaData()).thenReturn(resourceMetaData);
+        RuleMetaData ruleMetaData = mock(RuleMetaData.class);
+        
when(ruleMetaData.getConfigurations()).thenReturn(Collections.emptyList());
+        when(result.getRuleMetaData()).thenReturn(ruleMetaData);
+        return result;
+    }
+    
+    @Test
+    void assertGenerateYAMLFormatWithDataSourcesAndRules() {
+        String actual = new 
DatabaseExportMetaDataGenerator(mockDatabase()).generateYAMLFormat();
+        assertThat(actual, containsString("databaseName: logic_db"));
+        assertThat(actual, containsString("dataSources:" + 
System.lineSeparator() + "  ds_0:"));
+        assertThat(actual, containsString("url: jdbc:h2:mem:ds_0"));
+        assertThat(actual, containsString("username: sa"));
+        assertThat(actual, containsString("maxPoolSize: 30"));
+        assertThat(actual, not(containsString("idleTimeout")));
+        assertThat(actual, containsString("rules:"));
+        assertThat(actual, containsString("defaultDataSource: write_ds"));
+    }
+    
+    private ShardingSphereDatabase mockDatabase() {
+        ResourceMetaData resourceMetaData = mock(ResourceMetaData.class);
+        Map<String, StorageUnit> storageUnits = 
mockStorageUnits(Collections.singletonMap("ds_0", 
createDataSourcePoolProperties()));
+        when(resourceMetaData.getStorageUnits()).thenReturn(storageUnits);
+        ShardingSphereDatabase result = mock(ShardingSphereDatabase.class);
+        when(result.getName()).thenReturn("logic_db");
+        when(result.getResourceMetaData()).thenReturn(resourceMetaData);
+        Collection<RuleConfiguration> ruleConfigs = Arrays.asList(new 
SingleRuleConfiguration(), createSingleRuleConfiguration());
+        RuleMetaData ruleMetaData = mock(RuleMetaData.class);
+        when(ruleMetaData.getConfigurations()).thenReturn(ruleConfigs);
+        when(result.getRuleMetaData()).thenReturn(ruleMetaData);
+        return result;
+    }
+    
+    private Map<String, StorageUnit> mockStorageUnits(final Map<String, 
DataSourcePoolProperties> props) {
+        Map<String, StorageUnit> result = new LinkedHashMap<>(props.size(), 
1F);
+        for (Map.Entry<String, DataSourcePoolProperties> entry : 
props.entrySet()) {
+            StorageUnit storageUnit = mock(StorageUnit.class);
+            
when(storageUnit.getDataSourcePoolProperties()).thenReturn(entry.getValue());
+            result.put(entry.getKey(), storageUnit);
+        }
+        return result;
+    }
+    
+    private DataSourcePoolProperties createDataSourcePoolProperties() {
+        Map<String, Object> connectionProps = new LinkedHashMap<>(2, 1F);
+        connectionProps.put("url", "jdbc:h2:mem:ds_0");
+        connectionProps.put("username", "sa");
+        connectionProps.put("password", "pwd");
+        ConnectionPropertySynonyms connectionSynonyms = 
mock(ConnectionPropertySynonyms.class);
+        
when(connectionSynonyms.getStandardProperties()).thenReturn(connectionProps);
+        PoolPropertySynonyms poolSynonyms = mock(PoolPropertySynonyms.class);
+        Map<String, Object> poolProps = new LinkedHashMap<>(2, 1F);
+        poolProps.put("maxPoolSize", 30);
+        poolProps.put("idleTimeout", null);
+        when(poolSynonyms.getStandardProperties()).thenReturn(poolProps);
+        DataSourcePoolProperties result = mock(DataSourcePoolProperties.class);
+        
when(result.getConnectionPropertySynonyms()).thenReturn(connectionSynonyms);
+        when(result.getPoolPropertySynonyms()).thenReturn(poolSynonyms);
+        return result;
+    }
+    
+    private SingleRuleConfiguration createSingleRuleConfiguration() {
+        SingleRuleConfiguration result = new SingleRuleConfiguration();
+        result.setDefaultDataSource("write_ds");
+        return result;
+    }
+}

Reply via email to