From 7c14c0bec9ea65470ed792967bb7fcd8d5fce19c Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 17 Mar 2026 15:55:49 +0100 Subject: [PATCH 1/6] fix: Incorrect test isolation on the test kit folder From https://docs.gradle.org/8.14.4/javadoc/org/gradle/testkit/runner/GradleRunner.html#withTestKitDir(java.io.File) > If no value has been specified when the build is initiated, a directory will be created within a temporary directory. > > * When executed from a Gradle Test task, the Test task's temporary directory is used (see Task.getTemporaryDir()). --- buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt index 3bb1f85f2d5..fce5db321c6 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt @@ -23,7 +23,6 @@ internal open class GradleFixture(protected val projectDir: File) { */ fun run(vararg args: String, expectFailure: Boolean = false, env: Map = emptyMap()): BuildResult { val runner = GradleRunner.create() - .withTestKitDir(File(projectDir, ".gradle-test-kit")) .withPluginClasspath() .withProjectDir(projectDir) .withEnvironment(System.getenv() + env) From 6f9da4c11fea199ffd1b8bf85931537f55922b2e Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 17 Mar 2026 16:09:52 +0100 Subject: [PATCH 2/6] fix: buildSrc result files were never collected --- .gitlab/collect_results.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitlab/collect_results.sh b/.gitlab/collect_results.sh index 1d5027bc811..5991a125902 100755 --- a/.gitlab/collect_results.sh +++ b/.gitlab/collect_results.sh @@ -12,7 +12,13 @@ WORKSPACE_DIR=workspace mkdir -p $TEST_RESULTS_DIR mkdir -p $WORKSPACE_DIR -mapfile -t TEST_RESULT_DIRS < <(find $WORKSPACE_DIR -name test-results -type d) +# Main project modules redirect their build directory to workspace//build/ in CI +# (see build.gradle.kts layout.buildDirectory override). buildSrc is a separate Gradle build +# that runs before the main build is configured, so this redirect never applies to it; +# its test results always land in buildSrc/**/build/test-results/, not under workspace/. +SEARCH_DIRS=($WORKSPACE_DIR buildSrc) + +mapfile -t TEST_RESULT_DIRS < <(find "${SEARCH_DIRS[@]}" -name test-results -type d) if [[ ${#TEST_RESULT_DIRS[@]} -eq 0 ]]; then echo "No test results found" From 4ca54da4afde1f9a9c7bee6905dfd8ad039b6a60 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 17 Mar 2026 18:58:16 +0100 Subject: [PATCH 3/6] fix: Gradle daemon reuse causes stale MUZZLE_REPOS across functional tests MuzzleMavenRepoUtils.MUZZLE_REPOS is a lazy singleton initialized once per JVM from MAVEN_REPOSITORY_PROXY. When the Gradle daemon was reused across test cases, the env var value from the first test was cached, causing version range resolution to target a non-existent or unrelated local Maven repo in subsequent tests. Passing --no-daemon ensures each GradleRunner invocation starts a fresh JVM, so MUZZLE_REPOS is re-evaluated with the correct repo URL for each test. As a side effect, this also prevents the daemon from holding file handles on @TempDir directories at JUnit cleanup time. --- buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt index fce5db321c6..2d781304f96 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt @@ -26,7 +26,7 @@ internal open class GradleFixture(protected val projectDir: File) { .withPluginClasspath() .withProjectDir(projectDir) .withEnvironment(System.getenv() + env) - .withArguments(*args) + .withArguments("--no-daemon", *args) return try { if (expectFailure) runner.buildAndFail() else runner.build() } catch (e: UnexpectedBuildResultException) { From d6aaa9a49d534ce701369cd907def236e6d666be Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 17 Mar 2026 19:46:10 +0100 Subject: [PATCH 4/6] test(build): Replace --no-daemon by system property --- buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt index 2d781304f96..4057a795540 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt @@ -26,7 +26,7 @@ internal open class GradleFixture(protected val projectDir: File) { .withPluginClasspath() .withProjectDir(projectDir) .withEnvironment(System.getenv() + env) - .withArguments("--no-daemon", *args) + .withArguments("-Dorg.gradle.daemon=false", *args) return try { if (expectFailure) runner.buildAndFail() else runner.build() } catch (e: UnexpectedBuildResultException) { From 4d6fb07abdc01c7195288ca29fe62c9f09cfe43c Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 17 Mar 2026 20:19:58 +0100 Subject: [PATCH 5/6] t(build): disable daemin via gradle.properties --- .../kotlin/datadog/gradle/plugin/GradleFixture.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt index 4057a795540..5d28dbb72ea 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt @@ -13,6 +13,15 @@ import javax.xml.parsers.DocumentBuilderFactory * Provides common functionality for setting up test projects and running Gradle builds. */ internal open class GradleFixture(protected val projectDir: File) { + init { + // Disable the Gradle daemon so each GradleRunner invocation starts a fresh JVM. + // This prevents stale singleton state (e.g. MUZZLE_REPOS) from leaking across tests. + // Note: --no-daemon is unsupported by the Tooling API; -Dorg.gradle.daemon=false in + // withArguments() is ignored for daemon selection (build args are forwarded after daemon + // connection is established). Only gradle.properties is read early enough to take effect. + file("gradle.properties").appendText("org.gradle.daemon=false\n") + } + /** * Runs Gradle with the specified arguments. * @@ -26,7 +35,7 @@ internal open class GradleFixture(protected val projectDir: File) { .withPluginClasspath() .withProjectDir(projectDir) .withEnvironment(System.getenv() + env) - .withArguments("-Dorg.gradle.daemon=false", *args) + .withArguments(*args) return try { if (expectFailure) runner.buildAndFail() else runner.build() } catch (e: UnexpectedBuildResultException) { From 25009ba8e90f811587fdbb38a142080fa2de38c7 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 17 Mar 2026 21:28:00 +0100 Subject: [PATCH 6/6] test(build): Use project local test kit dir --- .../kotlin/datadog/gradle/plugin/GradleFixture.kt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt index 5d28dbb72ea..9401f399170 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/GradleFixture.kt @@ -13,15 +13,6 @@ import javax.xml.parsers.DocumentBuilderFactory * Provides common functionality for setting up test projects and running Gradle builds. */ internal open class GradleFixture(protected val projectDir: File) { - init { - // Disable the Gradle daemon so each GradleRunner invocation starts a fresh JVM. - // This prevents stale singleton state (e.g. MUZZLE_REPOS) from leaking across tests. - // Note: --no-daemon is unsupported by the Tooling API; -Dorg.gradle.daemon=false in - // withArguments() is ignored for daemon selection (build args are forwarded after daemon - // connection is established). Only gradle.properties is read early enough to take effect. - file("gradle.properties").appendText("org.gradle.daemon=false\n") - } - /** * Runs Gradle with the specified arguments. * @@ -32,6 +23,12 @@ internal open class GradleFixture(protected val projectDir: File) { */ fun run(vararg args: String, expectFailure: Boolean = false, env: Map = emptyMap()): BuildResult { val runner = GradleRunner.create() + // Use a testkit dir scoped to this fixture's projectDir. The Tooling API always uses a + // daemon and ignores org.gradle.daemon=false. By giving each test its own testkit dir, + // we force a fresh daemon per test — ensuring withEnvironment() vars (e.g. + // MAVEN_REPOSITORY_PROXY) are correctly set on the daemon JVM and not inherited from + // a previously-started daemon with a different test's environment. + .withTestKitDir(file(".testkit")) .withPluginClasspath() .withProjectDir(projectDir) .withEnvironment(System.getenv() + env)