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;
+ }
+}