Commit 0c5d1f89 authored by bsheedy's avatar bsheedy Committed by Commit Bot

Support specifying port for EmbeddedTestServer

Adds the ability for the native and Java versions of EmbeddedTestServer
to be started using a specified port instead of always using an auto
selected one.

The use case that prompted this is pixel tests in VR, which need to use
the test server (instead of file URLs) in order to grant permissions to
pages, but need the URL to remain constant so that captured images
don't differ between test runs.

Bug: 883940
Change-Id: I7c0fa1a86cdf15d0e3271de6722d315a0191327a
Reviewed-on: https://chromium-review.googlesource.com/1225304Reviewed-by: default avatarZhongyi Shi <zhongyi@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Brian Sheedy <bsheedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#591389}
parent f5fc2957
...@@ -44,6 +44,6 @@ public class AwEmbeddedTestServer extends EmbeddedTestServer { ...@@ -44,6 +44,6 @@ public class AwEmbeddedTestServer extends EmbeddedTestServer {
*/ */
public static AwEmbeddedTestServer createAndStartServer(Context context) public static AwEmbeddedTestServer createAndStartServer(Context context)
throws InterruptedException { throws InterruptedException {
return initializeAndStartServer(new AwEmbeddedTestServer(), context); return initializeAndStartServer(new AwEmbeddedTestServer(), context, 0 /* port */);
} }
} }
...@@ -277,7 +277,7 @@ public class EmbeddedTestServer { ...@@ -277,7 +277,7 @@ public class EmbeddedTestServer {
} }
} }
/** Starts the server. /** Starts the server with an automatically selected port.
* *
* Note that this should be called after handlers are set up, including any relevant calls * Note that this should be called after handlers are set up, including any relevant calls
* serveFilesFromDirectory. * serveFilesFromDirectory.
...@@ -285,10 +285,23 @@ public class EmbeddedTestServer { ...@@ -285,10 +285,23 @@ public class EmbeddedTestServer {
* @return Whether the server was successfully initialized. * @return Whether the server was successfully initialized.
*/ */
public boolean start() { public boolean start() {
return start(0);
}
/** Starts the server with the specified port.
*
* Note that this should be called after handlers are set up, including any relevant calls
* serveFilesFromDirectory.
*
* @param port The port to use for the server, 0 to auto-select an unused port.
*
* @return Whether the server was successfully initialized.
*/
public boolean start(int port) {
try { try {
synchronized (mImplMonitor) { synchronized (mImplMonitor) {
checkServiceLocked(); checkServiceLocked();
return mImpl.start(); return mImpl.start(port);
} }
} catch (RemoteException e) { } catch (RemoteException e) {
throw new EmbeddedTestServerFailure("Failed to start server.", e); throw new EmbeddedTestServerFailure("Failed to start server.", e);
...@@ -338,11 +351,25 @@ public class EmbeddedTestServer { ...@@ -338,11 +351,25 @@ public class EmbeddedTestServer {
*/ */
public static EmbeddedTestServer createAndStartServer(Context context) public static EmbeddedTestServer createAndStartServer(Context context)
throws InterruptedException { throws InterruptedException {
return createAndStartServerWithPort(context, 0);
}
/** Create and initialize a server with the default handlers and specified port.
*
* This handles native object initialization, server configuration, and server initialization.
* On returning, the server is ready for use.
*
* @param context The context in which the server will run.
* @param port The port to use for the server, 0 to auto-select an unused port.
* @return The created server.
*/
public static EmbeddedTestServer createAndStartServerWithPort(Context context, int port)
throws InterruptedException {
Assert.assertNotEquals("EmbeddedTestServer should not be created on UiThread, " Assert.assertNotEquals("EmbeddedTestServer should not be created on UiThread, "
+ "the instantiation will hang forever waiting for tasks to post to UI thread", + "the instantiation will hang forever waiting for tasks to post to UI thread",
Looper.getMainLooper(), Looper.myLooper()); Looper.getMainLooper(), Looper.myLooper());
EmbeddedTestServer server = new EmbeddedTestServer(); EmbeddedTestServer server = new EmbeddedTestServer();
return initializeAndStartServer(server, context); return initializeAndStartServer(server, context, port);
} }
/** Create and initialize an HTTPS server with the default handlers. /** Create and initialize an HTTPS server with the default handlers.
...@@ -356,12 +383,27 @@ public class EmbeddedTestServer { ...@@ -356,12 +383,27 @@ public class EmbeddedTestServer {
*/ */
public static EmbeddedTestServer createAndStartHTTPSServer( public static EmbeddedTestServer createAndStartHTTPSServer(
Context context, int serverCertificate) throws InterruptedException { Context context, int serverCertificate) throws InterruptedException {
return createAndStartHTTPSServerWithPort(context, serverCertificate, 0 /* port */);
}
/** Create and initialize an HTTPS server with the default handlers and specified port.
*
* This handles native object initialization, server configuration, and server initialization.
* On returning, the server is ready for use.
*
* @param context The context in which the server will run.
* @param serverCertificate The certificate option that the server will use.
* @param port The port to use for the server, 0 to auto-select an unused port.
* @return The created server.
*/
public static EmbeddedTestServer createAndStartHTTPSServerWithPort(
Context context, int serverCertificate, int port) throws InterruptedException {
Assert.assertNotEquals("EmbeddedTestServer should not be created on UiThread, " Assert.assertNotEquals("EmbeddedTestServer should not be created on UiThread, "
+ "the instantiation will hang forever waiting for tasks" + "the instantiation will hang forever waiting for tasks"
+ " to post to UI thread", + " to post to UI thread",
Looper.getMainLooper(), Looper.myLooper()); Looper.getMainLooper(), Looper.myLooper());
EmbeddedTestServer server = new EmbeddedTestServer(); EmbeddedTestServer server = new EmbeddedTestServer();
return initializeAndStartHTTPSServer(server, context, serverCertificate); return initializeAndStartHTTPSServer(server, context, serverCertificate, port);
} }
/** Initialize a server with the default handlers. /** Initialize a server with the default handlers.
...@@ -371,13 +413,14 @@ public class EmbeddedTestServer { ...@@ -371,13 +413,14 @@ public class EmbeddedTestServer {
* *
* @param server The server instance that will be initialized. * @param server The server instance that will be initialized.
* @param context The context in which the server will run. * @param context The context in which the server will run.
* @param port The port to use for the server, 0 to auto-select an unused port.
* @return The created server. * @return The created server.
*/ */
public static <T extends EmbeddedTestServer> T initializeAndStartServer( public static <T extends EmbeddedTestServer> T initializeAndStartServer(
T server, Context context) throws InterruptedException { T server, Context context, int port) throws InterruptedException {
server.initializeNative(context, ServerHTTPSSetting.USE_HTTP); server.initializeNative(context, ServerHTTPSSetting.USE_HTTP);
server.addDefaultHandlers(""); server.addDefaultHandlers("");
if (!server.start()) { if (!server.start(port)) {
throw new EmbeddedTestServerFailure("Failed to start serving using default handlers."); throw new EmbeddedTestServerFailure("Failed to start serving using default handlers.");
} }
return server; return server;
...@@ -392,14 +435,15 @@ public class EmbeddedTestServer { ...@@ -392,14 +435,15 @@ public class EmbeddedTestServer {
* @param server The server instance that will be initialized. * @param server The server instance that will be initialized.
* @param context The context in which the server will run. * @param context The context in which the server will run.
* @param serverCertificate The certificate option that the server will use. * @param serverCertificate The certificate option that the server will use.
* @param port The port to use for the server.
* @return The created server. * @return The created server.
*/ */
public static <T extends EmbeddedTestServer> T initializeAndStartHTTPSServer( public static <T extends EmbeddedTestServer> T initializeAndStartHTTPSServer(T server,
T server, Context context, int serverCertificate) throws InterruptedException { Context context, int serverCertificate, int port) throws InterruptedException {
server.initializeNative(context, ServerHTTPSSetting.USE_HTTPS); server.initializeNative(context, ServerHTTPSSetting.USE_HTTPS);
server.addDefaultHandlers(""); server.addDefaultHandlers("");
server.setSSLConfig(serverCertificate); server.setSSLConfig(serverCertificate);
if (!server.start()) { if (!server.start(port)) {
throw new EmbeddedTestServerFailure("Failed to start serving using default handlers."); throw new EmbeddedTestServerFailure("Failed to start serving using default handlers.");
} }
return server; return server;
......
...@@ -98,14 +98,16 @@ public class EmbeddedTestServerImpl extends IEmbeddedTestServerImpl.Stub { ...@@ -98,14 +98,16 @@ public class EmbeddedTestServerImpl extends IEmbeddedTestServerImpl.Stub {
* Note that this should be called after handlers are set up, including any relevant calls * Note that this should be called after handlers are set up, including any relevant calls
* serveFilesFromDirectory. * serveFilesFromDirectory.
* *
* @param port The port to use for the server, 0 to auto-select an unused port.
*
* @return Whether the server was successfully started. * @return Whether the server was successfully started.
*/ */
@Override @Override
public boolean start() { public boolean start(int port) {
return runOnHandlerThread(new Callable<Boolean>() { return runOnHandlerThread(new Callable<Boolean>() {
@Override @Override
public Boolean call() { public Boolean call() {
return nativeStart(mNativeEmbeddedTestServer); return nativeStart(mNativeEmbeddedTestServer, port);
} }
}); });
} }
...@@ -314,7 +316,7 @@ public class EmbeddedTestServerImpl extends IEmbeddedTestServerImpl.Stub { ...@@ -314,7 +316,7 @@ public class EmbeddedTestServerImpl extends IEmbeddedTestServerImpl.Stub {
private native void nativeInit(String testDataDir, boolean https); private native void nativeInit(String testDataDir, boolean https);
private native void nativeDestroy(long nativeEmbeddedTestServerAndroid); private native void nativeDestroy(long nativeEmbeddedTestServerAndroid);
private native boolean nativeStart(long nativeEmbeddedTestServerAndroid); private native boolean nativeStart(long nativeEmbeddedTestServerAndroid, int port);
private native String nativeGetRootCertPemPath(long nativeEmbeddedTestServerAndroid); private native String nativeGetRootCertPemPath(long nativeEmbeddedTestServerAndroid);
private native boolean nativeShutdownAndWaitUntilComplete(long nativeEmbeddedTestServerAndroid); private native boolean nativeShutdownAndWaitUntilComplete(long nativeEmbeddedTestServerAndroid);
private native void nativeAddDefaultHandlers( private native void nativeAddDefaultHandlers(
......
...@@ -14,13 +14,12 @@ import org.junit.runner.Description; ...@@ -14,13 +14,12 @@ import org.junit.runner.Description;
* finishes. * finishes.
*/ */
public class EmbeddedTestServerRule extends TestWatcher { public class EmbeddedTestServerRule extends TestWatcher {
EmbeddedTestServer mServer = new EmbeddedTestServer(); EmbeddedTestServer mServer;
@Override @Override
protected void starting(Description description) { protected void starting(Description description) {
try { try {
EmbeddedTestServer.initializeAndStartServer( mServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
mServer, InstrumentationRegistry.getContext());
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new EmbeddedTestServer.EmbeddedTestServerFailure("Test server didn't start"); throw new EmbeddedTestServer.EmbeddedTestServerFailure("Test server didn't start");
} }
......
...@@ -13,9 +13,10 @@ interface IEmbeddedTestServerImpl { ...@@ -13,9 +13,10 @@ interface IEmbeddedTestServerImpl {
/** Start the server. /** Start the server.
* *
* @param port The port to use for the server, 0 to auto-select an unused port.
* @return Whether the server was successfully started. * @return Whether the server was successfully started.
*/ */
boolean start(); boolean start(int port);
/** Get the path of the server's root certificate. /** Get the path of the server's root certificate.
* *
......
...@@ -56,8 +56,9 @@ EmbeddedTestServerAndroid::~EmbeddedTestServerAndroid() { ...@@ -56,8 +56,9 @@ EmbeddedTestServerAndroid::~EmbeddedTestServerAndroid() {
} }
jboolean EmbeddedTestServerAndroid::Start(JNIEnv* env, jboolean EmbeddedTestServerAndroid::Start(JNIEnv* env,
const JavaParamRef<jobject>& jobj) { const JavaParamRef<jobject>& jobj,
return test_server_.Start(); jint port) {
return test_server_.Start(static_cast<int>(port));
} }
ScopedJavaLocalRef<jstring> EmbeddedTestServerAndroid::GetRootCertPemPath( ScopedJavaLocalRef<jstring> EmbeddedTestServerAndroid::GetRootCertPemPath(
......
...@@ -28,7 +28,9 @@ class EmbeddedTestServerAndroid { ...@@ -28,7 +28,9 @@ class EmbeddedTestServerAndroid {
void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
jboolean Start(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); jboolean Start(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj,
jint port);
base::android::ScopedJavaLocalRef<jstring> GetRootCertPemPath( base::android::ScopedJavaLocalRef<jstring> GetRootCertPemPath(
JNIEnv* jenv, JNIEnv* jenv,
......
...@@ -89,15 +89,15 @@ void EmbeddedTestServer::SetConnectionListener( ...@@ -89,15 +89,15 @@ void EmbeddedTestServer::SetConnectionListener(
connection_listener_ = listener; connection_listener_ = listener;
} }
bool EmbeddedTestServer::Start() { bool EmbeddedTestServer::Start(int port) {
bool success = InitializeAndListen(); bool success = InitializeAndListen(port);
if (!success) if (!success)
return false; return false;
StartAcceptingConnections(); StartAcceptingConnections();
return true; return true;
} }
bool EmbeddedTestServer::InitializeAndListen() { bool EmbeddedTestServer::InitializeAndListen(int port) {
DCHECK(!Started()); DCHECK(!Started());
const int max_tries = 5; const int max_tries = 5;
...@@ -114,7 +114,8 @@ bool EmbeddedTestServer::InitializeAndListen() { ...@@ -114,7 +114,8 @@ bool EmbeddedTestServer::InitializeAndListen() {
listen_socket_.reset(new TCPServerSocket(nullptr, NetLogSource())); listen_socket_.reset(new TCPServerSocket(nullptr, NetLogSource()));
int result = listen_socket_->ListenWithAddressAndPort("127.0.0.1", 0, 10); int result =
listen_socket_->ListenWithAddressAndPort("127.0.0.1", port, 10);
if (result) { if (result) {
LOG(ERROR) << "Listen failed: " << ErrorToString(result); LOG(ERROR) << "Listen failed: " << ErrorToString(result);
listen_socket_.reset(); listen_socket_.reset();
......
...@@ -145,11 +145,11 @@ class EmbeddedTestServer { ...@@ -145,11 +145,11 @@ class EmbeddedTestServer {
// This is the equivalent of calling InitializeAndListen() followed by // This is the equivalent of calling InitializeAndListen() followed by
// StartAcceptingConnections(). // StartAcceptingConnections().
// Returns whether a listening socket has been successfully created. // Returns whether a listening socket has been successfully created.
bool Start() WARN_UNUSED_RESULT; bool Start(int port = 0) WARN_UNUSED_RESULT;
// Starts listening for incoming connections but will not yet accept them. // Starts listening for incoming connections but will not yet accept them.
// Returns whether a listening socket has been succesfully created. // Returns whether a listening socket has been succesfully created.
bool InitializeAndListen() WARN_UNUSED_RESULT; bool InitializeAndListen(int port = 0) WARN_UNUSED_RESULT;
// Starts the Accept IO Thread and begins accepting connections. // Starts the Accept IO Thread and begins accepting connections.
void StartAcceptingConnections(); void StartAcceptingConnections();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment