Using random port for HTTP integration tests
This commit is contained in:
parent
8762ec956c
commit
01120eb2f0
|
|
@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
|
@ -42,17 +41,21 @@ import org.springframework.http.HttpMethod;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public abstract class AbstractHttpRequestFactoryTestCase {
|
||||
|
||||
private ClientHttpRequestFactory factory;
|
||||
|
||||
private static Server jettyServer;
|
||||
|
||||
private static final String BASE_URL = "http://localhost:8889";
|
||||
private static String baseUrl;
|
||||
|
||||
@BeforeClass
|
||||
public static void startJettyServer() throws Exception {
|
||||
jettyServer = new Server(8889);
|
||||
int port = FreePortScanner.getFreePort();
|
||||
jettyServer = new Server(port);
|
||||
baseUrl = "http://localhost:" + port;
|
||||
Context jettyContext = new Context(jettyServer, "/");
|
||||
jettyContext.addServlet(new ServletHolder(new EchoServlet()), "/echo");
|
||||
jettyContext.addServlet(new ServletHolder(new StatusServlet(200)), "/status/ok");
|
||||
|
|
@ -83,7 +86,7 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
|
||||
@Test
|
||||
public void status() throws Exception {
|
||||
URI uri = new URI(BASE_URL + "/status/notfound");
|
||||
URI uri = new URI(baseUrl + "/status/notfound");
|
||||
ClientHttpRequest request =
|
||||
factory.createRequest(uri, HttpMethod.GET);
|
||||
assertEquals("Invalid HTTP method", HttpMethod.GET, request.getMethod());
|
||||
|
|
@ -94,7 +97,7 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
|
||||
@Test
|
||||
public void echo() throws Exception {
|
||||
ClientHttpRequest request = factory.createRequest(new URI(BASE_URL + "/echo"), HttpMethod.PUT);
|
||||
ClientHttpRequest request = factory.createRequest(new URI(baseUrl + "/echo"), HttpMethod.PUT);
|
||||
assertEquals("Invalid HTTP method", HttpMethod.PUT, request.getMethod());
|
||||
String headerName = "MyHeader";
|
||||
String headerValue1 = "value1";
|
||||
|
|
@ -114,7 +117,7 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void multipleWrites() throws Exception {
|
||||
ClientHttpRequest request = factory.createRequest(new URI(BASE_URL + "/echo"), HttpMethod.POST);
|
||||
ClientHttpRequest request = factory.createRequest(new URI(baseUrl + "/echo"), HttpMethod.POST);
|
||||
byte[] body = "Hello World".getBytes("UTF-8");
|
||||
FileCopyUtils.copy(body, request.getBody());
|
||||
ClientHttpResponse response = request.execute();
|
||||
|
|
@ -128,7 +131,7 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void headersAfterExecute() throws Exception {
|
||||
ClientHttpRequest request = factory.createRequest(new URI(BASE_URL + "/echo"), HttpMethod.POST);
|
||||
ClientHttpRequest request = factory.createRequest(new URI(baseUrl + "/echo"), HttpMethod.POST);
|
||||
request.getHeaders().add("MyHeader", "value");
|
||||
byte[] body = "Hello World".getBytes("UTF-8");
|
||||
FileCopyUtils.copy(body, request.getBody());
|
||||
|
|
@ -154,7 +157,7 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
private void assertHttpMethod(String path, HttpMethod method) throws Exception {
|
||||
ClientHttpResponse response = null;
|
||||
try {
|
||||
ClientHttpRequest request = factory.createRequest(new URI(BASE_URL + "/methods/" + path), method);
|
||||
ClientHttpRequest request = factory.createRequest(new URI(baseUrl + "/methods/" + path), method);
|
||||
response = request.execute();
|
||||
assertEquals("Invalid method", path.toUpperCase(Locale.ENGLISH), request.getMethod().name());
|
||||
}
|
||||
|
|
@ -169,9 +172,9 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
public void redirect() throws Exception {
|
||||
ClientHttpResponse response = null;
|
||||
try {
|
||||
ClientHttpRequest request = factory.createRequest(new URI(BASE_URL + "/redirect"), HttpMethod.PUT);
|
||||
ClientHttpRequest request = factory.createRequest(new URI(baseUrl + "/redirect"), HttpMethod.PUT);
|
||||
response = request.execute();
|
||||
assertEquals("Invalid Location value", new URI(BASE_URL + "/status/ok"), response.getHeaders().getLocation());
|
||||
assertEquals("Invalid Location value", new URI(baseUrl + "/status/ok"), response.getHeaders().getLocation());
|
||||
|
||||
} finally {
|
||||
if (response != null) {
|
||||
|
|
@ -180,7 +183,7 @@ public abstract class AbstractHttpRequestFactoryTestCase {
|
|||
}
|
||||
}
|
||||
try {
|
||||
ClientHttpRequest request = factory.createRequest(new URI(BASE_URL + "/redirect"), HttpMethod.GET);
|
||||
ClientHttpRequest request = factory.createRequest(new URI(baseUrl + "/redirect"), HttpMethod.GET);
|
||||
response = request.execute();
|
||||
assertNull("Invalid Location value", response.getHeaders().getLocation());
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2002-2010 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.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Utility class that finds free BSD ports for use in testing scenario's.
|
||||
*
|
||||
* @author Ben Hale
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class FreePortScanner {
|
||||
|
||||
private static final int MIN_SAFE_PORT = 1024;
|
||||
|
||||
private static final int MAX_PORT = 65535;
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
/**
|
||||
* Returns the number of a free port in the default range.
|
||||
*/
|
||||
public static int getFreePort() {
|
||||
return getFreePort(MIN_SAFE_PORT, MAX_PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of a free port in the given range.
|
||||
*/
|
||||
public static int getFreePort(int minPort, int maxPort) {
|
||||
Assert.isTrue(minPort > 0, "'minPort' must be larger than 0");
|
||||
Assert.isTrue(maxPort > minPort, "'maxPort' must be larger than minPort");
|
||||
int portRange = maxPort - minPort;
|
||||
int candidatePort;
|
||||
int searchCounter = 0;
|
||||
do {
|
||||
if (++searchCounter > portRange) {
|
||||
throw new IllegalStateException(
|
||||
String.format("There were no ports available in the range %d to %d", minPort, maxPort));
|
||||
}
|
||||
candidatePort = getRandomPort(minPort, portRange);
|
||||
}
|
||||
while (!isPortAvailable(candidatePort));
|
||||
|
||||
return candidatePort;
|
||||
}
|
||||
|
||||
private static int getRandomPort(int minPort, int portRange) {
|
||||
return minPort + random.nextInt(portRange);
|
||||
}
|
||||
|
||||
private static boolean isPortAvailable(int port) {
|
||||
ServerSocket serverSocket;
|
||||
try {
|
||||
serverSocket = new ServerSocket();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Unable to create ServerSocket.", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
InetSocketAddress sa = new InetSocketAddress(port);
|
||||
serverSocket.bind(sa);
|
||||
return true;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
serverSocket.close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -39,7 +39,6 @@ import org.apache.commons.fileupload.FileUploadException;
|
|||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
|
@ -56,10 +55,13 @@ import org.springframework.http.HttpStatus;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.CommonsClientHttpRequestFactory;
|
||||
import org.springframework.http.client.FreePortScanner;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public class RestTemplateIntegrationTests {
|
||||
|
||||
|
|
@ -69,20 +71,22 @@ public class RestTemplateIntegrationTests {
|
|||
|
||||
private static String helloWorld = "H\u00e9llo W\u00f6rld";
|
||||
|
||||
private static final String URI = "http://localhost:8889";
|
||||
private static String baseUrl;
|
||||
|
||||
private static MediaType contentType;
|
||||
|
||||
@BeforeClass
|
||||
public static void startJettyServer() throws Exception {
|
||||
jettyServer = new Server(8889);
|
||||
int port = FreePortScanner.getFreePort();
|
||||
jettyServer = new Server(port);
|
||||
baseUrl = "http://localhost:" + port;
|
||||
Context jettyContext = new Context(jettyServer, "/");
|
||||
byte[] bytes = helloWorld.getBytes("UTF-8");
|
||||
contentType = new MediaType("text", "plain", Collections.singletonMap("charset", "utf-8"));
|
||||
jettyContext.addServlet(new ServletHolder(new GetServlet(bytes, contentType)), "/get");
|
||||
jettyContext.addServlet(new ServletHolder(new GetServlet(new byte[0], contentType)), "/get/nothing");
|
||||
jettyContext.addServlet(
|
||||
new ServletHolder(new PostServlet(helloWorld, URI + "/post/1", bytes, contentType)),
|
||||
new ServletHolder(new PostServlet(helloWorld, baseUrl + "/post/1", bytes, contentType)),
|
||||
"/post");
|
||||
jettyContext.addServlet(new ServletHolder(new ErrorServlet(404)), "/errors/notfound");
|
||||
jettyContext.addServlet(new ServletHolder(new ErrorServlet(500)), "/errors/server");
|
||||
|
|
@ -105,13 +109,13 @@ public class RestTemplateIntegrationTests {
|
|||
|
||||
@Test
|
||||
public void getString() {
|
||||
String s = template.getForObject(URI + "/{method}", String.class, "get");
|
||||
String s = template.getForObject(baseUrl + "/{method}", String.class, "get");
|
||||
assertEquals("Invalid content", helloWorld, s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntity() {
|
||||
ResponseEntity<String> entity = template.getForEntity(URI + "/{method}", String.class, "get");
|
||||
ResponseEntity<String> entity = template.getForEntity(baseUrl + "/{method}", String.class, "get");
|
||||
assertEquals("Invalid content", helloWorld, entity.getBody());
|
||||
assertFalse("No headers", entity.getHeaders().isEmpty());
|
||||
assertEquals("Invalid content-type", contentType, entity.getHeaders().getContentType());
|
||||
|
|
@ -120,14 +124,14 @@ public class RestTemplateIntegrationTests {
|
|||
|
||||
@Test
|
||||
public void getNoResponse() {
|
||||
String s = template.getForObject(URI + "/get/nothing", String.class);
|
||||
String s = template.getForObject(baseUrl + "/get/nothing", String.class);
|
||||
assertEquals("Invalid content", "", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postForLocation() throws URISyntaxException {
|
||||
URI location = template.postForLocation(URI + "/{method}", helloWorld, "post");
|
||||
assertEquals("Invalid location", new URI(URI + "/post/1"), location);
|
||||
URI location = template.postForLocation(baseUrl + "/{method}", helloWorld, "post");
|
||||
assertEquals("Invalid location", new URI(baseUrl + "/post/1"), location);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -135,20 +139,20 @@ public class RestTemplateIntegrationTests {
|
|||
HttpHeaders entityHeaders = new HttpHeaders();
|
||||
entityHeaders.setContentType(new MediaType("text", "plain", Charset.forName("ISO-8859-15")));
|
||||
HttpEntity<String> entity = new HttpEntity<String>(helloWorld, entityHeaders);
|
||||
URI location = template.postForLocation(URI + "/{method}", entity, "post");
|
||||
assertEquals("Invalid location", new URI(URI + "/post/1"), location);
|
||||
URI location = template.postForLocation(baseUrl + "/{method}", entity, "post");
|
||||
assertEquals("Invalid location", new URI(baseUrl + "/post/1"), location);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postForObject() throws URISyntaxException {
|
||||
String s = template.postForObject(URI + "/{method}", helloWorld, String.class, "post");
|
||||
String s = template.postForObject(baseUrl + "/{method}", helloWorld, String.class, "post");
|
||||
assertEquals("Invalid content", helloWorld, s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notFound() {
|
||||
try {
|
||||
template.execute(URI + "/errors/notfound", HttpMethod.GET, null, null);
|
||||
template.execute(baseUrl + "/errors/notfound", HttpMethod.GET, null, null);
|
||||
fail("HttpClientErrorException expected");
|
||||
}
|
||||
catch (HttpClientErrorException ex) {
|
||||
|
|
@ -161,7 +165,7 @@ public class RestTemplateIntegrationTests {
|
|||
@Test
|
||||
public void serverError() {
|
||||
try {
|
||||
template.execute(URI + "/errors/server", HttpMethod.GET, null, null);
|
||||
template.execute(baseUrl + "/errors/server", HttpMethod.GET, null, null);
|
||||
fail("HttpServerErrorException expected");
|
||||
}
|
||||
catch (HttpServerErrorException ex) {
|
||||
|
|
@ -173,20 +177,20 @@ public class RestTemplateIntegrationTests {
|
|||
|
||||
@Test
|
||||
public void optionsForAllow() throws URISyntaxException {
|
||||
Set<HttpMethod> allowed = template.optionsForAllow(new URI(URI + "/get"));
|
||||
Set<HttpMethod> allowed = template.optionsForAllow(new URI(baseUrl + "/get"));
|
||||
assertEquals("Invalid response",
|
||||
EnumSet.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD, HttpMethod.TRACE), allowed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uri() throws InterruptedException, URISyntaxException {
|
||||
String result = template.getForObject(URI + "/uri/{query}", String.class, "Z\u00fcrich");
|
||||
String result = template.getForObject(baseUrl + "/uri/{query}", String.class, "Z\u00fcrich");
|
||||
assertEquals("Invalid request URI", "/uri/Z%C3%BCrich", result);
|
||||
|
||||
result = template.getForObject(URI + "/uri/query={query}", String.class, "foo@bar");
|
||||
result = template.getForObject(baseUrl + "/uri/query={query}", String.class, "foo@bar");
|
||||
assertEquals("Invalid request URI", "/uri/query=foo@bar", result);
|
||||
|
||||
result = template.getForObject(URI + "/uri/query={query}", String.class, "T\u014dky\u014d");
|
||||
result = template.getForObject(baseUrl + "/uri/query={query}", String.class, "T\u014dky\u014d");
|
||||
assertEquals("Invalid request URI", "/uri/query=T%C5%8Dky%C5%8D", result);
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +203,7 @@ public class RestTemplateIntegrationTests {
|
|||
Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg");
|
||||
parts.add("logo", logo);
|
||||
|
||||
template.postForLocation(URI + "/multipart", parts);
|
||||
template.postForLocation(baseUrl + "/multipart", parts);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -208,7 +212,7 @@ public class RestTemplateIntegrationTests {
|
|||
requestHeaders.set("MyHeader", "MyValue");
|
||||
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
|
||||
ResponseEntity<String> response =
|
||||
template.exchange(URI + "/{method}", HttpMethod.GET, requestEntity, String.class, "get");
|
||||
template.exchange(baseUrl + "/{method}", HttpMethod.GET, requestEntity, String.class, "get");
|
||||
assertEquals("Invalid content", helloWorld, response.getBody());
|
||||
}
|
||||
|
||||
|
|
@ -218,8 +222,8 @@ public class RestTemplateIntegrationTests {
|
|||
requestHeaders.set("MyHeader", "MyValue");
|
||||
requestHeaders.setContentType(MediaType.TEXT_PLAIN);
|
||||
HttpEntity<String> requestEntity = new HttpEntity<String>(helloWorld, requestHeaders);
|
||||
HttpEntity<?> result = template.exchange(URI + "/{method}", HttpMethod.POST, requestEntity, null, "post");
|
||||
assertEquals("Invalid location", new URI(URI + "/post/1"), result.getHeaders().getLocation());
|
||||
HttpEntity<?> result = template.exchange(baseUrl + "/{method}", HttpMethod.POST, requestEntity, null, "post");
|
||||
assertEquals("Invalid location", new URI(baseUrl + "/post/1"), result.getHeaders().getLocation());
|
||||
assertFalse(result.hasBody());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue