Merge pull request #21388 from aivinog1

* gh-21388:
  Polish "Test the launch script when executed directly"
  Test the launch script when executed directly

Closes gh-21388
pull/23053/head
Andy Wilkinson 4 years ago
commit c2ea114b61

@ -0,0 +1,122 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.launchscript;
import java.io.File;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.assertj.core.api.Condition;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.ToStringConsumer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.utility.MountableFile;
import org.springframework.boot.ansi.AnsiColor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
/**
* Abstract base class for testing the launch script.
*
* @author Andy Wilkinson
* @author Ali Shahbour
* @author Alexey Vinogradov
*/
abstract class AbstractLaunchScriptIT {
protected static final char ESC = 27;
private final String scriptsDir;
protected AbstractLaunchScriptIT(String scriptsDir) {
this.scriptsDir = scriptsDir;
}
static List<Object[]> parameters() {
List<Object[]> 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;
}
protected Condition<String> coloredString(AnsiColor color, String string) {
String colorString = ESC + "[0;" + color + "m" + string + ESC + "[0m";
return new Condition<String>() {
@Override
public boolean matches(String value) {
return containsString(colorString).matches(value);
}
};
}
protected void doLaunch(String os, String version, String script) throws Exception {
assertThat(doTest(os, version, script)).contains("Launched");
}
protected String doTest(String os, String version, String script) throws Exception {
ToStringConsumer consumer = new ToStringConsumer().withRemoveAnsiCodes(false);
try (LaunchScriptTestContainer container = new LaunchScriptTestContainer(os, version, this.scriptsDir,
script)) {
container.withLogConsumer(consumer);
container.start();
while (container.isRunning()) {
Thread.sleep(100);
}
}
return consumer.toUtf8String();
}
private static final class LaunchScriptTestContainer extends GenericContainer<LaunchScriptTestContainer> {
private LaunchScriptTestContainer(String os, String version, String scriptsDir, String testScript) {
super(new ImageFromDockerfile("spring-boot-launch-script/" + os.toLowerCase() + "-" + version)
.withFileFromFile("Dockerfile",
new File("src/test/resources/conf/" + os + "/" + version + "/Dockerfile")));
withCopyFileToContainer(MountableFile.forHostPath(findApplication().getAbsolutePath()),
"/spring-boot-launch-script-tests.jar");
withCopyFileToContainer(
MountableFile.forHostPath("src/test/resources/scripts/" + scriptsDir + "test-functions.sh"),
"/test-functions.sh");
withCopyFileToContainer(MountableFile.forHostPath("src/test/resources/scripts/" + scriptsDir + testScript),
"/" + testScript);
withCommand("/bin/bash", "-c", "chmod +x " + testScript + " && ./" + testScript);
withStartupTimeout(Duration.ofMinutes(10));
}
private static 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)?");
}
}
}

@ -0,0 +1,93 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.launchscript;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests of Spring Boot's launch script when executing the jar directly.
*
* @author Alexey Vinogradov
* @author Andy Wilkinson
*/
class JarLaunchScriptIT extends AbstractLaunchScriptIT {
JarLaunchScriptIT() {
super("jar/");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void basicLaunch(String os, String version) throws Exception {
doLaunch(os, version, "basic-launch.sh");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithDebugEnv(String os, String version) throws Exception {
final String output = doTest(os, version, "launch-with-debug.sh");
assertThat(output).contains("++ pwd");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithDifferentJarFileEnv(String os, String version) throws Exception {
final String output = doTest(os, version, "launch-with-jarfile.sh");
assertThat(output).contains("app-another.jar");
assertThat(output).doesNotContain("spring-boot-launch-script-tests.jar");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithSingleCommandLineArgument(String os, String version) throws Exception {
doLaunch(os, version, "launch-with-single-command-line-argument.sh");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithMultipleCommandLineArguments(String os, String version) throws Exception {
doLaunch(os, version, "launch-with-multiple-command-line-arguments.sh");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithSingleRunArg(String os, String version) throws Exception {
doLaunch(os, version, "launch-with-single-run-arg.sh");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithMultipleRunArgs(String os, String version) throws Exception {
doLaunch(os, version, "launch-with-multiple-run-args.sh");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithSingleJavaOpt(String os, String version) throws Exception {
doLaunch(os, version, "launch-with-single-java-opt.sh");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
void launchWithMultipleJavaOpts(String os, String version) throws Exception {
doLaunch(os, version, "launch-with-multiple-java-opts.sh");
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 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.
@ -16,35 +16,28 @@
package org.springframework.boot.launchscript;
import java.io.File;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.assertj.core.api.Condition;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.ToStringConsumer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.utility.MountableFile;
import org.springframework.boot.ansi.AnsiColor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
/**
* Integration tests for Spring Boot's launch script on OSs that use SysVinit.
*
* @author Andy Wilkinson
* @author Ali Shahbour
* @author Alexey Vinogradov
*/
class SysVinitLaunchScriptIT {
class SysVinitLaunchScriptIT extends AbstractLaunchScriptIT {
private static final char ESC = 27;
SysVinitLaunchScriptIT() {
super("init.d/");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
@ -277,44 +270,6 @@ class SysVinitLaunchScriptIT {
assertThat(output).has(coloredString(AnsiColor.RED, "Cannot run as 'wagner': current user is not root"));
}
static List<Object[]> parameters() {
List<Object[]> 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;
}
private void doLaunch(String os, String version, String script) throws Exception {
assertThat(doTest(os, version, script)).contains("Launched");
}
private String doTest(String os, String version, String script) throws Exception {
ToStringConsumer consumer = new ToStringConsumer().withRemoveAnsiCodes(false);
try (LaunchScriptTestContainer container = new LaunchScriptTestContainer(os, version, script)) {
container.withLogConsumer(consumer);
container.start();
while (container.isRunning()) {
Thread.sleep(100);
}
}
return consumer.toUtf8String();
}
private Condition<String> coloredString(AnsiColor color, String string) {
String colorString = ESC + "[0;" + color + "m" + string + ESC + "[0m";
return new Condition<String>() {
@Override
public boolean matches(String value) {
return containsString(colorString).matches(value);
}
};
}
private String extractPid(String output) {
return extract("PID", output);
}
@ -328,32 +283,4 @@ class SysVinitLaunchScriptIT {
throw new IllegalArgumentException("Failed to extract " + label + " from output: " + output);
}
private static final class LaunchScriptTestContainer extends GenericContainer<LaunchScriptTestContainer> {
private LaunchScriptTestContainer(String os, String version, String testScript) {
super(new ImageFromDockerfile("spring-boot-launch-script/" + os.toLowerCase() + "-" + version)
.withFileFromFile("Dockerfile",
new File("src/test/resources/conf/" + os + "/" + version + "/Dockerfile"))
.withFileFromFile("spring-boot-launch-script-tests.jar", findApplication())
.withFileFromFile("test-functions.sh", new File("src/test/resources/scripts/test-functions.sh")));
withCopyFileToContainer(MountableFile.forHostPath("src/test/resources/scripts/" + testScript),
"/" + testScript);
withCommand("/bin/bash", "-c", "chmod +x " + testScript + " && ./" + testScript);
withStartupTimeout(Duration.ofMinutes(10));
}
private static 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)?");
}
}
}

@ -7,5 +7,3 @@ RUN yum install -y wget && \
https://cdn.azul.com/zulu/bin/zulu8.21.0.1-jdk8.0.131-linux.x86_64.rpm && \
yum --nogpg localinstall -y jdk.rpm && \
rm -f jdk.rpm
ADD spring-boot-launch-script-tests.jar /spring-boot-launch-script-tests.jar
ADD test-functions.sh /test-functions.sh

@ -6,5 +6,3 @@ RUN apt-get update && \
curl -L https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u202-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u202b08.tar.gz | tar zx --strip-components=1
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
ADD spring-boot-launch-script-tests.jar /spring-boot-launch-script-tests.jar
ADD test-functions.sh /test-functions.sh

@ -6,5 +6,3 @@ RUN apt-get update && \
curl -L https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u202-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u202b08.tar.gz | tar zx --strip-components=1
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
ADD spring-boot-launch-script-tests.jar /spring-boot-launch-script-tests.jar
ADD test-functions.sh /test-functions.sh

@ -1,3 +1,22 @@
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
}
install_service() {
mkdir /test-service
mv /spring-boot-launch-script-tests.jar /test-service/spring-boot-app.jar
@ -31,23 +50,4 @@ stop_service() {
force_stop_service() {
service spring-boot-app force-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
}
}

@ -0,0 +1,4 @@
source ./test-functions.sh
launch_jar
await_app
curl -s http://127.0.0.1:8080/

@ -0,0 +1,5 @@
export DEBUG=true
source ./test-functions.sh
launch_jar
await_app
curl -s http://127.0.0.1:8080/

@ -0,0 +1,6 @@
source ./test-functions.sh
cp spring-boot-launch-script-tests.jar app-another.jar
export JARFILE=app-another.jar
launch_jar
await_app
curl -s http://127.0.0.1:8080/

@ -0,0 +1,4 @@
source ./test-functions.sh
launch_jar --server.port=8081 --server.servlet.context-path=/test
await_app http://127.0.0.1:8081/test/
curl -s http://127.0.0.1:8081/test/

@ -0,0 +1,5 @@
source ./test-functions.sh
echo 'JAVA_OPTS="-Dserver.port=8081 -Dserver.servlet.context-path=/test"' > spring-boot-launch-script-tests.conf
launch_jar
await_app http://127.0.0.1:8081/test/
curl -s http://127.0.0.1:8081/test/

@ -0,0 +1,5 @@
source ./test-functions.sh
echo 'RUN_ARGS="--server.port=8081 --server.servlet.context-path=/test"' > spring-boot-launch-script-tests.conf
launch_jar
await_app http://127.0.0.1:8081/test/
curl -s http://127.0.0.1:8081/test/

@ -0,0 +1,4 @@
source ./test-functions.sh
launch_jar --server.port=8081
await_app http://127.0.0.1:8081/
curl -s http://127.0.0.1:8081/

@ -0,0 +1,5 @@
source ./test-functions.sh
echo 'JAVA_OPTS=-Dserver.port=8081' > spring-boot-launch-script-tests.conf
launch_jar
await_app http://127.0.0.1:8081/
curl -s http://127.0.0.1:8081/

@ -0,0 +1,5 @@
source ./test-functions.sh
echo 'RUN_ARGS=--server.port=8081' > /spring-boot-launch-script-tests.conf
launch_jar
await_app http://127.0.0.1:8081/
curl -s http://127.0.0.1:8081/

@ -0,0 +1,22 @@
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
}
launch_jar() {
./spring-boot-launch-script-tests.jar $@ &
}
Loading…
Cancel
Save