@Override public void afterCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) { String currentName = Thread.currentThread().getName(); Thread.currentThread().setName(getProxyName()); if (request instanceof WebDriverRequest && "DELETE".equalsIgnoreCase(request.getMethod())) { WebDriverRequest seleniumRequest = (WebDriverRequest) request; if (seleniumRequest.getRequestType().equals(RequestType.STOP_SESSION)) { long executionTime = (System.currentTimeMillis() - session.getSlot().getLastSessionStart()) / 1000; getGa().testEvent(getProxyClassName(), session.getRequestedCapabilities().toString(), executionTime); addTestToDashboard(session.getExternalKey().getKey(), true); } } super.afterCommand(session, request, response); Thread.currentThread().setName(currentName); }
private String getSingleSlotHtml(TestSlot s) { TestSession session = s.getSession(); String icon = ""; if (proxy instanceof TestingBotRemoteProxy) { icon = contextPath + "/grid/resources/images/testingbot.png"; } if (proxy instanceof BrowserStackRemoteProxy) { icon = contextPath + "/grid/resources/images/browserstack.png"; } if (proxy instanceof SauceLabsRemoteProxy) { icon = contextPath + "/grid/resources/images/saucelabs.png"; } String slotClass = ""; String slotTitle; if (session != null) { slotClass = "busy"; slotTitle = session.get("lastCommand").toString(); } else { slotTitle = s.getCapabilities().toString(); } Map<String, String> singleSlotValues = new HashMap<>(); singleSlotValues.put("{{slotIcon}}", icon); singleSlotValues.put("{{slotClass}}", slotClass); singleSlotValues.put("{{slotTitle}}", slotTitle); return templateRenderer.renderSection("{{singleSlots}}", singleSlotValues); }
@VisibleForTesting public void terminateIdleSessions() { String currentName = Thread.currentThread().getName(); Thread.currentThread().setName(getProxyName()); for (TestSlot testSlot : getTestSlots()) { if (testSlot.getSession() != null && (testSlot.getSession().getInactivityTime() >= (getMaxTestIdleTime() * 1000L))) { long executionTime = (System.currentTimeMillis() - testSlot.getLastSessionStart()) / 1000; getGa().testEvent(getProxyClassName(), testSlot.getSession().getRequestedCapabilities().toString(), executionTime); // If it is null, it is probable that the test never reached the cloud service. if (testSlot.getSession().getExternalKey() != null) { addTestToDashboard(testSlot.getSession().getExternalKey().getKey(), false); } getRegistry().forceRelease(testSlot, SessionTerminationReason.ORPHAN); logger.warn("Releasing slot and terminating session due to inactivity."); } } Thread.currentThread().setName(currentName); }
/** * Ends this test session for the hub, releasing the resources in the hub / registry. It does not * release anything on the remote. The resources are released in a separate thread, so the call * returns immediately. It allows release with long duration not to block the test while the hub is * releasing the resource. * * @param session The session to terminate * @param reason the reason for termination */ public void terminate(final TestSession session, final SessionTerminationReason reason) { // Thread safety reviewed String remoteName = ""; if (session.getSlot().getProxy() instanceof DockerSeleniumRemoteProxy) { remoteName = ((DockerSeleniumRemoteProxy)session.getSlot().getProxy()).getRegistration().getContainerId(); } String internalKey = Optional.ofNullable(session.getInternalKey()).orElse("No internal key"); ExternalSessionKey externalKey = Optional.ofNullable(session.getExternalKey()).orElse(new ExternalSessionKey("No external key was assigned")); new Thread(() -> _release(session.getSlot(), reason), "Terminate Test Session int id: [" + internalKey + "] ext id: [" + externalKey + "] container: [" + remoteName + "]").start(); }
@Override public void afterCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) { String currentName = configureThreadName(); super.afterCommand(session, request, response); LOGGER.debug("lastCommand: {} - executing...", request.getMethod(), request.getPathInfo()); if (request instanceof WebDriverRequest && "POST".equalsIgnoreCase(request.getMethod())) { WebDriverRequest seleniumRequest = (WebDriverRequest) request; if (RequestType.START_SESSION.equals(seleniumRequest.getRequestType())) { ExternalSessionKey externalKey = Optional.ofNullable(session.getExternalKey()) .orElse(new ExternalSessionKey("[No external key present]")); LOGGER.debug(String.format("Test session started with internal key %s and external key %s assigned to remote %s.", session.getInternalKey(), externalKey, getId())); LOGGER.debug("Test session started with internal key {} and external key {} assigned to remote.", session.getInternalKey(), externalKey); videoRecording(DockerSeleniumContainerAction.START_RECORDING); } } this.lastCommandTime = System.currentTimeMillis(); setThreadName(currentName); }
public void beforeCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) { Map<String, Object> requestedCapabilities = session.getRequestedCapabilities(); // give up if sauce labs is down ... // this should fail faster vs. returning the session to hub by doing this check in #getNewSession // (DefaultRemoteProxy's behavior) if (down) { throw new GridException("Sauce Labs is currently down."); } if (session.get("authenticated-session") == null) { // error the session when there is no sauce user name and/or access key if (isMissingRequiredCapabilities(requestedCapabilities)) { throw new GridException("Sauce Labs credentials were not specified."); } final String username = (String) requestedCapabilities.get(SauceLabsCapability.USERNAME_CAPABILITY); final String accessKey = (String) requestedCapabilities.get(SauceLabsCapability.ACCESS_KEY_CAPABILITY); if (!sauceApi.isAuthenticated(username, accessKey)) { // TODO isAuthenticated will return false when Sauce labs is down even if the credentials are valid. throw new GridException("Sauce Labs credentials are invalid."); } // make a note that this session is already authenticated session.put("authenticated-session", true); } session.put("lastCommand", request.getMethod() + " - " + request.getPathInfo() + " executing ..."); }
@Override public void afterSession(TestSession session) { String currentName = configureThreadName(); try { // This means that the shutdown command was triggered before receiving this afterSession command if (!TestInformation.TestStatus.TIMEOUT.equals(testInformation.getTestStatus())) { long executionTime = (System.currentTimeMillis() - session.getSlot().getLastSessionStart()) / 1000; ga.testEvent(DockerSeleniumRemoteProxy.class.getName(), session.getRequestedCapabilities().toString(), executionTime); if (isTestSessionLimitReached()) { LOGGER.info("Session {} completed. Node should shutdown soon...", session.getInternalKey()); cleanupNode(true); } else { LOGGER.info("Session {} completed. Cleaning up node for reuse, used {} of max {} sessions", session.getInternalKey(), getAmountOfExecutedTests(), maxTestSessions); cleanupNode(false); } } } catch (Exception e) { LOGGER.warn(e.toString(), e); } finally { super.afterSession(session); } setThreadName(currentName); }
public void refreshTimeout(String sessionId) { for (TestSession activeSession : registry.getActiveSessions()) { if ((activeSession != null) && (sessionId != null) && (activeSession.getExternalKey() != null)) { if (sessionId.equals(activeSession.getExternalKey().getKey())) { refreshTimeout(activeSession); } } } }
@VisibleForTesting protected void terminateIdleTest() { for (TestSlot testSlot : getTestSlots()) { if (testSlot.getSession() != null) { long executionTime = (System.currentTimeMillis() - testSlot.getLastSessionStart()) / 1000; ga.testEvent(DockerSeleniumRemoteProxy.class.getName(), testSlot.getSession().getRequestedCapabilities().toString(), executionTime); getRegistry().forceRelease(testSlot, SessionTerminationReason.ORPHAN); } } }
public void afterCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) { session.put("lastCommand", request.getMethod() + " - " + request.getPathInfo() + " executed."); // throw an exception if we got back a HTTP 404 // ignore if we were trying to DELETE a session if ((response.getStatus() == HttpServletResponse.SC_NOT_FOUND) && (!isWebDriverCommand(request, HttpMethod.DELETE, String.format("/session/%s", session.getExternalKey())))) { throw new GridException("Sauce Labs session no longer exists. It may have timed out."); } }
public void beforeRelease(TestSession session) { // release the resources remotely if the remote started a browser. if (session.getExternalKey() == null) { return; } boolean ok = session.sendDeleteSessionRequest(); if (!ok) { LOGGER.warning("Error releasing the resources on timeout for session " + session); } }
public SessionInfoBean(TestSession session) { requestedCapabilities = session.getRequestedCapabilities(); nodeCapabilities = session.getSlot().getCapabilities(); }
public URL getRemoteHostForSession(String sessionId) { for (TestSession activeSession : registry.getActiveSessions()) { if (sessionId.equals(activeSession.getExternalKey().getKey())) { return activeSession.getSlot().getProxy().getRemoteHost(); } } throw new IllegalArgumentException("Invalid sessionId. No active session is present for id:" + sessionId); }
private boolean takeRequestHandler(RequestHandler handler) { final TestSession session = proxies.getNewSession(handler.getRequest().getDesiredCapabilities()); final boolean sessionCreated = session != null; if (sessionCreated) { String remoteName = session.getSlot().getProxy().getId(); long timeToAssignProxy = System.currentTimeMillis() - handler.getRequest().getCreationTime(); LOG.info("Test session with internal key {} assigned to remote ({}) after {} seconds ({} ms).", session.getInternalKey(), remoteName, timeToAssignProxy / 1000, timeToAssignProxy); seleniumTestSessionStartLatency.observe(timeToAssignProxy / Collector.MILLISECONDS_PER_SECOND); seleniumTestSessionsWaiting.dec(); activeTestSessions.add(session); handler.bindSession(session); } return sessionCreated; }
private void refreshTimeout(TestSession activeSession) { if (activeSession.getInactivityTime() != 0) { activeSession.setIgnoreTimeout(false); } }
String browserName = requestedCapability.get(CapabilityType.BROWSER_NAME).toString(); testName = getCapability(requestedCapability, ZaleniumCapabilityType.TEST_NAME, ""); String seleniumSessionId = newSession.getExternalKey() != null ? newSession.getExternalKey().getKey() : newSession.getInternalKey(); if (testName.isEmpty()) { testName = seleniumSessionId; String screenResolution = getCapability(newSession.getSlot().getCapabilities(), ZaleniumCapabilityType.SCREEN_RESOLUTION, "N/A"); String browserVersion = getCapability(newSession.getSlot().getCapabilities(), CapabilityType.VERSION, ""); String timeZone = getCapability(newSession.getSlot().getCapabilities(), ZaleniumCapabilityType.TIME_ZONE, "N/A"); testInformation = new TestInformation.TestInformationBuilder() .withTestName(testName)
public void beforeCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) { Map<String, Object> requestedCapabilities = session.getRequestedCapabilities(); // give up if sauce labs is down ... // this should fail faster vs. returning the session to hub by doing this check in #getNewSession // (DefaultRemoteProxy's behavior) if (down) { throw new GridException("Sauce Labs is currently down."); } if (session.get("authenticated-session") == null) { // error the session when there is no sauce user name and/or access key if (isMissingRequiredCapabilities(requestedCapabilities)) { throw new GridException("Sauce Labs credentials were not specified."); } final String username = (String) requestedCapabilities.get(SauceLabsCapability.USERNAME_CAPABILITY); final String accessKey = (String) requestedCapabilities.get(SauceLabsCapability.ACCESS_KEY_CAPABILITY); if (!sauceApi.isAuthenticated(username, accessKey)) { // TODO isAuthenticated will return false when Sauce labs is down even if the credentials are valid. throw new GridException("Sauce Labs credentials are invalid."); } // make a note that this session is already authenticated session.put("authenticated-session", true); } session.put("lastCommand", request.getMethod() + " - " + request.getPathInfo() + " executing ..."); }
public static void declareSessionStopping(TestSession session) { stoppingSessions.put(session.getExternalKey().getKey(), new VideoFuture()); }
Object sessionUuid = testSession.getRequestedCapabilities().get( AutomationConstants.UUID); if (targetUuid.equals(sessionUuid)) {
public void afterCommand(TestSession session, HttpServletRequest request, HttpServletResponse response) { session.put("lastCommand", request.getMethod() + " - " + request.getPathInfo() + " executed."); // throw an exception if we got back a HTTP 404 // ignore if we were trying to DELETE a session if ((response.getStatus() == HttpServletResponse.SC_NOT_FOUND) && (!isWebDriverCommand(request, HttpMethod.DELETE, String.format("/session/%s", session.getExternalKey())))) { throw new GridException("Sauce Labs session no longer exists. It may have timed out."); } }