Relocate projects to spring-boot-project

Move projects to better reflect the way that Spring Boot is released.

The following projects are under `spring-boot-project`:

  - `spring-boot`
  - `spring-boot-autoconfigure`
  - `spring-boot-tools`
  - `spring-boot-starters`
  - `spring-boot-actuator`
  - `spring-boot-actuator-autoconfigure`
  - `spring-boot-test`
  - `spring-boot-test-autoconfigure`
  - `spring-boot-devtools`
  - `spring-boot-cli`
  - `spring-boot-docs`

See gh-9316
This commit is contained in:
Phillip Webb
2017-09-19 14:29:46 -07:00
parent 0419d42b7c
commit 0ba4830b4f
4023 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2012-2017 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 com.example;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.Arrays;
/**
* Very basic application used for testing {@code BootRun}.
*
* @author Andy Wilkinson
*/
public class BootRunApplication {
protected BootRunApplication() {
}
public static void main(String[] args) {
dumpClassPath();
dumpArgs(args);
dumpJvmArgs();
}
private static void dumpClassPath() {
int i = 1;
for (String entry : ManagementFactory.getRuntimeMXBean().getClassPath()
.split(File.pathSeparator)) {
System.out.println(i++ + ". " + entry);
}
}
private static void dumpArgs(String[] args) {
System.out.println(Arrays.toString(args));
}
private static void dumpJvmArgs() {
System.out.println(ManagementFactory.getRuntimeMXBean().getInputArguments());
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2012-2017 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.gradle.docs;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
/**
* Tests for the getting started documentation.
*
* @author Andy Wilkinson
*/
public class GettingStartedDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
@Test
public void applyPluginSnapshotExampleEvaluatesSuccessfully() {
this.gradleBuild
.script("src/main/gradle/getting-started/apply-plugin-snapshot.gradle")
.build();
}
@Test
public void typicalPluginsAppliesExceptedPlugins() {
this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins.gradle")
.build("verify");
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright 2012-2017 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.gradle.docs;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the generating build info documentation.
*
* @author Andy Wilkinson
*/
public class IntegratingWithActuatorDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
@Test
public void basicBuildInfo() throws IOException {
this.gradleBuild
.script("src/main/gradle/integrating-with-actuator/build-info-basic.gradle")
.build("bootBuildInfo");
assertThat(new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties")).isFile();
}
@Test
public void buildInfoCustomValues() throws IOException {
this.gradleBuild
.script("src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle")
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties");
assertThat(file).isFile();
Properties properties = buildInfoProperties(file);
assertThat(properties).containsEntry("build.artifact", "example-app");
assertThat(properties).containsEntry("build.version", "1.2.3");
assertThat(properties).containsEntry("build.group", "com.example");
assertThat(properties).containsEntry("build.name", "Example application");
}
@Test
public void buildInfoAdditional() throws IOException {
this.gradleBuild
.script("src/main/gradle/integrating-with-actuator/build-info-additional.gradle")
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties");
assertThat(file).isFile();
Properties properties = buildInfoProperties(file);
assertThat(properties).containsEntry("build.a", "alpha");
assertThat(properties).containsEntry("build.b", "bravo");
}
private Properties buildInfoProperties(File file) {
assertThat(file).isFile();
Properties properties = new Properties();
try (FileReader reader = new FileReader(file)) {
properties.load(reader);
return properties;
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2012-2017 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.gradle.docs;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the managing dependencies documentation.
*
* @author Andy Wilkinson
*/
public class ManagingDependenciesDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
@Test
public void dependenciesExampleEvaluatesSuccessfully() {
this.gradleBuild
.script("src/main/gradle/managing-dependencies/dependencies.gradle")
.build();
}
@Test
public void customManagedVersions() {
assertThat(this.gradleBuild
.script("src/main/gradle/managing-dependencies/custom-version.gradle")
.build("slf4jVersion").getOutput()).contains("1.7.20");
}
}

View File

@@ -0,0 +1,189 @@
/*
* Copyright 2012-2017 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.gradle.docs;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import org.springframework.util.FileCopyUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the packaging documentation.
*
* @author Andy Wilkinson
*/
public class PackagingDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
@Test
public void warContainerDependencyEvaluatesSuccessfully() {
this.gradleBuild
.script("src/main/gradle/packaging/war-container-dependency.gradle")
.build();
}
@Test
public void bootJarMainClass() throws IOException {
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-main-class.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
}
}
@Test
public void bootJarManifestMainClass() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-manifest-main-class.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
}
}
@Test
public void applicationPluginMainClass() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/application-plugin-main-class.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
}
}
@Test
public void bootWarIncludeDevtools() throws IOException {
new File(this.gradleBuild.getProjectDir(),
"spring-boot-devtools-1.2.3.RELEASE.jar").createNewFile();
this.gradleBuild
.script("src/main/gradle/packaging/boot-war-include-devtools.gradle")
.build("bootWar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war");
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getEntry("WEB-INF/lib/spring-boot-devtools-1.2.3.RELEASE.jar"))
.isNotNull();
}
}
@Test
public void bootJarRequiresUnpack() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-requires-unpack.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
JarEntry entry = jar.getJarEntry("BOOT-INF/lib/jruby-complete-1.7.25.jar");
assertThat(entry).isNotNull();
assertThat(entry.getComment()).startsWith("UNPACK:");
}
}
@Test
public void bootJarIncludeLaunchScript() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-include-launch-script.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
assertThat(FileCopyUtils.copyToString(new FileReader(file)))
.startsWith("#!/bin/bash");
}
@Test
public void bootJarLaunchScriptProperties() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-launch-script-properties.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
assertThat(FileCopyUtils.copyToString(new FileReader(file)))
.contains("example-app.log");
}
@Test
public void bootJarCustomLaunchScript() throws IOException {
File customScriptFile = new File(this.gradleBuild.getProjectDir(),
"src/custom.script");
customScriptFile.getParentFile().mkdirs();
FileCopyUtils.copy("custom", new FileWriter(customScriptFile));
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-custom-launch-script.gradle")
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
assertThat(FileCopyUtils.copyToString(new FileReader(file))).startsWith("custom");
}
@Test
public void bootWarPropertiesLauncher() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-war-properties-launcher.gradle")
.build("bootWar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war");
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Main-Class"))
.isEqualTo("org.springframework.boot.loader.PropertiesLauncher");
}
}
@Test
public void bootJarAndJar() throws IOException {
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-and-jar.gradle")
.build("assemble");
File jar = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(jar).isFile();
File bootJar = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + "-boot.jar");
assertThat(bootJar).isFile();
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2012-2017 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.gradle.docs;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the publishing documentation.
*
* @author Andy Wilkinson
*/
public class PublishingDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
@Test
public void mavenUpload() throws IOException {
assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven.gradle")
.build("deployerRepository").getOutput())
.contains("https://repo.example.com");
}
@Test
public void mavenPublish() throws IOException {
assertThat(
this.gradleBuild.script("src/main/gradle/publishing/maven-publish.gradle")
.build("publishingConfiguration").getOutput())
.contains("MavenPublication")
.contains("https://repo.example.com");
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2012-2017 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.gradle.docs;
import java.io.File;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the documentation about running a Spring Boot application.
*
* @author Andy Wilkinson
*/
public class RunningDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
@Test
public void bootRunMain() throws IOException {
assertThat(this.gradleBuild.script("src/main/gradle/running/boot-run-main.gradle")
.build("configuredMainClass").getOutput())
.contains("com.example.ExampleApplication");
}
@Test
public void applicationPluginMainClassName() throws IOException {
assertThat(this.gradleBuild
.script("src/main/gradle/running/application-plugin-main-class-name.gradle")
.build("configuredMainClass").getOutput())
.contains("com.example.ExampleApplication");
}
@Test
public void bootRunSourceResources() throws IOException {
assertThat(this.gradleBuild
.script("src/main/gradle/running/boot-run-source-resources.gradle")
.build("configuredClasspath").getOutput())
.contains(new File("src/main/resources").getPath());
}
@Test
public void bootRunExecSpecCustomization() throws IOException {
this.gradleBuild
.script("src/main/gradle/running/boot-run-custom-exec-spec.gradle")
.build();
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2012-2017 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.gradle.dsl;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.tasks.buildinfo.BuildInfo;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link BuildInfo} created using the
* {@link org.springframework.boot.gradle.dsl.SpringBootExtension DSL}.
*
* @author Andy Wilkinson
*/
public class BuildInfoDslIntegrationTests {
@Rule
public final GradleBuild gradleBuild = new GradleBuild();
@Test
public void basicJar() throws IOException {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
.task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.group", "com.example");
assertThat(properties).containsEntry("build.version", "1.0");
}
@Test
public void jarWithCustomName() throws IOException {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
.task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", "foo");
assertThat(properties).containsEntry("build.group", "com.example");
assertThat(properties).containsEntry("build.version", "1.0");
}
@Test
public void basicWar() throws IOException {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
.task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.group", "com.example");
assertThat(properties).containsEntry("build.version", "1.0");
}
@Test
public void warWithCustomName() throws IOException {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
.task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", "foo");
assertThat(properties).containsEntry("build.group", "com.example");
assertThat(properties).containsEntry("build.version", "1.0");
}
@Test
public void additionalProperties() throws IOException {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
.task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact",
this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.group", "com.example");
assertThat(properties).containsEntry("build.version", "1.0");
assertThat(properties).containsEntry("build.a", "alpha");
assertThat(properties).containsEntry("build.b", "bravo");
}
@Test
public void classesDependency() throws IOException {
assertThat(this.gradleBuild.build("classes", "--stacktrace")
.task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
private Properties buildInfoProperties() {
File file = new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties");
assertThat(file).isFile();
Properties properties = new Properties();
try (FileReader reader = new FileReader(file)) {
properties.load(reader);
return properties;
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2012-2017 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.gradle.junit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.gradle.api.Rule;
import org.junit.runner.Runner;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Suite;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.springframework.boot.gradle.testkit.GradleBuild;
/**
* Custom {@link Suite} that runs tests against multiple version of Gradle. Test classes
* using the suite must have a public {@link GradleBuild} field named {@code gradleBuild}
* and annotated with {@link Rule}.
*
* @author Andy Wilkinson
*/
public final class GradleCompatibilitySuite extends Suite {
private static final List<String> GRADLE_VERSIONS = Arrays.asList("default", "4.1",
"4.2");
public GradleCompatibilitySuite(Class<?> clazz) throws InitializationError {
super(clazz, createRunners(clazz));
}
private static List<Runner> createRunners(Class<?> clazz) throws InitializationError {
List<Runner> runners = new ArrayList<>();
for (String version : GRADLE_VERSIONS) {
runners.add(new GradleCompatibilityClassRunner(clazz, version));
}
return runners;
}
private static final class GradleCompatibilityClassRunner
extends BlockJUnit4ClassRunner {
private final String gradleVersion;
private GradleCompatibilityClassRunner(Class<?> klass, String gradleVersion)
throws InitializationError {
super(klass);
this.gradleVersion = gradleVersion;
}
@Override
protected Object createTest() throws Exception {
Object test = super.createTest();
configureTest(test);
return test;
}
private void configureTest(Object test) throws Exception {
GradleBuild gradleBuild = new GradleBuild();
if (!"default".equals(this.gradleVersion)) {
gradleBuild = gradleBuild.gradleVersion(this.gradleVersion);
}
test.getClass().getField("gradleBuild").set(test, gradleBuild);
}
@Override
protected String getName() {
return "Gradle " + this.gradleVersion;
}
@Override
protected String testName(FrameworkMethod method) {
return method.getName() + " [" + getName() + "]";
}
}
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright 2012-2017 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.gradle.plugin;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link ApplicationPluginAction}.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class ApplicationPluginActionIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void noBootDistributionWithoutApplicationPluginApplied() {
assertThat(this.gradleBuild.build("distributionExists", "-PdistributionName=boot")
.getOutput()).contains("boot exists = false");
}
@Test
public void applyingApplicationPluginCreatesBootDistribution() {
assertThat(this.gradleBuild.build("distributionExists", "-PdistributionName=boot",
"-PapplyApplicationPlugin").getOutput()).contains("boot exists = true");
}
@Test
public void noBootStartScriptsTaskWithoutApplicationPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootStartScripts")
.getOutput()).contains("bootStartScripts exists = false");
}
@Test
public void applyingApplicationPluginCreatesBootStartScriptsTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootStartScripts",
"-PapplyApplicationPlugin").getOutput())
.contains("bootStartScripts exists = true");
}
@Test
public void zipDistributionForJarCanBeBuilt() throws IOException {
assertThat(
this.gradleBuild.build("bootDistZip").task(":bootDistZip").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(),
"build/distributions/" + name + "-boot.zip");
assertThat(distribution).isFile();
assertThat(zipEntryNames(distribution)).containsExactlyInAnyOrder(name + "-boot/",
name + "-boot/lib/", name + "-boot/lib/" + name + ".jar",
name + "-boot/bin/", name + "-boot/bin/" + name,
name + "-boot/bin/" + name + ".bat");
}
@Test
public void tarDistributionForJarCanBeBuilt() throws IOException {
assertThat(
this.gradleBuild.build("bootDistTar").task(":bootDistTar").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(),
"build/distributions/" + name + "-boot.tar");
assertThat(distribution).isFile();
assertThat(tarEntryNames(distribution)).containsExactlyInAnyOrder(name + "-boot/",
name + "-boot/lib/", name + "-boot/lib/" + name + ".jar",
name + "-boot/bin/", name + "-boot/bin/" + name,
name + "-boot/bin/" + name + ".bat");
}
@Test
public void zipDistributionForWarCanBeBuilt() throws IOException {
assertThat(
this.gradleBuild.build("bootDistZip").task(":bootDistZip").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(),
"build/distributions/" + name + "-boot.zip");
assertThat(distribution).isFile();
assertThat(zipEntryNames(distribution)).containsExactlyInAnyOrder(name + "-boot/",
name + "-boot/lib/", name + "-boot/lib/" + name + ".war",
name + "-boot/bin/", name + "-boot/bin/" + name,
name + "-boot/bin/" + name + ".bat");
}
@Test
public void tarDistributionForWarCanBeBuilt() throws IOException {
assertThat(
this.gradleBuild.build("bootDistTar").task(":bootDistTar").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(),
"build/distributions/" + name + "-boot.tar");
assertThat(distribution).isFile();
assertThat(tarEntryNames(distribution)).containsExactlyInAnyOrder(name + "-boot/",
name + "-boot/lib/", name + "-boot/lib/" + name + ".war",
name + "-boot/bin/", name + "-boot/bin/" + name,
name + "-boot/bin/" + name + ".bat");
}
private List<String> zipEntryNames(File distribution) throws IOException {
List<String> entryNames = new ArrayList<>();
try (ZipFile zipFile = new ZipFile(distribution)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
entryNames.add(entries.nextElement().getName());
}
}
return entryNames;
}
private List<String> tarEntryNames(File distribution) throws IOException {
List<String> entryNames = new ArrayList<>();
try (TarArchiveInputStream input = new TarArchiveInputStream(
new FileInputStream(distribution))) {
TarArchiveEntry entry;
while ((entry = input.getNextTarEntry()) != null) {
entryNames.add(entry.getName());
}
}
return entryNames;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2012-2017 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.gradle.plugin;
import java.io.File;
import java.io.IOException;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for the configuration applied by
* {@link DependencyManagementPluginAction}.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class DependencyManagementPluginActionIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void noDependencyManagementIsAppliedByDefault() {
assertThat(this.gradleBuild.build("doesNotHaveDependencyManagement")
.task(":doesNotHaveDependencyManagement").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
}
@Test
public void bomIsImportedWhenDependencyManagementPluginIsApplied() {
assertThat(this.gradleBuild
.build("hasDependencyManagement", "-PapplyDependencyManagementPlugin")
.task(":hasDependencyManagement").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
}
@Test
public void helpfulErrorWhenVersionlessDependencyFailsToResolve() throws IOException {
File examplePackage = new File(this.gradleBuild.getProjectDir(),
"src/main/java/com/example");
examplePackage.mkdirs();
FileSystemUtils.copyRecursively(new File("src/test/java/com/example"),
examplePackage);
BuildResult result = this.gradleBuild.buildAndFail("compileJava");
assertThat(result.task(":compileJava").getOutcome())
.isEqualTo(TaskOutcome.FAILED);
String output = result.getOutput();
assertThat(output).contains("During the build, one or more dependencies that "
+ "were declared without a version failed to resolve:");
assertThat(output).contains("org.springframework.boot:spring-boot-starter-web:");
assertThat(output).contains("Did you forget to apply the "
+ "io.spring.dependency-management plugin to the "
+ this.gradleBuild.getProjectDir().getName() + " project?");
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2012-2017 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.gradle.plugin;
import java.io.File;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link WarPluginAction}.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class JavaPluginActionIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void noBootJarTaskWithoutJavaPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootJar").getOutput())
.contains("bootJar exists = false");
}
@Test
public void applyingJavaPluginCreatesBootJarTask() {
assertThat(this.gradleBuild
.build("taskExists", "-PtaskName=bootJar", "-PapplyJavaPlugin")
.getOutput()).contains("bootJar exists = true");
}
@Test
public void noBootRunTaskWithoutJavaPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootRun").getOutput())
.contains("bootRun exists = false");
}
@Test
public void applyingJavaPluginCreatesBootRunTask() {
assertThat(this.gradleBuild
.build("taskExists", "-PtaskName=bootRun", "-PapplyJavaPlugin")
.getOutput()).contains("bootRun exists = true");
}
@Test
public void javaCompileTasksUseUtf8Encoding() {
assertThat(this.gradleBuild.build("javaCompileEncoding", "-PapplyJavaPlugin")
.getOutput()).contains("compileJava = UTF-8")
.contains("compileTestJava = UTF-8");
}
@Test
public void javaCompileTasksUseParametersCompilerFlagByDefault() {
assertThat(this.gradleBuild.build("javaCompileTasksCompilerArgs").getOutput())
.contains("compileJava compiler args: [-parameters]")
.contains("compileTestJava compiler args: [-parameters]");
}
@Test
public void javaCompileTasksUseParametersAndAdditionalCompilerFlags() {
assertThat(this.gradleBuild.build("javaCompileTasksCompilerArgs").getOutput())
.contains("compileJava compiler args: [-parameters, -Xlint:all]")
.contains("compileTestJava compiler args: [-parameters, -Xlint:all]");
}
@Test
public void javaCompileTasksCanOverrideDefaultParametersCompilerFlag() {
assertThat(this.gradleBuild.build("javaCompileTasksCompilerArgs").getOutput())
.contains("compileJava compiler args: [-Xlint:all]")
.contains("compileTestJava compiler args: [-Xlint:all]");
}
@Test
public void assembleRunsBootJarAndJarIsSkipped() {
BuildResult result = this.gradleBuild.build("assemble");
assertThat(result.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.task(":jar").getOutcome()).isEqualTo(TaskOutcome.SKIPPED);
}
@Test
public void jarAndBootJarCanBothBeBuilt() {
BuildResult result = this.gradleBuild.build("assemble");
assertThat(result.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.task(":jar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
assertThat(buildLibs.listFiles()).containsExactlyInAnyOrder(
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".jar"),
new File(buildLibs,
this.gradleBuild.getProjectDir().getName() + "-boot.jar"));
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2012-2017 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.gradle.plugin;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MavenPluginAction}.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class MavenPluginActionIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void clearsConf2ScopeMappingsOfUploadBootArchivesTask() {
assertThat(this.gradleBuild.build("conf2ScopeMappings").getOutput())
.contains("Conf2ScopeMappings = 0");
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2012-2017 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.gradle.plugin;
import org.gradle.testkit.runner.BuildResult;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link SpringBootPlugin}.
*
* @author Andy Wilkinson
*/
public class SpringBootPluginIntegrationTests {
@Rule
public final GradleBuild gradleBuild = new GradleBuild();
@Test
public void failFastWithVersionOfGradleLowerThanRequired() {
BuildResult result = this.gradleBuild.gradleVersion("3.5.1").buildAndFail();
assertThat(result.getOutput()).contains("Spring Boot plugin requires Gradle 4.0"
+ " or later. The current version is Gradle 3.5.1");
}
@Test
public void succeedWithVersionOfGradleHigherThanRequired() {
this.gradleBuild.gradleVersion("4.0.1").build();
}
@Test
public void succeedWithVersionOfGradleMatchingWhatIsRequired() {
this.gradleBuild.gradleVersion("4.0").build();
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2012-2017 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.gradle.plugin;
import java.io.File;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link JavaPluginAction}.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class WarPluginActionIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void noBootWarTaskWithoutWarPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootWar").getOutput())
.contains("bootWar exists = false");
}
@Test
public void applyingWarPluginCreatesBootWarTask() {
assertThat(this.gradleBuild
.build("taskExists", "-PtaskName=bootWar", "-PapplyWarPlugin")
.getOutput()).contains("bootWar exists = true");
}
@Test
public void assembleRunsBootWarAndWarIsSkipped() {
BuildResult result = this.gradleBuild.build("assemble");
assertThat(result.task(":bootWar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.task(":war").getOutcome()).isEqualTo(TaskOutcome.SKIPPED);
}
@Test
public void warAndBootWarCanBothBeBuilt() {
BuildResult result = this.gradleBuild.build("assemble");
assertThat(result.task(":bootWar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.task(":war").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
assertThat(buildLibs.listFiles()).containsExactlyInAnyOrder(
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"),
new File(buildLibs,
this.gradleBuild.getProjectDir().getName() + "-boot.war"));
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2012-2017 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.gradle.tasks.buildinfo;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for the {@link BuildInfo} task.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class BuildInfoIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void defaultValues() {
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
Properties buildInfoProperties = buildInfoProperties();
assertThat(buildInfoProperties).containsKey("build.time");
assertThat(buildInfoProperties).containsEntry("build.artifact", "unspecified");
assertThat(buildInfoProperties).containsEntry("build.group", "");
assertThat(buildInfoProperties).containsEntry("build.name",
this.gradleBuild.getProjectDir().getName());
assertThat(buildInfoProperties).containsEntry("build.version", "unspecified");
}
@Test
public void basicExecution() {
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
Properties buildInfoProperties = buildInfoProperties();
assertThat(buildInfoProperties).containsKey("build.time");
assertThat(buildInfoProperties).containsEntry("build.artifact", "foo");
assertThat(buildInfoProperties).containsEntry("build.group", "foo");
assertThat(buildInfoProperties).containsEntry("build.additional", "foo");
assertThat(buildInfoProperties).containsEntry("build.name", "foo");
assertThat(buildInfoProperties).containsEntry("build.version", "1.0");
}
@Test
public void upToDateWhenExecutedTwice() {
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
}
@Test
public void notUpToDateWhenDestinationDirChanges() {
notUpToDateWithChangeToProperty("buildInfoDestinationDir");
}
@Test
public void notUpToDateWhenProjectArtifactChanges() {
notUpToDateWithChangeToProperty("buildInfoArtifact");
}
@Test
public void notUpToDateWhenProjectGroupChanges() {
notUpToDateWithChangeToProperty("buildInfoGroup");
}
@Test
public void notUpToDateWhenProjectVersionChanges() {
notUpToDateWithChangeToProperty("buildInfoVersion");
}
@Test
public void notUpToDateWhenProjectNameChanges() {
notUpToDateWithChangeToProperty("buildInfoName");
}
@Test
public void notUpToDateWhenAdditionalPropertyChanges() {
notUpToDateWithChangeToProperty("buildInfoAdditional");
}
private void notUpToDateWithChangeToProperty(String name) {
assertThat(this.gradleBuild.build("buildInfo", "--stacktrace").task(":buildInfo")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("buildInfo", "-P" + name + "=changed")
.task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
private Properties buildInfoProperties() {
File file = new File(this.gradleBuild.getProjectDir(),
"build/build-info.properties");
assertThat(file).isFile();
Properties properties = new Properties();
try (FileReader reader = new FileReader(file)) {
properties.load(reader);
return properties;
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright 2012-2017 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.gradle.tasks.buildinfo;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import org.gradle.api.Project;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link BuildInfo}.
*
* @author Andy Wilkinson
*/
public class BuildInfoTests {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Test
public void basicExecution() {
Properties properties = buildInfoProperties(createTask(createProject("test")));
assertThat(properties).containsKey("build.time");
assertThat(properties).containsEntry("build.artifact", "unspecified");
assertThat(properties).containsEntry("build.group", "");
assertThat(properties).containsEntry("build.name", "test");
assertThat(properties).containsEntry("build.version", "unspecified");
}
@Test
public void customArtifactIsReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProperties().setArtifact("custom");
assertThat(buildInfoProperties(task)).containsEntry("build.artifact", "custom");
}
@Test
public void projectGroupIsReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProject().setGroup("com.example");
assertThat(buildInfoProperties(task)).containsEntry("build.group", "com.example");
}
@Test
public void customGroupIsReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProperties().setGroup("com.example");
assertThat(buildInfoProperties(task)).containsEntry("build.group", "com.example");
}
@Test
public void customNameIsReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProperties().setName("Example");
assertThat(buildInfoProperties(task)).containsEntry("build.name", "Example");
}
@Test
public void projectVersionIsReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProject().setVersion("1.2.3");
assertThat(buildInfoProperties(task)).containsEntry("build.version", "1.2.3");
}
@Test
public void customVersionIsReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProperties().setVersion("2.3.4");
assertThat(buildInfoProperties(task)).containsEntry("build.version", "2.3.4");
}
@Test
public void additionalPropertiesAreReflectedInProperties() {
BuildInfo task = createTask(createProject("test"));
task.getProperties().getAdditional().put("a", "alpha");
task.getProperties().getAdditional().put("b", "bravo");
assertThat(buildInfoProperties(task)).containsEntry("build.a", "alpha");
assertThat(buildInfoProperties(task)).containsEntry("build.b", "bravo");
}
private Project createProject(String projectName) {
try {
File projectDir = this.temp.newFolder(projectName);
return ProjectBuilder.builder().withProjectDir(projectDir)
.withName(projectName).build();
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
private BuildInfo createTask(Project project) {
return project.getTasks().create("testBuildInfo", BuildInfo.class);
}
private Properties buildInfoProperties(BuildInfo task) {
task.generateBuildProperties();
return buildInfoProperties(
new File(task.getDestinationDir(), "build-info.properties"));
}
private Properties buildInfoProperties(File file) {
assertThat(file).isFile();
Properties properties = new Properties();
try (FileReader reader = new FileReader(file)) {
properties.load(reader);
return properties;
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;
import org.gradle.testkit.runner.InvalidRunnerConfigurationException;
import org.gradle.testkit.runner.TaskOutcome;
import org.gradle.testkit.runner.UnexpectedBuildFailure;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link BootJar}.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public abstract class AbstractBootArchiveIntegrationTests {
@Rule
public GradleBuild gradleBuild;
private final String taskName;
protected AbstractBootArchiveIntegrationTests(String taskName) {
this.taskName = taskName;
}
@Test
public void basicBuild() throws InvalidRunnerConfigurationException,
UnexpectedBuildFailure, IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@Test
public void upToDateWhenBuiltTwice() throws InvalidRunnerConfigurationException,
UnexpectedBuildFailure, IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
}
@Test
public void upToDateWhenBuiltTwiceWithLaunchScriptIncluded()
throws InvalidRunnerConfigurationException, UnexpectedBuildFailure,
IOException {
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName)
.task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
}
@Test
public void notUpToDateWhenLaunchScriptWasNotIncludedAndThenIsIncluded() {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@Test
public void notUpToDateWhenLaunchScriptWasIncludedAndThenIsNotIncluded() {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@Test
public void notUpToDateWhenLaunchScriptPropertyChanges() {
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true",
"-PlaunchScriptProperty=foo", this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true",
"-PlaunchScriptProperty=bar", this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@Test
public void applicationPluginMainClassNameIsUsed() throws IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(
new File(this.gradleBuild.getProjectDir(), "build/libs")
.listFiles()[0])) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.CustomMain");
}
}
@Test
public void duplicatesAreHandledGracefully() throws IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
}

View File

@@ -0,0 +1,350 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.gradle.api.Project;
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.testfixtures.ProjectBuilder;
import org.gradle.util.GUtil;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.boot.loader.tools.DefaultLaunchScript;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Abstract base class for testing {@link BootArchive} implementations.
*
* @param <T> the type of the concrete BootArchive implementation
* @author Andy Wilkinson
*/
public abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Rule
public final TemporaryFolder temp = new TemporaryFolder();
private final Class<T> taskClass;
private final String launcherClass;
private final String libPath;
private final String classesPath;
private T task;
protected AbstractBootArchiveTests(Class<T> taskClass, String launcherClass,
String libPath, String classesPath) {
this.taskClass = taskClass;
this.launcherClass = launcherClass;
this.libPath = libPath;
this.classesPath = classesPath;
}
@Before
public void createTask() {
try {
Project project = ProjectBuilder.builder()
.withProjectDir(this.temp.newFolder()).build();
this.task = configure(
project.getTasks().create("testArchive", this.taskClass));
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Test
public void basicArchiveCreation() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class"))
.isEqualTo(this.launcherClass);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.Main");
}
}
@Test
public void classpathJarsArePackagedBeneathLibPath() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.classpath(this.temp.newFile("one.jar"), this.temp.newFile("two.jar"));
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(this.libPath + "/one.jar")).isNotNull();
assertThat(jarFile.getEntry(this.libPath + "/two.jar")).isNotNull();
}
}
@Test
public void classpathFoldersArePackagedBeneathClassesPath() throws IOException {
this.task.setMainClass("com.example.Main");
File classpathFolder = this.temp.newFolder();
File applicationClass = new File(classpathFolder,
"com/example/Application.class");
applicationClass.getParentFile().mkdirs();
applicationClass.createNewFile();
this.task.classpath(classpathFolder);
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(
jarFile.getEntry(this.classesPath + "/com/example/Application.class"))
.isNotNull();
}
}
@Test
public void loaderIsWrittenToTheRootOfTheJar() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(
"org/springframework/boot/loader/LaunchedURLClassLoader.class"))
.isNotNull();
assertThat(jarFile.getEntry("org/springframework/boot/loader/")).isNotNull();
}
}
@Test
public void loaderIsWrittenToTheRootOfTheJarWhenUsingThePropertiesLauncher()
throws IOException {
this.task.setMainClass("com.example.Main");
this.task.execute();
this.task.getManifest().getAttributes().put("Main-Class",
"org.springframework.boot.loader.PropertiesLauncher");
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(
"org/springframework/boot/loader/LaunchedURLClassLoader.class"))
.isNotNull();
assertThat(jarFile.getEntry("org/springframework/boot/loader/")).isNotNull();
}
}
@Test
public void unpackCommentIsAddedToEntryIdentifiedByAPattern() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.classpath(this.temp.newFile("one.jar"), this.temp.newFile("two.jar"));
this.task.requiresUnpack("**/one.jar");
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(this.libPath + "/one.jar").getComment())
.startsWith("UNPACK:");
assertThat(jarFile.getEntry(this.libPath + "/two.jar").getComment()).isNull();
}
}
@Test
public void unpackCommentIsAddedToEntryIdentifiedByASpec() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.classpath(this.temp.newFile("one.jar"), this.temp.newFile("two.jar"));
this.task.requiresUnpack((element) -> element.getName().endsWith("two.jar"));
this.task.execute();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(this.libPath + "/two.jar").getComment())
.startsWith("UNPACK:");
assertThat(jarFile.getEntry(this.libPath + "/one.jar").getComment()).isNull();
}
}
@Test
public void launchScriptCanBePrepended() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.launchScript();
this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.startsWith(new DefaultLaunchScript(null, null).toByteArray());
try {
Set<PosixFilePermission> permissions = Files
.getPosixFilePermissions(this.task.getArchivePath().toPath());
assertThat(permissions).contains(PosixFilePermission.OWNER_EXECUTE);
}
catch (UnsupportedOperationException ex) {
// Windows, presumably. Continue
}
}
@Test
public void customLaunchScriptCanBePrepended() throws IOException {
this.task.setMainClass("com.example.Main");
File customScript = this.temp.newFile("custom.script");
Files.write(customScript.toPath(), Arrays.asList("custom script"),
StandardOpenOption.CREATE);
this.task.launchScript((configuration) -> configuration.setScript(customScript));
this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.startsWith("custom script".getBytes());
}
@Test
public void launchScriptPropertiesAreReplaced() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.launchScript((configuration) -> configuration.getProperties()
.put("initInfoProvides", "test property value"));
this.task.execute();
assertThat(Files.readAllBytes(this.task.getArchivePath().toPath()))
.containsSequence("test property value".getBytes());
}
@Test
public void customMainClassInTheManifestIsHonored() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.getManifest().getAttributes().put("Main-Class",
"com.example.CustomLauncher");
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class"))
.isEqualTo("com.example.CustomLauncher");
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.Main");
assertThat(jarFile.getEntry(
"org/springframework/boot/loader/LaunchedURLClassLoader.class"))
.isNull();
}
}
@Test
public void customStartClassInTheManifestIsHonored() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.getManifest().getAttributes().put("Start-Class",
"com.example.CustomMain");
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class"))
.isEqualTo(this.launcherClass);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.CustomMain");
}
}
@Test
public void fileTimestampPreservationCanBeDisabled() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setPreserveFileTimestamps(false);
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
assertThat(entry.getTime())
.isEqualTo(GUtil.CONSTANT_TIME_FOR_ZIP_ENTRIES);
}
}
}
@Test
public void reproducibleOrderingCanBeEnabled() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.from(this.temp.newFile("bravo.txt"), this.temp.newFile("alpha.txt"),
this.temp.newFile("charlie.txt"));
this.task.setReproducibleFileOrder(true);
this.task.execute();
assertThat(this.task.getArchivePath().exists());
List<String> textFiles = new ArrayList<>();
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".txt")) {
textFiles.add(entry.getName());
}
}
}
assertThat(textFiles).containsExactly("alpha.txt", "bravo.txt", "charlie.txt");
}
@Test
public void devtoolsJarIsExcludedByDefault() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.classpath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(this.libPath + "/spring-boot-devtools-0.1.2.jar"))
.isNull();
}
}
@Test
public void devtoolsJarCanBeIncluded() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.classpath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
this.task.setExcludeDevtools(false);
this.task.execute();
assertThat(this.task.getArchivePath().exists());
try (JarFile jarFile = new JarFile(this.task.getArchivePath())) {
assertThat(jarFile.getEntry(this.libPath + "/spring-boot-devtools-0.1.2.jar"))
.isNotNull();
}
}
@Test
public void allEntriesUseUnixPlatformAndUtf8NameEncoding() throws IOException {
this.task.setMainClass("com.example.Main");
this.task.setMetadataCharset("UTF-8");
File classpathFolder = this.temp.newFolder();
File resource = new File(classpathFolder, "some-resource.xml");
resource.getParentFile().mkdirs();
resource.createNewFile();
this.task.classpath(classpathFolder);
this.task.execute();
File archivePath = this.task.getArchivePath();
try (ZipFile zip = new ZipFile(archivePath)) {
Enumeration<ZipArchiveEntry> entries = zip.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
assertThat(entry.getPlatform()).isEqualTo(ZipArchiveEntry.PLATFORM_UNIX);
assertThat(entry.getGeneralPurposeBit().usesUTF8ForNames()).isTrue();
}
}
}
private T configure(T task) throws IOException {
AbstractArchiveTask archiveTask = task;
archiveTask.setBaseName("test");
archiveTask.setDestinationDir(this.temp.newFolder());
return task;
}
protected T getTask() {
return this.task;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
/**
* Integration tests for {@link BootJar}.
*
* @author Andy Wilkinson
*/
public class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
public BootJarIntegrationTests() {
super("bootJar");
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
/**
* Tests for {@link BootJar}.
*
* @author Andy Wilkinson
*/
public class BootJarTests extends AbstractBootArchiveTests<BootJar> {
public BootJarTests() {
super(BootJar.class, "org.springframework.boot.loader.JarLauncher",
"BOOT-INF/lib", "BOOT-INF/classes");
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
/**
* Integration tests for {@link BootJar}.
*
* @author Andy Wilkinson
*/
public class BootWarIntegrationTests extends AbstractBootArchiveIntegrationTests {
public BootWarIntegrationTests() {
super("bootWar");
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link BootWar}.
*
* @author Andy Wilkinson
*/
public class BootWarTests extends AbstractBootArchiveTests<BootWar> {
public BootWarTests() {
super(BootWar.class, "org.springframework.boot.loader.WarLauncher", "WEB-INF/lib",
"WEB-INF/classes");
}
@Test
public void providedClasspathJarsArePackagedInWebInfLibProvided() throws IOException {
getTask().setMainClass("com.example.Main");
getTask().providedClasspath(this.temp.newFile("one.jar"),
this.temp.newFile("two.jar"));
getTask().execute();
try (JarFile jarFile = new JarFile(getTask().getArchivePath())) {
assertThat(jarFile.getEntry("WEB-INF/lib-provided/one.jar")).isNotNull();
assertThat(jarFile.getEntry("WEB-INF/lib-provided/two.jar")).isNotNull();
}
}
@Test
public void devtoolsJarIsExcludedByDefaultWhenItsOnTheProvidedClasspath()
throws IOException {
getTask().setMainClass("com.example.Main");
getTask().providedClasspath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
getTask().execute();
assertThat(getTask().getArchivePath().exists());
try (JarFile jarFile = new JarFile(getTask().getArchivePath())) {
assertThat(jarFile
.getEntry("WEB-INF/lib-provided/spring-boot-devtools-0.1.2.jar"))
.isNull();
}
}
@Test
public void devtoolsJarCanBeIncludedWhenItsOnTheProvidedClasspath()
throws IOException {
getTask().setMainClass("com.example.Main");
getTask().providedClasspath(this.temp.newFile("spring-boot-devtools-0.1.2.jar"));
getTask().setExcludeDevtools(false);
getTask().execute();
assertThat(getTask().getArchivePath().exists());
try (JarFile jarFile = new JarFile(getTask().getArchivePath())) {
assertThat(jarFile
.getEntry("WEB-INF/lib-provided/spring-boot-devtools-0.1.2.jar"))
.isNotNull();
}
}
@Test
public void webappResourcesInDirectoriesThatOverlapWithLoaderCanBePackaged()
throws IOException {
File webappFolder = this.temp.newFolder("src", "main", "webapp");
File orgFolder = new File(webappFolder, "org");
orgFolder.mkdir();
new File(orgFolder, "foo.txt").createNewFile();
getTask().from(webappFolder);
getTask().setMainClass("com.example.Main");
getTask().execute();
assertThat(getTask().getArchivePath().exists());
try (JarFile jarFile = new JarFile(getTask().getArchivePath())) {
assertThat(jarFile.getEntry("org/")).isNotNull();
assertThat(jarFile.getEntry("org/foo.txt")).isNotNull();
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for uploading Boot jars and wars using Gradle's Maven plugin.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class MavenIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void bootJarCanBeUploaded() throws FileNotFoundException, IOException {
BuildResult result = this.gradleBuild.build("uploadBootArchives");
assertThat(result.task(":uploadBootArchives").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("jar")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0")
.noPackaging().noDependencies());
}
@Test
public void bootWarCanBeUploaded() throws IOException {
BuildResult result = this.gradleBuild.build("uploadBootArchives");
assertThat(result.task(":uploadBootArchives").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("war")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0")
.packaging("war").noDependencies());
}
private File artifactWithSuffix(String suffix) {
String name = this.gradleBuild.getProjectDir().getName();
return new File(new File(this.gradleBuild.getProjectDir(), "build/repo"),
String.format("com/example/%s/1.0/%s-1.0.%s", name, name, suffix));
}
private PomCondition pomWith() {
return new PomCondition();
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for publishing Boot jars and wars using Gradle's Maven Publish
* plugin.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class MavenPublishingIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void bootJarCanBePublished() throws FileNotFoundException, IOException {
BuildResult result = this.gradleBuild.build("publish");
assertThat(result.task(":publish").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("jar")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0")
.noPackaging().noDependencies());
}
@Test
public void bootWarCanBePublished() throws IOException {
BuildResult result = this.gradleBuild.build("publish");
assertThat(result.task(":publish").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("war")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0")
.packaging("war").noDependencies());
}
private File artifactWithSuffix(String suffix) {
String name = this.gradleBuild.getProjectDir().getName();
return new File(new File(this.gradleBuild.getProjectDir(), "build/repo"),
String.format("com/example/%s/1.0/%s-1.0.%s", name, name, suffix));
}
private PomCondition pomWith() {
return new PomCondition();
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2012-2017 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.gradle.tasks.bundling;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.assertj.core.api.Condition;
import org.assertj.core.description.Description;
import org.assertj.core.description.TextDescription;
import org.springframework.util.FileCopyUtils;
/**
* AssertJ {@link Condition} for asserting the contents of a pom file.
*
* @author Andy Wilkinson
*/
class PomCondition extends Condition<File> {
private Set<String> expectedContents;
private Set<String> notExpectedContents;
PomCondition() {
this(new HashSet<>(), new HashSet<>());
}
private PomCondition(Set<String> expectedContents, Set<String> notExpectedContents) {
super(new TextDescription("Pom file containing %s and not containing %s",
expectedContents, notExpectedContents));
this.expectedContents = expectedContents;
this.notExpectedContents = notExpectedContents;
}
@Override
public boolean matches(File pom) {
try {
String contents = FileCopyUtils.copyToString(new FileReader(pom));
for (String expected : this.expectedContents) {
if (!contents.contains(expected)) {
return false;
}
}
for (String notExpected : this.notExpectedContents) {
if (contents.contains(notExpected)) {
return false;
}
}
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
return true;
}
@Override
public Description description() {
return new TextDescription("Pom file containing %s and not containing %s",
this.expectedContents, this.notExpectedContents);
}
PomCondition groupId(String groupId) {
this.expectedContents.add(String.format("<groupId>%s</groupId>", groupId));
return this;
}
PomCondition artifactId(String artifactId) {
this.expectedContents
.add(String.format("<artifactId>%s</artifactId>", artifactId));
return this;
}
PomCondition version(String version) {
this.expectedContents.add(String.format("<version>%s</version>", version));
return this;
}
PomCondition packaging(String packaging) {
this.expectedContents.add(String.format("<packaging>%s</packaging>", packaging));
return this;
}
PomCondition noDependencies() {
this.notExpectedContents.add("<dependencies>");
return this;
}
PomCondition noPackaging() {
this.notExpectedContents.add("<packaging>");
return this;
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright 2012-2017 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.gradle.tasks.run;
import java.io.File;
import java.io.IOException;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
import org.springframework.boot.gradle.testkit.GradleBuild;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for the {@link BootRun} task.
*
* @author Andy Wilkinson
*/
@RunWith(GradleCompatibilitySuite.class)
public class BootRunIntegrationTests {
@Rule
public GradleBuild gradleBuild;
@Test
public void basicExecution() throws IOException {
copyApplication();
new File(this.gradleBuild.getProjectDir(), "src/main/resources").mkdirs();
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput())
.contains("1. " + canonicalPathOf("build/classes/java/main"));
assertThat(result.getOutput())
.contains("2. " + canonicalPathOf("build/resources/main"));
assertThat(result.getOutput())
.doesNotContain(canonicalPathOf("src/main/resources"));
}
@Test
public void argsCanBeConfigured() throws IOException {
copyApplication();
new File(this.gradleBuild.getProjectDir(), "src/main/resources").mkdirs();
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("--com.example.foo=bar");
}
@Test
public void jvmArgsCanBeConfigured() throws IOException {
copyApplication();
new File(this.gradleBuild.getProjectDir(), "src/main/resources").mkdirs();
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("-Dcom.example.foo=bar");
}
@Test
public void execSpecCanBeConfigured() throws IOException {
copyApplication();
new File(this.gradleBuild.getProjectDir(), "src/main/resources").mkdirs();
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("-Dcom.example.foo=bar");
}
@Test
public void sourceResourcesCanBeUsed() throws IOException {
copyApplication();
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput())
.contains("1. " + canonicalPathOf("src/main/resources"));
assertThat(result.getOutput())
.contains("2. " + canonicalPathOf("build/classes/java/main"));
assertThat(result.getOutput())
.doesNotContain(canonicalPathOf("build/resources/main"));
}
@Test
public void applicationPluginMainClassNameIsUsed() throws IOException {
BuildResult result = this.gradleBuild.build("echoMainClassName");
assertThat(result.task(":echoMainClassName").getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
assertThat(result.getOutput())
.contains("Main class name = com.example.CustomMainClass");
}
@Test
public void applicationPluginMainClassNameIsNotUsedWhenItIsNull() throws IOException {
copyApplication();
BuildResult result = this.gradleBuild.build("echoMainClassName");
assertThat(result.task(":echoMainClassName").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput())
.contains("Main class name = com.example.BootRunApplication");
}
@Test
public void applicationPluginJvmArgumentsAreUsed() throws IOException {
BuildResult result = this.gradleBuild.build("echoJvmArguments");
assertThat(result.task(":echoJvmArguments").getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
assertThat(result.getOutput())
.contains("JVM arguments = [-Dcom.foo=bar, -Dcom.bar=baz]");
}
private void copyApplication() throws IOException {
File output = new File(this.gradleBuild.getProjectDir(),
"src/main/java/com/example");
output.mkdirs();
FileSystemUtils.copyRecursively(new File("src/test/java/com/example"), output);
}
private String canonicalPathOf(String path) throws IOException {
return new File(this.gradleBuild.getProjectDir(), path).getCanonicalPath();
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright 2012-2017 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.gradle.testkit;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import io.spring.gradle.dependencymanagement.DependencyManagementPlugin;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.xml.sax.InputSource;
import org.springframework.asm.ClassVisitor;
import org.springframework.boot.loader.tools.LaunchScript;
import org.springframework.util.FileCopyUtils;
/**
* A {@link TestRule} for running a Gradle build using {@link GradleRunner}.
*
* @author Andy Wilkinson
*/
public class GradleBuild implements TestRule {
private final TemporaryFolder temp = new TemporaryFolder();
private File projectDir;
private String script;
private String gradleVersion;
@Override
public Statement apply(Statement base, Description description) {
URL scriptUrl = findDefaultScript(description);
if (scriptUrl != null) {
script(scriptUrl.getFile());
}
return this.temp.apply(new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
}
finally {
after();
}
}
}, description);
}
private URL findDefaultScript(Description description) {
URL scriptUrl = getScriptForTestMethod(description);
if (scriptUrl != null) {
return scriptUrl;
}
return getScriptForTestClass(description.getTestClass());
}
private URL getScriptForTestMethod(Description description) {
String name = description.getTestClass().getSimpleName() + "-"
+ removeGradleVersion(description.getMethodName()) + ".gradle";
return description.getTestClass().getResource(name);
}
private String removeGradleVersion(String methodName) {
return methodName.replaceAll("\\[Gradle .+\\]", "").trim();
}
private URL getScriptForTestClass(Class<?> testClass) {
return testClass.getResource(testClass.getSimpleName() + ".gradle");
}
private void before() throws IOException {
this.projectDir = this.temp.newFolder();
}
private void after() {
GradleBuild.this.script = null;
}
private String pluginClasspath() {
return absolutePath("bin") + "," + absolutePath("build/classes/java/main") + ","
+ absolutePath("build/resources/main") + ","
+ pathOfJarContaining(LaunchScript.class) + ","
+ pathOfJarContaining(ClassVisitor.class) + ","
+ pathOfJarContaining(DependencyManagementPlugin.class) + ","
+ pathOfJarContaining(ArchiveEntry.class);
}
private String absolutePath(String path) {
return new File(path).getAbsolutePath();
}
private String pathOfJarContaining(Class<?> type) {
return type.getProtectionDomain().getCodeSource().getLocation().getPath();
}
public GradleBuild script(String script) {
this.script = script;
return this;
}
public BuildResult build(String... arguments) {
try {
return prepareRunner(arguments).build();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public BuildResult buildAndFail(String... arguments) {
try {
return prepareRunner(arguments).buildAndFail();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public GradleRunner prepareRunner(String... arguments) throws IOException {
String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script))
.replace("{version}", getBootVersion());
FileCopyUtils.copy(scriptContent,
new FileWriter(new File(this.projectDir, "build.gradle")));
GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir)
.withDebug(true);
if (this.gradleVersion != null) {
gradleRunner.withGradleVersion(this.gradleVersion);
}
List<String> allArguments = new ArrayList<>();
allArguments.add("-PpluginClasspath=" + pluginClasspath());
allArguments.add("-PbootVersion=" + getBootVersion());
allArguments.add("--stacktrace");
allArguments.addAll(Arrays.asList(arguments));
return gradleRunner.withArguments(allArguments);
}
public File getProjectDir() {
return this.projectDir;
}
public void setProjectDir(File projectDir) {
this.projectDir = projectDir;
}
public GradleBuild gradleVersion(String version) {
this.gradleVersion = version;
return this;
}
public String getGradleVersion() {
return this.gradleVersion;
}
private static String getBootVersion() {
return evaluateExpression(
"/*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']"
+ "/text()");
}
private static String evaluateExpression(String expression) {
try {
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
XPathExpression expr = xpath.compile(expression);
String version = expr.evaluate(new InputSource(new FileReader("pom.xml")));
return version;
}
catch (Exception ex) {
throw new IllegalStateException("Failed to evaluate expression", ex);
}
}
}