Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import javax.inject.Inject
* from the root build can be forwarded via [projectJar]; each entry is passed as
* `-P<propertyName>=<absolute-path>` and tracked as a task input so the nested build re-runs
* when the upstream jar changes.
*
* The temporary Gradle user home is preserved when daemon shutdown cannot be confirmed.
*/
@CacheableTask
abstract class NestedGradleBuild @Inject constructor(
Expand Down Expand Up @@ -137,7 +139,11 @@ abstract class NestedGradleBuild @Inject constructor(
@get:Input
abstract val buildCacheEnabled: Property<Boolean>

/** Timeout, in seconds, for stopping the nested Gradle daemon after the build. */
/**
* Timeout, in seconds, applied separately to the `--stop` command and the subsequent daemon
* exit wait. The two waits can take up to twice this value in total. When unset, `--stop`
* waits indefinitely and daemon exit waits up to 30 seconds.
*/
@get:Input
@get:Optional
abstract val stopTimeoutSeconds: Property<Long>
Expand Down Expand Up @@ -356,6 +362,12 @@ abstract class NestedGradleBuild @Inject constructor(
private fun createGradleUserHome(): File {
val directory = temporaryDir.resolve("gradle-user-home")
deleteGradleUserHome(directory)
if (directory.exists()) {
throw GradleException(
"Could not clean up existing nested Gradle user home: ${directory.absolutePath}. " +
"Check the preceding daemon shutdown and cleanup warnings.",
)
}
if (!directory.mkdirs()) {
throw GradleException(
"Could not create nested Gradle user home: ${directory.absolutePath}",
Expand All @@ -364,6 +376,7 @@ abstract class NestedGradleBuild @Inject constructor(
return directory
}

// Gradle's internal log naming also drives buildSrc's GradleFixture.stopDaemonsIn.
private fun findGradleDaemons(directory: File): List<ProcessHandle> =
directory.resolve("daemon").walkTopDown()
.filter { it.isFile && it.name.startsWith("daemon-") && it.name.endsWith(".out.log") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ abstract class GradleAppSpec @Inject constructor() : ApplicationSpec() {
*/
abstract val buildCacheEnabled: Property<Boolean>

/** Timeout, in seconds, for stopping the nested Gradle daemon after the build. */
/** Timeout, in seconds, for each shutdown wait. See [NestedGradleBuild.stopTimeoutSeconds]. */
abstract val stopTimeoutSeconds: Property<Long>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import datadog.buildlogic.smoketest.NestedGradleBuild.Companion.gradleExecutable
import datadog.buildlogic.smoketest.NestedGradleBuild.Companion.isGradleDaemonCandidate
import datadog.buildlogic.smoketest.NestedMavenBuild.Companion.mavenWrapperName
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.gradle.api.GradleException
import org.gradle.api.plugins.JavaPlugin
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.apply
Expand Down Expand Up @@ -111,6 +113,32 @@ class SmokeTestAppPluginTest {
}
}

@Test
fun `nested Gradle build reports a user home retained after cleanup`() {
val project = ProjectBuilder.builder().build()
project.apply<JavaPlugin>()
val task = project.tasks.register("nestedBuild", NestedGradleBuild::class.java).get()
task.applicationDir.set(project.layout.projectDirectory)
task.applicationBuildDir.set(project.layout.buildDirectory.dir("application"))
// Resolve the toolchain before simulating interrupted cleanup.
task.javaLauncher.get()
val userHome = task.temporaryDir.resolve("gradle-user-home")
assertThat(userHome.mkdirs()).isTrue()

Thread.currentThread().interrupt()
try {
assertThatThrownBy { task.runNestedBuild() }
.isInstanceOf(GradleException::class.java)
.hasMessageContaining("Could not clean up existing nested Gradle user home:")
.hasMessageContaining(userHome.absolutePath)

assertThat(Thread.currentThread().isInterrupted).isTrue()
assertThat(userHome).exists()
} finally {
Thread.interrupted()
}
}

@Test
fun `applying the plugin creates the smokeTestApp extension`() {
val project = ProjectBuilder.builder().build()
Expand Down
Loading