Skip to content

Commit c2ea114

Browse files
committed
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
2 parents b14bd45 + 84ff233 commit c2ea114

File tree

48 files changed

+306
-105
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

+306
-105
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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.images.builder.ImageFromDockerfile;
28+
import org.testcontainers.utility.MountableFile;
29+
30+
import org.springframework.boot.ansi.AnsiColor;
31+
32+
import static org.assertj.core.api.Assertions.assertThat;
33+
import static org.hamcrest.Matchers.containsString;
34+
35+
/**
36+
* Abstract base class for testing the launch script.
37+
*
38+
* @author Andy Wilkinson
39+
* @author Ali Shahbour
40+
* @author Alexey Vinogradov
41+
*/
42+
abstract class AbstractLaunchScriptIT {
43+
44+
protected static final char ESC = 27;
45+
46+
private final String scriptsDir;
47+
48+
protected AbstractLaunchScriptIT(String scriptsDir) {
49+
this.scriptsDir = scriptsDir;
50+
}
51+
52+
static List<Object[]> parameters() {
53+
List<Object[]> parameters = new ArrayList<>();
54+
for (File os : new File("src/test/resources/conf").listFiles()) {
55+
for (File version : os.listFiles()) {
56+
parameters.add(new Object[] { os.getName(), version.getName() });
57+
}
58+
}
59+
return parameters;
60+
}
61+
62+
protected Condition<String> coloredString(AnsiColor color, String string) {
63+
String colorString = ESC + "[0;" + color + "m" + string + ESC + "[0m";
64+
return new Condition<String>() {
65+
66+
@Override
67+
public boolean matches(String value) {
68+
return containsString(colorString).matches(value);
69+
}
70+
71+
};
72+
}
73+
74+
protected void doLaunch(String os, String version, String script) throws Exception {
75+
assertThat(doTest(os, version, script)).contains("Launched");
76+
}
77+
78+
protected String doTest(String os, String version, String script) throws Exception {
79+
ToStringConsumer consumer = new ToStringConsumer().withRemoveAnsiCodes(false);
80+
try (LaunchScriptTestContainer container = new LaunchScriptTestContainer(os, version, this.scriptsDir,
81+
script)) {
82+
container.withLogConsumer(consumer);
83+
container.start();
84+
while (container.isRunning()) {
85+
Thread.sleep(100);
86+
}
87+
}
88+
return consumer.toUtf8String();
89+
}
90+
91+
private static final class LaunchScriptTestContainer extends GenericContainer<LaunchScriptTestContainer> {
92+
93+
private LaunchScriptTestContainer(String os, String version, String scriptsDir, String testScript) {
94+
super(new ImageFromDockerfile("spring-boot-launch-script/" + os.toLowerCase() + "-" + version)
95+
.withFileFromFile("Dockerfile",
96+
new File("src/test/resources/conf/" + os + "/" + version + "/Dockerfile")));
97+
withCopyFileToContainer(MountableFile.forHostPath(findApplication().getAbsolutePath()),
98+
"/spring-boot-launch-script-tests.jar");
99+
withCopyFileToContainer(
100+
MountableFile.forHostPath("src/test/resources/scripts/" + scriptsDir + "test-functions.sh"),
101+
"/test-functions.sh");
102+
withCopyFileToContainer(MountableFile.forHostPath("src/test/resources/scripts/" + scriptsDir + testScript),
103+
"/" + testScript);
104+
withCommand("/bin/bash", "-c", "chmod +x " + testScript + " && ./" + testScript);
105+
withStartupTimeout(Duration.ofMinutes(10));
106+
}
107+
108+
private static File findApplication() {
109+
File targetDir = new File("target");
110+
for (File file : targetDir.listFiles()) {
111+
if (file.getName().startsWith("spring-boot-launch-script-tests") && file.getName().endsWith(".jar")
112+
&& !file.getName().endsWith("-sources.jar")) {
113+
return file;
114+
}
115+
}
116+
throw new IllegalStateException(
117+
"Could not find test application in target directory. Have you built it (mvn package)?");
118+
}
119+
120+
}
121+
122+
}
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 JarLaunchScriptIT extends AbstractLaunchScriptIT {
31+
32+
JarLaunchScriptIT() {
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/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java

Lines changed: 6 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,35 +16,28 @@
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

3627
import static org.assertj.core.api.Assertions.assertThat;
37-
import static org.hamcrest.Matchers.containsString;
3828

3929
/**
4030
* Integration tests for Spring Boot's launch script on OSs that use SysVinit.
4131
*
4232
* @author Andy Wilkinson
4333
* @author Ali Shahbour
34+
* @author Alexey Vinogradov
4435
*/
45-
class SysVinitLaunchScriptIT {
36+
class SysVinitLaunchScriptIT extends AbstractLaunchScriptIT {
4637

47-
private static final char ESC = 27;
38+
SysVinitLaunchScriptIT() {
39+
super("init.d/");
40+
}
4841

4942
@ParameterizedTest(name = "{0} {1}")
5043
@MethodSource("parameters")
@@ -277,44 +270,6 @@ void whenLaunchedUsingNonRootUserWithRunAsUserSpecifiedLaunchFailsWithInsufficie
277270
assertThat(output).has(coloredString(AnsiColor.RED, "Cannot run as 'wagner': current user is not root"));
278271
}
279272

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

331-
private static final class LaunchScriptTestContainer extends GenericContainer<LaunchScriptTestContainer> {
332-
333-
private LaunchScriptTestContainer(String os, String version, String testScript) {
334-
super(new ImageFromDockerfile("spring-boot-launch-script/" + os.toLowerCase() + "-" + version)
335-
.withFileFromFile("Dockerfile",
336-
new File("src/test/resources/conf/" + os + "/" + version + "/Dockerfile"))
337-
.withFileFromFile("spring-boot-launch-script-tests.jar", findApplication())
338-
.withFileFromFile("test-functions.sh", new File("src/test/resources/scripts/test-functions.sh")));
339-
withCopyFileToContainer(MountableFile.forHostPath("src/test/resources/scripts/" + testScript),
340-
"/" + testScript);
341-
withCommand("/bin/bash", "-c", "chmod +x " + testScript + " && ./" + testScript);
342-
withStartupTimeout(Duration.ofMinutes(10));
343-
}
344-
345-
private static File findApplication() {
346-
File targetDir = new File("target");
347-
for (File file : targetDir.listFiles()) {
348-
if (file.getName().startsWith("spring-boot-launch-script-tests") && file.getName().endsWith(".jar")
349-
&& !file.getName().endsWith("-sources.jar")) {
350-
return file;
351-
}
352-
}
353-
throw new IllegalStateException(
354-
"Could not find test application in target directory. Have you built it (mvn package)?");
355-
}
356-
357-
}
358-
359286
}

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/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 spring-boot-launch-script-tests.jar /spring-boot-launch-script-tests.jar
11-
ADD test-functions.sh /test-functions.sh

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/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 spring-boot-launch-script-tests.jar /spring-boot-launch-script-tests.jar
10-
ADD test-functions.sh /test-functions.sh

spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/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 spring-boot-launch-script-tests.jar /spring-boot-launch-script-tests.jar
10-
ADD test-functions.sh /test-functions.sh

0 commit comments

Comments
 (0)