From 3f71147d0aa9823975ec63ed6329d8af40023960 Mon Sep 17 00:00:00 2001 From: Almas Abdrazak Date: Wed, 1 Apr 2026 10:11:57 -0700 Subject: [PATCH 1/2] JAVA-6155 add thread dumps to failed test cases --- .../org.junit.jupiter.api.extension.Extension | 1 + .../test/resources/junit-platform.properties | 1 + .../ThreadDumpOnFailureExtension.java | 57 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 driver-core/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension create mode 100644 driver-core/src/test/resources/junit-platform.properties create mode 100644 driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java diff --git a/driver-core/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/driver-core/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension new file mode 100644 index 0000000000..f862b0ebe8 --- /dev/null +++ b/driver-core/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -0,0 +1 @@ +com.mongodb.internal.diagnostics.ThreadDumpOnFailureExtension diff --git a/driver-core/src/test/resources/junit-platform.properties b/driver-core/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000..6efc0d5e85 --- /dev/null +++ b/driver-core/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.extensions.autodetection.enabled=true diff --git a/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java b/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java new file mode 100644 index 0000000000..a0f465c2f9 --- /dev/null +++ b/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java @@ -0,0 +1,57 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed 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 com.mongodb.internal.diagnostics; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; + + +import com.mongodb.internal.diagnostics.logging.Logger; +import com.mongodb.internal.diagnostics.logging.Loggers; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestWatcher; + + +/** + * A JUnit 5 extension that prints a thread dump to the log when a test fails. + */ +public final class ThreadDumpOnFailureExtension implements TestWatcher { + + private static final Logger LOGGER = Loggers.getLogger(ThreadDumpOnFailureExtension.class.getName()); + + @Override + public void testFailed(final ExtensionContext context, final Throwable cause) { + String testName = context.getDisplayName(); + String threadDump = getAllThreadsDump(); + LOGGER.error("Test failed: " + testName + "\nThread dump:\n" + threadDump); + } + + private static String getAllThreadsDump() { + final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads( + threadMXBean.isObjectMonitorUsageSupported(), + threadMXBean.isSynchronizerUsageSupported() + ); + StringBuilder sb = new StringBuilder(1024); + for (ThreadInfo info : threadInfos) { + sb.append(info); + } + return sb.toString(); + } +} From 8102cec236271a815a86e96d5ca94b31d22ff1a5 Mon Sep 17 00:00:00 2001 From: Almas Abdrazak Date: Wed, 1 Apr 2026 12:00:42 -0700 Subject: [PATCH 2/2] address copilot review --- .../ThreadDumpOnFailureExtension.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java b/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java index a0f465c2f9..99e586cdb1 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java +++ b/driver-core/src/test/unit/com/mongodb/internal/diagnostics/ThreadDumpOnFailureExtension.java @@ -33,7 +33,7 @@ */ public final class ThreadDumpOnFailureExtension implements TestWatcher { - private static final Logger LOGGER = Loggers.getLogger(ThreadDumpOnFailureExtension.class.getName()); + private static final Logger LOGGER = Loggers.getLogger(ThreadDumpOnFailureExtension.class.getSimpleName()); @Override public void testFailed(final ExtensionContext context, final Throwable cause) { @@ -43,15 +43,19 @@ public void testFailed(final ExtensionContext context, final Throwable cause) { } private static String getAllThreadsDump() { - final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads( - threadMXBean.isObjectMonitorUsageSupported(), - threadMXBean.isSynchronizerUsageSupported() - ); - StringBuilder sb = new StringBuilder(1024); - for (ThreadInfo info : threadInfos) { - sb.append(info); + try { + final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads( + threadMXBean.isObjectMonitorUsageSupported(), + threadMXBean.isSynchronizerUsageSupported() + ); + StringBuilder sb = new StringBuilder(1024); + for (ThreadInfo info : threadInfos) { + sb.append(info); + } + return sb.toString(); + } catch (final SecurityException exc) { + return "Unable to get thread dump due to security manager restrictions: " + exc.getMessage(); } - return sb.toString(); } }