Merge branch '3.4.x' into 3.5.x

Closes gh-46480
This commit is contained in:
Andy Wilkinson
2025-07-22 11:25:22 +01:00
7 changed files with 47 additions and 25 deletions
@@ -32,6 +32,7 @@ import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import org.junit.platform.commons.util.AnnotationUtils;
import org.springframework.boot.gradle.testkit.PluginClasspathGradleBuild;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuildExtension;
import org.springframework.boot.testsupport.gradle.testkit.GradleVersions;
@@ -54,8 +55,8 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
.map(GradleVersion::version)
.collect(Collectors.toCollection(TreeSet::new))
.last();
GradleCompatibility gradleCompatibility = AnnotationUtils
.findAnnotation(context.getRequiredTestClass(), GradleCompatibility.class)
Class<?> testClass = context.getRequiredTestClass();
GradleCompatibility gradleCompatibility = AnnotationUtils.findAnnotation(testClass, GradleCompatibility.class)
.get();
Stream<String> gradleVersions = GRADLE_VERSIONS.stream();
if (StringUtils.hasText(gradleCompatibility.versionsLessThan())) {
@@ -65,10 +66,11 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
}
return gradleVersions.flatMap((version) -> {
List<TestTemplateInvocationContext> invocationContexts = new ArrayList<>();
invocationContexts.add(new GradleVersionTestTemplateInvocationContext(version, false));
BuildOutput buildOutput = new BuildOutput(testClass);
invocationContexts.add(new GradleVersionTestTemplateInvocationContext(version, false, buildOutput));
boolean configurationCache = gradleCompatibility.configurationCache();
if (configurationCache && GradleVersion.version(version).equals(highestVersion)) {
invocationContexts.add(new GradleVersionTestTemplateInvocationContext(version, true));
invocationContexts.add(new GradleVersionTestTemplateInvocationContext(version, true, buildOutput));
}
return invocationContexts.stream();
});
@@ -81,11 +83,15 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
private static final class GradleVersionTestTemplateInvocationContext implements TestTemplateInvocationContext {
private final BuildOutput buildOutput;
private final String gradleVersion;
private final boolean configurationCache;
GradleVersionTestTemplateInvocationContext(String gradleVersion, boolean configurationCache) {
GradleVersionTestTemplateInvocationContext(String gradleVersion, boolean configurationCache,
BuildOutput buildOutput) {
this.buildOutput = buildOutput;
this.gradleVersion = gradleVersion;
this.configurationCache = configurationCache;
}
@@ -97,7 +103,8 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
@Override
public List<Extension> getAdditionalExtensions() {
GradleBuild gradleBuild = new PluginClasspathGradleBuild().gradleVersion(this.gradleVersion);
GradleBuild gradleBuild = new PluginClasspathGradleBuild(this.buildOutput)
.gradleVersion(this.gradleVersion);
if (this.configurationCache) {
gradleBuild.configurationCache();
}
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import org.springframework.boot.gradle.testkit.PluginClasspathGradleBuild;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.gradle.testkit.Dsl;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuildExtension;
@@ -43,7 +44,8 @@ public class GradleMultiDslExtension implements TestTemplateInvocationContextPro
@Override
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
return Stream.of(Dsl.values()).map(DslTestTemplateInvocationContext::new);
BuildOutput buildOutput = new BuildOutput(context.getRequiredTestClass());
return Stream.of(Dsl.values()).map((dsl) -> new DslTestTemplateInvocationContext(buildOutput, dsl));
}
@Override
@@ -53,15 +55,18 @@ public class GradleMultiDslExtension implements TestTemplateInvocationContextPro
private static final class DslTestTemplateInvocationContext implements TestTemplateInvocationContext {
private final BuildOutput buildOutput;
private final Dsl dsl;
DslTestTemplateInvocationContext(Dsl dsl) {
DslTestTemplateInvocationContext(BuildOutput buildOutput, Dsl dsl) {
this.buildOutput = buildOutput;
this.dsl = dsl;
}
@Override
public List<Extension> getAdditionalExtensions() {
GradleBuild gradleBuild = new PluginClasspathGradleBuild(this.dsl)
GradleBuild gradleBuild = new PluginClasspathGradleBuild(this.buildOutput, this.dsl)
.gradleVersion(GradleVersions.minimumCompatible());
return Arrays.asList(new GradleBuildFieldSetter(gradleBuild), new GradleBuildExtension());
}
@@ -30,6 +30,7 @@ import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.gradle.testkit.PluginClasspathGradleBuild;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuildExtension;
@@ -44,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(GradleBuildExtension.class)
class KotlinPluginActionIntegrationTests {
GradleBuild gradleBuild = new PluginClasspathGradleBuild();
GradleBuild gradleBuild = new PluginClasspathGradleBuild(new BuildOutput(getClass()));
@Test
void noKotlinVersionPropertyWithoutKotlinPlugin() {
@@ -43,6 +43,7 @@ import org.tomlj.Toml;
import org.springframework.asm.ClassVisitor;
import org.springframework.boot.buildpack.platform.build.BuildRequest;
import org.springframework.boot.loader.tools.LaunchScript;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.gradle.testkit.Dsl;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
@@ -55,12 +56,12 @@ import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
*/
public class PluginClasspathGradleBuild extends GradleBuild {
public PluginClasspathGradleBuild() {
super();
public PluginClasspathGradleBuild(BuildOutput buildOutput) {
super(buildOutput);
}
public PluginClasspathGradleBuild(Dsl dsl) {
super(dsl);
public PluginClasspathGradleBuild(BuildOutput buildOutput, Dsl dsl) {
super(buildOutput, dsl);
}
@Override
@@ -21,6 +21,8 @@ plugins {
description = "Spring Boot Gradle Testing Support"
dependencies {
api(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
compileOnly("org.junit.jupiter:junit-jupiter")
implementation(gradleTestKit())
@@ -37,6 +37,7 @@ import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.util.GradleVersion;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.FileSystemUtils;
@@ -51,6 +52,8 @@ import static org.assertj.core.api.Assertions.fail;
*/
public class GradleBuild {
private final BuildOutput buildOutput;
private final Dsl dsl;
private File projectDir;
@@ -71,11 +74,12 @@ public class GradleBuild {
private final Map<String, String> scriptProperties = new HashMap<>();
public GradleBuild() {
this(Dsl.GROOVY);
public GradleBuild(BuildOutput buildOutput) {
this(buildOutput, Dsl.GROOVY);
}
protected GradleBuild(Dsl dsl) {
protected GradleBuild(BuildOutput buildOutput, Dsl dsl) {
this.buildOutput = buildOutput;
this.dsl = dsl;
}
@@ -206,10 +210,10 @@ public class GradleBuild {
}
private File getTestKitDir() {
File temp = new File(System.getProperty("java.io.tmpdir"));
String username = System.getProperty("user.name");
File build = this.buildOutput.getRootLocation();
File testKitRoot = new File(build, "gradle-test-kit");
String gradleVersion = (this.gradleVersion != null) ? this.gradleVersion : "default";
return new File(temp, ".gradle-test-kit-" + username + "-" + getBootVersion() + "-" + gradleVersion);
return new File(testKitRoot, gradleVersion).getAbsoluteFile();
}
public File getProjectDir() {
@@ -21,6 +21,7 @@ import java.lang.reflect.Field;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
import org.springframework.boot.testsupport.gradle.testkit.GradleVersions;
import org.springframework.util.Assert;
@@ -34,21 +35,22 @@ import org.springframework.util.ReflectionUtils;
*/
public class GradleBuildInjectionExtension implements BeforeEachCallback {
private final GradleBuild gradleBuild;
private final String bootVersion;
GradleBuildInjectionExtension() {
this.gradleBuild = new GradleBuild();
this.gradleBuild.gradleVersion(GradleVersions.minimumCompatible());
String bootVersion = System.getProperty("springBootVersion");
Assert.state(bootVersion != null, "Property 'springBootVersion' must be set in build environment");
this.gradleBuild.bootVersion(bootVersion);
this.bootVersion = bootVersion;
}
@Override
public void beforeEach(ExtensionContext context) throws Exception {
GradleBuild gradleBuild = new GradleBuild(new BuildOutput(context.getRequiredTestClass()))
.gradleVersion(GradleVersions.minimumCompatible())
.bootVersion(this.bootVersion);
Field field = ReflectionUtils.findField(context.getRequiredTestClass(), "gradleBuild");
field.setAccessible(true);
field.set(context.getRequiredTestInstance(), this.gradleBuild);
field.set(context.getRequiredTestInstance(), gradleBuild);
}
}