diff --git a/seata-spring-boot-starter/pom.xml b/seata-spring-boot-starter/pom.xml
index 24f449166b0..45462b3ecaa 100644
--- a/seata-spring-boot-starter/pom.xml
+++ b/seata-spring-boot-starter/pom.xml
@@ -71,6 +71,23 @@
rocketmq-client
true
+
+ org.springframework.boot
+ spring-boot-test
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ test
+
+
+ org.apache.seata
+ seata-mock-server
+ ${project.version}
+ test
+
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/AutoConfigurationBaseTest.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/AutoConfigurationBaseTest.java
new file mode 100644
index 00000000000..196c38a1383
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/AutoConfigurationBaseTest.java
@@ -0,0 +1,23 @@
+package org.apache.seata.spring.boot.autoconfigure;
+
+import org.apache.seata.config.ConfigurationFactory;
+import org.apache.seata.mockserver.MockServer;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+public class AutoConfigurationBaseTest {
+ public static final int MOCK_SERVER_PORT = 8099;
+
+ @BeforeAll
+ public static void before() {
+ ConfigurationFactory.reload();
+ MockServer.start(MOCK_SERVER_PORT);
+ }
+
+ @AfterAll
+ public static void after() {
+ MockServer.close();
+ }
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/PropertyBeanPostProcessorTest.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/PropertyBeanPostProcessorTest.java
index f0148ab8a1e..a162e12406b 100644
--- a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/PropertyBeanPostProcessorTest.java
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/PropertyBeanPostProcessorTest.java
@@ -16,12 +16,9 @@
*/
package org.apache.seata.spring.boot.autoconfigure;
-import org.apache.seata.spring.boot.autoconfigure.properties.SeataProperties;
-import org.apache.seata.spring.boot.autoconfigure.properties.SpringCloudAlibabaConfiguration;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -35,18 +32,6 @@ public static void initContext() {
}
- @Bean
- public SeataProperties seataProperties() {
- SeataProperties seataProperties = new SeataProperties();
- seataProperties.setApplicationId("test-id");
- return seataProperties;
- }
-
- @Bean
- public SpringCloudAlibabaConfiguration springCloudAlibabaConfiguration() {
- return new SpringCloudAlibabaConfiguration();
- }
-
@AfterAll
public static void closeContext() {
context.close();
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataAutoConfigurationTest.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataAutoConfigurationTest.java
new file mode 100644
index 00000000000..f894d4647b6
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataAutoConfigurationTest.java
@@ -0,0 +1,52 @@
+package org.apache.seata.spring.boot.autoconfigure;
+
+
+import org.apache.seata.spring.annotation.GlobalTransactionScanner;
+import org.apache.seata.spring.boot.autoconfigure.properties.SeataProperties;
+import org.apache.seata.spring.boot.autoconfigure.properties.SpringCloudAlibabaConfiguration;
+import org.apache.seata.spring.boot.autoconfigure.provider.SpringApplicationContextProvider;
+import org.apache.seata.tm.api.FailureHandler;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.apache.seata.common.Constants.BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {SeataAutoConfigurationTest.TestConfig.class, SeataAutoConfiguration.class})
+@Import({SeataProperties.class,SpringCloudAlibabaConfiguration.class})
+public class SeataAutoConfigurationTest extends AutoConfigurationBaseTest{
+
+ @Autowired
+ private GlobalTransactionScanner scanner;
+
+ @Autowired
+ private FailureHandler failureHandler;
+
+ @Test
+ void testSeataAutoConfiguration() {
+ assertNotNull(failureHandler);
+ assertNotNull(scanner);
+ assertEquals(scanner.getTxServiceGroup(), "default_tx_group");
+ }
+
+ @Configuration
+ static class TestConfig {
+
+ @Bean(BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER)
+ @ConditionalOnMissingBean(name = {BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER})
+ public org.apache.seata.spring.boot.autoconfigure.provider.SpringApplicationContextProvider springApplicationContextProvider() {
+ return new SpringApplicationContextProvider();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataDataSourceAutoConfigurationTest.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataDataSourceAutoConfigurationTest.java
new file mode 100644
index 00000000000..276ad2a5cf6
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataDataSourceAutoConfigurationTest.java
@@ -0,0 +1,40 @@
+package org.apache.seata.spring.boot.autoconfigure;
+
+import org.apache.seata.spring.annotation.datasource.SeataAutoDataSourceProxyCreator;
+import org.apache.seata.spring.boot.autoconfigure.mock.MockDataSource;
+import org.apache.seata.spring.boot.autoconfigure.properties.SeataProperties;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.sql.DataSource;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {SeataDataSourceAutoConfigurationTest.TestConfig.class,SeataDataSourceAutoConfiguration.class})
+public class SeataDataSourceAutoConfigurationTest extends AutoConfigurationBaseTest{
+
+ @Autowired
+ private SeataAutoDataSourceProxyCreator seataAutoDataSourceProxyCreator;
+
+ @Test
+ public void assertDataSourceProxyNotNull() {
+ assertNotNull(seataAutoDataSourceProxyCreator);
+ }
+
+ @Configuration
+ @SpringBootApplication
+ static class TestConfig {
+ @Bean
+ public DataSource mockDataSource() {
+ return new MockDataSource();
+ }
+ }
+
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataSagaAutoConfigurationTest.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataSagaAutoConfigurationTest.java
new file mode 100644
index 00000000000..3bea91736e1
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/SeataSagaAutoConfigurationTest.java
@@ -0,0 +1,78 @@
+package org.apache.seata.spring.boot.autoconfigure;
+
+import org.apache.seata.saga.engine.StateMachineConfig;
+import org.apache.seata.saga.engine.StateMachineEngine;
+import org.apache.seata.saga.engine.config.DbStateMachineConfig;
+import org.apache.seata.spring.boot.autoconfigure.mock.MockDataSource;
+import org.apache.seata.spring.boot.autoconfigure.properties.SagaAsyncThreadPoolProperties;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {SeataSagaAutoConfigurationTest.TestConfig.class, SeataSagaAutoConfiguration.class})
+public class SeataSagaAutoConfigurationTest extends AutoConfigurationBaseTest {
+
+ @Autowired
+ private StateMachineConfig stateMachineConfig;
+
+ @Autowired
+ private StateMachineEngine stateMachineEngine;
+
+ @Resource(name = "seataSagaRejectedExecutionHandler")
+ private RejectedExecutionHandler rejectedExecutionHandler;
+
+ @Autowired
+ private ThreadPoolExecutor threadPoolExecutor;
+
+
+ @Test
+ public void assertDbStateMachineConfigNotNull() {
+ assertNotNull(stateMachineConfig);
+ Assertions.assertEquals(((DbStateMachineConfig) stateMachineConfig).getApplicationId(), "test");
+ }
+
+ @Test
+ public void assertStateMachineEngine() {
+ assertNotNull(stateMachineEngine);
+ }
+
+ @Test
+ public void testSagaAsyncThreadPoolExecutorConfiguration() {
+ assertNotNull(rejectedExecutionHandler);
+ assertNotNull(threadPoolExecutor);
+ Assertions.assertEquals(threadPoolExecutor.getCorePoolSize(), 1);
+ Assertions.assertEquals(threadPoolExecutor.getMaximumPoolSize(), 20);
+ }
+
+ @Configuration
+ static class TestConfig {
+ @Bean
+ public DataSource mockDataSource() {
+ return new MockDataSource();
+ }
+
+ @Bean
+ public SagaAsyncThreadPoolProperties mockSagaAsyncThreadPoolProperties() {
+ SagaAsyncThreadPoolProperties sagaAsyncThreadPoolProperties = new SagaAsyncThreadPoolProperties();
+ sagaAsyncThreadPoolProperties.setCorePoolSize(1);
+ sagaAsyncThreadPoolProperties.setMaxPoolSize(20);
+ sagaAsyncThreadPoolProperties.setKeepAliveTime(60);
+ return sagaAsyncThreadPoolProperties;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockBlob.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockBlob.java
new file mode 100644
index 00000000000..9d520ede2c3
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockBlob.java
@@ -0,0 +1,84 @@
+/*
+ * 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.seata.spring.boot.autoconfigure.mock;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+
+public class MockBlob implements Blob {
+
+ public MockBlob() {
+ }
+
+ @Override
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes(long pos, int length) throws SQLException {
+ return new byte[0];
+ }
+
+ @Override
+ public InputStream getBinaryStream() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public long position(byte[] pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public long position(Blob pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setBytes(long pos, byte[] bytes) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public OutputStream setBinaryStream(long pos) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void truncate(long len) throws SQLException {
+
+ }
+
+ @Override
+ public void free() throws SQLException {
+
+ }
+
+ @Override
+ public InputStream getBinaryStream(long pos, long length) throws SQLException {
+ return null;
+ }
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockClob.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockClob.java
new file mode 100644
index 00000000000..bedecdfd455
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockClob.java
@@ -0,0 +1,90 @@
+/*
+ * 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.seata.spring.boot.autoconfigure.mock;
+
+import java.io.*;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+
+public class MockClob implements Clob {
+
+ @Override
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public String getSubString(long pos, int length) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Reader getCharacterStream() throws SQLException {
+ return new CharArrayReader(new char[0]);
+ }
+
+ @Override
+ public InputStream getAsciiStream() throws SQLException {
+ return new ByteArrayInputStream(new byte[0]);
+ }
+
+ @Override
+ public long position(String searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public long position(Clob searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setString(long pos, String str) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setString(long pos, String str, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public OutputStream setAsciiStream(long pos) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Writer setCharacterStream(long pos) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void truncate(long len) throws SQLException {
+
+ }
+
+ @Override
+ public void free() throws SQLException {
+
+ }
+
+ @Override
+ public Reader getCharacterStream(long pos, long length) throws SQLException {
+ return null;
+ }
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockConnection.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockConnection.java
new file mode 100644
index 00000000000..86bc92bc04c
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockConnection.java
@@ -0,0 +1,71 @@
+/*
+ * 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.seata.spring.boot.autoconfigure.mock;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.sql.Savepoint;
+import java.util.Properties;
+
+/**
+ * Mock connection
+ */
+public class MockConnection extends com.alibaba.druid.mock.MockConnection {
+
+ private MockDriver mockDriver;
+
+ /**
+ * Instantiate a new MockConnection
+ * @param driver
+ * @param url
+ * @param connectProperties
+ */
+ public MockConnection(MockDriver driver, String url, Properties connectProperties) {
+ super(driver, url, connectProperties);
+ this.mockDriver = driver;
+ }
+
+ @Override
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return new MockDatabaseMetaData(this);
+ }
+
+ @Override
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+
+ }
+
+ @Override
+ public void rollback() {
+
+ }
+
+ @Override
+ public void rollback(Savepoint savepoint) {
+
+ }
+
+ @Override
+ public MockDriver getDriver() {
+ return mockDriver;
+ }
+
+ @Override
+ public String getSchema() {
+ return null;
+ }
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockConnectionProxy.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockConnectionProxy.java
new file mode 100644
index 00000000000..dfdb1314cb2
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockConnectionProxy.java
@@ -0,0 +1,42 @@
+/*
+ * 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.seata.spring.boot.autoconfigure.mock;
+
+import org.apache.seata.rm.datasource.ConnectionProxy;
+import org.apache.seata.rm.datasource.DataSourceProxy;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+
+public class MockConnectionProxy extends ConnectionProxy {
+ /**
+ * Instantiates a new Connection proxy.
+ *
+ * @param dataSourceProxy the data source proxy
+ * @param targetConnection the target connection
+ */
+ public MockConnectionProxy(DataSourceProxy dataSourceProxy,
+ Connection targetConnection) {
+ super(dataSourceProxy, targetConnection);
+ }
+
+ @Override
+ public void checkLock(String lockKeys) throws SQLException {
+ //do nothing
+ }
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockDataSource.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockDataSource.java
new file mode 100644
index 00000000000..55db6408cb0
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockDataSource.java
@@ -0,0 +1,72 @@
+/*
+ * 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.seata.spring.boot.autoconfigure.mock;
+
+import javax.sql.DataSource;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
+
+
+public class MockDataSource implements DataSource {
+ @Override
+ public Connection getConnection() throws SQLException {
+ return new MockConnection(new MockDriver(), "jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true", null);
+ }
+
+ @Override
+ public Connection getConnection(String username, String password) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public T unwrap(Class iface) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return false;
+ }
+
+ @Override
+ public PrintWriter getLogWriter() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void setLogWriter(PrintWriter out) throws SQLException {
+
+ }
+
+ @Override
+ public void setLoginTimeout(int seconds) throws SQLException {
+
+ }
+
+ @Override
+ public int getLoginTimeout() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return null;
+ }
+}
diff --git a/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockDatabaseMetaData.java b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockDatabaseMetaData.java
new file mode 100644
index 00000000000..b5f6b341b4a
--- /dev/null
+++ b/seata-spring-boot-starter/src/test/java/org/apache/seata/spring/boot/autoconfigure/mock/MockDatabaseMetaData.java
@@ -0,0 +1,1019 @@
+/*
+ * 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.seata.spring.boot.autoconfigure.mock;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ */
+public class MockDatabaseMetaData implements DatabaseMetaData {
+
+ protected MockConnection connection;
+
+ private static List columnMetaColumnLabels = Arrays.asList(
+ "TABLE_CAT",
+ "TABLE_SCHEM",
+ "TABLE_NAME",
+ "COLUMN_NAME",
+ "DATA_TYPE",
+ "TYPE_NAME",
+ "COLUMN_SIZE",
+ "DECIMAL_DIGITS",
+ "NUM_PREC_RADIX",
+ "NULLABLE",
+ "REMARKS",
+ "COLUMN_DEF",
+ "SQL_DATA_TYPE",
+ "SQL_DATETIME_SUB",
+ "CHAR_OCTET_LENGTH",
+ "ORDINAL_POSITION",
+ "IS_NULLABLE",
+ "IS_AUTOINCREMENT"
+ );
+
+ private static List indexMetaColumnLabels = Arrays.asList(
+ "INDEX_NAME",
+ "COLUMN_NAME",
+ "NON_UNIQUE",
+ "INDEX_QUALIFIER",
+ "TYPE",
+ "ORDINAL_POSITION",
+ "ASC_OR_DESC",
+ "CARDINALITY"
+ );
+
+ private static List pkMetaColumnLabels = Arrays.asList(
+ "PK_NAME"
+ );
+
+ private static List mockColumnsMetasLabels = Arrays.asList(
+ "SCOPE",
+ "COLUMN_NAME",
+ "DATA_TYPE",
+ "TYPE_NAME",
+ "COLUMN_SIZE",
+ "BUFFER_LENGTH",
+ "DECIMAL_DIGITS",
+ "PSEUDO_COLUMN"
+ );
+
+ private static List tableMetaColumnLabels = Arrays.asList(
+ "TABLE_CAT",
+ "TABLE_SCHEM",
+ "TABLE_NAME"
+ );
+
+ private Object[][] columnsMetasReturnValue;
+
+ private Object[][] indexMetasReturnValue;
+
+ private Object[][] pkMetasReturnValue;
+
+ private Object[][] mockColumnsMetasReturnValue;
+
+ private Object[][] mockTableMetasReturnValue;
+
+ /**
+ * Instantiate a new MockDatabaseMetaData
+ */
+ public MockDatabaseMetaData(MockConnection connection) {
+ this.connection = connection;
+ this.columnsMetasReturnValue = connection.getDriver().getMockColumnsMetasReturnValue();
+ this.indexMetasReturnValue = connection.getDriver().getMockIndexMetasReturnValue();
+ this.pkMetasReturnValue = connection.getDriver().getMockPkMetasReturnValue();
+ this.mockColumnsMetasReturnValue = connection.getDriver().getMockOnUpdateColumnsReturnValue();
+ this.mockTableMetasReturnValue = connection.getDriver().getMockTableMetasReturnValue();
+ }
+
+ @Override
+ public boolean allProceduresAreCallable() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean allTablesAreSelectable() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public String getURL() throws SQLException {
+ return this.connection.getUrl();
+ }
+
+ @Override
+ public String getUserName() throws SQLException {
+ return this.connection.getConnectProperties().getProperty("user");
+ }
+
+ @Override
+ public boolean isReadOnly() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean nullsAreSortedHigh() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean nullsAreSortedLow() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean nullsAreSortedAtStart() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean nullsAreSortedAtEnd() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public String getDatabaseProductName() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getDatabaseProductVersion() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getDriverName() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getDriverVersion() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public int getDriverMajorVersion() {
+ return 0;
+ }
+
+ @Override
+ public int getDriverMinorVersion() {
+ return 0;
+ }
+
+ @Override
+ public boolean usesLocalFiles() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean usesLocalFilePerTable() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean storesUpperCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean storesLowerCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean storesMixedCaseIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public String getIdentifierQuoteString() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getSQLKeywords() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getNumericFunctions() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getStringFunctions() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getSystemFunctions() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getTimeDateFunctions() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getSearchStringEscape() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getExtraNameCharacters() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public boolean supportsAlterTableWithAddColumn() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsAlterTableWithDropColumn() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsColumnAliasing() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean nullPlusNonNullIsNull() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsConvert() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsConvert(int fromType, int toType) throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTableCorrelationNames() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsExpressionsInOrderBy() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsOrderByUnrelated() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupBy() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupByUnrelated() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupByBeyondSelect() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsLikeEscapeClause() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsMultipleResultSets() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsMultipleTransactions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsNonNullableColumns() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsMinimumSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCoreSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsExtendedSQLGrammar() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsANSI92IntermediateSQL() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsANSI92FullSQL() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsOuterJoins() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsFullOuterJoins() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsLimitedOuterJoins() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public String getSchemaTerm() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getProcedureTerm() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public String getCatalogTerm() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public boolean isCatalogAtStart() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public String getCatalogSeparator() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public boolean supportsSchemasInDataManipulation() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSchemasInProcedureCalls() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSchemasInTableDefinitions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCatalogsInDataManipulation() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsPositionedDelete() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsPositionedUpdate() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSelectForUpdate() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsStoredProcedures() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSubqueriesInComparisons() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSubqueriesInExists() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSubqueriesInIns() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsCorrelatedSubqueries() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsUnion() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsUnionAll() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public int getMaxBinaryLiteralLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxCharLiteralLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxColumnNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxColumnsInGroupBy() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxColumnsInIndex() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxColumnsInOrderBy() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxColumnsInSelect() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxColumnsInTable() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxConnections() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxCursorNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxIndexLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxSchemaNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxProcedureNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxCatalogNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxRowSize() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public int getMaxStatementLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxStatements() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxTableNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxTablesInSelect() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getMaxUserNameLength() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int getDefaultTransactionIsolation() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public boolean supportsTransactions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
+ throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
+ String columnNamePattern) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
+ throws SQLException {
+ return new MockResultSet(this.connection.createStatement())
+ .mockResultSet(tableMetaColumnLabels, mockTableMetasReturnValue);
+ }
+
+ @Override
+ public ResultSet getSchemas() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getCatalogs() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getTableTypes() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
+ throws SQLException {
+ List