From e858d8e6586632a36b925251d5101e5ef8fa6cd8 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Fri, 25 Jul 2025 15:36:04 -0400 Subject: [PATCH 01/22] Attempt to debug CI flaky timeout. DO NOT MERGE! --- .../groovy/StructuredConcurrencyTest.groovy | 26 +++++++++++++++++++ .../test/groovy/Lettuce4ClientTestBase.groovy | 23 ++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 0c0280afbaf..c67a400766d 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -2,13 +2,39 @@ import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.Trace import java.util.concurrent.Callable +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.ScheduledFuture import java.util.concurrent.StructuredTaskScope +import java.util.concurrent.TimeUnit import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace import static datadog.trace.agent.test.utils.TraceUtils.runnableUnderTrace import static java.time.Instant.now class StructuredConcurrencyTest extends AgentTestRunner { + ScheduledExecutorService scheduler + ScheduledFuture threadDumpTask + + def setup() { + scheduler = Executors.newSingleThreadScheduledExecutor() + + threadDumpTask = scheduler.schedule({ + println "=== Thread Dump Triggered at ${new Date()} ===" + Thread.getAllStackTraces().each { thread, stack -> + println "Thread: ${thread.name}, daemon: ${thread.daemon}" + stack.each { println "\tat ${it}" } + } + println "===============================================" + }, 7, TimeUnit.MINUTES) + } + + def cleanup() { + threadDumpTask?.cancel(false) + scheduler?.shutdownNow() + } + + /** * Tests the structured task scope with a single task. */ diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 6d178e33622..b13b9cad1a5 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -8,6 +8,11 @@ import datadog.trace.agent.test.utils.PortUtils import redis.embedded.RedisServer import spock.lang.Shared +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.ScheduledFuture +import java.util.concurrent.TimeUnit + import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { @@ -32,6 +37,9 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { @Shared RedisServer redisServer + ScheduledExecutorService scheduler + ScheduledFuture threadDumpTask + @Shared Map testHashMap = [ firstname: "John", @@ -61,6 +69,18 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } def setup() { + scheduler = Executors.newSingleThreadScheduledExecutor() + + threadDumpTask = scheduler.schedule({ + println "=== Thread Dump Triggered at ${new Date()} ===" + Thread.getAllStackTraces().each { thread, stack -> + println "Thread: ${thread.name}, daemon: ${thread.daemon}" + stack.each { println "\tat ${it}" } + } + println "===============================================" + }, 7, TimeUnit.MINUTES) + + redisServer.start() redisClient = RedisClient.create(embeddedDbUri) @@ -79,6 +99,9 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } def cleanup() { + threadDumpTask?.cancel(false) + scheduler?.shutdownNow() + connection.close() redisClient.shutdown() redisServer.stop() From 99bf38c75bae8d7ee71912cc685fb289965f5434 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Mon, 28 Jul 2025 10:26:26 -0400 Subject: [PATCH 02/22] Attempt to collect thread dump. --- .../groovy/StructuredConcurrencyTest.groovy | 35 +++++++++++++------ .../test/groovy/Lettuce4ClientTestBase.groovy | 34 ++++++++++++------ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index c67a400766d..b5a459fdb6c 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -20,12 +20,25 @@ class StructuredConcurrencyTest extends AgentTestRunner { scheduler = Executors.newSingleThreadScheduledExecutor() threadDumpTask = scheduler.schedule({ - println "=== Thread Dump Triggered at ${new Date()} ===" - Thread.getAllStackTraces().each { thread, stack -> - println "Thread: ${thread.name}, daemon: ${thread.daemon}" - stack.each { println "\tat ${it}" } + File reportDir = new File("build/reports") + + // Ensure the directory exists + if (!reportDir.exists()) { + reportDir.mkdirs() + } + + // Define the file path + File reportFile = new File(reportDir, String.format("thread-dump-%d.log", System.currentTimeMillis())) + + // Write to the file + try (FileWriter writer = new FileWriter(reportFile)) { + writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") + Thread.getAllStackTraces().each { thread, stack -> + writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") + stack.each { writer.write("\tat ${it}\n") } + } + writer.write("==============================================\n") } - println "===============================================" }, 7, TimeUnit.MINUTES) } @@ -46,12 +59,12 @@ class StructuredConcurrencyTest extends AgentTestRunner { when: runUnderTrace("parent") { def task = taskScope.fork(new Callable() { - @Trace(operationName = "child") - @Override - Boolean call() throws Exception { - return true - } - }) + @Trace(operationName = "child") + @Override + Boolean call() throws Exception { + return true + } + }) taskScope.joinUntil(now() + 10) // Wait for 10 seconds at maximum result = task.get() } diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index b13b9cad1a5..16543649cbc 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -61,25 +61,37 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { embeddedDbUri = "redis://" + dbAddr redisServer = RedisServer.newRedisServer() - // bind to localhost to avoid firewall popup - .setting("bind " + HOST) - // set max memory to avoid problems in CI - .setting("maxmemory 128M") - .port(port).build() + // bind to localhost to avoid firewall popup + .setting("bind " + HOST) + // set max memory to avoid problems in CI + .setting("maxmemory 128M") + .port(port).build() } def setup() { scheduler = Executors.newSingleThreadScheduledExecutor() threadDumpTask = scheduler.schedule({ - println "=== Thread Dump Triggered at ${new Date()} ===" - Thread.getAllStackTraces().each { thread, stack -> - println "Thread: ${thread.name}, daemon: ${thread.daemon}" - stack.each { println "\tat ${it}" } + File reportDir = new File("build/reports") + + // Ensure the directory exists + if (!reportDir.exists()) { + reportDir.mkdirs() } - println "===============================================" - }, 7, TimeUnit.MINUTES) + // Define the file path + File reportFile = new File(reportDir, String.format("thread-dump-%d.log", System.currentTimeMillis())) + + // Write to the file + try (FileWriter writer = new FileWriter(reportFile)) { + writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") + Thread.getAllStackTraces().each { thread, stack -> + writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") + stack.each { writer.write("\tat ${it}\n") } + } + writer.write("==============================================\n") + } + }, 7, TimeUnit.MINUTES) redisServer.start() From 057d106626c02ea069f08bc858a3df2df8ebc8bd Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Mon, 28 Jul 2025 12:18:40 -0400 Subject: [PATCH 03/22] Attempt to collect thread dump. --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 2 +- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index b5a459fdb6c..f3b46bff36b 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -39,7 +39,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 7, TimeUnit.MINUTES) + }, 1, TimeUnit.MILLISECONDS) } def cleanup() { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 16543649cbc..8ec026eeb1c 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -91,7 +91,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 7, TimeUnit.MINUTES) + }, 1, TimeUnit.MILLISECONDS) redisServer.start() From d338595ffb5e073ceb290d6934af2206b707f76f Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Mon, 28 Jul 2025 12:45:31 -0400 Subject: [PATCH 04/22] Attempt to collect thread dump. --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index f3b46bff36b..39c0f4a7933 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -57,6 +57,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { def result = false when: + Thread.sleep(100) runUnderTrace("parent") { def task = taskScope.fork(new Callable() { @Trace(operationName = "child") From 119f5290ba59b7e59c8d30e18593f83503539b34 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 29 Jul 2025 13:02:10 -0400 Subject: [PATCH 05/22] Another attempt. --- .gitlab/collect_reports.sh | 1 + .../previewTest/groovy/StructuredConcurrencyTest.groovy | 9 +++++---- .../src/test/groovy/Lettuce4ClientTestBase.groovy | 9 +++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.gitlab/collect_reports.sh b/.gitlab/collect_reports.sh index 83c3d99d38a..41967b27278 100755 --- a/.gitlab/collect_reports.sh +++ b/.gitlab/collect_reports.sh @@ -62,6 +62,7 @@ function process_reports () { cp -r workspace/$project_to_save/build/reports/* $report_path/ 2>/dev/null || true cp workspace/$project_to_save/build/hs_err_pid*.log $report_path/ 2>/dev/null || true cp workspace/$project_to_save/build/javacore*.txt $report_path/ 2>/dev/null || true + cp workspace/$project_to_save/build/thread-dump-*.log $report_path/ 2>/dev/null || true fi } diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 39c0f4a7933..2dd4ab4b877 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -19,12 +19,13 @@ class StructuredConcurrencyTest extends AgentTestRunner { def setup() { scheduler = Executors.newSingleThreadScheduledExecutor() - threadDumpTask = scheduler.schedule({ - File reportDir = new File("build/reports") + threadDumpTask = scheduler.scheduleAtFixedRate({ + File reportDir = new File("build") // Ensure the directory exists if (!reportDir.exists()) { - reportDir.mkdirs() + println("build folder not found") + return } // Define the file path @@ -39,7 +40,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 1, TimeUnit.MILLISECONDS) + }, 10, 60_000, TimeUnit.MILLISECONDS) } def cleanup() { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 8ec026eeb1c..282d8d49e5a 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -71,12 +71,13 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { def setup() { scheduler = Executors.newSingleThreadScheduledExecutor() - threadDumpTask = scheduler.schedule({ - File reportDir = new File("build/reports") + threadDumpTask = scheduler.scheduleAtFixedRate({ + File reportDir = new File("build") // Ensure the directory exists if (!reportDir.exists()) { - reportDir.mkdirs() + println("build folder not found") + return } // Define the file path @@ -91,7 +92,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 1, TimeUnit.MILLISECONDS) + }, 10, 60_000, TimeUnit.MILLISECONDS) redisServer.start() From bbe67ef8efb3692b69b8d83d0f2d5aca42880781 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 29 Jul 2025 13:38:55 -0400 Subject: [PATCH 06/22] Another attempt. --- .../groovy/StructuredConcurrencyTest.groovy | 16 ++++++++++++---- .../test/groovy/Lettuce4ClientTestBase.groovy | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 2dd4ab4b877..60d9f9eb66e 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -21,8 +21,8 @@ class StructuredConcurrencyTest extends AgentTestRunner { threadDumpTask = scheduler.scheduleAtFixedRate({ File reportDir = new File("build") + println("DEBUG: " + reportDir.absolutePath) - // Ensure the directory exists if (!reportDir.exists()) { println("build folder not found") return @@ -33,10 +33,18 @@ class StructuredConcurrencyTest extends AgentTestRunner { // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { - writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") + def s = "=== Thread Dump Triggered at ${new Date()} ===\n" + println(s) + writer.write(s) Thread.getAllStackTraces().each { thread, stack -> - writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") - stack.each { writer.write("\tat ${it}\n") } + def t = "Thread: ${thread.name}, daemon: ${thread.daemon}\n" + println(t) + writer.write(t) + stack.each { + def st = "\tat ${it}\n" + println(st) + writer.write(st) + } } writer.write("==============================================\n") } diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 282d8d49e5a..5b83e5311bf 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -73,8 +73,8 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { threadDumpTask = scheduler.scheduleAtFixedRate({ File reportDir = new File("build") + println("DEBUG: " + reportDir.absolutePath) - // Ensure the directory exists if (!reportDir.exists()) { println("build folder not found") return @@ -85,10 +85,18 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { - writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") + def s = "=== Thread Dump Triggered at ${new Date()} ===\n" + println(s) + writer.write(s) Thread.getAllStackTraces().each { thread, stack -> - writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") - stack.each { writer.write("\tat ${it}\n") } + def t = "Thread: ${thread.name}, daemon: ${thread.daemon}\n" + println(t) + writer.write(t) + stack.each { + def st = "\tat ${it}\n" + println(st) + writer.write(st) + } } writer.write("==============================================\n") } From 9e8a13e52718d7b86b5679af61a62fb862c4aae9 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 30 Jul 2025 15:47:58 -0400 Subject: [PATCH 07/22] Attempt to specify full path --- .../previewTest/groovy/StructuredConcurrencyTest.groovy | 7 ++++--- .../src/test/groovy/Lettuce4ClientTestBase.groovy | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 60d9f9eb66e..33379c09813 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -21,15 +21,16 @@ class StructuredConcurrencyTest extends AgentTestRunner { threadDumpTask = scheduler.scheduleAtFixedRate({ File reportDir = new File("build") - println("DEBUG: " + reportDir.absolutePath) + String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", + "dd-trace-java/workspace/dd-java-agent") if (!reportDir.exists()) { - println("build folder not found") + println("Folder not found: " + fullPath) return } // Define the file path - File reportFile = new File(reportDir, String.format("thread-dump-%d.log", System.currentTimeMillis())) + File reportFile = new File(fullPath, String.format("thread-dump-%d.log", System.currentTimeMillis())) // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 5b83e5311bf..aca7c07c7f6 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -73,18 +73,20 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { threadDumpTask = scheduler.scheduleAtFixedRate({ File reportDir = new File("build") - println("DEBUG: " + reportDir.absolutePath) + String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", + "dd-trace-java/workspace/dd-java-agent") if (!reportDir.exists()) { - println("build folder not found") + println("Folder not found: " + fullPath) return } // Define the file path - File reportFile = new File(reportDir, String.format("thread-dump-%d.log", System.currentTimeMillis())) + File reportFile = new File(fullPath, String.format("thread-dump-%d.log", System.currentTimeMillis())) // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { + println() def s = "=== Thread Dump Triggered at ${new Date()} ===\n" println(s) writer.write(s) From 88dcfa39605b7adc04243d34ac2769d5d494a89f Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 30 Jul 2025 19:52:32 -0400 Subject: [PATCH 08/22] Attempt to specify full path --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 3 ++- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 33379c09813..8a3c0ee71e9 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -24,9 +24,10 @@ class StructuredConcurrencyTest extends AgentTestRunner { String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", "dd-trace-java/workspace/dd-java-agent") + reportDir = new File(fullPath) if (!reportDir.exists()) { println("Folder not found: " + fullPath) - return + reportDir.mkdirs() } // Define the file path diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index aca7c07c7f6..b292a288c39 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -76,9 +76,10 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", "dd-trace-java/workspace/dd-java-agent") + reportDir = new File(fullPath) if (!reportDir.exists()) { println("Folder not found: " + fullPath) - return + reportDir.mkdirs() } // Define the file path From 9d9f1615a57b7d526e03f4b9601d988dbe5faf55 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 30 Jul 2025 21:17:36 -0400 Subject: [PATCH 09/22] Cleanup --- .../groovy/StructuredConcurrencyTest.groovy | 12 ++++-------- .../src/test/groovy/Lettuce4ClientTestBase.groovy | 13 ++++--------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 8a3c0ee71e9..3097f2f0563 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -35,22 +35,18 @@ class StructuredConcurrencyTest extends AgentTestRunner { // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { - def s = "=== Thread Dump Triggered at ${new Date()} ===\n" println(s) - writer.write(s) + writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") Thread.getAllStackTraces().each { thread, stack -> - def t = "Thread: ${thread.name}, daemon: ${thread.daemon}\n" println(t) - writer.write(t) + writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") stack.each { - def st = "\tat ${it}\n" - println(st) - writer.write(st) + writer.write("\tat ${it}\n") } } writer.write("==============================================\n") } - }, 10, 60_000, TimeUnit.MILLISECONDS) + }, 60_000, 60_000, TimeUnit.MILLISECONDS) } def cleanup() { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index b292a288c39..77462be2f21 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -87,23 +87,18 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { - println() - def s = "=== Thread Dump Triggered at ${new Date()} ===\n" println(s) - writer.write(s) + writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") Thread.getAllStackTraces().each { thread, stack -> - def t = "Thread: ${thread.name}, daemon: ${thread.daemon}\n" println(t) - writer.write(t) + writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") stack.each { - def st = "\tat ${it}\n" - println(st) - writer.write(st) + writer.write("\tat ${it}\n") } } writer.write("==============================================\n") } - }, 10, 60_000, TimeUnit.MILLISECONDS) + }, 60_000, 60_000, TimeUnit.MILLISECONDS) redisServer.start() From 84290621a5bb63661cdc53abc3a16eb28c82423b Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 30 Jul 2025 22:52:00 -0400 Subject: [PATCH 10/22] One more try --- .../groovy/StructuredConcurrencyTest.groovy | 26 +++++++++---------- .../test/groovy/Lettuce4ClientTestBase.groovy | 26 +++++++++---------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 3097f2f0563..31a29bddf6e 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -17,28 +17,26 @@ class StructuredConcurrencyTest extends AgentTestRunner { ScheduledFuture threadDumpTask def setup() { - scheduler = Executors.newSingleThreadScheduledExecutor() + File reportDir = new File("build") + String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", + "dd-trace-java/workspace/dd-java-agent") + + reportDir = new File(fullPath) + if (!reportDir.exists()) { + println("Folder not found: " + fullPath) + reportDir.mkdirs() + } + else println("Folder found: " + fullPath) + scheduler = Executors.newSingleThreadScheduledExecutor() threadDumpTask = scheduler.scheduleAtFixedRate({ - File reportDir = new File("build") - String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", - "dd-trace-java/workspace/dd-java-agent") - - reportDir = new File(fullPath) - if (!reportDir.exists()) { - println("Folder not found: " + fullPath) - reportDir.mkdirs() - } - // Define the file path File reportFile = new File(fullPath, String.format("thread-dump-%d.log", System.currentTimeMillis())) // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { - println(s) writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") Thread.getAllStackTraces().each { thread, stack -> - println(t) writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") stack.each { writer.write("\tat ${it}\n") @@ -46,7 +44,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 60_000, 60_000, TimeUnit.MILLISECONDS) + }, 10, 60_000, TimeUnit.MILLISECONDS) } def cleanup() { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 77462be2f21..753ab542b9f 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -69,28 +69,26 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } def setup() { - scheduler = Executors.newSingleThreadScheduledExecutor() + File reportDir = new File("build") + String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", + "dd-trace-java/workspace/dd-java-agent") + + reportDir = new File(fullPath) + if (!reportDir.exists()) { + println("Folder not found: " + fullPath) + reportDir.mkdirs() + } + else println("Folder found: " + fullPath) + scheduler = Executors.newSingleThreadScheduledExecutor() threadDumpTask = scheduler.scheduleAtFixedRate({ - File reportDir = new File("build") - String fullPath = reportDir.absolutePath.replace("dd-trace-java/dd-java-agent", - "dd-trace-java/workspace/dd-java-agent") - - reportDir = new File(fullPath) - if (!reportDir.exists()) { - println("Folder not found: " + fullPath) - reportDir.mkdirs() - } - // Define the file path File reportFile = new File(fullPath, String.format("thread-dump-%d.log", System.currentTimeMillis())) // Write to the file try (FileWriter writer = new FileWriter(reportFile)) { - println(s) writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") Thread.getAllStackTraces().each { thread, stack -> - println(t) writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") stack.each { writer.write("\tat ${it}\n") @@ -98,7 +96,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 60_000, 60_000, TimeUnit.MILLISECONDS) + }, 10, 60_000, TimeUnit.MILLISECONDS) redisServer.start() From d58d75b940d290182f823e0f374cab326e088ba8 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Fri, 1 Aug 2025 13:00:03 -0400 Subject: [PATCH 11/22] Added test info to dump. --- .../groovy/StructuredConcurrencyTest.groovy | 65 +++++++++++------- .../test/groovy/Lettuce4ClientTestBase.groovy | 66 ++++++++++++------- 2 files changed, 83 insertions(+), 48 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 31a29bddf6e..9137fc84766 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -13,8 +13,7 @@ import static datadog.trace.agent.test.utils.TraceUtils.runnableUnderTrace import static java.time.Instant.now class StructuredConcurrencyTest extends AgentTestRunner { - ScheduledExecutorService scheduler - ScheduledFuture threadDumpTask + ThreadDumpLogger threadDumpLogger def setup() { File reportDir = new File("build") @@ -25,31 +24,17 @@ class StructuredConcurrencyTest extends AgentTestRunner { if (!reportDir.exists()) { println("Folder not found: " + fullPath) reportDir.mkdirs() - } - else println("Folder found: " + fullPath) - - scheduler = Executors.newSingleThreadScheduledExecutor() - threadDumpTask = scheduler.scheduleAtFixedRate({ - // Define the file path - File reportFile = new File(fullPath, String.format("thread-dump-%d.log", System.currentTimeMillis())) - - // Write to the file - try (FileWriter writer = new FileWriter(reportFile)) { - writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") - Thread.getAllStackTraces().each { thread, stack -> - writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") - stack.each { - writer.write("\tat ${it}\n") - } - } - writer.write("==============================================\n") - } - }, 10, 60_000, TimeUnit.MILLISECONDS) + } else println("Folder found: " + fullPath) + + // Use the current feature name as the test name + String testName = "${specificationContext?.currentSpec?.name ?: "unknown-spec"} : ${specificationContext?.currentFeature?.name ?: "unknown-test"}" + + threadDumpLogger = new ThreadDumpLogger(testName, reportDir) + threadDumpLogger.start() } def cleanup() { - threadDumpTask?.cancel(false) - scheduler?.shutdownNow() + threadDumpLogger.stop() } @@ -209,4 +194,36 @@ class StructuredConcurrencyTest extends AgentTestRunner { } } } + // 🔒 Private helper class for thread dump logging + private static class ThreadDumpLogger { + private final String testName + private final File outputDir + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor() + private ScheduledFuture task + + ThreadDumpLogger(String testName, File outputDir) { + this.testName = testName + this.outputDir = outputDir + } + + void start() { + task = scheduler.scheduleAtFixedRate({ + def reportFile = new File(outputDir, "thread-dump-${System.currentTimeMillis()}.log") + try (def writer = new FileWriter(reportFile)) { + writer.write("=== Test: ${testName} ===\n") + writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") + Thread.getAllStackTraces().each { thread, stack -> + writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") + stack.each { writer.write("\tat ${it}\n") } + } + writer.write("==============================================\n") + } + }, 10000, 60000, TimeUnit.MILLISECONDS) + } + + void stop() { + task?.cancel(false) + scheduler.shutdownNow() + } + } } diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 753ab542b9f..4024e74aa12 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -37,8 +37,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { @Shared RedisServer redisServer - ScheduledExecutorService scheduler - ScheduledFuture threadDumpTask + ThreadDumpLogger threadDumpLogger @Shared Map testHashMap = [ @@ -77,26 +76,13 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { if (!reportDir.exists()) { println("Folder not found: " + fullPath) reportDir.mkdirs() - } - else println("Folder found: " + fullPath) - - scheduler = Executors.newSingleThreadScheduledExecutor() - threadDumpTask = scheduler.scheduleAtFixedRate({ - // Define the file path - File reportFile = new File(fullPath, String.format("thread-dump-%d.log", System.currentTimeMillis())) - - // Write to the file - try (FileWriter writer = new FileWriter(reportFile)) { - writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") - Thread.getAllStackTraces().each { thread, stack -> - writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") - stack.each { - writer.write("\tat ${it}\n") - } - } - writer.write("==============================================\n") - } - }, 10, 60_000, TimeUnit.MILLISECONDS) + } else println("Folder found: " + fullPath) + + // Use the current feature name as the test name + String testName = "${specificationContext?.currentSpec?.name ?: "unknown-spec"} : ${specificationContext?.currentFeature?.name ?: "unknown-test"}" + + threadDumpLogger = new ThreadDumpLogger(testName, reportDir) + threadDumpLogger.start() redisServer.start() @@ -116,11 +102,43 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } def cleanup() { - threadDumpTask?.cancel(false) - scheduler?.shutdownNow() + threadDumpLogger.stop() connection.close() redisClient.shutdown() redisServer.stop() } + + // 🔒 Private helper class for thread dump logging + private static class ThreadDumpLogger { + private final String testName + private final File outputDir + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor() + private ScheduledFuture task + + ThreadDumpLogger(String testName, File outputDir) { + this.testName = testName + this.outputDir = outputDir + } + + void start() { + task = scheduler.scheduleAtFixedRate({ + def reportFile = new File(outputDir, "thread-dump-${System.currentTimeMillis()}.log") + try (def writer = new FileWriter(reportFile)) { + writer.write("=== Test: ${testName} ===\n") + writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") + Thread.getAllStackTraces().each { thread, stack -> + writer.write("Thread: ${thread.name}, daemon: ${thread.daemon}\n") + stack.each { writer.write("\tat ${it}\n") } + } + writer.write("==============================================\n") + } + }, 10000, 60000, TimeUnit.MILLISECONDS) + } + + void stop() { + task?.cancel(false) + scheduler.shutdownNow() + } + } } From 1f22349d8871a9aebb40e620371d134b83c080f5 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Sun, 3 Aug 2025 14:16:07 -0400 Subject: [PATCH 12/22] One more try --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 2 +- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 9137fc84766..f3b2a7f33a1 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -218,7 +218,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 10000, 60000, TimeUnit.MILLISECONDS) + }, 10001, 60001, TimeUnit.MILLISECONDS) } void stop() { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 4024e74aa12..f5c09783499 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -133,7 +133,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 10000, 60000, TimeUnit.MILLISECONDS) + }, 10001, 60000, TimeUnit.MILLISECONDS) } void stop() { From 8539c897bfdbba6bd79f169bed3b2470160c5b28 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Mon, 4 Aug 2025 17:15:03 -0400 Subject: [PATCH 13/22] Try to fix test freeze by updating logback version. --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index add010d57a4..46a936a565d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ spock = "2.3-groovy-3.0" spock24 = "2.4-M6-groovy-3.0" groovy = "3.0.24" junit5 = "5.9.2" -logback = "1.2.3" +logback = "1.3.15" bytebuddy = "1.17.5" scala = "2.11.12" # Last version to support Java 7 (2.12+ require Java 8+) scala211 = "2.11.12" From e18624868c5c663d02b3f571d99f5f4e7cc4be82 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Mon, 4 Aug 2025 18:02:56 -0400 Subject: [PATCH 14/22] Try to fix test freeze by updating logback version to 1.2.9. --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 46a936a565d..ede7f97e707 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ spock = "2.3-groovy-3.0" spock24 = "2.4-M6-groovy-3.0" groovy = "3.0.24" junit5 = "5.9.2" -logback = "1.3.15" +logback = "1.2.9" bytebuddy = "1.17.5" scala = "2.11.12" # Last version to support Java 7 (2.12+ require Java 8+) scala211 = "2.11.12" From ffa412c265b5ba590afb95937d051ff4a584e71f Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 5 Aug 2025 11:14:08 -0400 Subject: [PATCH 15/22] Added heap dump --- .../groovy/StructuredConcurrencyTest.groovy | 20 +++++++++++++++++-- .../test/groovy/Lettuce4ClientTestBase.groovy | 20 +++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index f3b2a7f33a1..357ff30ebe6 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -1,6 +1,9 @@ +import com.sun.management.HotSpotDiagnosticMXBean import datadog.trace.agent.test.AgentTestRunner import datadog.trace.api.Trace +import javax.management.MBeanServer +import java.lang.management.ManagementFactory import java.util.concurrent.Callable import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService @@ -207,8 +210,13 @@ class StructuredConcurrencyTest extends AgentTestRunner { } void start() { + new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName + heapDump("initial") + task = scheduler.scheduleAtFixedRate({ - def reportFile = new File(outputDir, "thread-dump-${System.currentTimeMillis()}.log") + heapDump("test") + + def reportFile = new File(outputDir, "${System.currentTimeMillis()}-thread-dump.log") try (def writer = new FileWriter(reportFile)) { writer.write("=== Test: ${testName} ===\n") writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") @@ -218,7 +226,15 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 10001, 60001, TimeUnit.MILLISECONDS) + }, 10000, 60000, TimeUnit.MILLISECONDS) + } + + void heapDump(String kind) { + def heapDumpFile = new File(outputDir, "${System.currentTimeMillis()}-heap-dump-${kind}.hprof").absolutePath + MBeanServer server = ManagementFactory.getPlatformMBeanServer() + HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy( + server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class) + mxBean.dumpHeap(heapDumpFile, true) } void stop() { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index f5c09783499..37e6e35b8a1 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -3,11 +3,14 @@ import com.lambdaworks.redis.RedisClient import com.lambdaworks.redis.api.StatefulConnection import com.lambdaworks.redis.api.async.RedisAsyncCommands import com.lambdaworks.redis.api.sync.RedisCommands +import com.sun.management.HotSpotDiagnosticMXBean import datadog.trace.agent.test.naming.VersionedNamingTestBase import datadog.trace.agent.test.utils.PortUtils import redis.embedded.RedisServer import spock.lang.Shared +import javax.management.MBeanServer +import java.lang.management.ManagementFactory import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture @@ -122,8 +125,13 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } void start() { + new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName + heapDump("initial") + task = scheduler.scheduleAtFixedRate({ - def reportFile = new File(outputDir, "thread-dump-${System.currentTimeMillis()}.log") + heapDump("test") + + def reportFile = new File(outputDir, "${System.currentTimeMillis()}-thread-dump.log") try (def writer = new FileWriter(reportFile)) { writer.write("=== Test: ${testName} ===\n") writer.write("=== Thread Dump Triggered at ${new Date()} ===\n") @@ -133,7 +141,15 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 10001, 60000, TimeUnit.MILLISECONDS) + }, 10000, 60000, TimeUnit.MILLISECONDS) + } + + void heapDump(String kind) { + def heapDumpFile = new File(outputDir, "${System.currentTimeMillis()}-heap-dump-${kind}.hprof").absolutePath + MBeanServer server = ManagementFactory.getPlatformMBeanServer() + HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy( + server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class) + mxBean.dumpHeap(heapDumpFile, true) } void stop() { From 48e34d7306bea26024b3e67af0f6ba04efe3ae3d Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 5 Aug 2025 12:24:58 -0400 Subject: [PATCH 16/22] Fixed report script --- .gitlab/collect_reports.sh | 2 +- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 2 +- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab/collect_reports.sh b/.gitlab/collect_reports.sh index 41967b27278..1b30beb6a6e 100755 --- a/.gitlab/collect_reports.sh +++ b/.gitlab/collect_reports.sh @@ -62,7 +62,7 @@ function process_reports () { cp -r workspace/$project_to_save/build/reports/* $report_path/ 2>/dev/null || true cp workspace/$project_to_save/build/hs_err_pid*.log $report_path/ 2>/dev/null || true cp workspace/$project_to_save/build/javacore*.txt $report_path/ 2>/dev/null || true - cp workspace/$project_to_save/build/thread-dump-*.log $report_path/ 2>/dev/null || true + cp workspace/$project_to_save/build/*.* $report_path/ 2>/dev/null || true fi } diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 357ff30ebe6..1d61a12de40 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -226,7 +226,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 10000, 60000, TimeUnit.MILLISECONDS) + }, 10001, 60000, TimeUnit.MILLISECONDS) } void heapDump(String kind) { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 37e6e35b8a1..265f3d2a783 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -141,7 +141,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 10000, 60000, TimeUnit.MILLISECONDS) + }, 10001, 60000, TimeUnit.MILLISECONDS) } void heapDump(String kind) { From 892be196afa6253dcd09f1c32ba3fbd39fec1b90 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 5 Aug 2025 14:26:14 -0400 Subject: [PATCH 17/22] Another attempt. --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 1 - .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 1 - 2 files changed, 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 1d61a12de40..83e37349069 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -211,7 +211,6 @@ class StructuredConcurrencyTest extends AgentTestRunner { void start() { new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName - heapDump("initial") task = scheduler.scheduleAtFixedRate({ heapDump("test") diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 265f3d2a783..b00ab6900cb 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -126,7 +126,6 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { void start() { new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName - heapDump("initial") task = scheduler.scheduleAtFixedRate({ heapDump("test") From 7518114e768796f65522764ff0ee3919b7d39f01 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 5 Aug 2025 18:07:33 -0400 Subject: [PATCH 18/22] Another attempt. --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 2 +- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 83e37349069..0c5693269e2 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -225,7 +225,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 10001, 60000, TimeUnit.MILLISECONDS) + }, 10002, 60000, TimeUnit.MILLISECONDS) } void heapDump(String kind) { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index b00ab6900cb..105488ded79 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -140,7 +140,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 10001, 60000, TimeUnit.MILLISECONDS) + }, 10002, 60000, TimeUnit.MILLISECONDS) } void heapDump(String kind) { From ab90b231bba2176852bca370edcf49c31d75fdd6 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 5 Aug 2025 18:46:24 -0400 Subject: [PATCH 19/22] Another attempt. --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 2 +- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 0c5693269e2..46c6821e54f 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -210,7 +210,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } void start() { - new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName + // new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName task = scheduler.scheduleAtFixedRate({ heapDump("test") diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 105488ded79..8acf3d20476 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -125,7 +125,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } void start() { - new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName + // new File(outputDir, "${System.currentTimeMillis()}-start-mark.txt") << testName task = scheduler.scheduleAtFixedRate({ heapDump("test") From f0cd3d49ed0a77ec2bd7c7016d670f72625dc96c Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 6 Aug 2025 09:25:14 -0400 Subject: [PATCH 20/22] Another attempt 3. --- .../src/previewTest/groovy/StructuredConcurrencyTest.groovy | 2 +- .../lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy index 46c6821e54f..dcf9ed7543c 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/src/previewTest/groovy/StructuredConcurrencyTest.groovy @@ -225,7 +225,7 @@ class StructuredConcurrencyTest extends AgentTestRunner { } writer.write("==============================================\n") } - }, 10002, 60000, TimeUnit.MILLISECONDS) + }, 10003, 60000, TimeUnit.MILLISECONDS) } void heapDump(String kind) { diff --git a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy index 8acf3d20476..7e1edfea332 100644 --- a/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy +++ b/dd-java-agent/instrumentation/lettuce-4/src/test/groovy/Lettuce4ClientTestBase.groovy @@ -140,7 +140,7 @@ abstract class Lettuce4ClientTestBase extends VersionedNamingTestBase { } writer.write("==============================================\n") } - }, 10002, 60000, TimeUnit.MILLISECONDS) + }, 10003, 60000, TimeUnit.MILLISECONDS) } void heapDump(String kind) { From 901b3a3feb50704a00efb2970670bd8ea48cb818 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 6 Aug 2025 14:10:09 -0400 Subject: [PATCH 21/22] Spock 2.4 --- .../instrumentation/spring-webflux-6/build.gradle | 6 +++--- dd-smoke-tests/apm-tracing-disabled/build.gradle | 3 +++ gradle/libs.versions.toml | 12 ++++-------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/dd-java-agent/instrumentation/spring-webflux-6/build.gradle b/dd-java-agent/instrumentation/spring-webflux-6/build.gradle index c7af51aeaf6..0f21d1a3057 100644 --- a/dd-java-agent/instrumentation/spring-webflux-6/build.gradle +++ b/dd-java-agent/instrumentation/spring-webflux-6/build.gradle @@ -53,7 +53,7 @@ dependencies { } bootTestImplementation project(':dd-java-agent:instrumentation:spring-webflux-5') // our default version of spock is too old - bootTestImplementation libs.bundles.spock24.spring + bootTestImplementation libs.bundles.spock.spring latestDepBootTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '3.+' latestDepBootTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '3.+', { @@ -62,7 +62,7 @@ dependencies { } latestDepBootTestImplementation project(':dd-java-agent:instrumentation:spring-webflux-5') // our default version of spock is too old - latestDepBootTestImplementation libs.bundles.spock24.spring + latestDepBootTestImplementation libs.bundles.spock.spring iastTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-reactor-netty', version: '3.0.0' iastTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-json', version: '3.0.0' @@ -80,6 +80,6 @@ dependencies { iastTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-json', version: '3.0.0' // our default version of spock is too old - iastTestImplementation libs.bundles.spock24.spring + iastTestImplementation libs.bundles.spock.spring } diff --git a/dd-smoke-tests/apm-tracing-disabled/build.gradle b/dd-smoke-tests/apm-tracing-disabled/build.gradle index 6035c46a8b9..36fc3003131 100644 --- a/dd-smoke-tests/apm-tracing-disabled/build.gradle +++ b/dd-smoke-tests/apm-tracing-disabled/build.gradle @@ -19,6 +19,9 @@ dependencies { implementation project(':dd-trace-api') testImplementation project(':dd-smoke-tests') testImplementation(testFixtures(project(":dd-smoke-tests:iast-util"))) + + // Spock 2.4 requires + testRuntimeOnly("org.junit.platform:junit-platform-engine:1.12.2") } tasks.withType(Test).configureEach { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6b797ee41ec..99ad4e669bf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,8 +6,7 @@ okhttp = "3.12.15" # Datadog fork to support Java 7 okhttp-legacy = "[3.0,3.12.12]" # 3.12.x is last version to support Java7 okio = "1.17.6" # Datadog fork -spock = "2.3-groovy-3.0" -spock24 = "2.4-M6-groovy-3.0" +spock = "2.4-M6-groovy-3.0" groovy = "3.0.24" junit5 = "5.9.2" logback = "1.2.13" @@ -64,11 +63,8 @@ aircompressor = { module = 'io.airlift:aircompressor', version = '2.0.2'} # Testing spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" } spock-junit4 = { module = "org.spockframework:spock-junit4", version.ref = "spock" } -objenesis = { module = "org.objenesis:objenesis", version = "3.3" } # Used by Spock for mocking: - -spock24-core = { module = "org.spockframework:spock-core", version.ref = "spock24" } -spock24-junit4 = { module = "org.spockframework:spock-junit4", version.ref = "spock24" } -spock24-spring = { module = "org.spockframework:spock-spring", version = "spock24" } +spock-spring = { module = "org.spockframework:spock-spring", version.ref = "spock" } +objenesis = { module = "org.objenesis:objenesis", version = "3.4" } # Used by Spock for mocking: groovy = { module = "org.codehaus.groovy:groovy-all", version.ref = "groovy" } groovy-yaml = { module = "org.codehaus.groovy:groovy-yaml", version.ref = "groovy" } @@ -107,7 +103,7 @@ asm = ["asm", "asmcommons"] cafe-crypto = ["cafe-crypto-curve25519", "cafe-crypto-ed25519"] # Testing spock = ["spock-core", "spock-junit4", "objenesis"] -spock24-spring = ["spock24-core", "spock24-junit4", "spock24-spring"] +spock-spring = ["spock-core", "spock-junit4", "spock-spring"] junit5 = ["junit-jupiter", "junit-jupiter-params"] mockito = ["mokito-core", "mokito-junit-jupiter", "byte-buddy", "byte-buddy-agent"] test-logging = ["logback-classic", "log4j-over-slf4j", "jcl-over-slf4j", "jul-to-slf4j"] From 9bf1b6bc3a4132fd65503ebe99d2ffbb29e781fc Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 6 Aug 2025 15:29:22 -0400 Subject: [PATCH 22/22] Update Spock only for one module. --- .../java-concurrent-21/build.gradle | 1 + .../instrumentation/spring-webflux-6/build.gradle | 6 +++--- dd-smoke-tests/apm-tracing-disabled/build.gradle | 3 --- gradle/libs.versions.toml | 14 ++++++++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/build.gradle b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/build.gradle index 361477f06ff..66e73501fa8 100644 --- a/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/build.gradle +++ b/dd-java-agent/instrumentation/java-concurrent/java-concurrent-21/build.gradle @@ -46,6 +46,7 @@ tasks.named("check").configure { dependencies { testImplementation project(':dd-java-agent:instrumentation:trace-annotation') + testImplementation libs.bundles.spock24 } // Set all compile tasks to use JDK21 but let instrumentation code targets 1.8 compatibility diff --git a/dd-java-agent/instrumentation/spring-webflux-6/build.gradle b/dd-java-agent/instrumentation/spring-webflux-6/build.gradle index 0f21d1a3057..c7af51aeaf6 100644 --- a/dd-java-agent/instrumentation/spring-webflux-6/build.gradle +++ b/dd-java-agent/instrumentation/spring-webflux-6/build.gradle @@ -53,7 +53,7 @@ dependencies { } bootTestImplementation project(':dd-java-agent:instrumentation:spring-webflux-5') // our default version of spock is too old - bootTestImplementation libs.bundles.spock.spring + bootTestImplementation libs.bundles.spock24.spring latestDepBootTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '3.+' latestDepBootTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '3.+', { @@ -62,7 +62,7 @@ dependencies { } latestDepBootTestImplementation project(':dd-java-agent:instrumentation:spring-webflux-5') // our default version of spock is too old - latestDepBootTestImplementation libs.bundles.spock.spring + latestDepBootTestImplementation libs.bundles.spock24.spring iastTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-reactor-netty', version: '3.0.0' iastTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-json', version: '3.0.0' @@ -80,6 +80,6 @@ dependencies { iastTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-json', version: '3.0.0' // our default version of spock is too old - iastTestImplementation libs.bundles.spock.spring + iastTestImplementation libs.bundles.spock24.spring } diff --git a/dd-smoke-tests/apm-tracing-disabled/build.gradle b/dd-smoke-tests/apm-tracing-disabled/build.gradle index 36fc3003131..6035c46a8b9 100644 --- a/dd-smoke-tests/apm-tracing-disabled/build.gradle +++ b/dd-smoke-tests/apm-tracing-disabled/build.gradle @@ -19,9 +19,6 @@ dependencies { implementation project(':dd-trace-api') testImplementation project(':dd-smoke-tests') testImplementation(testFixtures(project(":dd-smoke-tests:iast-util"))) - - // Spock 2.4 requires - testRuntimeOnly("org.junit.platform:junit-platform-engine:1.12.2") } tasks.withType(Test).configureEach { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 99ad4e669bf..72baad1050a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,8 @@ okhttp = "3.12.15" # Datadog fork to support Java 7 okhttp-legacy = "[3.0,3.12.12]" # 3.12.x is last version to support Java7 okio = "1.17.6" # Datadog fork -spock = "2.4-M6-groovy-3.0" +spock = "2.3-groovy-3.0" +spock24 = "2.4-M6-groovy-3.0" groovy = "3.0.24" junit5 = "5.9.2" logback = "1.2.13" @@ -63,8 +64,12 @@ aircompressor = { module = 'io.airlift:aircompressor', version = '2.0.2'} # Testing spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" } spock-junit4 = { module = "org.spockframework:spock-junit4", version.ref = "spock" } -spock-spring = { module = "org.spockframework:spock-spring", version.ref = "spock" } -objenesis = { module = "org.objenesis:objenesis", version = "3.4" } # Used by Spock for mocking: +objenesis = { module = "org.objenesis:objenesis", version = "3.3" } # Used by Spock for mocking: + +spock24-core = { module = "org.spockframework:spock-core", version.ref = "spock24" } +spock24-junit4 = { module = "org.spockframework:spock-junit4", version.ref = "spock24" } +spock24-spring = { module = "org.spockframework:spock-spring", version.ref = "spock24" } +objenesis34 = { module = "org.objenesis:objenesis", version = "3.4" } groovy = { module = "org.codehaus.groovy:groovy-all", version.ref = "groovy" } groovy-yaml = { module = "org.codehaus.groovy:groovy-yaml", version.ref = "groovy" } @@ -103,7 +108,8 @@ asm = ["asm", "asmcommons"] cafe-crypto = ["cafe-crypto-curve25519", "cafe-crypto-ed25519"] # Testing spock = ["spock-core", "spock-junit4", "objenesis"] -spock-spring = ["spock-core", "spock-junit4", "spock-spring"] +spock24 = ["spock24-core", "spock24-junit4", "objenesis34"] +spock24-spring = ["spock24-core", "spock24-junit4", "spock24-spring"] junit5 = ["junit-jupiter", "junit-jupiter-params"] mockito = ["mokito-core", "mokito-junit-jupiter", "byte-buddy", "byte-buddy-agent"] test-logging = ["logback-classic", "log4j-over-slf4j", "jcl-over-slf4j", "jul-to-slf4j"]