From 8525e87e04505f5115315d24b9cabb6990639988 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 1 Nov 2023 21:25:44 +0200 Subject: [PATCH] Ignore threads created by Testcontainers --- .../tests/ThreadLeakDetectorListener.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/buildtools/src/main/java/org/apache/pulsar/tests/ThreadLeakDetectorListener.java b/buildtools/src/main/java/org/apache/pulsar/tests/ThreadLeakDetectorListener.java index 0f9bc228b3efbd..189c1a71efde12 100644 --- a/buildtools/src/main/java/org/apache/pulsar/tests/ThreadLeakDetectorListener.java +++ b/buildtools/src/main/java/org/apache/pulsar/tests/ThreadLeakDetectorListener.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.Field; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Collections; @@ -56,6 +57,16 @@ public class ThreadLeakDetectorListener extends BetweenTestClassesListenerAdapte private Set capturedThreadKeys; + private static Field THREAD_TARGET_FIELD; + static { + try { + THREAD_TARGET_FIELD = Thread.class.getDeclaredField("target"); + THREAD_TARGET_FIELD.setAccessible(true); + } catch (NoSuchFieldException e) { + LOG.warn("Cannot find target field in Thread.class", e); + THREAD_TARGET_FIELD = null; + } + } @Override protected void onBetweenTestClasses(Class endedTestClass, Class startedTestClass) { @@ -206,6 +217,19 @@ private static boolean shouldSkipThread(Thread thread) { return true; } } + Runnable target = null; + try { + target = (Runnable) THREAD_TARGET_FIELD.get(thread); + } catch (IllegalAccessException e) { + LOG.warn("Cannot access target field in Thread.class", e); + } + if (target != null) { + String targetClassName = target.getClass().getName(); + // ignore threads created by Testcontainers + if (targetClassName.startsWith("org.testcontainers.")) { + return true; + } + } return false; }