Add tests to verify starter dependencies when used with Gradle
We've had problems with the starters when used with Gradle. They have been pulling in commons-logging (#987) and the wrong version of Spring (#1028) due to Gradle's different exclusion and dependency resolution semantics. This commit adds some integration tests that use Gradle's tooling API to take each starter in turn and build a Gradle project that depends upon it. The build looks at the transitive dependencies and checks that neither commons-logging nor any Spring modules with the wrong version are present. Closes #1036
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<relativePath>../spring-boot-parent</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-boot-integration-tests</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Boot Integration Tests</name>
|
||||
<description>Spring Boot Integration Tests</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
@@ -19,6 +19,19 @@
|
||||
<properties>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gradle</groupId>
|
||||
<artifactId>gradle-tooling-api</artifactId>
|
||||
<version>${gradle.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependency-tools</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>default</id>
|
||||
@@ -57,4 +70,16 @@
|
||||
<id>full</id>
|
||||
</profile>
|
||||
</profiles>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gradle</id>
|
||||
<url>http://repo.gradle.org/gradle/libs-releases-local</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.starter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.gradle.tooling.BuildException;
|
||||
import org.gradle.tooling.GradleConnector;
|
||||
import org.gradle.tooling.ProjectConnection;
|
||||
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.boot.dependency.tools.VersionManagedDependencies;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests for the various starter projects to check that they don't pull in unwanted
|
||||
* transitive dependencies when used with Gradle
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StarterDependenciesIntegrationTests {
|
||||
|
||||
private static final String STARTER_NAME_PREFIX = "spring-boot-starter";
|
||||
|
||||
private static final List<String> EXCLUDED_STARTERS = Arrays
|
||||
.asList("spring-boot-starter-parent");
|
||||
|
||||
private static ProjectConnection project;
|
||||
|
||||
private static String bootVersion;
|
||||
|
||||
private static String springVersion;
|
||||
|
||||
private final String[] buildArguments;
|
||||
|
||||
@Parameters
|
||||
public static List<String[]> getStarters() {
|
||||
List<String[]> starters = new ArrayList<String[]>();
|
||||
for (File file : new File("../spring-boot-starters").listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
String name = file.getName();
|
||||
if (name.startsWith(STARTER_NAME_PREFIX)
|
||||
&& !EXCLUDED_STARTERS.contains(file.getName())) {
|
||||
starters.add(new String[] { file.getName() });
|
||||
}
|
||||
}
|
||||
}
|
||||
return starters;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void createProject() throws IOException {
|
||||
File projectDirectory = new File("target/starter-dependencies");
|
||||
projectDirectory.mkdirs();
|
||||
|
||||
File gradleScript = new File(projectDirectory, "build.gradle");
|
||||
FileCopyUtils.copy(new File("src/test/resources/build.gradle"), gradleScript);
|
||||
|
||||
GradleConnector gradleConnector = GradleConnector.newConnector();
|
||||
((DefaultGradleConnector) gradleConnector).embedded(true);
|
||||
project = gradleConnector.forProjectDirectory(projectDirectory).connect();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void determineVersions() throws Exception {
|
||||
springVersion = new VersionManagedDependencies().find("spring-core").getVersion();
|
||||
bootVersion = new VersionManagedDependencies().find("spring-boot").getVersion();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void closeProject() {
|
||||
project.close();
|
||||
}
|
||||
|
||||
public StarterDependenciesIntegrationTests(String starter) {
|
||||
this.buildArguments = new String[] { "-Pstarter=" + starter,
|
||||
"-PbootVersion=" + bootVersion, "-PspringVersion=" + springVersion };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commonsLoggingIsNotATransitiveDependency() throws IOException {
|
||||
runBuildForTask("checkCommonsLogging");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oldSpringModulesAreNotTransitiveDependencies() throws IOException {
|
||||
runBuildForTask("checkSpring");
|
||||
}
|
||||
|
||||
private void runBuildForTask(String task) {
|
||||
try {
|
||||
project.newBuild().forTasks(task).withArguments(this.buildArguments).run();
|
||||
}
|
||||
catch (BuildException ex) {
|
||||
Throwable root = ex;
|
||||
while (root.getCause() != null) {
|
||||
root = root.getCause();
|
||||
}
|
||||
fail(root.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import org.gradle.api.artifacts.result.UnresolvedDependencyResult;
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
configurations {
|
||||
springBootStarter
|
||||
}
|
||||
|
||||
dependencies {
|
||||
springBootStarter "org.springframework.boot:${project.starter}:${project.bootVersion}"
|
||||
}
|
||||
|
||||
task checkCommonsLogging {
|
||||
doFirst {
|
||||
def commonsLogging = resolvedDependencies
|
||||
.find { it.selected.id.group == 'commons-logging' }
|
||||
if (commonsLogging) {
|
||||
throw new GradleException("${project.starter} pulls in commons-logging")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task checkSpring {
|
||||
doFirst {
|
||||
def wrongSpring = resolvedDependencies
|
||||
.findAll{it.selected.id.group == 'org.springframework'}
|
||||
.findAll{it.selected.id.version != project.springVersion}
|
||||
.collect {it.selected.id}
|
||||
if (wrongSpring) {
|
||||
throw new GradleException("${project.starter} pulled in ${wrongSpring as Set}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def getResolvedDependencies() {
|
||||
def allDependencies = configurations.springBootStarter.incoming
|
||||
.resolutionResult.allDependencies
|
||||
.split { it instanceof UnresolvedDependencyResult }
|
||||
|
||||
def unresolved = allDependencies.first()
|
||||
def resolved = allDependencies.last()
|
||||
if (unresolved) {
|
||||
throw new GradleException("Resolution of ${project.starter} failed: ${unresolved}")
|
||||
}
|
||||
resolved
|
||||
}
|
||||
Reference in New Issue
Block a user