Skip to content

Commit 3210bc5

Browse files
committed
Merge branch '2.3.x'
Closes gh-22722
2 parents 3354e0f + 323b097 commit 3210bc5

File tree

48 files changed

+302
-100
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+302
-100
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.launchscript;
18+
19+
import java.io.File;
20+
import java.time.Duration;
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
24+
import org.assertj.core.api.Condition;
25+
import org.testcontainers.containers.GenericContainer;
26+
import org.testcontainers.containers.output.ToStringConsumer;
27+
import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy;
28+
import org.testcontainers.images.builder.ImageFromDockerfile;
29+
import org.testcontainers.utility.MountableFile;
30+
31+
import org.springframework.boot.ansi.AnsiColor;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.hamcrest.Matchers.containsString;
35+
36+
/**
37+
* Abstract base class for testing the launch script.
38+
*
39+
* @author Andy Wilkinson
40+
* @author Ali Shahbour
41+
* @author Alexey Vinogradov
42+
*/
43+
abstract class AbstractLaunchScriptIntegrationTests {
44+
45+
protected static final char ESC = 27;
46+
47+
private final String scriptsDir;
48+
49+
protected AbstractLaunchScriptIntegrationTests(String scriptsDir) {
50+
this.scriptsDir = scriptsDir;
51+
}
52+
53+
static List<Object[]> parameters() {
54+
List<Object[]> parameters = new ArrayList<>();
55+
for (File os : new File("src/intTest/resources/conf").listFiles()) {
56+
for (File version : os.listFiles()) {
57+
parameters.add(new Object[] { os.getName(), version.getName() });
58+
}
59+
}
60+
return parameters;
61+
}
62+
63+
protected Condition<String> coloredString(AnsiColor color, String string) {
64+
String colorString = ESC + "[0;" + color + "m" + string + ESC + "[0m";
65+
return new Condition<String>() {
66+
67+
@Override
68+
public boolean matches(String value) {
69+
return containsString(colorString).matches(value);
70+
}
71+
72+
};
73+
}
74+
75+
protected void doLaunch(String os, String version, String script) throws Exception {
76+
assertThat(doTest(os, version, script)).contains("Launched");
77+
}
78+
79+
protected String doTest(String os, String version, String script) throws Exception {
80+
ToStringConsumer consumer = new ToStringConsumer().withRemoveAnsiCodes(false);
81+
try (LaunchScriptTestContainer container = new LaunchScriptTestContainer(os, version, this.scriptsDir,
82+
script)) {
83+
container.withLogConsumer(consumer);
84+
container.start();
85+
while (container.isRunning()) {
86+
Thread.sleep(100);
87+
}
88+
}
89+
return consumer.toUtf8String();
90+
}
91+
92+
private static final class LaunchScriptTestContainer extends GenericContainer<LaunchScriptTestContainer> {
93+
94+
private LaunchScriptTestContainer(String os, String version, String scriptsDir, String testScript) {
95+
super(new ImageFromDockerfile("spring-boot-launch-script/" + os.toLowerCase() + "-" + version)
96+
.withFileFromFile("Dockerfile",
97+
new File("src/intTest/resources/conf/" + os + "/" + version + "/Dockerfile")));
98+
withCopyFileToContainer(MountableFile.forHostPath(findApplication().getAbsolutePath()), "/app.jar");
99+
withCopyFileToContainer(
100+
MountableFile.forHostPath("src/intTest/resources/scripts/" + scriptsDir + "test-functions.sh"),
101+
"/test-functions.sh");
102+
withCopyFileToContainer(
103+
MountableFile.forHostPath("src/intTest/resources/scripts/" + scriptsDir + testScript),
104+
"/" + testScript);
105+
withCommand("/bin/bash", "-c", "chmod +x " + testScript + " && ./" + testScript);
106+
withStartupCheckStrategy(new OneShotStartupCheckStrategy().withTimeout(Duration.ofMinutes(5)));
107+
}
108+
109+
private static File findApplication() {
110+
File appJar = new File("build/app/build/libs/app.jar");
111+
if (appJar.isFile()) {
112+
return appJar;
113+
}
114+
throw new IllegalStateException(
115+
"Could not find test application in build/app/build/libs directory. Have you built it?");
116+
}
117+
118+
}
119+
120+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.launchscript;
18+
19+
import org.junit.jupiter.params.ParameterizedTest;
20+
import org.junit.jupiter.params.provider.MethodSource;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
24+
/**
25+
* Integration tests of Spring Boot's launch script when executing the jar directly.
26+
*
27+
* @author Alexey Vinogradov
28+
* @author Andy Wilkinson
29+
*/
30+
class JarLaunchScriptIntegrationTests extends AbstractLaunchScriptIntegrationTests {
31+
32+
JarLaunchScriptIntegrationTests() {
33+
super("jar/");
34+
}
35+
36+
@ParameterizedTest(name = "{0} {1}")
37+
@MethodSource("parameters")
38+
void basicLaunch(String os, String version) throws Exception {
39+
doLaunch(os, version, "basic-launch.sh");
40+
}
41+
42+
@ParameterizedTest(name = "{0} {1}")
43+
@MethodSource("parameters")
44+
void launchWithDebugEnv(String os, String version) throws Exception {
45+
final String output = doTest(os, version, "launch-with-debug.sh");
46+
assertThat(output).contains("++ pwd");
47+
}
48+
49+
@ParameterizedTest(name = "{0} {1}")
50+
@MethodSource("parameters")
51+
void launchWithDifferentJarFileEnv(String os, String version) throws Exception {
52+
final String output = doTest(os, version, "launch-with-jarfile.sh");
53+
assertThat(output).contains("app-another.jar");
54+
assertThat(output).doesNotContain("spring-boot-launch-script-tests.jar");
55+
}
56+
57+
@ParameterizedTest(name = "{0} {1}")
58+
@MethodSource("parameters")
59+
void launchWithSingleCommandLineArgument(String os, String version) throws Exception {
60+
doLaunch(os, version, "launch-with-single-command-line-argument.sh");
61+
}
62+
63+
@ParameterizedTest(name = "{0} {1}")
64+
@MethodSource("parameters")
65+
void launchWithMultipleCommandLineArguments(String os, String version) throws Exception {
66+
doLaunch(os, version, "launch-with-multiple-command-line-arguments.sh");
67+
}
68+
69+
@ParameterizedTest(name = "{0} {1}")
70+
@MethodSource("parameters")
71+
void launchWithSingleRunArg(String os, String version) throws Exception {
72+
doLaunch(os, version, "launch-with-single-run-arg.sh");
73+
}
74+
75+
@ParameterizedTest(name = "{0} {1}")
76+
@MethodSource("parameters")
77+
void launchWithMultipleRunArgs(String os, String version) throws Exception {
78+
doLaunch(os, version, "launch-with-multiple-run-args.sh");
79+
}
80+
81+
@ParameterizedTest(name = "{0} {1}")
82+
@MethodSource("parameters")
83+
void launchWithSingleJavaOpt(String os, String version) throws Exception {
84+
doLaunch(os, version, "launch-with-single-java-opt.sh");
85+
}
86+
87+
@ParameterizedTest(name = "{0} {1}")
88+
@MethodSource("parameters")
89+
void launchWithMultipleJavaOpts(String os, String version) throws Exception {
90+
doLaunch(os, version, "launch-with-multiple-java-opts.sh");
91+
}
92+
93+
}

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIntegrationTests.java

Lines changed: 5 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,30 @@
1616

1717
package org.springframework.boot.launchscript;
1818

19-
import java.io.File;
20-
import java.time.Duration;
21-
import java.util.ArrayList;
22-
import java.util.List;
2319
import java.util.regex.Pattern;
2420

25-
import org.assertj.core.api.Condition;
2621
import org.junit.jupiter.api.Assumptions;
2722
import org.junit.jupiter.params.ParameterizedTest;
2823
import org.junit.jupiter.params.provider.MethodSource;
29-
import org.testcontainers.containers.GenericContainer;
30-
import org.testcontainers.containers.output.ToStringConsumer;
31-
import org.testcontainers.images.builder.ImageFromDockerfile;
32-
import org.testcontainers.utility.MountableFile;
3324

3425
import org.springframework.boot.ansi.AnsiColor;
3526
import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable;
3627

3728
import static org.assertj.core.api.Assertions.assertThat;
38-
import static org.hamcrest.Matchers.containsString;
3929

4030
/**
4131
* Integration tests for Spring Boot's launch script on OSs that use SysVinit.
4232
*
4333
* @author Andy Wilkinson
4434
* @author Ali Shahbour
35+
* @author Alexey Vinogradov
4536
*/
4637
@DisabledIfDockerUnavailable
47-
class SysVinitLaunchScriptIntegrationTests {
38+
class SysVinitLaunchScriptIntegrationTests extends AbstractLaunchScriptIntegrationTests {
4839

49-
private static final char ESC = 27;
40+
SysVinitLaunchScriptIntegrationTests() {
41+
super("init.d/");
42+
}
5043

5144
@ParameterizedTest(name = "{0} {1}")
5245
@MethodSource("parameters")
@@ -279,44 +272,6 @@ void whenLaunchedUsingNonRootUserWithRunAsUserSpecifiedLaunchFailsWithInsufficie
279272
assertThat(output).has(coloredString(AnsiColor.RED, "Cannot run as 'wagner': current user is not root"));
280273
}
281274

282-
static List<Object[]> parameters() {
283-
List<Object[]> parameters = new ArrayList<>();
284-
for (File os : new File("src/intTest/resources/conf").listFiles()) {
285-
for (File version : os.listFiles()) {
286-
parameters.add(new Object[] { os.getName(), version.getName() });
287-
}
288-
}
289-
return parameters;
290-
}
291-
292-
private void doLaunch(String os, String version, String script) throws Exception {
293-
assertThat(doTest(os, version, script)).contains("Launched");
294-
}
295-
296-
private String doTest(String os, String version, String script) throws Exception {
297-
ToStringConsumer consumer = new ToStringConsumer().withRemoveAnsiCodes(false);
298-
try (LaunchScriptTestContainer container = new LaunchScriptTestContainer(os, version, script)) {
299-
container.withLogConsumer(consumer);
300-
container.start();
301-
while (container.isRunning()) {
302-
Thread.sleep(100);
303-
}
304-
}
305-
return consumer.toUtf8String();
306-
}
307-
308-
private Condition<String> coloredString(AnsiColor color, String string) {
309-
String colorString = ESC + "[0;" + color + "m" + string + ESC + "[0m";
310-
return new Condition<String>() {
311-
312-
@Override
313-
public boolean matches(String value) {
314-
return containsString(colorString).matches(value);
315-
}
316-
317-
};
318-
}
319-
320275
private String extractPid(String output) {
321276
return extract("PID", output);
322277
}
@@ -330,29 +285,4 @@ private String extract(String label, String output) {
330285
throw new IllegalArgumentException("Failed to extract " + label + " from output: " + output);
331286
}
332287

333-
private static final class LaunchScriptTestContainer extends GenericContainer<LaunchScriptTestContainer> {
334-
335-
private LaunchScriptTestContainer(String os, String version, String testScript) {
336-
super(new ImageFromDockerfile("spring-boot-launch-script/" + os.toLowerCase() + "-" + version)
337-
.withFileFromFile("Dockerfile",
338-
new File("src/intTest/resources/conf/" + os + "/" + version + "/Dockerfile"))
339-
.withFileFromFile("app.jar", findApplication()).withFileFromFile("test-functions.sh",
340-
new File("src/intTest/resources/scripts/test-functions.sh")));
341-
withCopyFileToContainer(MountableFile.forHostPath("src/intTest/resources/scripts/" + testScript),
342-
"/" + testScript);
343-
withCommand("/bin/bash", "-c", "chmod +x " + testScript + " && ./" + testScript);
344-
withStartupTimeout(Duration.ofMinutes(10));
345-
}
346-
347-
private static File findApplication() {
348-
File appJar = new File("build/app/build/libs/app.jar");
349-
if (appJar.isFile()) {
350-
return appJar;
351-
}
352-
throw new IllegalStateException(
353-
"Could not find test application in build/app/build/libs directory. Have you built it?");
354-
}
355-
356-
}
357-
358288
}

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/resources/conf/CentOS/6.9-a23bced6/Dockerfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,3 @@ RUN yum install -y wget && \
77
https://cdn.azul.com/zulu/bin/zulu8.21.0.1-jdk8.0.131-linux.x86_64.rpm && \
88
yum --nogpg localinstall -y jdk.rpm && \
99
rm -f jdk.rpm
10-
ADD app.jar /app.jar
11-
ADD test-functions.sh /test-functions.sh

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/resources/conf/Ubuntu/trusty-20160914/Dockerfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,3 @@ RUN apt-get update && \
66
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
77
ENV JAVA_HOME /opt/openjdk
88
ENV PATH $JAVA_HOME/bin:$PATH
9-
ADD app.jar /app.jar
10-
ADD test-functions.sh /test-functions.sh

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/resources/conf/Ubuntu/xenial-20160914/Dockerfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,3 @@ RUN apt-get update && \
66
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
77
ENV JAVA_HOME /opt/openjdk
88
ENV PATH $JAVA_HOME/bin:$PATH
9-
ADD app.jar /app.jar
10-
ADD test-functions.sh /test-functions.sh
Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
await_app() {
2+
if [ -z $1 ]
3+
then
4+
url=http://127.0.0.1:8080
5+
else
6+
url=$1
7+
fi
8+
end=$(date +%s)
9+
let "end+=30"
10+
until curl -s $url > /dev/null
11+
do
12+
now=$(date +%s)
13+
if [[ $now -ge $end ]]; then
14+
break
15+
fi
16+
sleep 1
17+
done
18+
}
19+
120
install_service() {
221
mkdir /test-service
322
mv /app.jar /test-service/spring-boot-app.jar
@@ -32,22 +51,3 @@ stop_service() {
3251
force_stop_service() {
3352
service spring-boot-app force-stop
3453
}
35-
36-
await_app() {
37-
if [ -z $1 ]
38-
then
39-
url=http://127.0.0.1:8080
40-
else
41-
url=$1
42-
fi
43-
end=$(date +%s)
44-
let "end+=600"
45-
until curl -s $url > /dev/null
46-
do
47-
now=$(date +%s)
48-
if [[ $now -ge $end ]]; then
49-
break
50-
fi
51-
sleep 1
52-
done
53-
}

0 commit comments

Comments
 (0)