diff --git a/java/server/src/org/openqa/grid/common/RegistrationRequest.java b/java/server/src/org/openqa/grid/common/RegistrationRequest.java index a2c0ecbfd9881..7d695ec35b7b0 100644 --- a/java/server/src/org/openqa/grid/common/RegistrationRequest.java +++ b/java/server/src/org/openqa/grid/common/RegistrationRequest.java @@ -29,9 +29,6 @@ import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration.CollectionOfDesiredCapabilitiesDeSerializer; import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration.CollectionOfDesiredCapabilitiesSerializer; import org.openqa.selenium.MutableCapabilities; -import org.openqa.selenium.Platform; -import org.openqa.selenium.net.NetworkUtils; -import org.openqa.selenium.remote.CapabilityType; import java.util.List; @@ -103,9 +100,9 @@ public RegistrationRequest(GridNodeConfiguration configuration, String name, Str this.description = description; // make sure we have something that looks like a valid host - fixUpHost(); + this.configuration.fixUpHost(); // make sure the capabilities are updated with required fields - fixUpCapabilities(); + this.configuration.fixUpCapabilities(); } public String getName() { @@ -241,31 +238,6 @@ public static RegistrationRequest build(GridNodeConfiguration configuration, Str return pendingRequest; } - private void fixUpCapabilities() { - if (configuration.capabilities == null) { - return; // assumes the caller set it/wants it this way - } - - Platform current = Platform.getCurrent(); - for (MutableCapabilities cap : configuration.capabilities) { - if (cap.getPlatform() == null) { - cap.setCapability(CapabilityType.PLATFORM, current); - } - if (cap.getCapability(SELENIUM_PROTOCOL) == null) { - cap.setCapability(SELENIUM_PROTOCOL, SeleniumProtocol.WebDriver.toString()); - } - } - } - - private void fixUpHost() { - NetworkUtils util = new NetworkUtils(); - if (configuration.host == null || "ip".equalsIgnoreCase(configuration.host)) { - configuration.host = util.getIp4NonLoopbackAddressOfThisMachine().getHostAddress(); - } else if ("host".equalsIgnoreCase(configuration.host)) { - configuration.host = util.getIp4NonLoopbackAddressOfThisMachine().getHostName(); - } - } - /** * Validate the current setting and throw a config exception is an invalid setup is detected. * diff --git a/java/server/src/org/openqa/grid/internal/TestSlot.java b/java/server/src/org/openqa/grid/internal/TestSlot.java index 4782903437a8f..e2599309fffa4 100644 --- a/java/server/src/org/openqa/grid/internal/TestSlot.java +++ b/java/server/src/org/openqa/grid/internal/TestSlot.java @@ -23,6 +23,7 @@ import org.openqa.grid.internal.listeners.TestSessionListener; import org.openqa.grid.internal.utils.CapabilityMatcher; import org.openqa.grid.internal.utils.configuration.GridHubConfiguration; +import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration; import java.net.MalformedURLException; import java.net.URL; @@ -132,6 +133,8 @@ public TestSession getNewSession(Map desiredCapabilities) { } if (matches(desiredCapabilities)) { log.info("Trying to create a new session on test slot " + this.capabilities); + desiredCapabilities.put(GridNodeConfiguration.CONFIG_UUID_CAPABILITY, + capabilities.get(GridNodeConfiguration.CONFIG_UUID_CAPABILITY)); TestSession session = new TestSession(this, desiredCapabilities, Clock.systemUTC()); currentSession = session; lastSessionStart = System.currentTimeMillis(); diff --git a/java/server/src/org/openqa/grid/internal/utils/SelfRegisteringRemote.java b/java/server/src/org/openqa/grid/internal/utils/SelfRegisteringRemote.java index 4133f041f61de..c66c39e120405 100644 --- a/java/server/src/org/openqa/grid/internal/utils/SelfRegisteringRemote.java +++ b/java/server/src/org/openqa/grid/internal/utils/SelfRegisteringRemote.java @@ -166,6 +166,7 @@ public void addBrowser(DesiredCapabilities cap, int instances) { } cap.setCapability(RegistrationRequest.MAX_INSTANCES, instances); registrationRequest.getConfiguration().capabilities.add(cap); + registrationRequest.getConfiguration().fixUpCapabilities(); } /** diff --git a/java/server/src/org/openqa/grid/internal/utils/configuration/GridNodeConfiguration.java b/java/server/src/org/openqa/grid/internal/utils/configuration/GridNodeConfiguration.java index aca7876fa454d..e2fd30df743f5 100644 --- a/java/server/src/org/openqa/grid/internal/utils/configuration/GridNodeConfiguration.java +++ b/java/server/src/org/openqa/grid/internal/utils/configuration/GridNodeConfiguration.java @@ -51,9 +51,11 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.UUID; public class GridNodeConfiguration extends GridConfiguration { public static final String DEFAULT_NODE_CONFIG_FILE = "defaults/DefaultNodeWebDriver.json"; + public static final String CONFIG_UUID_CAPABILITY = "_CONFIG_UUID"; /* * IMPORTANT - Keep these constant values in sync with the ones specified in @@ -520,6 +522,7 @@ public void fixUpCapabilities() { if (cap.getCapability(RegistrationRequest.SELENIUM_PROTOCOL) == null) { cap.setCapability(RegistrationRequest.SELENIUM_PROTOCOL, SeleniumProtocol.WebDriver.toString()); } + cap.setCapability(CONFIG_UUID_CAPABILITY, UUID.randomUUID().toString()); } } diff --git a/java/server/src/org/openqa/grid/web/servlet/RegistrationServlet.java b/java/server/src/org/openqa/grid/web/servlet/RegistrationServlet.java index 81661972a6726..7b417960fd757 100644 --- a/java/server/src/org/openqa/grid/web/servlet/RegistrationServlet.java +++ b/java/server/src/org/openqa/grid/web/servlet/RegistrationServlet.java @@ -178,6 +178,7 @@ private void considerV2Json(GridNodeConfiguration configuration, JsonObject json MutableCapabilities cap = converter.toType(capabilities.get(i), DesiredCapabilities.class); configuration.capabilities.add(cap); } + configuration.fixUpCapabilities(); } } diff --git a/java/server/test/org/openqa/grid/e2e/GridE2ETests.java b/java/server/test/org/openqa/grid/e2e/GridE2ETests.java index 23269328aae75..814aaec1b9b78 100644 --- a/java/server/test/org/openqa/grid/e2e/GridE2ETests.java +++ b/java/server/test/org/openqa/grid/e2e/GridE2ETests.java @@ -35,7 +35,7 @@ import org.openqa.grid.e2e.misc.WebDriverPriorityDemo; import org.openqa.grid.e2e.node.BrowserTimeOutTest; import org.openqa.grid.e2e.node.CrashWhenStartingBrowserTest; -import org.openqa.grid.e2e.node.DefaultProxyFindsFirefoxLocationsTest; +import org.openqa.grid.e2e.node.DefaultProxyInjectsConfigurationUuidTest; import org.openqa.grid.e2e.node.DefaultProxyIsUnregisteredIfDownForTooLongTest; import org.openqa.grid.e2e.node.NodeGoingDownAndUpTest; import org.openqa.grid.e2e.node.NodeRecoveryTest; @@ -48,7 +48,7 @@ BrowserTimeOutTest.class, ConfigInheritanceTest.class, CrashWhenStartingBrowserTest.class, - DefaultProxyFindsFirefoxLocationsTest.class, + DefaultProxyInjectsConfigurationUuidTest.class, DefaultProxyIsUnregisteredIfDownForTooLongTest.class, ExtraServletUtilTest.class, Grid1HeartbeatTest.class, diff --git a/java/server/test/org/openqa/grid/e2e/node/DefaultProxyFindsFirefoxLocationsTest.java b/java/server/test/org/openqa/grid/e2e/node/DefaultProxyFindsFirefoxLocationsTest.java deleted file mode 100644 index 4e4cc2dd64736..0000000000000 --- a/java/server/test/org/openqa/grid/e2e/node/DefaultProxyFindsFirefoxLocationsTest.java +++ /dev/null @@ -1,237 +0,0 @@ -// Licensed to the Software Freedom Conservancy (SFC) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The SFC licenses this file -// to you 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.openqa.grid.e2e.node; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.grid.common.GridRole; -import org.openqa.grid.e2e.utils.GridTestHelper; -import org.openqa.grid.e2e.utils.RegistryTestHelper; -import org.openqa.grid.internal.ExternalSessionKey; -import org.openqa.grid.internal.GridRegistry; -import org.openqa.grid.internal.TestSession; -import org.openqa.grid.internal.exception.NewSessionException; -import org.openqa.grid.internal.utils.SelfRegisteringRemote; -import org.openqa.grid.web.Hub; -import org.openqa.grid.web.servlet.handler.RequestHandler; -import org.openqa.grid.web.servlet.handler.RequestType; -import org.openqa.grid.web.servlet.handler.SeleniumBasedRequest; -import org.openqa.selenium.chrome.ChromeOptions; -import org.openqa.selenium.firefox.FirefoxDriver; -import org.openqa.selenium.remote.BrowserType; -import org.openqa.selenium.remote.CapabilityType; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.server.SeleniumServer; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -public class DefaultProxyFindsFirefoxLocationsTest { - - private static final String LOCATION_FF_7 = "/home/ff7"; - private static final String LOCATION_FF_3 = "c:\\program files\\ff3"; - - private static final String LOCATION_CHROME_27 = "/home/chrome27"; - private static final String LOCATION_CHROME_29 = "c:\\program files\\Chrome29.exe"; - - private Hub hub; - private GridRegistry registry; - private SelfRegisteringRemote remote; - - @Before - public void prepare() throws Exception { - - hub = GridTestHelper.getHub(); - registry = hub.getRegistry(); - registry.setThrowOnCapabilityNotPresent(false); - - remote = GridTestHelper.getRemoteWithoutCapabilities(hub.getUrl(), GridRole.NODE); - remote.setMaxConcurrent(100); - - DesiredCapabilities caps = null; - - // firefox - - caps = DesiredCapabilities.firefox(); - caps.setCapability(FirefoxDriver.BINARY, LOCATION_FF_7); - caps.setVersion("7"); - remote.addBrowser(caps, 1); - caps = DesiredCapabilities.firefox(); - caps.setCapability(FirefoxDriver.BINARY, LOCATION_FF_3); - caps.setVersion("3"); - remote.addBrowser(caps, 1); - caps = DesiredCapabilities.firefox(); - caps.setCapability(FirefoxDriver.BINARY, "should be overwritten"); - caps.setVersion("20"); - remote.addBrowser(caps, 1); - - // chrome - - caps = DesiredCapabilities.chrome(); - caps.setCapability("chrome_binary", LOCATION_CHROME_27); - caps.setVersion("27"); - remote.addBrowser(caps, 1); - caps = DesiredCapabilities.chrome(); - caps.setCapability("chrome_binary", LOCATION_CHROME_29); - caps.setVersion("29"); - remote.addBrowser(caps, 2); - caps = DesiredCapabilities.chrome(); - caps.setCapability("chrome_binary", "should be overwritten"); - caps.setVersion("30"); - remote.addBrowser(caps, 1); - - remote.setRemoteServer(new SeleniumServer(remote.getConfiguration())); - remote.startRemoteServer(); - remote.sendRegistrationRequest(); - RegistryTestHelper.waitForNode(registry, 1); - } - - @Test(timeout = 5000) - public void testBrowserLocations() throws MalformedURLException { - Map req_caps = null; - RequestHandler newSessionRequest = null; - - // firefox - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX); - req_caps.put(CapabilityType.VERSION, "7"); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - assertEquals(LOCATION_FF_7, - newSessionRequest.getSession().getRequestedCapabilities() - .get(FirefoxDriver.BINARY)); - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX); - req_caps.put(CapabilityType.VERSION, "3"); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - assertEquals(LOCATION_FF_3, - newSessionRequest.getSession().getRequestedCapabilities() - .get(FirefoxDriver.BINARY)); - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX); - req_caps.put(CapabilityType.VERSION, "20"); - req_caps.put(FirefoxDriver.BINARY, "custom"); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - assertEquals("custom", - newSessionRequest.getSession().getRequestedCapabilities() - .get(FirefoxDriver.BINARY)); - - // chrome - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.CHROME); - req_caps.put(CapabilityType.VERSION, "27"); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - - Map json = (Map) newSessionRequest.getSession().getRequestedCapabilities().get(ChromeOptions.CAPABILITY); - assertEquals(LOCATION_CHROME_27, json.get("binary")); - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.CHROME); - req_caps.put(CapabilityType.VERSION, "29"); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - - json = (Map) newSessionRequest.getSession().getRequestedCapabilities().get(ChromeOptions.CAPABILITY); - assertEquals(LOCATION_CHROME_29, json.get("binary")); - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.CHROME); - req_caps.put(CapabilityType.VERSION, "29"); - Map options = new HashMap<>(); - options.put("test1", "test2"); - req_caps.put(ChromeOptions.CAPABILITY, options); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - - json = (Map) newSessionRequest.getSession().getRequestedCapabilities().get(ChromeOptions.CAPABILITY); - assertEquals(LOCATION_CHROME_29, json.get("binary")); - assertEquals("test2", json.get("test1")); - - req_caps = new HashMap<>(); - req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.CHROME); - req_caps.put(CapabilityType.VERSION, "30"); - options = new HashMap<>(); - options.put("test11", "test22"); - options.put("binary", "custom"); - req_caps.put(ChromeOptions.CAPABILITY, options); - newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); - newSessionRequest.process(); - - json = (Map) newSessionRequest.getSession().getRequestedCapabilities().get(ChromeOptions.CAPABILITY); - assertEquals("custom", json.get("binary")); - assertEquals("test22", json.get("test11")); - } - - @After - public void teardown() throws Exception { - remote.stopRemoteServer(); - hub.stop(); - } - - private SeleniumBasedRequest getNewRequest(Map desiredCapability) { - HttpServletRequest httpreq = mock(HttpServletRequest.class); - return new SeleniumBasedRequest(httpreq, registry, RequestType.START_SESSION, desiredCapability) { - - public ExternalSessionKey extractSession() { - return null; - } - - public RequestType extractRequestType() { - return null; - } - - public Map extractDesiredCapability() { - return getDesiredCapabilities(); - } - }; - } - - class MockedRequestHandler extends RequestHandler { - - public MockedRequestHandler(SeleniumBasedRequest request) { - super(request,null, request.getRegistry()); - } - - public void setSession(TestSession session) { - super.setSession(session); - } - - @Override - protected void forwardRequest(TestSession session, RequestHandler handler) throws IOException {} - - @Override - public void forwardNewSessionRequestAndUpdateRegistry(TestSession session) - throws NewSessionException {} - } - -} diff --git a/java/server/test/org/openqa/grid/e2e/node/DefaultProxyInjectsConfigurationUuidTest.java b/java/server/test/org/openqa/grid/e2e/node/DefaultProxyInjectsConfigurationUuidTest.java new file mode 100644 index 0000000000000..e1e418f62abaf --- /dev/null +++ b/java/server/test/org/openqa/grid/e2e/node/DefaultProxyInjectsConfigurationUuidTest.java @@ -0,0 +1,141 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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.openqa.grid.e2e.node; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.openqa.grid.common.GridRole; +import org.openqa.grid.e2e.utils.GridTestHelper; +import org.openqa.grid.e2e.utils.RegistryTestHelper; +import org.openqa.grid.internal.ExternalSessionKey; +import org.openqa.grid.internal.GridRegistry; +import org.openqa.grid.internal.TestSession; +import org.openqa.grid.internal.exception.NewSessionException; +import org.openqa.grid.internal.utils.SelfRegisteringRemote; +import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration; +import org.openqa.grid.web.Hub; +import org.openqa.grid.web.servlet.handler.RequestHandler; +import org.openqa.grid.web.servlet.handler.RequestType; +import org.openqa.grid.web.servlet.handler.SeleniumBasedRequest; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.remote.BrowserType; +import org.openqa.selenium.remote.CapabilityType; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.server.SeleniumServer; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +public class DefaultProxyInjectsConfigurationUuidTest { + + private Hub hub; + private GridRegistry registry; + private SelfRegisteringRemote remote; + + private DesiredCapabilities ff20_caps; + + @Before + public void prepare() throws Exception { + + hub = GridTestHelper.getHub(); + registry = hub.getRegistry(); + registry.setThrowOnCapabilityNotPresent(false); + + remote = GridTestHelper.getRemoteWithoutCapabilities(hub.getUrl(), GridRole.NODE); + remote.setMaxConcurrent(100); + + ff20_caps = DesiredCapabilities.firefox(); + ff20_caps.setCapability(FirefoxDriver.BINARY, "should be overwritten"); + ff20_caps.setVersion("20"); + remote.addBrowser(ff20_caps, 1); + + remote.setRemoteServer(new SeleniumServer(remote.getConfiguration())); + remote.startRemoteServer(); + remote.sendRegistrationRequest(); + RegistryTestHelper.waitForNode(registry, 1); + } + + @Test(timeout = 5000) + public void testProxyInjectsConfigurationUUID() throws MalformedURLException { + Map req_caps = new HashMap<>(); + req_caps.put(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX); + req_caps.put(CapabilityType.VERSION, "20"); + req_caps.put(FirefoxDriver.BINARY, "custom"); + + RequestHandler newSessionRequest = new MockedRequestHandler(getNewRequest(req_caps)); + newSessionRequest.process(); + + assertEquals(ff20_caps.getCapability(GridNodeConfiguration.CONFIG_UUID_CAPABILITY), + newSessionRequest.getSession().getRequestedCapabilities() + .get(GridNodeConfiguration.CONFIG_UUID_CAPABILITY)); + assertEquals("custom", + newSessionRequest.getSession().getRequestedCapabilities() + .get(FirefoxDriver.BINARY)); + } + + @After + public void teardown() throws Exception { + remote.stopRemoteServer(); + hub.stop(); + } + + private SeleniumBasedRequest getNewRequest(Map desiredCapability) { + HttpServletRequest httpreq = mock(HttpServletRequest.class); + return new SeleniumBasedRequest(httpreq, registry, RequestType.START_SESSION, desiredCapability) { + + public ExternalSessionKey extractSession() { + return null; + } + + public RequestType extractRequestType() { + return null; + } + + public Map extractDesiredCapability() { + return getDesiredCapabilities(); + } + }; + } + + class MockedRequestHandler extends RequestHandler { + + public MockedRequestHandler(SeleniumBasedRequest request) { + super(request,null, request.getRegistry()); + } + + public void setSession(TestSession session) { + super.setSession(session); + } + + @Override + protected void forwardRequest(TestSession session, RequestHandler handler) throws IOException {} + + @Override + public void forwardNewSessionRequestAndUpdateRegistry(TestSession session) + throws NewSessionException {} + } + +} diff --git a/java/server/test/org/openqa/grid/internal/utils/configuration/GridNodeConfigurationTest.java b/java/server/test/org/openqa/grid/internal/utils/configuration/GridNodeConfigurationTest.java index b3d70a5101db5..4541d603f18f7 100644 --- a/java/server/test/org/openqa/grid/internal/utils/configuration/GridNodeConfigurationTest.java +++ b/java/server/test/org/openqa/grid/internal/utils/configuration/GridNodeConfigurationTest.java @@ -305,4 +305,13 @@ public void testMergeWithRealValues() { // is not a merged value assertNull(gnc.nodeConfigFile); } + + @Test + public void testFixupCapabilitiesAddsUUID() { + GridNodeConfiguration gnc = new GridNodeConfiguration(); + gnc.fixUpCapabilities(); + assertTrue(gnc.capabilities.stream() + .allMatch(cap -> cap.getCapability(GridNodeConfiguration.CONFIG_UUID_CAPABILITY) != null)); + } + }