mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Introduce docker-test plugin for running tests that require Docker
See gh-41228
This commit is contained in:
parent
07442f8366
commit
d78c7b541a
@ -93,6 +93,10 @@ gradlePlugin {
|
|||||||
id = "org.springframework.boot.deployed"
|
id = "org.springframework.boot.deployed"
|
||||||
implementationClass = "org.springframework.boot.build.DeployedPlugin"
|
implementationClass = "org.springframework.boot.build.DeployedPlugin"
|
||||||
}
|
}
|
||||||
|
dockerTestPlugin {
|
||||||
|
id = "org.springframework.boot.docker-test"
|
||||||
|
implementationClass = "org.springframework.boot.build.test.DockerTestPlugin"
|
||||||
|
}
|
||||||
integrationTestPlugin {
|
integrationTestPlugin {
|
||||||
id = "org.springframework.boot.integration-test"
|
id = "org.springframework.boot.integration-test"
|
||||||
implementationClass = "org.springframework.boot.build.test.IntegrationTestPlugin"
|
implementationClass = "org.springframework.boot.build.test.IntegrationTestPlugin"
|
||||||
|
@ -87,6 +87,7 @@ import org.xml.sax.SAXException;
|
|||||||
|
|
||||||
import org.springframework.boot.build.DeployedPlugin;
|
import org.springframework.boot.build.DeployedPlugin;
|
||||||
import org.springframework.boot.build.MavenRepositoryPlugin;
|
import org.springframework.boot.build.MavenRepositoryPlugin;
|
||||||
|
import org.springframework.boot.build.test.DockerTestPlugin;
|
||||||
import org.springframework.boot.build.test.IntegrationTestPlugin;
|
import org.springframework.boot.build.test.IntegrationTestPlugin;
|
||||||
import org.springframework.core.CollectionFactory;
|
import org.springframework.core.CollectionFactory;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
@ -138,11 +139,15 @@ public class MavenPluginPlugin implements Plugin<Project> {
|
|||||||
.set(new File(project.getBuildDir(), "runtime-classpath-repository"));
|
.set(new File(project.getBuildDir(), "runtime-classpath-repository"));
|
||||||
project.getDependencies()
|
project.getDependencies()
|
||||||
.components((components) -> components.all(MavenRepositoryComponentMetadataRule.class));
|
.components((components) -> components.all(MavenRepositoryComponentMetadataRule.class));
|
||||||
Sync task = project.getTasks().create("populateIntTestMavenRepository", Sync.class);
|
Sync task = project.getTasks().create("populateTestMavenRepository", Sync.class);
|
||||||
task.setDestinationDir(new File(project.getBuildDir(), "int-test-maven-repository"));
|
task.setDestinationDir(new File(project.getBuildDir(), "test-maven-repository"));
|
||||||
task.with(copyIntTestMavenRepositoryFiles(project, runtimeClasspathMavenRepository));
|
task.with(copyIntTestMavenRepositoryFiles(project, runtimeClasspathMavenRepository));
|
||||||
task.dependsOn(project.getTasks().getByName(MavenRepositoryPlugin.PUBLISH_TO_PROJECT_REPOSITORY_TASK_NAME));
|
task.dependsOn(project.getTasks().getByName(MavenRepositoryPlugin.PUBLISH_TO_PROJECT_REPOSITORY_TASK_NAME));
|
||||||
project.getTasks().getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME).dependsOn(task);
|
project.getTasks().getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME).dependsOn(task);
|
||||||
|
project.getPlugins()
|
||||||
|
.withType(DockerTestPlugin.class)
|
||||||
|
.all((dockerTestPlugin) -> project.getTasks()
|
||||||
|
.named(DockerTestPlugin.DOCKER_TEST_TASK_NAME, (dockerTest) -> dockerTest.dependsOn(task)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private CopySpec copyIntTestMavenRepositoryFiles(Project project,
|
private CopySpec copyIntTestMavenRepositoryFiles(Project project,
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.build.test;
|
||||||
|
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.provider.Provider;
|
||||||
|
import org.gradle.api.services.BuildService;
|
||||||
|
import org.gradle.api.services.BuildServiceParameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build service for Docker-based tests. Configured to only allow serial execution,
|
||||||
|
* thereby ensuring that Docker-based tests do not run in parallel.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
abstract class DockerTestBuildService implements BuildService<BuildServiceParameters.None> {
|
||||||
|
|
||||||
|
static Provider<DockerTestBuildService> registerIfNecessary(Project project) {
|
||||||
|
return project.getGradle()
|
||||||
|
.getSharedServices()
|
||||||
|
.registerIfAbsent("dockerTest", DockerTestBuildService.class, (spec) -> spec.getMaxParallelUsages().set(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.build.test;
|
||||||
|
|
||||||
|
import org.gradle.api.Plugin;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.plugins.JavaPlugin;
|
||||||
|
import org.gradle.api.plugins.JavaPluginExtension;
|
||||||
|
import org.gradle.api.provider.Provider;
|
||||||
|
import org.gradle.api.services.BuildService;
|
||||||
|
import org.gradle.api.tasks.SourceSet;
|
||||||
|
import org.gradle.api.tasks.SourceSetContainer;
|
||||||
|
import org.gradle.api.tasks.testing.Test;
|
||||||
|
import org.gradle.language.base.plugins.LifecycleBasePlugin;
|
||||||
|
import org.gradle.plugins.ide.eclipse.EclipsePlugin;
|
||||||
|
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin for Docker-based tests. Creates a {@link SourceSet source set}, {@link Test
|
||||||
|
* test} task, and {@link BuildService shared service} named {@code dockerTest}. The build
|
||||||
|
* service is configured to only allow serial usage and the {@code dockerTest} task is
|
||||||
|
* configured to use the build service. In a parallel build, this ensures that only a
|
||||||
|
* single {@code dockerTest} task can run at any given time.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
public class DockerTestPlugin implements Plugin<Project> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the {@code dockerTest} task.
|
||||||
|
*/
|
||||||
|
public static String DOCKER_TEST_TASK_NAME = "dockerTest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the {@code dockerTest} source set.
|
||||||
|
*/
|
||||||
|
public static String DOCKER_TEST_SOURCE_SET_NAME = "dockerTest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the {@code dockerTest} shared service.
|
||||||
|
*/
|
||||||
|
public static String DOCKER_TEST_SERVICE_NAME = "dockerTest";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Project project) {
|
||||||
|
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> configureDockerTesting(project));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureDockerTesting(Project project) {
|
||||||
|
Provider<DockerTestBuildService> buildService = DockerTestBuildService.registerIfNecessary(project);
|
||||||
|
SourceSet dockerTestSourceSet = createSourceSet(project);
|
||||||
|
Provider<Test> dockerTest = createTestTask(project, dockerTestSourceSet, buildService);
|
||||||
|
project.getTasks().getByName(LifecycleBasePlugin.CHECK_TASK_NAME).dependsOn(dockerTest);
|
||||||
|
project.getPlugins().withType(EclipsePlugin.class, (eclipsePlugin) -> {
|
||||||
|
EclipseModel eclipse = project.getExtensions().getByType(EclipseModel.class);
|
||||||
|
eclipse.classpath((classpath) -> classpath.getPlusConfigurations()
|
||||||
|
.add(project.getConfigurations()
|
||||||
|
.getByName(dockerTestSourceSet.getRuntimeClasspathConfigurationName())));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private SourceSet createSourceSet(Project project) {
|
||||||
|
SourceSetContainer sourceSets = project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets();
|
||||||
|
SourceSet dockerTestSourceSet = sourceSets.create(DOCKER_TEST_SOURCE_SET_NAME);
|
||||||
|
SourceSet main = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
|
||||||
|
SourceSet test = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);
|
||||||
|
dockerTestSourceSet.setCompileClasspath(dockerTestSourceSet.getCompileClasspath()
|
||||||
|
.plus(main.getOutput())
|
||||||
|
.plus(main.getCompileClasspath())
|
||||||
|
.plus(test.getOutput()));
|
||||||
|
dockerTestSourceSet.setRuntimeClasspath(dockerTestSourceSet.getRuntimeClasspath()
|
||||||
|
.plus(main.getOutput())
|
||||||
|
.plus(main.getRuntimeClasspath())
|
||||||
|
.plus(test.getOutput()));
|
||||||
|
project.getPlugins().withType(IntegrationTestPlugin.class, (integrationTestPlugin) -> {
|
||||||
|
SourceSet intTest = sourceSets.getByName(IntegrationTestPlugin.INT_TEST_SOURCE_SET_NAME);
|
||||||
|
dockerTestSourceSet
|
||||||
|
.setCompileClasspath(dockerTestSourceSet.getCompileClasspath().plus(intTest.getOutput()));
|
||||||
|
dockerTestSourceSet
|
||||||
|
.setRuntimeClasspath(dockerTestSourceSet.getRuntimeClasspath().plus(intTest.getOutput()));
|
||||||
|
});
|
||||||
|
return dockerTestSourceSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Provider<Test> createTestTask(Project project, SourceSet dockerTestSourceSet,
|
||||||
|
Provider<DockerTestBuildService> buildService) {
|
||||||
|
Provider<Test> dockerTest = project.getTasks().register(DOCKER_TEST_TASK_NAME, Test.class, (task) -> {
|
||||||
|
task.usesService(buildService);
|
||||||
|
task.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP);
|
||||||
|
task.setDescription("Runs Docker-based tests.");
|
||||||
|
task.setTestClassesDirs(dockerTestSourceSet.getOutput().getClassesDirs());
|
||||||
|
task.setClasspath(dockerTestSourceSet.getRuntimeClasspath());
|
||||||
|
task.shouldRunAfter(JavaPlugin.TEST_TASK_NAME);
|
||||||
|
});
|
||||||
|
return dockerTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -59,6 +59,8 @@
|
|||||||
<suppress files="[\\/]spring-boot-smoke-tests[\\/]spring-boot-smoke-test-testng[\\/]" checks="SpringJUnit5" />
|
<suppress files="[\\/]spring-boot-smoke-tests[\\/]spring-boot-smoke-test-testng[\\/]" checks="SpringJUnit5" />
|
||||||
<suppress files="[\\/]spring-boot-test-support[\\/]" checks="SpringJavadoc" message="\@since" />
|
<suppress files="[\\/]spring-boot-test-support[\\/]" checks="SpringJavadoc" message="\@since" />
|
||||||
<suppress files="[\\/]spring-boot-gradle-test-support[\\/]" checks="SpringJavadoc" message="\@since" />
|
<suppress files="[\\/]spring-boot-gradle-test-support[\\/]" checks="SpringJavadoc" message="\@since" />
|
||||||
|
<suppress files="[\\/]src[\\/]dockerTest[\\/]java[\\/]" checks="JavadocPackage" />
|
||||||
|
<suppress files="[\\/]src[\\/]dockerTest[\\/]java[\\/]" checks="SpringJavadoc" message="\@since" />
|
||||||
<suppress files="[\\/]src[\\/]intTest[\\/]java[\\/]" checks="JavadocPackage" />
|
<suppress files="[\\/]src[\\/]intTest[\\/]java[\\/]" checks="JavadocPackage" />
|
||||||
<suppress files="[\\/]src[\\/]intTest[\\/]java[\\/]" checks="SpringJavadoc" message="\@since" />
|
<suppress files="[\\/]src[\\/]intTest[\\/]java[\\/]" checks="SpringJavadoc" message="\@since" />
|
||||||
<suppress files="[\\/]src[\\/]systemTest[\\/]java[\\/]" checks="JavadocPackage" />
|
<suppress files="[\\/]src[\\/]systemTest[\\/]java[\\/]" checks="JavadocPackage" />
|
||||||
|
Loading…
Reference in New Issue
Block a user