You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2026/10/02 05:06:10 UTC

(shardingsphere) branch master updated: Capture expected exception logs in additional unit tests (#40039)

This is an automated email from the ASF dual-hosted git repository.

terrymanu 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 691f7b2bea5 Capture expected exception logs in additional unit tests (#40039)
691f7b2bea5 is described below

commit 691f7b2bea5ad0fac488a250484c6c5e43b319ae
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Fri Oct 2 13:06:02 2026 +0800

    Capture expected exception logs in additional unit tests (#40039)
    
    * Update checkstyle's dtd
    
    * Capture expected exception logs in additional unit tests
---
 .../PrometheusPluginLifecycleServiceTest.java      | 13 +++++-
 .../data/loader/type/ColumnMetaDataLoaderTest.java | 14 ++++--
 .../CRC32TableInventoryCheckCalculatorTest.java    | 14 ++++--
 .../PipelineJobProgressPersistServiceTest.java     | 52 +++++++++++++++-------
 ...ipelineContextManagerLifecycleListenerTest.java | 16 +++++--
 .../core/task/TaskExecuteCallbackTest.java         | 15 ++++++-
 .../incremental/client/MySQLBinlogClientTest.java  | 14 ++++--
 .../data/pipeline/cdc/CDCJobTest.java              | 25 ++++++++---
 .../mode/manager/ContextManagerTest.java           | 27 ++++++++---
 .../manager/resource/StorageUnitManagerTest.java   | 29 ++++++++----
 .../frontend/command/CommandExecutorTaskTest.java  | 41 ++++++++++++-----
 .../netty/FrontendChannelInboundHandlerTest.java   | 20 +++++++--
 12 files changed, 211 insertions(+), 69 deletions(-)

diff --git a/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/prometheus/PrometheusPluginLifecycleServiceTest.java b/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/prometheus/PrometheusPluginLifecycleServiceTest.java
index 7955c5f3b3f..e639ce2b7ab 100644
--- a/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/prometheus/PrometheusPluginLifecycleServiceTest.java
+++ b/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/prometheus/PrometheusPluginLifecycleServiceTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.agent.plugin.metrics.prometheus;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import io.prometheus.client.CollectorRegistry;
 import org.apache.shardingsphere.agent.api.PluginConfiguration;
 import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
@@ -37,6 +38,9 @@ import org.apache.shardingsphere.mode.manager.standalone.workerid.StandaloneWork
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.mode.spi.repository.PersistRepository;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 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.AfterEach;
@@ -44,17 +48,21 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 import java.io.IOException;
+import java.net.BindException;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.Collections;
 import java.util.Properties;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isA;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(AutoMockExtension.class)
+@ExtendWith({AutoMockExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @StaticMockSettings(ProxyContext.class)
 class PrometheusPluginLifecycleServiceTest {
     
@@ -89,10 +97,11 @@ class PrometheusPluginLifecycleServiceTest {
     }
     
     @Test
-    void assertStartWhenPortIsOccupied() throws IOException {
+    void assertStartWhenPortIsOccupied(final LogCaptureAssertion logCaptureAssertion) throws IOException {
         try (ServerSocket serverSocket = new ServerSocket(0)) {
             assertDoesNotThrow(() -> pluginLifecycleService.start(new PluginConfiguration(null, serverSocket.getLocalPort(), "", PropertiesBuilder.build()), false));
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), isA(BindException.class)));
     }
     
     private ContextManager mockContextManager() {
diff --git a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/ColumnMetaDataLoaderTest.java b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/ColumnMetaDataLoaderTest.java
index d03e5399d9e..730aba6e289 100644
--- a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/ColumnMetaDataLoaderTest.java
+++ b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/ColumnMetaDataLoaderTest.java
@@ -17,9 +17,13 @@
 
 package org.apache.shardingsphere.database.connector.core.metadata.data.loader.type;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import org.apache.shardingsphere.database.connector.core.metadata.data.model.ColumnMetaData;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -37,12 +41,14 @@ import java.util.Iterator;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(MockitoExtension.class)
+@ExtendWith({MockitoExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 class ColumnMetaDataLoaderTest {
     
     private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
@@ -91,12 +97,14 @@ class ColumnMetaDataLoaderTest {
     }
     
     @Test
-    void assertLoadWhenThrowsSQLException() throws SQLException {
+    void assertLoadWhenThrowsSQLException(final LogCaptureAssertion logCaptureAssertion) throws SQLException {
         when(columnResultSet.next()).thenReturn(true, false);
         when(columnResultSet.getString("TABLE_NAME")).thenReturn("tbl");
         when(columnResultSet.getString("COLUMN_NAME")).thenReturn("pk_col");
         when(columnResultSet.getInt("DATA_TYPE")).thenReturn(Types.INTEGER);
-        when(connection.createStatement().executeQuery(anyString())).thenThrow(SQLException.class);
+        SQLException expectedException = new SQLException();
+        when(connection.createStatement().executeQuery(anyString())).thenThrow(expectedException);
         assertThrows(SQLException.class, () -> ColumnMetaDataLoader.load(connection, "tbl", databaseType));
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
 }
diff --git a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/consistencycheck/table/calculator/CRC32TableInventoryCheckCalculatorTest.java b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/consistencycheck/table/calculator/CRC32TableInventoryCheckCalculatorTest.java
index 7e52368c098..288b58300ec 100644
--- a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/consistencycheck/table/calculator/CRC32TableInventoryCheckCalculatorTest.java
+++ b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/consistencycheck/table/calculator/CRC32TableInventoryCheckCalculatorTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.data.pipeline.core.consistencycheck.table.calculator;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import org.apache.shardingsphere.data.pipeline.core.consistencycheck.result.TableInventoryCheckCalculatedResult;
 import org.apache.shardingsphere.data.pipeline.core.datasource.PipelineDataSource;
 import org.apache.shardingsphere.data.pipeline.core.exception.data.PipelineTableDataConsistencyCheckLoadingFailedException;
@@ -27,6 +28,9 @@ import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable;
 import org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContextFactory;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -46,6 +50,7 @@ import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -53,7 +58,8 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(MockitoExtension.class)
+@ExtendWith({MockitoExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 class CRC32TableInventoryCheckCalculatorTest {
     
     private TableInventoryCalculateParameter parameter;
@@ -96,8 +102,10 @@ class CRC32TableInventoryCheckCalculatorTest {
     }
     
     @Test
-    void assertCalculateFailed() throws SQLException {
-        when(connection.prepareStatement(anyString())).thenThrow(new SQLException(""));
+    void assertCalculateFailed(final LogCaptureAssertion logCaptureAssertion) throws SQLException {
+        SQLException expectedException = new SQLException("");
+        when(connection.prepareStatement(anyString())).thenThrow(expectedException);
         assertThrows(PipelineTableDataConsistencyCheckLoadingFailedException.class, () -> new CRC32TableInventoryCheckCalculator().calculate(parameter));
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
 }
diff --git a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/job/progress/persist/PipelineJobProgressPersistServiceTest.java b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/job/progress/persist/PipelineJobProgressPersistServiceTest.java
index 4f5bef445fd..8f5eba83ecd 100644
--- a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/job/progress/persist/PipelineJobProgressPersistServiceTest.java
+++ b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/job/progress/persist/PipelineJobProgressPersistServiceTest.java
@@ -25,6 +25,9 @@ import org.apache.shardingsphere.data.pipeline.core.job.service.PipelineJobItemM
 import org.apache.shardingsphere.data.pipeline.core.job.type.PipelineJobOption;
 import org.apache.shardingsphere.data.pipeline.core.job.type.PipelineJobType;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 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.AfterEach;
@@ -54,7 +57,8 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(AutoMockExtension.class)
+@ExtendWith({AutoMockExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @StaticMockSettings(PipelineJobRegistry.class)
 class PipelineJobProgressPersistServiceTest {
     
@@ -174,22 +178,36 @@ class PipelineJobProgressPersistServiceTest {
     }
     
     @Test
-    void assertPersistNowHandlesSubsequentExceptionLoggingBranches() {
-        String jobId = "foo_id_exception_follow";
-        int shardingItem = 1;
-        PipelineJobProgressPersistService.add(jobId, shardingItem);
-        PipelineJobProgressPersistContext persistContext = getJobProgressPersistMap().get(jobId).get(shardingItem);
-        persistContext.getUnhandledEventCount().set(-1L);
-        when(PipelineJobRegistry.getItemContext(jobId, shardingItem)).thenReturn(Optional.empty());
-        assertDoesNotThrow(() -> PipelineJobProgressPersistService.persistNow(jobId, shardingItem));
-        assertTrue(persistContext.getFirstExceptionLogged().get());
-        try (MockedStatic<ThreadLocalRandom> ignored = mockStatic(ThreadLocalRandom.class)) {
-            ThreadLocalRandom randomMock = mock(ThreadLocalRandom.class);
-            when(ThreadLocalRandom.current()).thenReturn(randomMock);
-            when(randomMock.nextInt(60)).thenReturn(5, 4);
-            assertDoesNotThrow(() -> PipelineJobProgressPersistService.persistNow(jobId, shardingItem));
-            assertDoesNotThrow(() -> PipelineJobProgressPersistService.persistNow(jobId, shardingItem));
-            verify(randomMock, times(2)).nextInt(60);
+    void assertPersistNowHandlesSubsequentExceptionLoggingBranches(final LogCaptureAssertion logCaptureAssertion) throws ClassNotFoundException {
+        synchronized (Class.forName(PipelineJobProgressPersistService.class.getName() + "$PersistJobContextRunnable")) {
+            String jobId = "foo_id_exception_follow";
+            int shardingItem = 1;
+            PipelineJobProgressPersistService.add(jobId, shardingItem);
+            PipelineJobProgressPersistContext persistContext = getJobProgressPersistMap().get(jobId).get(shardingItem);
+            try {
+                persistContext.getUnhandledEventCount().set(-1L);
+                when(PipelineJobRegistry.getItemContext(jobId, shardingItem)).thenReturn(Optional.empty());
+                assertDoesNotThrow(() -> PipelineJobProgressPersistService.persistNow(jobId, shardingItem));
+                logCaptureAssertion.assertErrorLog(actualException -> {
+                    assertThat(actualException.getClassName(), is(IllegalStateException.class.getName()));
+                    assertThat(actualException.getMessage(), is("Current unhandled event count must be greater than or equal to 0"));
+                });
+                assertTrue(persistContext.getFirstExceptionLogged().get());
+                try (MockedStatic<ThreadLocalRandom> ignored = mockStatic(ThreadLocalRandom.class)) {
+                    ThreadLocalRandom randomMock = mock(ThreadLocalRandom.class);
+                    when(ThreadLocalRandom.current()).thenReturn(randomMock);
+                    when(randomMock.nextInt(60)).thenReturn(5, 4);
+                    assertDoesNotThrow(() -> PipelineJobProgressPersistService.persistNow(jobId, shardingItem));
+                    logCaptureAssertion.assertErrorLog(actualException -> {
+                        assertThat(actualException.getClassName(), is(IllegalStateException.class.getName()));
+                        assertThat(actualException.getMessage(), is("Current unhandled event count must be greater than or equal to 0"));
+                    });
+                    assertDoesNotThrow(() -> PipelineJobProgressPersistService.persistNow(jobId, shardingItem));
+                    verify(randomMock, times(2)).nextInt(60);
+                }
+            } finally {
+                persistContext.getUnhandledEventCount().set(0L);
+            }
         }
     }
 }
diff --git a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/listener/PipelineContextManagerLifecycleListenerTest.java b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/listener/PipelineContextManagerLifecycleListenerTest.java
index 7cf492c470b..0fe07ecb409 100644
--- a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/listener/PipelineContextManagerLifecycleListenerTest.java
+++ b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/listener/PipelineContextManagerLifecycleListenerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.data.pipeline.core.listener;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import org.apache.shardingsphere.data.pipeline.core.context.PipelineContextKey;
 import org.apache.shardingsphere.data.pipeline.core.context.PipelineContextManager;
 import org.apache.shardingsphere.data.pipeline.core.exception.job.PipelineJobNotFoundException;
@@ -36,7 +37,11 @@ import org.apache.shardingsphere.infra.instance.metadata.InstanceType;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.schedule.spi.CoordinatorRegistryCenterProvider;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.MockedConstruction;
 import org.mockito.MockedStatic;
 
@@ -52,12 +57,15 @@ import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 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.mockConstruction;
 import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+@ExtendWith(LogCaptureExtension.class)
+@LogCaptureSettings(suppressOutput = true)
 class PipelineContextManagerLifecycleListenerTest {
     
     @Test
@@ -129,9 +137,10 @@ class PipelineContextManagerLifecycleListenerTest {
     }
     
     @Test
-    void assertInitializeIgnoresDispatchFailure() {
+    void assertInitializeIgnoresDispatchFailure(final LogCaptureAssertion logCaptureAssertion) {
         ContextManager contextManager = mockContextManager();
         PipelineContextKey contextKey = new PipelineContextKey("foo_db", InstanceType.JDBC);
+        RuntimeException expectedException = new RuntimeException("expected");
         try (
                 MockedStatic<PipelineContextManager> ignoredContextManager = mockStatic(PipelineContextManager.class);
                 MockedStatic<PipelineMetaDataNodeWatcher> ignoredWatcher = mockStatic(PipelineMetaDataNodeWatcher.class);
@@ -139,9 +148,10 @@ class PipelineContextManagerLifecycleListenerTest {
                 MockedStatic<TypedSPILoader> typedSPILoader = mockStatic(TypedSPILoader.class);
                 MockedStatic<PipelineAPIFactory> pipelineAPIFactory = mockStatic(PipelineAPIFactory.class)) {
             typedSPILoader.when(() -> TypedSPILoader.findService(CoordinatorRegistryCenterProvider.class, "FIXTURE")).thenReturn(Optional.of(mock(CoordinatorRegistryCenterProvider.class)));
-            pipelineAPIFactory.when(() -> PipelineAPIFactory.getJobConfigurationAPI(contextKey)).thenThrow(new RuntimeException("expected"));
+            pipelineAPIFactory.when(() -> PipelineAPIFactory.getJobConfigurationAPI(contextKey)).thenThrow(expectedException);
             assertDoesNotThrow(() -> new PipelineContextManagerLifecycleListener().onInitialized(contextManager));
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
@@ -179,7 +189,7 @@ class PipelineContextManagerLifecycleListenerTest {
         ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
         when(result.getPreSelectedDatabaseName()).thenReturn("foo_db");
         when(result.getComputeNodeInstanceContext().getInstance().getMetaData().getType()).thenReturn(InstanceType.JDBC);
-        when(result.getComputeNodeInstanceContext().getModeConfiguration().getRepository().getType()).thenReturn("FIXTURE");
+        lenient().when(result.getComputeNodeInstanceContext().getModeConfiguration().getRepository().getType()).thenReturn("FIXTURE");
         return result;
     }
     
diff --git a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/task/TaskExecuteCallbackTest.java b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/task/TaskExecuteCallbackTest.java
index c5a9588c693..6477d5c29c5 100644
--- a/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/task/TaskExecuteCallbackTest.java
+++ b/kernel/data-pipeline/core/src/test/java/org/apache/shardingsphere/data/pipeline/core/task/TaskExecuteCallbackTest.java
@@ -17,17 +17,28 @@
 
 package org.apache.shardingsphere.data.pipeline.core.task;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
+@ExtendWith(LogCaptureExtension.class)
+@LogCaptureSettings(suppressOutput = true)
 class TaskExecuteCallbackTest {
     
     @Test
-    void assertOnFailure() {
+    void assertOnFailure(final LogCaptureAssertion logCaptureAssertion) {
         PipelineTask task = mock(PipelineTask.class);
-        new TaskExecuteCallback(task).onFailure(new RuntimeException(""));
+        RuntimeException expectedException = new RuntimeException("");
+        new TaskExecuteCallback(task).onFailure(expectedException);
         verify(task).stop();
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
 }
diff --git a/kernel/data-pipeline/dialect/mysql/src/test/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/MySQLBinlogClientTest.java b/kernel/data-pipeline/dialect/mysql/src/test/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/MySQLBinlogClientTest.java
index e7aea5b78a0..da8e7d72665 100644
--- a/kernel/data-pipeline/dialect/mysql/src/test/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/MySQLBinlogClientTest.java
+++ b/kernel/data-pipeline/dialect/mysql/src/test/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/MySQLBinlogClientTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.data.pipeline.mysql.ingest.incremental.client;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
@@ -44,6 +45,9 @@ import org.apache.shardingsphere.database.protocol.mysql.packet.command.query.te
 import org.apache.shardingsphere.database.protocol.mysql.packet.generic.MySQLErrPacket;
 import org.apache.shardingsphere.database.protocol.mysql.packet.generic.MySQLOKPacket;
 import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -72,6 +76,7 @@ import java.util.stream.Collectors;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isA;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -90,7 +95,8 @@ import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.withSettings;
 
 @SuppressWarnings("ProhibitedExceptionDeclared")
-@ExtendWith(MockitoExtension.class)
+@ExtendWith({MockitoExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @MockitoSettings(strictness = Strictness.LENIENT)
 class MySQLBinlogClientTest {
     
@@ -348,7 +354,7 @@ class MySQLBinlogClientTest {
     }
     
     @Test
-    void assertMySQLCommandResponseHandlerBranches() throws Exception {
+    void assertMySQLCommandResponseHandlerBranches(final LogCaptureAssertion logCaptureAssertion) throws Exception {
         final AtomicReference<ChannelInitializer<SocketChannel>> initializer = new AtomicReference<>();
         SocketChannel socketChannel = mock(SocketChannel.class, RETURNS_DEEP_STUBS);
         when(socketChannel.pipeline()).thenReturn(pipeline);
@@ -382,12 +388,14 @@ class MySQLBinlogClientTest {
         assertTrue(callback.isSuccess());
         callback = new DefaultPromise<>(eventLoopGroup.next());
         setResponseCallback(callback);
-        handler.exceptionCaught(mock(ChannelHandlerContext.class), new RuntimeException("ex"));
+        RuntimeException expectedException = new RuntimeException("ex");
+        handler.exceptionCaught(mock(ChannelHandlerContext.class), expectedException);
         assertTrue(callback.isDone());
         setResponseCallback(null);
         handler.channelRead(mock(ChannelHandlerContext.class), new Object());
         handler.exceptionCaught(mock(ChannelHandlerContext.class), new RuntimeException("ex"));
         client.closeChannel(true);
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     private InternalResultSet createResultSet(final String checksum) {
diff --git a/kernel/data-pipeline/scenario/cdc/core/src/test/java/org/apache/shardingsphere/data/pipeline/cdc/CDCJobTest.java b/kernel/data-pipeline/scenario/cdc/core/src/test/java/org/apache/shardingsphere/data/pipeline/cdc/CDCJobTest.java
index 7e3a5df1251..83104483f16 100644
--- a/kernel/data-pipeline/scenario/cdc/core/src/test/java/org/apache/shardingsphere/data/pipeline/cdc/CDCJobTest.java
+++ b/kernel/data-pipeline/scenario/cdc/core/src/test/java/org/apache/shardingsphere/data/pipeline/cdc/CDCJobTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.data.pipeline.cdc;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import io.netty.channel.Channel;
 import org.apache.shardingsphere.data.pipeline.api.PipelineDataSourceConfiguration;
 import org.apache.shardingsphere.data.pipeline.api.type.ShardingSpherePipelineDataSourceConfiguration;
@@ -66,6 +67,9 @@ import org.apache.shardingsphere.infra.instance.metadata.InstanceType;
 import org.apache.shardingsphere.infra.metadata.identifier.ShardingSphereIdentifier;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 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;
@@ -105,7 +109,8 @@ import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(AutoMockExtension.class)
+@ExtendWith({AutoMockExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @StaticMockSettings({
         PipelineJobIdUtils.class, PipelineProcessConfigurationUtils.class, PipelineDataSourceConfigurationFactory.class,
         OrderedSPILoader.class, PipelineAPIFactory.class, PipelineJobProgressPersistService.class,
@@ -157,17 +162,18 @@ class CDCJobTest {
     }
     
     @Test
-    void assertExecuteInitTasksFailureStopsJob() {
+    void assertExecuteInitTasksFailureStopsJob(final LogCaptureAssertion logCaptureAssertion) {
         CDCJobConfiguration jobConfig = mockJobConfiguration(
                 Collections.singletonList(new JobDataNodeLine(Collections.singletonList(new JobDataNodeEntry("logic_tbl", Collections.singletonList(new DataNode("ds_0.tbl_0")))))));
         ShardingContext shardingContext = mockShardingContext("param");
         prepareJobTypeAndContext(jobConfig);
         CDCJobAPI jobAPI = mock(CDCJobAPI.class);
+        RuntimeException expectedException = new RuntimeException();
         try (
                 MockedStatic<TypedSPILoader> typedSPILoader = mockStatic(TypedSPILoader.class);
                 MockedConstruction<PipelineProcessConfigurationPersistService> ignoredProcess = mockPersistService(
                         new PipelineProcessConfiguration(new PipelineReadConfiguration(1, 1, 1, null), new PipelineWriteConfiguration(1, 1, null), null));
-                MockedConstruction<CDCJobPreparer> ignoredPreparer = mockConstruction(CDCJobPreparer.class, (mock, context) -> doThrow(RuntimeException.class).when(mock).initTasks(anyCollection()));
+                MockedConstruction<CDCJobPreparer> ignoredPreparer = mockConstruction(CDCJobPreparer.class, (mock, context) -> doThrow(expectedException).when(mock).initTasks(anyCollection()));
                 MockedStatic<PipelineJobRegistry> jobRegistryMocked = mockStatic(PipelineJobRegistry.class)) {
             typedSPILoader.when(() -> TypedSPILoader.getService(TransmissionJobAPI.class, "STREAMING")).thenReturn(jobAPI);
             PipelineGovernanceFacade governanceFacade = mock(PipelineGovernanceFacade.class, RETURNS_DEEP_STUBS);
@@ -181,6 +187,7 @@ class CDCJobTest {
             verify(jobAPI).disable("foo_job_id");
             jobRegistryMocked.verify(() -> PipelineJobRegistry.stop("foo_job_id"));
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @SuppressWarnings({"rawtypes", "unchecked"})
@@ -267,12 +274,13 @@ class CDCJobTest {
     
     @SuppressWarnings("unchecked")
     @Test
-    void assertExecuteIncrementalFailureSendError() {
+    void assertExecuteIncrementalFailureSendError(final LogCaptureAssertion logCaptureAssertion) {
         CDCJobConfiguration jobConfig = mockJobConfiguration(
                 Collections.singletonList(new JobDataNodeLine(Collections.singletonList(new JobDataNodeEntry("logic_tbl", Collections.singletonList(new DataNode("ds_0.tbl_0")))))));
         ShardingContext shardingContext = mockShardingContext("param");
         prepareJobTypeAndContext(jobConfig);
         CDCJobAPI jobAPI = mock(CDCJobAPI.class);
+        RuntimeException expectedException = new RuntimeException("failure");
         try (
                 MockedStatic<TypedSPILoader> typedSPILoader = mockStatic(TypedSPILoader.class);
                 MockedConstruction<PipelineProcessConfigurationPersistService> ignoredProcess = mockPersistService(
@@ -302,7 +310,7 @@ class CDCJobTest {
                 if (0 == triggerCounter.getAndIncrement()) {
                     callback.onSuccess();
                 } else {
-                    callback.onFailure(new RuntimeException("failure"));
+                    callback.onFailure(expectedException);
                 }
                 return null;
             });
@@ -313,16 +321,18 @@ class CDCJobTest {
             verify(jobAPI).disable("foo_job_id");
             jobRegistryMocked.verify(() -> PipelineJobRegistry.stop("foo_job_id"));
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @SuppressWarnings("unchecked")
     @Test
-    void assertExecuteIncrementalFailureWithoutSocketSink() {
+    void assertExecuteIncrementalFailureWithoutSocketSink(final LogCaptureAssertion logCaptureAssertion) {
         CDCJobConfiguration jobConfig = mockJobConfiguration(
                 Collections.singletonList(new JobDataNodeLine(Collections.singletonList(new JobDataNodeEntry("logic_tbl", Collections.singletonList(new DataNode("ds_0.tbl_0")))))));
         ShardingContext shardingContext = mockShardingContext("param");
         prepareJobTypeAndContext(jobConfig);
         CDCJobAPI jobAPI = mock(CDCJobAPI.class);
+        RuntimeException expectedException = new RuntimeException("failure");
         try (
                 MockedStatic<TypedSPILoader> typedSPILoader = mockStatic(TypedSPILoader.class);
                 MockedConstruction<PipelineProcessConfigurationPersistService> ignoredProcess = mockPersistService(
@@ -346,7 +356,7 @@ class CDCJobTest {
                 if (0 == triggerCounter.getAndIncrement()) {
                     callback.onSuccess();
                 } else {
-                    callback.onFailure(new RuntimeException("failure"));
+                    callback.onFailure(expectedException);
                 }
                 return null;
             });
@@ -355,6 +365,7 @@ class CDCJobTest {
             verify(jobAPI).disable("foo_job_id");
             jobRegistryMocked.verify(() -> PipelineJobRegistry.stop("foo_job_id"));
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @SuppressWarnings("unchecked")
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
index 35da34bb208..0c021e2b70a 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.mode.manager;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoader;
 import org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderMaterial;
@@ -60,6 +61,9 @@ import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistFacade;
 import org.apache.shardingsphere.mode.persist.PersistServiceFacade;
 import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 import org.apache.shardingsphere.test.infra.fixture.jdbc.MockedDataSource;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -82,6 +86,7 @@ import java.util.Properties;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -101,7 +106,8 @@ import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(MockitoExtension.class)
+@ExtendWith({MockitoExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @MockitoSettings(strictness = Strictness.LENIENT)
 class ContextManagerTest {
     
@@ -219,18 +225,20 @@ class ContextManagerTest {
     }
     
     @Test
-    void assertReloadDatabaseWhenSQLExceptionThrown() {
+    void assertReloadDatabaseWhenSQLExceptionThrown(final LogCaptureAssertion logCaptureAssertion) {
         setPersistServiceFacade(mockPersistServiceFacade());
         MetaDataContextManager metaDataContextManager = mock(MetaDataContextManager.class, RETURNS_DEEP_STUBS);
         SwitchingResource switchingResource = new SwitchingResource(Collections.emptyMap(), Collections.emptyMap(), Collections.emptyList(), Collections.emptyMap());
         when(metaDataContextManager.getResourceSwitchManager().switchByAlterStorageUnit(any(ResourceMetaData.class), anyMap(), anyBoolean())).thenReturn(switchingResource);
         setMetaDataContextManager(metaDataContextManager);
+        SQLException expectedException = new SQLException();
         try (
                 MockedConstruction<MetaDataContextsFactory> ignored = mockConstruction(MetaDataContextsFactory.class,
-                        (mock, context) -> when(mock.createChangedDatabaseByRebuild("foo_db", switchingResource, Collections.emptyList(), metaDataContexts)).thenThrow(SQLException.class))) {
+                        (mock, context) -> when(mock.createChangedDatabaseByRebuild("foo_db", switchingResource, Collections.emptyList(), metaDataContexts)).thenThrow(expectedException))) {
             contextManager.reloadDatabase(database);
             verify(metaDataContexts, never()).update(any());
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
@@ -266,14 +274,16 @@ class ContextManagerTest {
     }
     
     @Test
-    void assertReloadSchemaWithSQLException() {
+    void assertReloadSchemaWithSQLException(final LogCaptureAssertion logCaptureAssertion) {
         setPersistServiceFacade(mockPersistServiceFacade());
+        SQLException expectedException = new SQLException();
         try (MockedStatic<GenericSchemaBuilder> schemaBuilderMock = mockStatic(GenericSchemaBuilder.class)) {
-            schemaBuilderMock.when(() -> GenericSchemaBuilder.build(any(DatabaseType.class), any(GenericSchemaBuilderMaterial.class))).thenThrow(SQLException.class);
+            schemaBuilderMock.when(() -> GenericSchemaBuilder.build(any(DatabaseType.class), any(GenericSchemaBuilderMaterial.class))).thenThrow(expectedException);
             contextManager.reloadSchema(database, "foo_schema", "foo_ds");
             verify(database, never()).dropSchema(any());
             verify(database, never()).addSchema(any());
         }
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
@@ -354,13 +364,16 @@ class ContextManagerTest {
     }
     
     @Test
-    void assertReloadTableWithSQLException() {
+    void assertReloadTableWithSQLException(final LogCaptureAssertion logCaptureAssertion) {
         PersistServiceFacade persistServiceFacade = mockPersistServiceFacade();
         setPersistServiceFacade(persistServiceFacade);
+        SQLException expectedException = new SQLException();
         try (MockedStatic<GenericSchemaBuilder> schemaBuilderMock = mockStatic(GenericSchemaBuilder.class)) {
-            schemaBuilderMock.when(() -> GenericSchemaBuilder.build(anySet(), any(DatabaseType.class), any(GenericSchemaBuilderMaterial.class))).thenThrow(SQLException.class);
+            schemaBuilderMock.when(() -> GenericSchemaBuilder.build(anySet(), any(DatabaseType.class), any(GenericSchemaBuilderMaterial.class))).thenThrow(expectedException);
             contextManager.reloadTable(database, "foo_schema", "foo_tbl");
+            logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
             contextManager.reloadTable(database, "foo_schema", "foo_ds", "foo_tbl");
+            logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
             verify(persistServiceFacade.getMetaDataFacade().getDatabaseMetaDataFacade().getTable(), never()).persist(any(), any(), any());
             verify(persistServiceFacade.getModeFacade().getMetaDataManagerService(), never()).dropTables(any(), any(), any());
         }
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java
index bafe3c8c14d..e2d6205973f 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.mode.metadata.manager.resource;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
@@ -35,6 +36,9 @@ import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistFacade;
 import org.apache.shardingsphere.mode.metadata.persist.metadata.DatabaseMetaDataPersistFacade;
 import org.apache.shardingsphere.mode.metadata.persist.metadata.service.ViewMetaDataPersistService;
 import org.apache.shardingsphere.test.infra.fixture.jdbc.MockedDataSource;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 import org.apache.shardingsphere.test.infra.framework.extension.mock.AutoMockExtension;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.Test;
@@ -49,6 +53,8 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.TimeUnit;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -65,7 +71,8 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.withSettings;
 
-@ExtendWith(AutoMockExtension.class)
+@ExtendWith({AutoMockExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 class StorageUnitManagerTest {
     
     private static final String DATABASE_NAME = "foo_db";
@@ -94,15 +101,17 @@ class StorageUnitManagerTest {
     }
     
     @Test
-    void assertRegisterLogsErrorWhenSQLException() {
+    void assertRegisterLogsErrorWhenSQLException(final LogCaptureAssertion logCaptureAssertion) {
         MetaDataContexts metaDataContexts = mockMetaDataContexts();
         ResourceSwitchManager resourceSwitchManager = mock(ResourceSwitchManager.class);
+        SQLException expectedException = new SQLException("register error");
         doAnswer(invocation -> {
-            throw new SQLException("register error");
+            throw expectedException;
         }).when(resourceSwitchManager).switchByRegisterStorageUnit(any(ResourceMetaData.class), any(Map.class), anyBoolean());
         assertDoesNotThrow(() -> createManager(metaDataContexts, resourceSwitchManager).register(DATABASE_NAME, Collections.emptyMap()));
         verify(metaDataContexts, never()).update(any(MetaDataContexts.class));
         verify(metaDataContexts.getMetaData(), never()).putDatabase(any(ShardingSphereDatabase.class));
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
@@ -145,15 +154,17 @@ class StorageUnitManagerTest {
     }
     
     @Test
-    void assertAlterLogsErrorWhenSQLException() {
+    void assertAlterLogsErrorWhenSQLException(final LogCaptureAssertion logCaptureAssertion) {
         MetaDataContexts metaDataContexts = mockMetaDataContexts();
         ResourceSwitchManager resourceSwitchManager = mock(ResourceSwitchManager.class);
+        SQLException expectedException = new SQLException("alter error");
         doAnswer(invocation -> {
-            throw new SQLException("alter error");
+            throw expectedException;
         }).when(resourceSwitchManager).switchByAlterStorageUnit(any(ResourceMetaData.class), any(Map.class), anyBoolean());
         assertDoesNotThrow(() -> createManager(metaDataContexts, resourceSwitchManager).alter(DATABASE_NAME, Collections.emptyMap()));
         verify(metaDataContexts, never()).update(any(MetaDataContexts.class));
         verify(metaDataContexts.getMetaData(), never()).putDatabase(any(ShardingSphereDatabase.class));
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
@@ -178,15 +189,17 @@ class StorageUnitManagerTest {
     }
     
     @Test
-    void assertUnregisterLogsErrorWhenSQLException() {
+    void assertUnregisterLogsErrorWhenSQLException(final LogCaptureAssertion logCaptureAssertion) {
         MetaDataContexts metaDataContexts = mockMetaDataContexts();
         ResourceSwitchManager resourceSwitchManager = mock(ResourceSwitchManager.class);
+        SQLException expectedException = new SQLException("unregister error");
         doAnswer(invocation -> {
-            throw new SQLException("unregister error");
+            throw expectedException;
         }).when(resourceSwitchManager).switchByUnregisterStorageUnit(any(ResourceMetaData.class), any(Collection.class));
         assertDoesNotThrow(() -> createManager(metaDataContexts, resourceSwitchManager).unregister(DATABASE_NAME, "ds_0"));
         verify(metaDataContexts, never()).update(any(MetaDataContexts.class));
         verify(metaDataContexts.getMetaData(), never()).putDatabase(any(ShardingSphereDatabase.class));
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     private MetaDataContexts mockMetaDataContexts() {
@@ -197,7 +210,7 @@ class StorageUnitManagerTest {
         when(database.getResourceMetaData()).thenReturn(new ResourceMetaData(Collections.emptyMap(), Collections.emptyMap()));
         when(database.getRuleMetaData().getRules()).thenReturn(Arrays.asList(mock(ShardingSphereRule.class, withSettings().extraInterfaces(AutoCloseable.class)), mock(ShardingSphereRule.class)));
         when(metaData.getDatabase(DATABASE_NAME)).thenReturn(database);
-        when(metaData.getTemporaryProps()).thenReturn(new TemporaryConfigurationProperties(new Properties()));
+        lenient().when(metaData.getTemporaryProps()).thenReturn(new TemporaryConfigurationProperties(new Properties()));
         return result;
     }
     
diff --git a/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/command/CommandExecutorTaskTest.java b/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/command/CommandExecutorTaskTest.java
index 9c8f1895f5a..e527f5d9c67 100644
--- a/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/command/CommandExecutorTaskTest.java
+++ b/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/command/CommandExecutorTaskTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.proxy.frontend.command;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.CompositeByteBuf;
 import io.netty.channel.ChannelHandlerContext;
@@ -41,6 +42,9 @@ import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor;
 import org.apache.shardingsphere.proxy.frontend.command.executor.QueryCommandExecutor;
 import org.apache.shardingsphere.proxy.frontend.spi.DatabaseProtocolFrontendEngine;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 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.BeforeEach;
@@ -58,6 +62,7 @@ import java.util.Optional;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.inOrder;
@@ -66,7 +71,8 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(AutoMockExtension.class)
+@ExtendWith({AutoMockExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @StaticMockSettings(ProxyContext.class)
 class CommandExecutorTaskTest {
     
@@ -112,14 +118,15 @@ class CommandExecutorTaskTest {
     }
     
     @Test
-    void assertRunNeedFlushByFalse() throws SQLException, BackendConnectionException {
+    void assertRunNeedFlushByFalse(final LogCaptureAssertion logCaptureAssertion) throws SQLException, BackendConnectionException {
         mockProxyContext(false);
         when(queryCommandExecutor.execute()).thenReturn(Collections.emptyList());
         when(engine.getCommandExecuteEngine().getCommandExecutor(commandPacketType, commandPacket, connectionSession)).thenReturn(queryCommandExecutor);
         CompositeByteBuf compositeMessage = mock(CompositeByteBuf.class);
         when(compositeMessage.readableBytes()).thenReturn(0);
         when(engine.getCodecEngine().createPacketPayload(compositeMessage, StandardCharsets.UTF_8)).thenReturn(payload);
-        BackendConnectionException backendConnectionException = new BackendConnectionException(Collections.singleton(new SQLException("foo_close")));
+        SQLException expectedException = new SQLException("foo_close");
+        BackendConnectionException backendConnectionException = new BackendConnectionException(Collections.singleton(expectedException));
         doThrow(backendConnectionException).when(databaseConnectionManager).closeExecutionResources();
         when(engine.getCommandExecuteEngine().getErrorPacket(any(Exception.class))).thenReturn(databasePacket);
         when(engine.getCommandExecuteEngine().getOtherPacket(connectionSession)).thenReturn(Optional.empty());
@@ -130,6 +137,10 @@ class CommandExecutorTaskTest {
         verify(databaseConnectionManager).closeExecutionResources();
         verify(compositeMessage).discardReadComponents();
         verify(compositeMessage).release();
+        logCaptureAssertion.assertErrorLog(actualException -> {
+            SQLException actualSQLException = (SQLException) ((ThrowableProxy) actualException).getThrowable();
+            assertThat(actualSQLException.getNextException(), sameInstance(expectedException));
+        });
     }
     
     @Test
@@ -158,7 +169,7 @@ class CommandExecutorTaskTest {
     }
     
     @Test
-    void assertRunWithCloseSQLException() throws SQLException, BackendConnectionException {
+    void assertRunWithCloseSQLException(final LogCaptureAssertion logCaptureAssertion) throws SQLException, BackendConnectionException {
         mockProxyContext(false);
         SQLException expectedException = new SQLException("foo_close");
         when(commandExecutor.execute()).thenReturn(Collections.emptyList());
@@ -173,6 +184,7 @@ class CommandExecutorTaskTest {
         verify(connectionSession).clearQueryContext();
         verify(databaseConnectionManager).closeExecutionResources();
         verify(message).release();
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
@@ -200,7 +212,7 @@ class CommandExecutorTaskTest {
     }
     
     @Test
-    void assertRunWithExecuteAndCloseSQLExceptions() throws SQLException {
+    void assertRunWithExecuteAndCloseSQLExceptions(final LogCaptureAssertion logCaptureAssertion) throws SQLException {
         mockProxyContext(false);
         SQLException expectedException = new SQLException("foo_execute");
         SQLException expectedCloseException = new SQLException("bar_close");
@@ -218,10 +230,11 @@ class CommandExecutorTaskTest {
         inOrder.verify(engine).handleException(connectionSession, expectedException);
         inOrder.verify(commandExecutor).close();
         verify(commandExecutor).close();
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
-    void assertRunWithException() throws BackendConnectionException, SQLException {
+    void assertRunWithException(final LogCaptureAssertion logCaptureAssertion) throws BackendConnectionException, SQLException {
         mockProxyContext(false);
         RuntimeException mockException = new RuntimeException("foo_mock");
         doThrow(mockException).when(commandExecutor).execute();
@@ -233,10 +246,11 @@ class CommandExecutorTaskTest {
         verify(handlerContext, times(2)).write(databasePacket);
         verify(handlerContext).flush();
         verify(databaseConnectionManager).closeExecutionResources();
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(mockException)));
     }
     
     @Test
-    void assertRunWithRuntimeExceptionAndCloseSQLException() throws SQLException {
+    void assertRunWithRuntimeExceptionAndCloseSQLException(final LogCaptureAssertion logCaptureAssertion) throws SQLException {
         mockProxyContext(false);
         RuntimeException expectedException = new RuntimeException("foo_execute");
         SQLException expectedCloseException = new SQLException("bar_close");
@@ -251,12 +265,14 @@ class CommandExecutorTaskTest {
         assertThat(expectedException.getSuppressed()[0], is(expectedCloseException));
         verify(engine.getCommandExecuteEngine()).getErrorPacket(expectedException);
         verify(commandExecutor).close();
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(expectedException)));
     }
     
     @Test
-    void assertRunWithOOMError() throws BackendConnectionException, SQLException {
+    void assertRunWithOOMError(final LogCaptureAssertion logCaptureAssertion) throws BackendConnectionException, SQLException {
         mockProxyContext(false);
-        doThrow(OutOfMemoryError.class).when(commandExecutor).execute();
+        Error expectedError = new OutOfMemoryError();
+        doThrow(expectedError).when(commandExecutor).execute();
         when(engine.getCodecEngine().createPacketPayload(message, StandardCharsets.UTF_8)).thenReturn(payload);
         when(engine.getCommandExecuteEngine().getCommandExecutor(commandPacketType, commandPacket, connectionSession)).thenReturn(commandExecutor);
         when(engine.getCommandExecuteEngine().getErrorPacket(any(RuntimeException.class))).thenReturn(databasePacket);
@@ -265,10 +281,14 @@ class CommandExecutorTaskTest {
         verify(handlerContext).write(databasePacket);
         verify(handlerContext).flush();
         verify(databaseConnectionManager).closeExecutionResources();
+        logCaptureAssertion.assertErrorLog(actualException -> {
+            assertThat(actualException.getClassName(), is(RuntimeException.class.getName()));
+            assertThat(((ThrowableProxy) actualException).getThrowable().getCause(), sameInstance(expectedError));
+        });
     }
     
     @Test
-    void assertRunWithErrorAndCloseSQLException() throws SQLException {
+    void assertRunWithErrorAndCloseSQLException(final LogCaptureAssertion logCaptureAssertion) throws SQLException {
         mockProxyContext(false);
         Error expectedError = new OutOfMemoryError("foo_execute");
         SQLException expectedCloseException = new SQLException("bar_close");
@@ -286,6 +306,7 @@ class CommandExecutorTaskTest {
         assertThat(expectedError.getSuppressed().length, is(1));
         assertThat(expectedError.getSuppressed()[0], is(expectedCloseException));
         verify(commandExecutor).close();
+        logCaptureAssertion.assertErrorLog(actualLogException -> assertThat(((ThrowableProxy) actualLogException).getThrowable(), sameInstance(actualException)));
     }
     
     private void mockProxyContext(final boolean sqlShowEnabled) {
diff --git a/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandlerTest.java b/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandlerTest.java
index 9574ff6f11d..3602b368cfb 100644
--- a/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandlerTest.java
+++ b/proxy/frontend/core/src/test/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandlerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.proxy.frontend.netty;
 
+import ch.qos.logback.classic.spi.ThrowableProxy;
 import com.google.common.util.concurrent.MoreExecutors;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
@@ -48,6 +49,9 @@ import org.apache.shardingsphere.proxy.frontend.executor.ConnectionThreadExecuto
 import org.apache.shardingsphere.proxy.frontend.executor.UserExecutorGroup;
 import org.apache.shardingsphere.proxy.frontend.spi.DatabaseProtocolFrontendEngine;
 import org.apache.shardingsphere.proxy.frontend.state.ProxyStateContext;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureAssertion;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureExtension;
+import org.apache.shardingsphere.test.infra.framework.extension.log.LogCaptureSettings;
 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;
@@ -70,6 +74,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -83,7 +88,8 @@ import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(AutoMockExtension.class)
+@ExtendWith({AutoMockExtension.class, LogCaptureExtension.class})
+@LogCaptureSettings(suppressOutput = true)
 @StaticMockSettings({ProxyContext.class, ProcessRegistry.class})
 class FrontendChannelInboundHandlerTest {
     
@@ -174,7 +180,7 @@ class FrontendChannelInboundHandlerTest {
     }
     
     @Test
-    void assertChannelReadNotAuthenticatedAndExceptionOccur() throws Exception {
+    void assertChannelReadNotAuthenticatedAndExceptionOccur(final LogCaptureAssertion logCaptureAssertion) throws Exception {
         channel.register();
         RuntimeException cause = new RuntimeException("assertChannelReadNotAuthenticatedAndExceptionOccur");
         doThrow(cause).when(authenticationEngine).authenticate(any(ChannelHandlerContext.class), any(PacketPayload.class));
@@ -182,12 +188,14 @@ class FrontendChannelInboundHandlerTest {
         when(frontendEngine.getCommandExecuteEngine().getErrorPacket(cause)).thenReturn(expectedPacket);
         channel.writeInbound(Unpooled.EMPTY_BUFFER);
         assertThat(channel.readOutbound(), is(expectedPacket));
+        logCaptureAssertion.assertErrorLog(actualException -> assertThat(((ThrowableProxy) actualException).getThrowable(), sameInstance(cause)));
     }
     
     @Test
-    void assertChannelInactiveWithUnexpectedException() throws Exception {
+    void assertChannelInactiveWithUnexpectedException(final LogCaptureAssertion logCaptureAssertion) throws Exception {
         ProxyDatabaseConnectionManager databaseConnectionManager = mock(ProxyDatabaseConnectionManager.class);
-        when(databaseConnectionManager.closeAllResources()).thenReturn(Collections.singleton(new SQLException("assertChannelInactiveWithUnexpectedException")));
+        SQLException expectedException = new SQLException("assertChannelInactiveWithUnexpectedException");
+        when(databaseConnectionManager.closeAllResources()).thenReturn(Collections.singleton(expectedException));
         setDatabaseConnectionManager(databaseConnectionManager);
         ProcessEngine processEngine = mock(ProcessEngine.class);
         setProcessEngine(processEngine);
@@ -209,6 +217,10 @@ class FrontendChannelInboundHandlerTest {
             verify(frontendEngine).release(connectionSession);
         }
         executorService.shutdownNow();
+        logCaptureAssertion.assertErrorLog(actualException -> {
+            SQLException actualSQLException = (SQLException) ((ThrowableProxy) actualException).getThrowable();
+            assertThat(actualSQLException.getNextException(), sameInstance(expectedException));
+        });
     }
     
     @Test