Skip to content

Commit 2df3646

Browse files
committed
Let Jetty pick its own available port
In an attempt to make our Jetty-based integration tests more robust, this commit discontinues use of SocketUtils for picking a random, available port and instead lets the Jetty Server pick its own port.
1 parent 6085be3 commit 2df3646

File tree

5 files changed

+83
-49
lines changed

5 files changed

+83
-49
lines changed

spring-web/src/test/java/org/springframework/http/client/AbstractJettyServerTestCase.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.InputStream;
2121
import java.util.Enumeration;
2222
import java.util.Map;
23+
2324
import javax.servlet.GenericServlet;
2425
import javax.servlet.ServletException;
2526
import javax.servlet.ServletRequest;
@@ -28,31 +29,34 @@
2829
import javax.servlet.http.HttpServletRequest;
2930
import javax.servlet.http.HttpServletResponse;
3031

32+
import org.eclipse.jetty.server.Connector;
33+
import org.eclipse.jetty.server.NetworkConnector;
3134
import org.eclipse.jetty.server.Server;
3235
import org.eclipse.jetty.servlet.ServletContextHandler;
3336
import org.eclipse.jetty.servlet.ServletHolder;
37+
3438
import org.junit.AfterClass;
35-
import static org.junit.Assert.assertEquals;
3639
import org.junit.BeforeClass;
3740

38-
import org.springframework.util.SocketUtils;
3941
import org.springframework.util.StreamUtils;
4042

43+
import static org.junit.Assert.*;
44+
4145
/**
4246
* @author Arjen Poutsma
47+
* @author Sam Brannen
4348
*/
4449
public abstract class AbstractJettyServerTestCase {
4550

46-
protected static String baseUrl;
47-
4851
private static Server jettyServer;
4952

53+
protected static String baseUrl;
5054

5155
@BeforeClass
5256
public static void startJettyServer() throws Exception {
53-
int port = SocketUtils.findAvailableTcpPort();
54-
jettyServer = new Server(port);
55-
baseUrl = "http://localhost:" + port;
57+
58+
// Let server pick its own random, available port.
59+
jettyServer = new Server(0);
5660

5761
ServletContextHandler handler = new ServletContextHandler();
5862
handler.setContextPath("/");
@@ -71,6 +75,10 @@ public static void startJettyServer() throws Exception {
7175

7276
jettyServer.setHandler(handler);
7377
jettyServer.start();
78+
79+
Connector[] connectors = jettyServer.getConnectors();
80+
NetworkConnector connector = (NetworkConnector) connectors[0];
81+
baseUrl = "http://localhost:" + connector.getLocalPort();
7482
}
7583

7684
@AfterClass

spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2015 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.
@@ -25,11 +25,13 @@
2525
import javax.servlet.http.HttpServletResponse;
2626
import javax.servlet.http.Part;
2727

28+
import org.eclipse.jetty.server.Connector;
29+
import org.eclipse.jetty.server.NetworkConnector;
2830
import org.eclipse.jetty.server.Server;
2931
import org.eclipse.jetty.servlet.ServletContextHandler;
3032
import org.eclipse.jetty.servlet.ServletHolder;
33+
3134
import org.junit.AfterClass;
32-
import org.junit.Before;
3335
import org.junit.BeforeClass;
3436
import org.junit.Test;
3537

@@ -39,44 +41,37 @@
3941
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
4042
import org.springframework.util.LinkedMultiValueMap;
4143
import org.springframework.util.MultiValueMap;
42-
import org.springframework.util.SocketUtils;
4344
import org.springframework.web.client.RestTemplate;
4445
import org.springframework.web.context.request.ServletWebRequest;
4546

4647
import static org.junit.Assert.*;
4748

4849
/**
4950
* @author Brian Clozel
51+
* @author Sam Brannen
5052
*/
5153
public class WebRequestDataBinderIntegrationTests {
5254

53-
protected static String baseUrl;
54-
55-
protected static MediaType contentType;
56-
5755
private static Server jettyServer;
5856

59-
private RestTemplate template;
57+
private static final PartsServlet partsServlet = new PartsServlet();
6058

61-
private static PartsServlet partsServlet;
59+
private static final PartListServlet partListServlet = new PartListServlet();
6260

63-
private static PartListServlet partListServlet;
61+
private final RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
6462

63+
protected static String baseUrl;
64+
65+
protected static MediaType contentType;
6566

66-
@Before
67-
public void createTemplate() {
68-
template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
69-
}
7067

7168
@BeforeClass
7269
public static void startJettyServer() throws Exception {
73-
int port = SocketUtils.findAvailableTcpPort();
74-
jettyServer = new Server(port);
75-
baseUrl = "http://localhost:" + port;
76-
ServletContextHandler handler = new ServletContextHandler();
7770

78-
partsServlet = new PartsServlet();
79-
partListServlet = new PartListServlet();
71+
// Let server pick its own random, available port.
72+
jettyServer = new Server(0);
73+
74+
ServletContextHandler handler = new ServletContextHandler();
8075

8176
MultipartConfigElement multipartConfig = new MultipartConfigElement("");
8277

@@ -87,8 +82,13 @@ public static void startJettyServer() throws Exception {
8782
holder = new ServletHolder(partListServlet);
8883
holder.getRegistration().setMultipartConfig(multipartConfig);
8984
handler.addServlet(holder, "/partlist");
85+
9086
jettyServer.setHandler(handler);
9187
jettyServer.start();
88+
89+
Connector[] connectors = jettyServer.getConnectors();
90+
NetworkConnector connector = (NetworkConnector) connectors[0];
91+
baseUrl = "http://localhost:" + connector.getLocalPort();
9292
}
9393

9494
@AfterClass

spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,47 +33,58 @@
3333
import org.apache.commons.fileupload.FileUploadException;
3434
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
3535
import org.apache.commons.fileupload.servlet.ServletFileUpload;
36+
37+
import org.eclipse.jetty.server.Connector;
38+
import org.eclipse.jetty.server.NetworkConnector;
3639
import org.eclipse.jetty.server.Server;
3740
import org.eclipse.jetty.servlet.ServletContextHandler;
3841
import org.eclipse.jetty.servlet.ServletHolder;
42+
3943
import org.junit.AfterClass;
4044
import org.junit.BeforeClass;
4145

4246
import org.springframework.http.MediaType;
4347
import org.springframework.util.FileCopyUtils;
44-
import org.springframework.util.SocketUtils;
4548

4649
import static org.junit.Assert.*;
4750

4851
/**
4952
* @author Arjen Poutsma
53+
* @author Sam Brannen
5054
*/
5155
public class AbstractJettyServerTestCase {
5256

5357
protected static final String helloWorld = "H\u00e9llo W\u00f6rld";
5458

55-
protected static final int port = SocketUtils.findAvailableTcpPort();
59+
protected static final MediaType textContentType = new MediaType("text", "plain",
60+
Collections.singletonMap("charset", "UTF-8"));
5661

57-
protected static final String baseUrl = "http://localhost:" + port;
62+
protected static final MediaType jsonContentType = new MediaType("application",
63+
"json", Collections.singletonMap("charset", "utf-8"));
5864

59-
protected static final MediaType textContentType = new MediaType("text", "plain", Collections.singletonMap("charset", "UTF-8"));
65+
private static Server jettyServer;
6066

61-
protected static final MediaType jsonContentType = new MediaType("application", "json", Collections.singletonMap("charset", "utf-8"));
67+
protected static int port;
68+
69+
protected static String baseUrl;
6270

63-
private static final Server jettyServer = new Server(port);
6471

6572
@BeforeClass
6673
public static void startJettyServer() throws Exception {
74+
75+
// Let server pick its own random, available port.
76+
jettyServer = new Server(0);
77+
6778
ServletContextHandler handler = new ServletContextHandler();
6879
byte[] bytes = helloWorld.getBytes("utf-8");
6980
handler.addServlet(new ServletHolder(new GetServlet(bytes, textContentType)), "/get");
7081
handler.addServlet(new ServletHolder(new GetServlet(new byte[0], textContentType)), "/get/nothing");
7182
handler.addServlet(new ServletHolder(new GetServlet(bytes, null)), "/get/nocontenttype");
7283
handler.addServlet(
73-
new ServletHolder(new PostServlet(helloWorld, baseUrl + "/post/1", bytes, textContentType)),
84+
new ServletHolder(new PostServlet(helloWorld, "/post/1", bytes, textContentType)),
7485
"/post");
7586
handler.addServlet(
76-
new ServletHolder(new JsonPostServlet(baseUrl + "/jsonpost/1", jsonContentType)),
87+
new ServletHolder(new JsonPostServlet("/jsonpost/1", jsonContentType)),
7788
"/jsonpost");
7889
handler.addServlet(new ServletHolder(new StatusCodeServlet(204)), "/status/nocontent");
7990
handler.addServlet(new ServletHolder(new StatusCodeServlet(304)), "/status/notmodified");
@@ -86,8 +97,14 @@ public static void startJettyServer() throws Exception {
8697
handler.addServlet(
8798
new ServletHolder(new PutServlet(helloWorld, bytes, textContentType)),
8899
"/put");
100+
89101
jettyServer.setHandler(handler);
90102
jettyServer.start();
103+
104+
Connector[] connectors = jettyServer.getConnectors();
105+
NetworkConnector connector = (NetworkConnector) connectors[0];
106+
port = connector.getLocalPort();
107+
baseUrl = "http://localhost:" + port;
91108
}
92109

93110
@AfterClass
@@ -179,7 +196,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
179196
String body = FileCopyUtils.copyToString(request.getReader());
180197
assertEquals("Invalid request body", s, body);
181198
response.setStatus(HttpServletResponse.SC_CREATED);
182-
response.setHeader("Location", location);
199+
response.setHeader("Location", baseUrl + location);
183200
response.setContentLength(buf.length);
184201
response.setContentType(contentType.toString());
185202
FileCopyUtils.copy(buf, response.getOutputStream());
@@ -205,7 +222,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
205222
assertNotNull("No content-type", request.getContentType());
206223
String body = FileCopyUtils.copyToString(request.getReader());
207224
response.setStatus(HttpServletResponse.SC_CREATED);
208-
response.setHeader("Location", location);
225+
response.setHeader("Location", baseUrl +location);
209226
response.setContentType(contentType.toString());
210227
byte[] bytes = body.getBytes("utf-8");
211228
response.setContentLength(bytes.length);;

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartIntegrationTests.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.web.servlet.mvc.method.annotation;
1818

19-
import static org.junit.Assert.*;
20-
2119
import java.net.URI;
2220
import java.nio.charset.Charset;
2321
import java.util.ArrayList;
@@ -26,9 +24,12 @@
2624

2725
import javax.servlet.MultipartConfigElement;
2826

27+
import org.eclipse.jetty.server.Connector;
28+
import org.eclipse.jetty.server.NetworkConnector;
2929
import org.eclipse.jetty.server.Server;
3030
import org.eclipse.jetty.servlet.ServletContextHandler;
3131
import org.eclipse.jetty.servlet.ServletHolder;
32+
3233
import org.junit.AfterClass;
3334
import org.junit.Assert;
3435
import org.junit.Before;
@@ -52,7 +53,6 @@
5253
import org.springframework.stereotype.Controller;
5354
import org.springframework.util.LinkedMultiValueMap;
5455
import org.springframework.util.MultiValueMap;
55-
import org.springframework.util.SocketUtils;
5656
import org.springframework.web.bind.annotation.RequestMapping;
5757
import org.springframework.web.bind.annotation.RequestMethod;
5858
import org.springframework.web.bind.annotation.RequestPart;
@@ -66,11 +66,14 @@
6666
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
6767
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
6868

69+
import static org.junit.Assert.*;
70+
6971
/**
7072
* Test access to parts of a multipart request with {@link RequestPart}.
7173
*
7274
* @author Rossen Stoyanchev
7375
* @author Brian Clozel
76+
* @author Sam Brannen
7477
*/
7578
public class RequestPartIntegrationTests {
7679

@@ -83,10 +86,10 @@ public class RequestPartIntegrationTests {
8386

8487
@BeforeClass
8588
public static void startServer() throws Exception {
86-
int port = SocketUtils.findAvailableTcpPort();
87-
baseUrl = "http://localhost:" + port;
8889

89-
server = new Server(port);
90+
// Let server pick its own random, available port.
91+
server = new Server(0);
92+
9093
ServletContextHandler handler = new ServletContextHandler();
9194
handler.setContextPath("/");
9295

@@ -105,6 +108,10 @@ public static void startServer() throws Exception {
105108

106109
server.setHandler(handler);
107110
server.start();
111+
112+
Connector[] connectors = server.getConnectors();
113+
NetworkConnector connector = (NetworkConnector) connectors[0];
114+
baseUrl = "http://localhost:" + connector.getLocalPort();
108115
}
109116

110117
@Before

spring-websocket/src/test/java/org/springframework/web/socket/JettyWebSocketTestServer.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,17 @@
1717
package org.springframework.web.socket;
1818

1919
import java.util.EnumSet;
20-
2120
import javax.servlet.DispatcherType;
2221
import javax.servlet.Filter;
2322
import javax.servlet.ServletContext;
2423

24+
import org.eclipse.jetty.server.Connector;
25+
import org.eclipse.jetty.server.NetworkConnector;
2526
import org.eclipse.jetty.server.Server;
2627
import org.eclipse.jetty.servlet.FilterHolder;
2728
import org.eclipse.jetty.servlet.ServletContextHandler;
2829
import org.eclipse.jetty.servlet.ServletHolder;
2930

30-
import org.springframework.util.Assert;
31-
import org.springframework.util.SocketUtils;
3231
import org.springframework.web.context.WebApplicationContext;
3332
import org.springframework.web.servlet.DispatcherServlet;
3433

@@ -49,8 +48,8 @@ public class JettyWebSocketTestServer implements WebSocketTestServer {
4948

5049
@Override
5150
public void setup() {
52-
this.port = SocketUtils.findAvailableTcpPort();
53-
this.jettyServer = new Server(this.port);
51+
// Let server pick its own random, available port.
52+
this.jettyServer = new Server(0);
5453
}
5554

5655
@Override
@@ -60,7 +59,6 @@ public int getPort() {
6059

6160
@Override
6261
public void deployConfig(WebApplicationContext wac, Filter... filters) {
63-
Assert.state(this.port != -1, "setup() was never called.");
6462
ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(wac));
6563
this.contextHandler = new ServletContextHandler();
6664
this.contextHandler.addServlet(servletHolder, "/");
@@ -87,6 +85,10 @@ public void undeployConfig() {
8785
@Override
8886
public void start() throws Exception {
8987
this.jettyServer.start();
88+
89+
Connector[] connectors = jettyServer.getConnectors();
90+
NetworkConnector connector = (NetworkConnector) connectors[0];
91+
this.port = connector.getLocalPort();
9092
}
9193

9294
@Override

0 commit comments

Comments
 (0)