diff --git a/spring-boot-integration-tests/pom.xml b/spring-boot-integration-tests/pom.xml index a7459ddf000..06f8844b070 100644 --- a/spring-boot-integration-tests/pom.xml +++ b/spring-boot-integration-tests/pom.xml @@ -19,9 +19,11 @@ ${basedir}/.. 1.8 + 2.1.2 spring-boot-gradle-tests + spring-boot-launch-script-tests spring-boot-security-tests diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/README.adoc b/spring-boot-integration-tests/spring-boot-launch-script-tests/README.adoc new file mode 100644 index 00000000000..3a4739015e2 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/README.adoc @@ -0,0 +1,75 @@ += Spring Boot Launch Script Tests + +This module contains integration tests for the default launch script that is used +to make a jar file fully executable on Linux. The tests use Docker to verify the +functionality in a variety of Linux distributions. + +== Setting up Docker + +The setup that's required varies depending on your operating system. + +=== Docker on OS X + +Docker relies on Linux kernel features so the Docker Daemon must be run inside a Linux VM. +Following the https://docs.docker.com/engine/installation/mac/[OS X installation +instructions] to install Docker Toolbox which uses VirtualBox to host the required VM. + +=== Docker on Linux + +Install Docker as appropriate for your Linux distribution. See the +https://docs.docker.com/engine/installation/[Linux installation instructions] for more +information. + +Next, add your user to the `docker` group. For example: + +---- +$ sudo usermod -a -G docker awilkinson +---- + +You may need to log out and back in again for this change to take affect and for your +user to be able to connect to the daemon. + +== Preparing to run the tests + +Before running the tests, you must prepare your environment according to your operating +system. + +=== Preparation on OS X + +The tests must be run in an environment where various environment variables including +`DOCKER_HOST` and `DOCKER_CERT_PATH` have been set: + +---- +$ eval $(docker-machine env default) +---- + +=== Preparation on Linux + +Docker Daemon's default configuration on Linux uses a Unix socket for communication. +However, Docker's Java client uses HTTP by default. Docker Java's client can be configured +to use the Unix socket via the `DOCKER_URL` environment variable: + +---- +$ export DOCKER_URL=unix:///var/run/docker.sock +---- + +== Running the tests + +You're now ready to run the tests. Assuming that you're in the same directory as this +README, the tests can be launched as follows: + +---- +$ mvn -Pdocker clean verify +---- + +The first time the tests are run, Docker will create the container images that are used to +run the tests. This can take several minutes, particularly if you have a slow network +connection. Subsequent runs will be faster as the images are cached locally. You can run +`docker images` to see a list of the cached images. + +== Cleaning up + +If you want to reclaim the disk space used by the cached images (at the expense of having +to wait for them to be downloaded and rebuilt the next time you run the tests), you can +use `docker images` to list the images and `docker rmi ` to delete them. See +`docker rmi --help` for further details. \ No newline at end of file diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/pom.xml b/spring-boot-integration-tests/spring-boot-launch-script-tests/pom.xml new file mode 100644 index 00000000000..04f83a5f24c --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-integration-tests + 1.3.2.BUILD-SNAPSHOT + + spring-boot-launch-script-tests + jar + Spring Boot Launch Script Integration Tests + Spring Boot Launch Script Integration Tests + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-undertow + + + com.github.docker-java + docker-java + 2.1.4 + test + + + org.springframework.boot + spring-boot-starter-test + test + + + + + docker + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + + + diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/main/java/org/springframework/boot/launchscript/LaunchScriptTestApplication.java b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/main/java/org/springframework/boot/launchscript/LaunchScriptTestApplication.java new file mode 100644 index 00000000000..dae663ff172 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/main/java/org/springframework/boot/launchscript/LaunchScriptTestApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2016 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.launchscript; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class LaunchScriptTestApplication { + + public static void main(String[] args) { + SpringApplication.run(LaunchScriptTestApplication.class, args); + } + +} diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/main/java/org/springframework/boot/launchscript/LaunchVerficationController.java b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/main/java/org/springframework/boot/launchscript/LaunchVerficationController.java new file mode 100644 index 00000000000..d5f0d697488 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/main/java/org/springframework/boot/launchscript/LaunchVerficationController.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-2016 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.launchscript; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class LaunchVerficationController { + + @RequestMapping("/") + public String verifyLaunch() { + return "Launched"; + } + +} diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java new file mode 100644 index 00000000000..69e50381903 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java @@ -0,0 +1,365 @@ +/* + * Copyright 2012-2016 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.launchscript; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.DockerCmd; +import com.github.dockerjava.api.model.Frame; +import com.github.dockerjava.core.CompressArchiveUtil; +import com.github.dockerjava.core.DockerClientBuilder; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.command.AttachContainerResultCallback; +import com.github.dockerjava.core.command.BuildImageResultCallback; +import com.github.dockerjava.jaxrs.AbstrSyncDockerCmdExec; +import com.github.dockerjava.jaxrs.DockerCmdExecFactoryImpl; +import org.hamcrest.Matcher; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import org.springframework.boot.ansi.AnsiColor; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Integration tests for Spring Boot's launch script on OSs that use SysVinit. + * + * @author Andy Wilkinson + */ +@RunWith(Parameterized.class) +public class SysVinitLaunchScriptIT { + + private final SpringBootDockerCmdExecFactory commandExecFactory = new SpringBootDockerCmdExecFactory(); + + private static final char ESC = 27; + + private final String os; + + private final String version; + + @Parameters(name = "{0} {1}") + public static List parameters() { + List parameters = new ArrayList(); + for (File os : new File("src/test/resources/conf").listFiles()) { + for (File version : os.listFiles()) { + parameters.add(new Object[] { os.getName(), version.getName() }); + } + } + return parameters; + } + + public SysVinitLaunchScriptIT(String os, String version) { + this.os = os; + this.version = version; + } + + @Test + public void statusWhenStopped() throws Exception { + String output = doTest("status-when-stopped.sh"); + assertThat(output, containsString("Status: 3")); + assertThat(output, containsColoredString(AnsiColor.RED, "Not running")); + } + + @Test + public void statusWhenStarted() throws Exception { + String output = doTest("status-when-started.sh"); + assertThat(output, containsString("Status: 0")); + assertThat(output, containsColoredString(AnsiColor.GREEN, + "Started [" + extractPid(output) + "]")); + } + + @Test + public void statusWhenKilled() throws Exception { + String output = doTest("status-when-killed.sh"); + assertThat(output, containsString("Status: 1")); + assertThat(output, containsColoredString(AnsiColor.RED, + "Not running (process " + extractPid(output) + " not found)")); + } + + @Test + public void stopWhenStopped() throws Exception { + String output = doTest("stop-when-stopped.sh"); + assertThat(output, containsString("Status: 0")); + assertThat(output, containsColoredString(AnsiColor.YELLOW, + "Not running (pidfile not found)")); + } + + @Test + public void startWhenStarted() throws Exception { + String output = doTest("start-when-started.sh"); + assertThat(output, containsString("Status: 0")); + assertThat(output, containsColoredString(AnsiColor.YELLOW, + "Already running [" + extractPid(output) + "]")); + } + + @Test + public void restartWhenStopped() throws Exception { + String output = doTest("restart-when-stopped.sh"); + assertThat(output, containsString("Status: 0")); + assertThat(output, containsColoredString(AnsiColor.YELLOW, + "Not running (pidfile not found)")); + assertThat(output, containsColoredString(AnsiColor.GREEN, + "Started [" + extractPid(output) + "]")); + } + + @Test + public void restartWhenStarted() throws Exception { + String output = doTest("restart-when-started.sh"); + assertThat(output, containsString("Status: 0")); + assertThat(output, containsColoredString(AnsiColor.GREEN, + "Started [" + extract("PID1", output) + "]")); + assertThat(output, containsColoredString(AnsiColor.GREEN, + "Stopped [" + extract("PID1", output) + "]")); + assertThat(output, containsColoredString(AnsiColor.GREEN, + "Started [" + extract("PID2", output) + "]")); + } + + @Test + public void startWhenStopped() throws Exception { + String output = doTest("start-when-stopped.sh"); + assertThat(output, containsString("Status: 0")); + assertThat(output, containsColoredString(AnsiColor.GREEN, + "Started [" + extractPid(output) + "]")); + } + + @Test + public void basicLaunch() throws Exception { + doLaunch("basic-launch.sh"); + } + + @Test + public void launchWithSingleCommandLineArgument() throws Exception { + doLaunch("launch-with-single-command-line-argument.sh"); + } + + @Test + public void launchWithMultipleCommandLineArguments() throws Exception { + doLaunch("launch-with-multiple-command-line-arguments.sh"); + } + + @Test + public void launchWithSingleRunArg() throws Exception { + doLaunch("launch-with-single-run-arg.sh"); + } + + @Test + public void launchWithMultipleRunArgs() throws Exception { + doLaunch("launch-with-multiple-run-args.sh"); + } + + @Test + public void launchWithSingleJavaOpt() throws Exception { + doLaunch("launch-with-single-java-opt.sh"); + } + + @Test + public void launchWithMultipleJavaOpts() throws Exception { + doLaunch("launch-with-multiple-java-opts.sh"); + } + + private void doLaunch(String script) throws Exception { + assertThat(doTest(script), containsString("Launched")); + } + + private String doTest(String script) throws Exception { + DockerClient docker = createClient(); + String imageId = buildImage(docker); + String container = createContainer(docker, imageId, script); + copyFilesToContainer(docker, container, script); + docker.startContainerCmd(container).exec(); + StringBuilder output = new StringBuilder(); + AttachContainerResultCallback resultCallback = docker + .attachContainerCmd(container).withStdOut(true).withStdErr(true) + .withFollowStream(true).withLogs(true) + .exec(new AttachContainerResultCallback() { + + @Override + public void onNext(Frame item) { + output.append(new String(item.getPayload())); + super.onNext(item); + } + + }); + resultCallback.awaitCompletion(60, TimeUnit.SECONDS).close(); + docker.waitContainerCmd(container).exec(); + return output.toString(); + } + + private DockerClient createClient() { + DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder() + .build(); + DockerClient docker = DockerClientBuilder.getInstance(config) + .withDockerCmdExecFactory(this.commandExecFactory).build(); + return docker; + } + + private String buildImage(DockerClient docker) { + BuildImageResultCallback resultCallback = new BuildImageResultCallback(); + String dockerfile = "src/test/resources/conf/" + this.os + "/" + this.version + + "/Dockerfile"; + docker.buildImageCmd(new File(dockerfile)).exec(resultCallback); + String imageId = resultCallback.awaitImageId(); + return imageId; + } + + private String createContainer(DockerClient docker, String imageId, + String testScript) { + return docker.createContainerCmd(imageId).withTty(false).withCmd("/bin/bash", + "-c", "chmod +x " + testScript + " && ./" + testScript).exec().getId(); + } + + private void copyFilesToContainer(DockerClient docker, final String container, + String script) { + copyToContainer(docker, container, findApplication()); + copyToContainer(docker, container, + new File("src/test/resources/scripts/test-functions.sh")); + copyToContainer(docker, container, + new File("src/test/resources/scripts/" + script)); + } + + private void copyToContainer(DockerClient docker, final String container, + final File file) { + this.commandExecFactory.createCopyToContainerCmdExec() + .exec(new CopyToContainerCmd(container, file)); + } + + private File findApplication() { + File targetDir = new File("target"); + for (File file : targetDir.listFiles()) { + if (file.getName().startsWith("spring-boot-launch-script-tests") + && file.getName().endsWith(".jar") + && !file.getName().endsWith("-sources.jar")) { + return file; + } + } + throw new IllegalStateException( + "Could not find test application in target directory. Have you built it (mvn package)?"); + } + + private Matcher containsColoredString(AnsiColor color, String string) { + return containsString(ESC + "[0;" + color + "m" + string + ESC + "[0m"); + } + + private String extractPid(String output) { + return extract("PID", output); + } + + private String extract(String label, String output) { + Pattern pattern = Pattern.compile(".*" + label + ": ([0-9]+).*", Pattern.DOTALL); + java.util.regex.Matcher matcher = pattern.matcher(output); + if (matcher.matches()) { + return matcher.group(1); + } + throw new IllegalArgumentException( + "Failed to extract " + label + " from output: " + output); + } + + private static final class CopyToContainerCmdExec + extends AbstrSyncDockerCmdExec { + + private CopyToContainerCmdExec(WebTarget baseResource, + DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(CopyToContainerCmd command) { + try { + InputStream streamToUpload = new FileInputStream(CompressArchiveUtil + .archiveTARFiles(command.getFile().getParentFile(), + Arrays.asList(command.getFile()), + command.getFile().getName())); + WebTarget webResource = getBaseResource().path("/containers/{id}/archive") + .resolveTemplate("id", command.getContainer()); + webResource.queryParam("path", ".") + .queryParam("noOverwriteDirNonDir", false).request() + .put(Entity.entity(streamToUpload, "application/x-tar")).close(); + return null; + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + } + + private static final class CopyToContainerCmd implements DockerCmd { + + private final String container; + + private final File file; + + private CopyToContainerCmd(String container, File file) { + this.container = container; + this.file = file; + } + + public String getContainer() { + return this.container; + } + + public File getFile() { + return this.file; + } + + @Override + public void close() { + + } + + } + + private static final class SpringBootDockerCmdExecFactory + extends DockerCmdExecFactoryImpl { + + private SpringBootDockerCmdExecFactory() { + withClientRequestFilters(new ClientRequestFilter() { + + @Override + public void filter(ClientRequestContext requestContext) + throws IOException { + // Workaround for https://go-review.googlesource.com/#/c/3821/ + requestContext.getHeaders().add("Connection", "close"); + } + + }); + } + + private CopyToContainerCmdExec createCopyToContainerCmdExec() { + return new CopyToContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + } + +} diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/CentOS/5.11/Dockerfile b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/CentOS/5.11/Dockerfile new file mode 100644 index 00000000000..e5b17b24ec0 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/CentOS/5.11/Dockerfile @@ -0,0 +1,11 @@ +FROM centos:5.11 +RUN yum install -y wget && \ + yum install -y system-config-services && \ + yum install -y curl && \ + wget --no-cookies \ + --no-check-certificate \ + --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" \ + --output-document jdk.rpm \ + http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.rpm && \ + yum --nogpg localinstall -y jdk.rpm && \ + rm -f jdk.rpm diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/CentOS/6.7/Dockerfile b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/CentOS/6.7/Dockerfile new file mode 100644 index 00000000000..919ab0f9918 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/CentOS/6.7/Dockerfile @@ -0,0 +1,11 @@ +FROM centos:6.7 +RUN yum install -y wget && \ + yum install -y system-config-services && \ + yum install -y curl && \ + wget --no-cookies \ + --no-check-certificate \ + --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" \ + --output-document jdk.rpm \ + http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.rpm && \ + yum --nogpg localinstall -y jdk.rpm && \ + rm -f jdk.rpm diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/Ubuntu/14.04.3/Dockerfile b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/Ubuntu/14.04.3/Dockerfile new file mode 100644 index 00000000000..935cd05dd2f --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/conf/Ubuntu/14.04.3/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:14.04.3 +RUN apt-get install -y software-properties-common && \ + add-apt-repository ppa:webupd8team/java -y && \ + apt-get update && \ + echo oracle-java7-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \ + apt-get install -y oracle-java8-installer && \ + apt-get install -y curl && \ + apt-get clean diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/logback.xml b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/logback.xml new file mode 100644 index 00000000000..51a2f698fab --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/basic-launch.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/basic-launch.sh new file mode 100755 index 00000000000..44f44a856c6 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/basic-launch.sh @@ -0,0 +1,5 @@ +source ./test-functions.sh +install_service +start_service +await_app +curl -s http://127.0.0.1:8080/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-command-line-arguments.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-command-line-arguments.sh new file mode 100755 index 00000000000..7086d3051cd --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-command-line-arguments.sh @@ -0,0 +1,5 @@ +source ./test-functions.sh +install_service +start_service --server.port=8081 --server.context-path=/test +await_app http://127.0.0.1:8081/test/ +curl -s http://127.0.0.1:8081/test/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-java-opts.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-java-opts.sh new file mode 100755 index 00000000000..701ba50ee80 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-java-opts.sh @@ -0,0 +1,6 @@ +source ./test-functions.sh +echo 'JAVA_OPTS="-Dserver.port=8081 -Dserver.context-path=/test"' > /spring-boot-app.conf +install_service +start_service +await_app http://127.0.0.1:8081/test/ +curl -s http://127.0.0.1:8081/test/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-run-args.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-run-args.sh new file mode 100755 index 00000000000..9ab7c4b869c --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-multiple-run-args.sh @@ -0,0 +1,6 @@ +source ./test-functions.sh +echo 'RUN_ARGS="--server.port=8081 --server.context-path=/test"' > /spring-boot-app.conf +install_service +start_service +await_app http://127.0.0.1:8081/test/ +curl -s http://127.0.0.1:8081/test/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-command-line-argument.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-command-line-argument.sh new file mode 100755 index 00000000000..2adb76da3fc --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-command-line-argument.sh @@ -0,0 +1,5 @@ +source ./test-functions.sh +install_service +start_service --server.port=8081 +await_app http://127.0.0.1:8081/ +curl -s http://127.0.0.1:8081/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-java-opt.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-java-opt.sh new file mode 100755 index 00000000000..f7052dc5ee5 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-java-opt.sh @@ -0,0 +1,6 @@ +source ./test-functions.sh +echo 'JAVA_OPTS=-Dserver.port=8081' > /spring-boot-app.conf +install_service +start_service +await_app http://127.0.0.1:8081/ +curl -s http://127.0.0.1:8081/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-run-arg.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-run-arg.sh new file mode 100755 index 00000000000..c79633e32de --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/launch-with-single-run-arg.sh @@ -0,0 +1,6 @@ +source ./test-functions.sh +echo 'RUN_ARGS=--server.port=8081' > /spring-boot-app.conf +install_service +start_service +await_app http://127.0.0.1:8081/ +curl -s http://127.0.0.1:8081/ diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/restart-when-started.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/restart-when-started.sh new file mode 100755 index 00000000000..017b4c18e84 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/restart-when-started.sh @@ -0,0 +1,7 @@ +source ./test-functions.sh +install_service +start_service +echo "PID1: $(cat /var/run/spring-boot-app/spring-boot-app.pid)" +restart_service +echo "Status: $?" +echo "PID2: $(cat /var/run/spring-boot-app/spring-boot-app.pid)" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/restart-when-stopped.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/restart-when-stopped.sh new file mode 100755 index 00000000000..95fd91c3b44 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/restart-when-stopped.sh @@ -0,0 +1,5 @@ +source ./test-functions.sh +install_service +restart_service +echo "Status: $?" +echo "PID: $(cat /var/run/spring-boot-app/spring-boot-app.pid)" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/start-when-started.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/start-when-started.sh new file mode 100755 index 00000000000..fd9e4f2f6b8 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/start-when-started.sh @@ -0,0 +1,6 @@ +source ./test-functions.sh +install_service +start_service +echo "PID: $(cat /var/run/spring-boot-app/spring-boot-app.pid)" +start_service +echo "Status: $?" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/start-when-stopped.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/start-when-stopped.sh new file mode 100755 index 00000000000..427fff4406a --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/start-when-stopped.sh @@ -0,0 +1,5 @@ +source ./test-functions.sh +install_service +start_service +echo "Status: $?" +echo "PID: $(cat /var/run/spring-boot-app/spring-boot-app.pid)" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-killed.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-killed.sh new file mode 100755 index 00000000000..4a9c5f6fe12 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-killed.sh @@ -0,0 +1,8 @@ +source ./test-functions.sh +install_service +start_service +pid=$(cat /var/run/spring-boot-app/spring-boot-app.pid) +echo "PID: $pid" +kill -9 $pid +status_service +echo "Status: $?" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-started.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-started.sh new file mode 100755 index 00000000000..89c1ccc1fb5 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-started.sh @@ -0,0 +1,6 @@ +source ./test-functions.sh +install_service +start_service +status_service +echo "Status: $?" +echo "PID: $(cat /var/run/spring-boot-app/spring-boot-app.pid)" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-stopped.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-stopped.sh new file mode 100755 index 00000000000..24ca2253444 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/status-when-stopped.sh @@ -0,0 +1,4 @@ +source ./test-functions.sh +install_service +status_service +echo "Status: $?" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/stop-when-stopped.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/stop-when-stopped.sh new file mode 100755 index 00000000000..b74faddbafd --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/stop-when-stopped.sh @@ -0,0 +1,4 @@ +source ./test-functions.sh +install_service +stop_service +echo "Status: $?" diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/test-functions.sh b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/test-functions.sh new file mode 100644 index 00000000000..30f509db924 --- /dev/null +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/resources/scripts/test-functions.sh @@ -0,0 +1,40 @@ +install_service() { + mv /spring-boot-launch-script-tests-*.jar /spring-boot-app.jar + chmod +x /spring-boot-app.jar + ln -s /spring-boot-app.jar /etc/init.d/spring-boot-app +} + +start_service() { + service spring-boot-app start $@ +} + +restart_service() { + service spring-boot-app restart +} + +status_service() { + service spring-boot-app status +} + +stop_service() { + service spring-boot-app stop +} + +await_app() { + if [ -z $1 ] + then + url=http://127.0.0.1:8080 + else + url=$1 + fi + end=$(date +%s) + let "end+=30" + until curl -s $url > /dev/null + do + now=$(date +%s) + if [[ $now -ge $end ]]; then + break + fi + sleep 1 + done +} diff --git a/spring-boot-parent/src/checkstyle/checkstyle-suppressions.xml b/spring-boot-parent/src/checkstyle/checkstyle-suppressions.xml index f2d48950261..88ab83c12b2 100644 --- a/spring-boot-parent/src/checkstyle/checkstyle-suppressions.xml +++ b/spring-boot-parent/src/checkstyle/checkstyle-suppressions.xml @@ -5,6 +5,7 @@ +