Skip to content

Commit

Permalink
Query Selenium Server to retrieve actual running port.
Browse files Browse the repository at this point in the history
Fixes SeleniumHQ#1299

Altered the registration logic as below :
If port given was 0, then query server to find
running port and update registration request with
correct values for remoteHost.

Signed-off-by: Luke Inman-Semerau <luke.semerau@gmail.com>
  • Loading branch information
krmahadevan authored and lukeis committed Mar 15, 2016
1 parent c33471b commit 31a9914
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
import org.openqa.grid.common.RegistrationRequest;
import org.openqa.grid.common.exception.GridConfigurationException;
import org.openqa.grid.common.exception.GridException;
import org.openqa.grid.shared.GridNodeServer;
import org.openqa.selenium.Platform;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.internal.HttpClientFactory;
import org.openqa.selenium.remote.server.log.LoggingManager;
import org.openqa.grid.shared.GridNodeServer;

import java.io.BufferedReader;
import java.io.IOException;
Expand Down Expand Up @@ -216,6 +216,7 @@ private void registerToHub(boolean checkPresenceFirst) {

BasicHttpEntityEnclosingRequest r =
new BasicHttpEntityEnclosingRequest("POST", registration.toExternalForm());
updateConfigWithRealPort();
String json = nodeConfig.toJSON();
r.setEntity(new StringEntity(json,"UTF-8"));

Expand All @@ -236,6 +237,19 @@ private void registerToHub(boolean checkPresenceFirst) {

}

void updateConfigWithRealPort() throws MalformedURLException {
int port = Integer.parseInt(nodeConfig.getConfigAsString(RegistrationRequest.PORT));
if (port != 0) {
return;
}
port = server.getRealPort();
Map<String, Object> config = nodeConfig.getConfiguration();
config.put(RegistrationRequest.PORT, server.getRealPort());
URL url = new URL(nodeConfig.getConfigAsString(RegistrationRequest.REMOTE_HOST));
String newUrl = url.getProtocol() + "://" + url.getHost() + ":" + port;
config.put(RegistrationRequest.REMOTE_HOST, newUrl);
}

/**
* uses the hub API to get some of its configuration.
* @return json object of the current hub configuration
Expand Down
1 change: 1 addition & 0 deletions java/server/src/org/openqa/grid/shared/GridNodeServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@
public interface GridNodeServer {
void boot() throws Exception;
void stop();
int getRealPort();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.beust.jcommander.JCommander;

import org.openqa.grid.shared.GridNodeServer;
import org.openqa.jetty.http.SocketListener;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.server.handler.DeleteSession;
import org.seleniumhq.jetty9.server.Connector;
Expand Down Expand Up @@ -58,6 +59,14 @@ public class SeleniumServer implements GridNodeServer {
public SeleniumServer(int port) {
this.port = port;
}
public int getRealPort() {
if (server.isStarted()) {
ServerConnector socket = (ServerConnector)server.getConnectors()[0];
return socket.getPort();
}
return this.port;
}


private void addRcSupport(ServletContextHandler handler) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,14 @@ public int getPort() {
return configuration.getPort();
}

public int getRealPort() {
if (server.isStarted()) {
SocketListener socket = (SocketListener) server.getListeners()[0];
return socket.getPort();
}
return getPort();
}

/**
* Exposes the internal Jetty server used by Selenium. This lets users add their own webapp to the
* Selenium Server jetty instance. It is also a minor violation of encapsulation principles (what
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.openqa.grid.internal.listener.RegistrationListenerTest;
import org.openqa.grid.internal.listener.SessionListenerTest;
import org.openqa.grid.internal.utils.DefaultCapabilityMatcherTest;
import org.openqa.grid.internal.utils.SelfRegisteringRemoteTest;
import org.openqa.grid.plugin.RemoteProxyInheritanceTest;

@RunWith(Suite.class)
Expand All @@ -47,7 +48,8 @@
StatusServletTests.class,
Grid1ConfigurationLoaderTest.class,
UserDefinedCapabilityMatcherTests.class,
GridShutdownTest.class
GridShutdownTest.class,
SelfRegisteringRemoteTest.class
})
public class GridInternalTests {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.openqa.grid.internal.utils;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.openqa.grid.common.GridRole;
import org.openqa.grid.common.RegistrationRequest;
import org.openqa.grid.shared.GridNodeServer;

import java.net.MalformedURLException;

public class SelfRegisteringRemoteTest {

@Test
public void testHubRegistrationWhenPortExplicitlyZeroedOut() throws MalformedURLException {
GridNodeServer server = new GridNodeServer() {
@Override
public void boot() throws Exception {}

@Override
public void stop() {}

@Override
public int getRealPort() {
return 1234;
}
};
RegistrationRequest config = new RegistrationRequest();
config.setRole(GridRole.NODE);
config.getConfiguration().put(RegistrationRequest.HUB_HOST, "localhost");
config.getConfiguration().put(RegistrationRequest.HUB_PORT, 4444);
config.getConfiguration().put(RegistrationRequest.PORT, 0);
config.getConfiguration().put(RegistrationRequest.REMOTE_HOST, "http://localhost:0/");
SelfRegisteringRemote remote = new SelfRegisteringRemote(config);
remote.setRemoteServer(server);
remote.updateConfigWithRealPort();
String host = (String) remote.getConfiguration().get(RegistrationRequest.REMOTE_HOST);
assertEquals("Ensure that the remote host is updated properly",
"http://localhost:" + server.getRealPort(), host);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@
package org.openqa.selenium.server;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Test;
import org.openqa.selenium.net.PortProber;

import java.io.IOException;
import java.net.ServerSocket;

/**
* Unit tests for SeleniumServer.
Expand Down Expand Up @@ -66,6 +71,42 @@ public void testJettyThreadsPositive() throws Exception {
positiveJettyThreads, server.getJettyThreads());
}

@Test
public void testServerStartupWhenPortExplicitlyZeroed() throws Exception {
RemoteControlConfiguration configuration = new RemoteControlConfiguration();
configuration.setPort(0);
SeleniumServer server = null;
try {
server = new SeleniumServer(configuration);
server.start();
assertTrue("Ensure that Jetty server spawns on a valid port", server.getRealPort() != 0);
assertTrue("Ensure that Jetty server is listening on the port", isPortUsed(server.getRealPort()));
} finally {
if (server != null) {
server.stop();
}
}
}

private boolean isPortUsed(int port) {
boolean used = false;
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
} catch (IOException e) {
used = true;
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {

}
}
}
return used;
}

// /**
// * Test for a positive result when passing a positive argument for
// * -jettyThreads.
Expand Down

0 comments on commit 31a9914

Please sign in to comment.