Minimise our usage of SocketUtils.findAvailableTcpPort

Closes gh-9382
This commit is contained in:
Andy Wilkinson
2017-06-08 10:37:40 +01:00
parent 10868519e1
commit f7e9ec5f42
26 changed files with 442 additions and 286 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* 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.
@@ -24,7 +24,6 @@ import org.springframework.boot.cli.command.archive.WarCommand;
import org.springframework.boot.cli.infrastructure.CommandLineInvoker;
import org.springframework.boot.cli.infrastructure.CommandLineInvoker.Invocation;
import org.springframework.boot.loader.tools.JavaExecutable;
import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -41,15 +40,13 @@ public class WarCommandIT {
@Test
public void warCreation() throws Exception {
int port = SocketUtils.findAvailableTcpPort();
File war = new File("target/test-app.war");
Invocation invocation = this.cli.invoke("war", war.getAbsolutePath(),
"war.groovy");
invocation.await();
assertThat(war.exists()).isTrue();
Process process = new JavaExecutable()
.processBuilder("-jar", war.getAbsolutePath(), "--server.port=" + port)
.start();
.processBuilder("-jar", war.getAbsolutePath(), "--server.port=0").start();
invocation = new Invocation(process);
invocation.await();
assertThat(invocation.getOutput()).contains("onStart error");

View File

@@ -18,6 +18,7 @@ package org.springframework.boot.cli;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
@@ -41,7 +42,7 @@ import org.springframework.boot.cli.command.archive.JarCommand;
import org.springframework.boot.cli.command.grab.GrabCommand;
import org.springframework.boot.cli.command.run.RunCommand;
import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.util.SocketUtils;
import org.springframework.util.FileCopyUtils;
/**
* {@link TestRule} that can be used to invoke CLI commands.
@@ -60,8 +61,6 @@ public class CliTester implements TestRule {
private final String prefix;
private final int port = SocketUtils.findAvailableTcpPort();
public CliTester(String prefix) {
this.prefix = prefix;
}
@@ -71,7 +70,21 @@ public class CliTester implements TestRule {
}
public String run(String... args) throws Exception {
Future<RunCommand> future = submitCommand(new RunCommand(), args);
List<String> updatedArgs = new ArrayList<>();
boolean classpathUpdated = false;
for (String arg : args) {
if (arg.startsWith("--classpath=")) {
arg = arg + ":" + new File("target/test-classes").getAbsolutePath();
classpathUpdated = true;
}
updatedArgs.add(arg);
}
if (!classpathUpdated) {
updatedArgs.add(
"--classpath=.:" + new File("target/test-classes").getAbsolutePath());
}
Future<RunCommand> future = submitCommand(new RunCommand(),
updatedArgs.toArray(new String[updatedArgs.size()]));
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
@@ -96,13 +109,19 @@ public class CliTester implements TestRule {
@Override
public T call() throws Exception {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.setProperty("server.port", String.valueOf(CliTester.this.port));
System.setProperty("server.port", "0");
System.setProperty("spring.application.class.name",
"org.springframework.boot.cli.CliTesterSpringApplication");
System.setProperty("portfile",
new File("target/server.port").getAbsolutePath());
try {
command.run(sources);
return command;
}
finally {
System.clearProperty("server.port");
System.clearProperty("spring.application.class.name");
System.clearProperty("portfile");
Thread.currentThread().setContextClassLoader(loader);
}
}
@@ -137,7 +156,7 @@ public class CliTester implements TestRule {
}
}
else {
sources[i] = this.prefix + arg;
sources[i] = new File(arg).isAbsolute() ? arg : this.prefix + arg;
}
}
return sources;
@@ -172,7 +191,9 @@ public class CliTester implements TestRule {
public String getHttpOutput(String uri) {
try {
InputStream stream = URI.create("http://localhost:" + this.port + uri).toURL()
int port = Integer.parseInt(
FileCopyUtils.copyToString(new FileReader("target/server.port")));
InputStream stream = URI.create("http://localhost:" + port + uri).toURL()
.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;

View File

@@ -0,0 +1,39 @@
/*
* 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.cli;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.system.EmbeddedServerPortFileWriter;
import org.springframework.context.ConfigurableApplicationContext;
/**
* Custom {@link SpringApplication} used by {@link CliTester}.
*
* @author Andy Wilkinson
*/
public class CliTesterSpringApplication extends SpringApplication {
public CliTesterSpringApplication(Class<?>... sources) {
super(sources);
}
@Override
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
context.addApplicationListener(new EmbeddedServerPortFileWriter());
}
}