How to use Session class of org.openqa.selenium.grid.data package

Best Selenium code snippet using org.openqa.selenium.grid.data.Session

Source:GraphqlHandlerTest.java Github

copy

Full Screen

...19import org.junit.Before;20import org.junit.Test;21import org.openqa.selenium.Capabilities;22import org.openqa.selenium.ImmutableCapabilities;23import org.openqa.selenium.SessionNotCreatedException;24import org.openqa.selenium.WebDriverException;25import org.openqa.selenium.events.EventBus;26import org.openqa.selenium.events.local.GuavaEventBus;27import org.openqa.selenium.grid.data.CreateSessionRequest;28import org.openqa.selenium.grid.data.CreateSessionResponse;29import org.openqa.selenium.grid.data.DefaultSlotMatcher;30import org.openqa.selenium.grid.data.NewSessionRequestEvent;31import org.openqa.selenium.grid.data.RequestId;32import org.openqa.selenium.grid.data.Session;33import org.openqa.selenium.grid.data.Slot;34import org.openqa.selenium.grid.distributor.Distributor;35import org.openqa.selenium.grid.distributor.local.LocalDistributor;36import org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector;37import org.openqa.selenium.grid.node.ActiveSession;38import org.openqa.selenium.grid.node.Node;39import org.openqa.selenium.grid.node.SessionFactory;40import org.openqa.selenium.grid.node.local.LocalNode;41import org.openqa.selenium.grid.security.Secret;42import org.openqa.selenium.grid.sessionmap.SessionMap;43import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;44import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;45import org.openqa.selenium.grid.data.SessionRequest;46import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;47import org.openqa.selenium.grid.testing.TestSessionFactory;48import org.openqa.selenium.internal.Either;49import org.openqa.selenium.json.Json;50import org.openqa.selenium.remote.http.Contents;51import org.openqa.selenium.remote.http.HttpClient;52import org.openqa.selenium.remote.http.HttpHandler;53import org.openqa.selenium.remote.http.HttpRequest;54import org.openqa.selenium.remote.http.HttpResponse;55import org.openqa.selenium.remote.tracing.DefaultTestTracer;56import org.openqa.selenium.remote.tracing.Tracer;57import org.openqa.selenium.support.ui.FluentWait;58import org.openqa.selenium.support.ui.Wait;59import java.net.URI;60import java.net.URISyntaxException;61import java.time.Duration;62import java.time.Instant;63import java.util.Collections;64import java.util.Map;65import java.util.Set;66import java.util.UUID;67import java.util.concurrent.CountDownLatch;68import java.util.concurrent.atomic.AtomicInteger;69import static java.util.Collections.singletonList;70import static java.util.Collections.singletonMap;71import static java.util.concurrent.TimeUnit.SECONDS;72import static org.assertj.core.api.Assertions.assertThat;73import static org.assertj.core.api.Assertions.fail;74import static org.assertj.core.api.InstanceOfAssertFactories.LIST;75import static org.assertj.core.api.InstanceOfAssertFactories.MAP;76import static org.openqa.selenium.json.Json.MAP_TYPE;77import static org.openqa.selenium.remote.Dialect.OSS;78import static org.openqa.selenium.remote.Dialect.W3C;79import static org.openqa.selenium.remote.http.HttpMethod.GET;80public class GraphqlHandlerTest {81 private static final Json JSON = new Json();82 private final Secret registrationSecret = new Secret("stilton");83 private final URI publicUri = new URI("http://example.com/grid-o-matic");84 private final String version = "4.0.0";85 private final Wait<Object> wait = new FluentWait<>(new Object()).withTimeout(Duration.ofSeconds(5));86 private Distributor distributor;87 private NewSessionQueue queue;88 private Tracer tracer;89 private EventBus events;90 private ImmutableCapabilities caps;91 private ImmutableCapabilities stereotype;92 private SessionRequest sessionRequest;93 public GraphqlHandlerTest() throws URISyntaxException {94 }95 @Before96 public void setupGrid() {97 tracer = DefaultTestTracer.createTracer();98 events = new GuavaEventBus();99 HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();100 SessionMap sessions = new LocalSessionMap(tracer, events);101 stereotype = new ImmutableCapabilities("browserName", "cheese");102 caps = new ImmutableCapabilities("browserName", "cheese");103 sessionRequest = new SessionRequest(104 new RequestId(UUID.randomUUID()),105 Instant.now(),106 Set.of(OSS, W3C),107 Set.of(caps),108 Map.of(),109 Map.of());110 queue = new LocalNewSessionQueue(111 tracer,112 events,113 new DefaultSlotMatcher(),114 Duration.ofSeconds(2),115 Duration.ofSeconds(2),116 registrationSecret);117 distributor = new LocalDistributor(118 tracer,119 events,120 clientFactory,121 sessions,122 queue,123 new DefaultSlotSelector(),124 registrationSecret,125 Duration.ofMinutes(5),126 false);127 }128 @Test129 public void shouldBeAbleToGetGridUri() {130 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);131 Map<String, Object> topLevel = executeQuery(handler, "{ grid { uri } }");132 assertThat(topLevel).isEqualTo(133 singletonMap(134 "data", singletonMap(135 "grid", singletonMap(136 "uri", publicUri.toString()))));137 }138 @Test139 public void shouldBeAbleToGetGridVersion() {140 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);141 Map<String, Object> topLevel = executeQuery(handler, "{ grid { version } }");142 assertThat(topLevel).isEqualTo(143 singletonMap(144 "data", singletonMap(145 "grid", singletonMap(146 "version", version))));147 }148 private void continueOnceAddedToQueue(SessionRequest request) {149 // Add to the queue in the background150 CountDownLatch latch = new CountDownLatch(1);151 events.addListener(NewSessionRequestEvent.listener(id -> latch.countDown()));152 new Thread(() -> {153 queue.addToQueue(request);154 }).start();155 try {156 assertThat(latch.await(5, SECONDS)).isTrue();157 } catch (InterruptedException e) {158 Thread.currentThread().interrupt();159 throw new RuntimeException(e);160 }161 }162 @Test163 public void shouldBeAbleToGetSessionQueueSize() throws URISyntaxException {164 SessionRequest request = new SessionRequest(165 new RequestId(UUID.randomUUID()),166 Instant.now(),167 Set.of(W3C),168 Set.of(caps),169 Map.of(),170 Map.of());171 continueOnceAddedToQueue(request);172 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);173 Map<String, Object> topLevel = executeQuery(handler, "{ grid { sessionQueueSize } }");174 assertThat(topLevel).isEqualTo(175 singletonMap(176 "data", singletonMap(177 "grid", singletonMap(178 "sessionQueueSize", 1L))));179 }180 @Test181 public void shouldBeAbleToGetSessionQueueRequests() throws URISyntaxException {182 SessionRequest request = new SessionRequest(183 new RequestId(UUID.randomUUID()),184 Instant.now(),185 Set.of(W3C),186 Set.of(caps),187 Map.of(),188 Map.of());189 continueOnceAddedToQueue(request);190 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);191 Map<String, Object> topLevel = executeQuery(handler,192 "{ sessionsInfo { sessionQueueRequests } }");193 assertThat(topLevel).isEqualTo(194 singletonMap(195 "data", singletonMap(196 "sessionsInfo", singletonMap(197 "sessionQueueRequests", singletonList(JSON.toJson(caps))))));198 }199 @Test200 public void shouldBeReturnAnEmptyListIfQueueIsEmpty() {201 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);202 Map<String, Object> topLevel = executeQuery(handler,203 "{ sessionsInfo { sessionQueueRequests } }");204 assertThat(topLevel).isEqualTo(205 singletonMap(206 "data", singletonMap(207 "sessionsInfo", singletonMap(208 "sessionQueueRequests", Collections.emptyList()))));209 }210 @Test211 public void shouldReturnAnEmptyListForNodesIfNoneAreRegistered() {212 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);213 Map<String, Object> topLevel = executeQuery(handler, "{ nodesInfo { nodes { uri } } }");214 assertThat(topLevel).describedAs(topLevel.toString()).isEqualTo(215 singletonMap(216 "data", singletonMap(217 "nodesInfo", singletonMap(218 "nodes", Collections.emptyList()))));219 }220 @Test221 public void shouldBeAbleToGetUrlsOfAllNodes() throws URISyntaxException {222 Capabilities stereotype = new ImmutableCapabilities("cheese", "stilton");223 String nodeUri = "http://localhost:5556";224 Node node = LocalNode.builder(tracer, events, new URI(nodeUri), publicUri, registrationSecret)225 .add(stereotype, new SessionFactory() {226 @Override227 public Either<WebDriverException, ActiveSession> apply(228 CreateSessionRequest createSessionRequest) {229 return Either.left(new SessionNotCreatedException("Factory for testing"));230 }231 @Override232 public boolean test(Capabilities capabilities) {233 return false;234 }235 })236 .build();237 distributor.add(node);238 wait.until(obj -> distributor.getStatus().hasCapacity());239 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);240 Map<String, Object> topLevel = executeQuery(handler, "{ nodesInfo { nodes { uri } } }");241 assertThat(topLevel).describedAs(topLevel.toString()).isEqualTo(242 singletonMap(243 "data", singletonMap(244 "nodesInfo", singletonMap(245 "nodes", singletonList(singletonMap("uri", nodeUri))))));246 }247 @Test248 public void shouldBeAbleToGetSessionCount() throws URISyntaxException {249 String nodeUrl = "http://localhost:5556";250 URI nodeUri = new URI(nodeUrl);251 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)252 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(253 id,254 nodeUri,255 stereotype,256 caps,257 Instant.now()))).build();258 distributor.add(node);259 wait.until(obj -> distributor.getStatus().hasCapacity());260 Either<SessionNotCreatedException, CreateSessionResponse> response = distributor.newSession(sessionRequest);261 if (response.isRight()) {262 Session session = response.right().getSession();263 assertThat(session).isNotNull();264 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);265 Map<String, Object> topLevel = executeQuery(handler,266 "{ grid { sessionCount } }");267 assertThat(topLevel).isEqualTo(268 singletonMap(269 "data", singletonMap(270 "grid", singletonMap(271 "sessionCount", 1L ))));272 } else {273 fail("Session creation failed", response.left());274 }275 }276 @Test277 public void shouldBeAbleToGetSessionInfo() throws URISyntaxException {278 String nodeUrl = "http://localhost:5556";279 URI nodeUri = new URI(nodeUrl);280 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)281 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(282 id,283 nodeUri,284 stereotype,285 caps,286 Instant.now()))).build();287 distributor.add(node);288 wait.until(obj -> distributor.getStatus().hasCapacity());289 Either<SessionNotCreatedException, CreateSessionResponse> response = distributor.newSession(sessionRequest);290 if (response.isRight()) {291 Session session = response.right().getSession();292 assertThat(session).isNotNull();293 String sessionId = session.getId().toString();294 Set<Slot> slots = distributor.getStatus().getNodes().stream().findFirst().get().getSlots();295 Slot slot = slots.stream().findFirst().get();296 org.openqa.selenium.grid.graphql.Session graphqlSession =297 new org.openqa.selenium.grid.graphql.Session(298 sessionId,299 session.getCapabilities(),300 session.getStartTime(),301 session.getUri(),302 node.getId().toString(),303 node.getUri(),304 slot);305 String query = String.format(306 "{ session (id: \"%s\") { id, capabilities, startTime, uri } }", sessionId);307 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);308 Map<String, Object> result = executeQuery(handler, query);309 assertThat(result).describedAs(result.toString()).isEqualTo(310 singletonMap(311 "data", singletonMap(312 "session", ImmutableMap.of(313 "id", sessionId,314 "capabilities", graphqlSession.getCapabilities(),315 "startTime", graphqlSession.getStartTime(),316 "uri", graphqlSession.getUri().toString()))));317 } else {318 fail("Session creation failed", response.left());319 }320 }321 @Test322 public void shouldBeAbleToGetNodeInfoForSession() throws URISyntaxException {323 String nodeUrl = "http://localhost:5556";324 URI nodeUri = new URI(nodeUrl);325 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)326 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(327 id,328 nodeUri,329 stereotype,330 caps,331 Instant.now()))).build();332 distributor.add(node);333 wait.until(obj -> distributor.getStatus().hasCapacity());334 Either<SessionNotCreatedException, CreateSessionResponse> response = distributor.newSession(sessionRequest);335 if (response.isRight()) {336 Session session = response.right().getSession();337 assertThat(session).isNotNull();338 String sessionId = session.getId().toString();339 Set<Slot> slots = distributor.getStatus().getNodes().stream().findFirst().get().getSlots();340 Slot slot = slots.stream().findFirst().get();341 org.openqa.selenium.grid.graphql.Session graphqlSession =342 new org.openqa.selenium.grid.graphql.Session(343 sessionId,344 session.getCapabilities(),345 session.getStartTime(),346 session.getUri(),347 node.getId().toString(),348 node.getUri(),349 slot);350 String query = String.format("{ session (id: \"%s\") { nodeId, nodeUri } }", sessionId);351 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);352 Map<String, Object> result = executeQuery(handler, query);353 assertThat(result).describedAs(result.toString()).isEqualTo(354 singletonMap(355 "data", singletonMap(356 "session", ImmutableMap.of(357 "nodeId", graphqlSession.getNodeId(),358 "nodeUri", graphqlSession.getNodeUri().toString()))));359 } else {360 fail("Session creation failed", response.left());361 }362 }363 @Test364 public void shouldBeAbleToGetSlotInfoForSession() throws URISyntaxException {365 String nodeUrl = "http://localhost:5556";366 URI nodeUri = new URI(nodeUrl);367 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)368 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(369 id,370 nodeUri,371 stereotype,372 caps,373 Instant.now()))).build();374 distributor.add(node);375 wait.until(obj -> distributor.getStatus().hasCapacity());376 Either<SessionNotCreatedException, CreateSessionResponse> response = distributor.newSession(sessionRequest);377 if (response.isRight()) {378 Session session = response.right().getSession();379 assertThat(session).isNotNull();380 String sessionId = session.getId().toString();381 Set<Slot> slots = distributor.getStatus().getNodes().stream().findFirst().get().getSlots();382 Slot slot = slots.stream().findFirst().get();383 org.openqa.selenium.grid.graphql.Session graphqlSession =384 new org.openqa.selenium.grid.graphql.Session(385 sessionId,386 session.getCapabilities(),387 session.getStartTime(),388 session.getUri(),389 node.getId().toString(),390 node.getUri(),391 slot);392 org.openqa.selenium.grid.graphql.Slot graphqlSlot = graphqlSession.getSlot();393 String query = String.format(394 "{ session (id: \"%s\") { slot { id, stereotype, lastStarted } } }", sessionId);395 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);396 Map<String, Object> result = executeQuery(handler, query);397 assertThat(result).describedAs(result.toString()).isEqualTo(398 singletonMap(399 "data", singletonMap(400 "session", singletonMap(401 "slot", ImmutableMap.of(402 "id", graphqlSlot.getId(),403 "stereotype", graphqlSlot.getStereotype(),404 "lastStarted", graphqlSlot.getLastStarted())))));405 } else {406 fail("Session creation failed", response.left());407 }408 }409 @Test410 public void shouldBeAbleToGetSessionDuration() throws URISyntaxException {411 String nodeUrl = "http://localhost:5556";412 URI nodeUri = new URI(nodeUrl);413 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)414 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(415 id,416 nodeUri,417 stereotype,418 caps,419 Instant.now()))).build();420 distributor.add(node);421 wait.until(obj -> distributor.getStatus().hasCapacity());422 Either<SessionNotCreatedException, CreateSessionResponse> response = distributor.newSession(sessionRequest);423 if (response.isRight()) {424 Session session = response.right().getSession();425 assertThat(session).isNotNull();426 String sessionId = session.getId().toString();427 String query = String.format("{ session (id: \"%s\") { sessionDurationMillis } }", sessionId);428 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);429 Map<String, Object> result = executeQuery(handler, query);430 assertThat(result)431 .containsOnlyKeys("data")432 .extracting("data").asInstanceOf(MAP).containsOnlyKeys("session")433 .extracting("session").asInstanceOf(MAP).containsOnlyKeys("sessionDurationMillis");434 } else {435 fail("Session creation failed", response.left());436 }437 }438 @Test439 public void shouldThrowExceptionWhenSessionNotFound() throws URISyntaxException {440 String nodeUrl = "http://localhost:5556";441 URI nodeUri = new URI(nodeUrl);442 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)443 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(444 id,445 nodeUri,446 stereotype,447 caps,448 Instant.now()))).build();449 distributor.add(node);450 wait.until(obj -> distributor.getStatus().hasCapacity());451 String randomSessionId = UUID.randomUUID().toString();452 String query = "{ session (id: \"" + randomSessionId + "\") { sessionDurationMillis } }";453 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);454 Map<String, Object> result = executeQuery(handler, query);455 assertThat(result)456 .containsEntry("data", null)457 .containsKey("errors")458 .extracting("errors").asInstanceOf(LIST).isNotEmpty()459 .element(0).asInstanceOf(MAP).containsKey("extensions")460 .extracting("extensions").asInstanceOf(MAP).containsKey("sessionId")461 .extracting("sessionId").isEqualTo(randomSessionId);462 }463 @Test464 public void shouldThrowExceptionWhenSessionIsEmpty() throws URISyntaxException {465 String nodeUrl = "http://localhost:5556";466 URI nodeUri = new URI(nodeUrl);467 Node node = LocalNode.builder(tracer, events, nodeUri, publicUri, registrationSecret)468 .add(caps, new TestSessionFactory((id, caps) -> new org.openqa.selenium.grid.data.Session(469 id,470 nodeUri,471 stereotype,472 caps,473 Instant.now()))).build();474 distributor.add(node);475 wait.until(obj -> distributor.getStatus().hasCapacity());476 String query = "{ session (id: \"\") { sessionDurationMillis } }";477 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);478 Map<String, Object> result = executeQuery(handler, query);479 assertThat(result)480 .containsEntry("data", null)481 .containsKey("errors")482 .extracting("errors").asInstanceOf(LIST).isNotEmpty();...

Full Screen

Full Screen

Source:AddingNodesTest.java Github

copy

Full Screen

...20import org.junit.Before;21import org.junit.Test;22import org.openqa.selenium.Capabilities;23import org.openqa.selenium.ImmutableCapabilities;24import org.openqa.selenium.NoSuchSessionException;25import org.openqa.selenium.SessionNotCreatedException;26import org.openqa.selenium.WebDriverException;27import org.openqa.selenium.events.EventBus;28import org.openqa.selenium.events.local.GuavaEventBus;29import org.openqa.selenium.grid.data.CreateSessionRequest;30import org.openqa.selenium.grid.data.CreateSessionResponse;31import org.openqa.selenium.grid.data.DefaultSlotMatcher;32import org.openqa.selenium.grid.data.NodeId;33import org.openqa.selenium.grid.data.NodeStatus;34import org.openqa.selenium.grid.data.NodeStatusEvent;35import org.openqa.selenium.grid.data.Session;36import org.openqa.selenium.grid.data.SessionClosedEvent;37import org.openqa.selenium.grid.data.Slot;38import org.openqa.selenium.grid.data.SlotId;39import org.openqa.selenium.grid.distributor.local.LocalDistributor;40import org.openqa.selenium.grid.distributor.remote.RemoteDistributor;41import org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector;42import org.openqa.selenium.grid.node.CapabilityResponseEncoder;43import org.openqa.selenium.grid.node.HealthCheck;44import org.openqa.selenium.grid.node.Node;45import org.openqa.selenium.grid.node.local.LocalNode;46import org.openqa.selenium.grid.security.Secret;47import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;48import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;49import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;50import org.openqa.selenium.grid.testing.TestSessionFactory;51import org.openqa.selenium.grid.web.CombinedHandler;52import org.openqa.selenium.grid.web.RoutableHttpClientFactory;53import org.openqa.selenium.internal.Either;54import org.openqa.selenium.remote.SessionId;55import org.openqa.selenium.remote.http.HttpClient;56import org.openqa.selenium.remote.http.HttpRequest;57import org.openqa.selenium.remote.http.HttpResponse;58import org.openqa.selenium.remote.tracing.DefaultTestTracer;59import org.openqa.selenium.remote.tracing.Tracer;60import org.openqa.selenium.support.ui.FluentWait;61import org.openqa.selenium.support.ui.Wait;62import java.net.MalformedURLException;63import java.net.URI;64import java.net.URISyntaxException;65import java.net.URL;66import java.time.Duration;67import java.time.Instant;68import java.util.HashMap;69import java.util.Map;70import java.util.Objects;71import java.util.Optional;72import java.util.Set;73import java.util.UUID;74import java.util.function.Function;75import static com.google.common.collect.Iterables.getOnlyElement;76import static org.junit.Assert.assertEquals;77import static org.openqa.selenium.grid.data.Availability.UP;78import static org.openqa.selenium.remote.Dialect.W3C;79public class AddingNodesTest {80 private static final Capabilities CAPS = new ImmutableCapabilities("cheese", "gouda");81 private static final Secret registrationSecret = new Secret("caerphilly");82 private Distributor distributor;83 private Tracer tracer;84 private EventBus bus;85 private Wait<Object> wait;86 private URL externalUrl;87 private CombinedHandler handler;88 private Capabilities stereotype;89 @Before90 public void setUpDistributor() throws MalformedURLException {91 tracer = DefaultTestTracer.createTracer();92 bus = new GuavaEventBus();93 handler = new CombinedHandler();94 externalUrl = new URL("http://example.com");95 HttpClient.Factory clientFactory = new RoutableHttpClientFactory(96 externalUrl,97 handler,98 HttpClient.Factory.createDefault());99 LocalSessionMap sessions = new LocalSessionMap(tracer, bus);100 NewSessionQueue queue = new LocalNewSessionQueue(101 tracer,102 bus,103 new DefaultSlotMatcher(),104 Duration.ofSeconds(2),105 Duration.ofSeconds(2),106 registrationSecret);107 Distributor local = new LocalDistributor(108 tracer,109 bus,110 clientFactory,111 sessions,112 queue,113 new DefaultSlotSelector(),114 registrationSecret,115 Duration.ofMinutes(5),116 false);117 handler.addHandler(local);118 distributor = new RemoteDistributor(tracer, clientFactory, externalUrl, registrationSecret);119 stereotype = new ImmutableCapabilities("browserName", "gouda");120 wait = new FluentWait<>(121 new Object()).ignoring(Throwable.class).withTimeout(Duration.ofSeconds(2));122 }123 @Test124 public void shouldBeAbleToRegisterALocalNode() throws URISyntaxException {125 URI sessionUri = new URI("http://example:1234");126 Node node = LocalNode127 .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)128 .add(129 CAPS,130 new TestSessionFactory(131 (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))132 .build();133 handler.addHandler(node);134 distributor.add(node);135 wait.until(obj -> distributor.getStatus().hasCapacity());136 NodeStatus status = getOnlyElement(distributor.getStatus().getNodes());137 assertEquals(1, getStereotypes(status).get(CAPS).intValue());138 }139 @Test140 public void shouldBeAbleToRegisterACustomNode() throws URISyntaxException {141 URI sessionUri = new URI("http://example:1234");142 Node node = new CustomNode(143 bus,144 new NodeId(UUID.randomUUID()),145 externalUrl.toURI(),146 c -> new Session(147 new SessionId(UUID.randomUUID()), sessionUri, stereotype, c, Instant.now()));148 handler.addHandler(node);149 distributor.add(node);150 wait.until(obj -> distributor.getStatus().hasCapacity());151 NodeStatus status = getOnlyElement(distributor.getStatus().getNodes());152 assertEquals(1, getStereotypes(status).get(CAPS).intValue());153 }154 @Test155 public void shouldBeAbleToRegisterNodesByListeningForEvents() throws URISyntaxException {156 URI sessionUri = new URI("http://example:1234");157 Node node = LocalNode158 .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)159 .add(160 CAPS,161 new TestSessionFactory(162 (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))163 .build();164 handler.addHandler(node);165 bus.fire(new NodeStatusEvent(node.getStatus()));166 wait.until(obj -> distributor.getStatus().hasCapacity());167 NodeStatus status = getOnlyElement(distributor.getStatus().getNodes());168 assertEquals(1, getStereotypes(status).get(CAPS).intValue());169 }170 @Test171 public void shouldKeepOnlyOneNodeWhenTwoRegistrationsHaveTheSameUriByListeningForEvents()172 throws URISyntaxException {173 URI sessionUri = new URI("http://example:1234");174 Node firstNode = LocalNode175 .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)176 .add(177 CAPS,178 new TestSessionFactory(179 (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))180 .build();181 Node secondNode = LocalNode182 .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)183 .add(184 CAPS,185 new TestSessionFactory(186 (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))187 .build();188 handler.addHandler(firstNode);189 handler.addHandler(secondNode);190 bus.fire(new NodeStatusEvent(firstNode.getStatus()));191 bus.fire(new NodeStatusEvent(secondNode.getStatus()));192 wait.until(obj -> distributor.getStatus());193 Set<NodeStatus> nodes = distributor.getStatus().getNodes();194 assertEquals(1, nodes.size());195 }196 @Test197 public void distributorShouldUpdateStateOfExistingNodeWhenNodePublishesStateChange()198 throws URISyntaxException {199 URI sessionUri = new URI("http://example:1234");200 Node node = LocalNode201 .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)202 .add(203 CAPS,204 new TestSessionFactory(205 (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))206 .build();207 handler.addHandler(node);208 bus.fire(new NodeStatusEvent(node.getStatus()));209 // Start empty210 wait.until(obj -> distributor.getStatus().hasCapacity());211 NodeStatus nodeStatus = getOnlyElement(distributor.getStatus().getNodes());212 assertEquals(1, getStereotypes(nodeStatus).get(CAPS).intValue());213 // Craft a status that makes it look like the node is busy, and post it on the bus.214 NodeStatus status = node.getStatus();215 NodeStatus crafted = new NodeStatus(216 status.getId(),217 status.getUri(),218 status.getMaxSessionCount(),219 ImmutableSet.of(220 new Slot(221 new SlotId(status.getId(), UUID.randomUUID()),222 CAPS,223 Instant.now(),224 Optional.of(new Session(225 new SessionId(UUID.randomUUID()), sessionUri, CAPS, CAPS, Instant.now())))),226 UP,227 Duration.ofSeconds(10),228 status.getVersion(),229 status.getOsInfo());230 bus.fire(new NodeStatusEvent(crafted));231 // We claimed the only slot is filled. Life is good.232 wait.until(obj -> !distributor.getStatus().hasCapacity());233 }234 private Map<Capabilities, Integer> getStereotypes(NodeStatus status) {235 Map<Capabilities, Integer> stereotypes = new HashMap<>();236 for (Slot slot : status.getSlots()) {237 int count = stereotypes.getOrDefault(slot.getStereotype(), 0);238 count++;239 stereotypes.put(slot.getStereotype(), count);240 }241 return ImmutableMap.copyOf(stereotypes);242 }243 static class CustomNode extends Node {244 private final EventBus bus;245 private final Function<Capabilities, Session> factory;246 private Session running;247 protected CustomNode(248 EventBus bus,249 NodeId nodeId,250 URI uri,251 Function<Capabilities, Session> factory) {252 super(DefaultTestTracer.createTracer(), nodeId, uri, registrationSecret);253 this.bus = bus;254 this.factory = Objects.requireNonNull(factory);255 }256 @Override257 public boolean isReady() {258 return true;259 }260 @Override261 public Either<WebDriverException, CreateSessionResponse> newSession(CreateSessionRequest sessionRequest) {262 Objects.requireNonNull(sessionRequest);263 if (running != null) {264 return Either.left(new SessionNotCreatedException("Session already exists"));265 }266 Session session = factory.apply(sessionRequest.getDesiredCapabilities());267 running = session;268 return Either.right(269 new CreateSessionResponse(270 session,271 CapabilityResponseEncoder.getEncoder(W3C).apply(session)));272 }273 @Override274 public HttpResponse executeWebDriverCommand(HttpRequest req) {275 throw new UnsupportedOperationException("executeWebDriverCommand");276 }277 @Override278 public HttpResponse uploadFile(HttpRequest req, SessionId id) {279 throw new UnsupportedOperationException("uploadFile");280 }281 @Override282 public Session getSession(SessionId id) throws NoSuchSessionException {283 if (running == null || !running.getId().equals(id)) {284 throw new NoSuchSessionException();285 }286 return running;287 }288 @Override289 public void stop(SessionId id) throws NoSuchSessionException {290 getSession(id);291 running = null;292 bus.fire(new SessionClosedEvent(id));293 }294 @Override295 public boolean isSessionOwner(SessionId id) {296 return running != null && running.getId().equals(id);297 }298 @Override299 public boolean isSupporting(Capabilities capabilities) {300 return Objects.equals("cake", capabilities.getCapability("cheese"));301 }302 @Override303 public NodeStatus getStatus() {304 Session sess = null;305 if (running != null) {306 try {307 sess = new Session(308 running.getId(),309 new URI("http://localhost:14568"),310 CAPS,311 running.getCapabilities(),312 Instant.now());313 } catch (URISyntaxException e) {314 throw new RuntimeException(e);315 }316 }317 return new NodeStatus(318 getId(),319 getUri(),320 1,321 ImmutableSet.of(...

Full Screen

Full Screen

Source:OneShotNode.java Github

copy

Full Screen

...18import com.google.common.collect.ImmutableMap;19import com.google.common.collect.ImmutableSet;20import org.openqa.selenium.Capabilities;21import org.openqa.selenium.ImmutableCapabilities;22import org.openqa.selenium.NoSuchSessionException;23import org.openqa.selenium.PersistentCapabilities;24import org.openqa.selenium.WebDriver;25import org.openqa.selenium.WebDriverException;26import org.openqa.selenium.WebDriverInfo;27import org.openqa.selenium.events.EventBus;28import org.openqa.selenium.grid.config.Config;29import org.openqa.selenium.grid.config.ConfigException;30import org.openqa.selenium.grid.data.CreateSessionRequest;31import org.openqa.selenium.grid.data.CreateSessionResponse;32import org.openqa.selenium.grid.data.NodeDrainComplete;33import org.openqa.selenium.grid.data.NodeDrainStarted;34import org.openqa.selenium.grid.data.NodeId;35import org.openqa.selenium.grid.data.NodeStatus;36import org.openqa.selenium.grid.data.Session;37import org.openqa.selenium.grid.data.SessionClosedEvent;38import org.openqa.selenium.grid.data.Slot;39import org.openqa.selenium.grid.data.SlotId;40import org.openqa.selenium.grid.log.LoggingOptions;41import org.openqa.selenium.grid.node.HealthCheck;42import org.openqa.selenium.grid.node.Node;43import org.openqa.selenium.grid.node.config.NodeOptions;44import org.openqa.selenium.grid.security.Secret;45import org.openqa.selenium.grid.security.SecretOptions;46import org.openqa.selenium.grid.server.BaseServerOptions;47import org.openqa.selenium.grid.server.EventBusOptions;48import org.openqa.selenium.internal.Either;49import org.openqa.selenium.internal.Require;50import org.openqa.selenium.json.Json;51import org.openqa.selenium.remote.CommandExecutor;52import org.openqa.selenium.remote.RemoteWebDriver;53import org.openqa.selenium.remote.SessionId;54import org.openqa.selenium.remote.http.HttpClient;55import org.openqa.selenium.remote.http.HttpRequest;56import org.openqa.selenium.remote.http.HttpResponse;57import org.openqa.selenium.remote.tracing.Tracer;58import java.lang.reflect.Field;59import java.net.URI;60import java.net.URISyntaxException;61import java.time.Duration;62import java.time.Instant;63import java.util.Map;64import java.util.Optional;65import java.util.ServiceLoader;66import java.util.UUID;67import java.util.logging.Logger;68import java.util.stream.StreamSupport;69import static java.nio.charset.StandardCharsets.UTF_8;70import static org.openqa.selenium.grid.data.Availability.DRAINING;71import static org.openqa.selenium.grid.data.Availability.UP;72import static org.openqa.selenium.json.Json.MAP_TYPE;73import static org.openqa.selenium.remote.http.HttpMethod.DELETE;74/**75 * An implementation of {@link Node} that marks itself as draining immediately76 * after starting, and which then shuts down after usage. This will allow an77 * appropriately configured Kubernetes cluster to start a new node once the78 * session is finished.79 */80public class OneShotNode extends Node {81 private static final Logger LOG = Logger.getLogger(OneShotNode.class.getName());82 private static final Json JSON = new Json();83 private final EventBus events;84 private final WebDriverInfo driverInfo;85 private final Capabilities stereotype;86 private final Duration heartbeatPeriod;87 private final URI gridUri;88 private final UUID slotId = UUID.randomUUID();89 private RemoteWebDriver driver;90 private SessionId sessionId;91 private HttpClient client;92 private Capabilities capabilities;93 private Instant sessionStart = Instant.EPOCH;94 private OneShotNode(95 Tracer tracer,96 EventBus events,97 Secret registrationSecret,98 Duration heartbeatPeriod,99 NodeId id,100 URI uri,101 URI gridUri,102 Capabilities stereotype,103 WebDriverInfo driverInfo) {104 super(tracer, id, uri, registrationSecret);105 this.heartbeatPeriod = heartbeatPeriod;106 this.events = Require.nonNull("Event bus", events);107 this.gridUri = Require.nonNull("Public Grid URI", gridUri);108 this.stereotype = ImmutableCapabilities.copyOf(Require.nonNull("Stereotype", stereotype));109 this.driverInfo = Require.nonNull("Driver info", driverInfo);110 }111 public static Node create(Config config) {112 LoggingOptions loggingOptions = new LoggingOptions(config);113 EventBusOptions eventOptions = new EventBusOptions(config);114 BaseServerOptions serverOptions = new BaseServerOptions(config);115 SecretOptions secretOptions = new SecretOptions(config);116 NodeOptions nodeOptions = new NodeOptions(config);117 Map<String, Object> raw = new Json().toType(118 config.get("k8s", "stereotype")119 .orElseThrow(() -> new ConfigException("Unable to find node stereotype")),120 MAP_TYPE);121 Capabilities stereotype = new ImmutableCapabilities(raw);122 Optional<String> driverName = config.get("k8s", "driver_name").map(String::toLowerCase);123 // Find the webdriver info corresponding to the driver name124 WebDriverInfo driverInfo = StreamSupport.stream(ServiceLoader.load(WebDriverInfo.class).spliterator(), false)125 .filter(info -> info.isSupporting(stereotype))126 .filter(info -> driverName.map(name -> name.equals(info.getDisplayName().toLowerCase())).orElse(true))127 .findFirst()128 .orElseThrow(() -> new ConfigException(129 "Unable to find matching driver for %s and %s", stereotype, driverName.orElse("any driver")));130 LOG.info(String.format("Creating one-shot node for %s with stereotype %s", driverInfo, stereotype));131 LOG.info("Grid URI is: " + nodeOptions.getPublicGridUri());132 return new OneShotNode(133 loggingOptions.getTracer(),134 eventOptions.getEventBus(),135 secretOptions.getRegistrationSecret(),136 nodeOptions.getHeartbeatPeriod(),137 new NodeId(UUID.randomUUID()),138 serverOptions.getExternalUri(),139 nodeOptions.getPublicGridUri().orElseThrow(() -> new ConfigException("Unable to determine public grid address")),140 stereotype,141 driverInfo);142 }143 @Override144 public Either<WebDriverException, CreateSessionResponse> newSession(CreateSessionRequest sessionRequest) {145 if (driver != null) {146 throw new IllegalStateException("Only expected one session at a time");147 }148 Optional<WebDriver> driver = driverInfo.createDriver(sessionRequest.getDesiredCapabilities());149 if (!driver.isPresent()) {150 return Either.left(new WebDriverException("Unable to create a driver instance"));151 }152 if (!(driver.get() instanceof RemoteWebDriver)) {153 driver.get().quit();154 return Either.left(new WebDriverException("Driver is not a RemoteWebDriver instance"));155 }156 this.driver = (RemoteWebDriver) driver.get();157 this.sessionId = this.driver.getSessionId();158 this.client = extractHttpClient(this.driver);159 this.capabilities = rewriteCapabilities(this.driver);160 this.sessionStart = Instant.now();161 LOG.info("Encoded response: " + JSON.toJson(ImmutableMap.of(162 "value", ImmutableMap.of(163 "sessionId", sessionId,164 "capabilities", capabilities))));165 events.fire(new NodeDrainStarted(getId()));166 return Either.right(167 new CreateSessionResponse(168 getSession(sessionId),169 JSON.toJson(ImmutableMap.of(170 "value", ImmutableMap.of(171 "sessionId", sessionId,172 "capabilities", capabilities))).getBytes(UTF_8)));173 }174 private HttpClient extractHttpClient(RemoteWebDriver driver) {175 CommandExecutor executor = driver.getCommandExecutor();176 try {177 Field client = null;178 Class<?> current = executor.getClass();179 while (client == null && (current != null || Object.class.equals(current))) {180 client = findClientField(current);181 current = current.getSuperclass();182 }183 if (client == null) {184 throw new IllegalStateException("Unable to find client field in " + executor.getClass());185 }186 if (!HttpClient.class.isAssignableFrom(client.getType())) {187 throw new IllegalStateException("Client field is not assignable to http client");188 }189 client.setAccessible(true);190 return (HttpClient) client.get(executor);191 } catch (ReflectiveOperationException e) {192 throw new IllegalStateException(e);193 }194 }195 private Field findClientField(Class<?> clazz) {196 try {197 return clazz.getDeclaredField("client");198 } catch (NoSuchFieldException e) {199 return null;200 }201 }202 private Capabilities rewriteCapabilities(RemoteWebDriver driver) {203 // Rewrite the se:options if necessary to add cdp url204 if (driverInfo.isSupportingCdp()) {205 String cdpPath = String.format("/session/%s/se/cdp", driver.getSessionId());206 return new PersistentCapabilities(driver.getCapabilities()).setCapability("se:cdp", rewrite(cdpPath));207 }208 return ImmutableCapabilities.copyOf(driver.getCapabilities());209 }210 private URI rewrite(String path) {211 try {212 return new URI(213 gridUri.getScheme(),214 gridUri.getUserInfo(),215 gridUri.getHost(),216 gridUri.getPort(),217 path,218 null,219 null);220 } catch (URISyntaxException e) {221 throw new RuntimeException(e);222 }223 }224 @Override225 public HttpResponse executeWebDriverCommand(HttpRequest req) {226 LOG.info("Executing " + req);227 HttpResponse res = client.execute(req);228 if (DELETE.equals(req.getMethod()) && req.getUri().equals("/session/" + sessionId)) {229 // Ensure the response is sent before we viciously kill the node230 new Thread(231 () -> {232 try {233 Thread.sleep(500);234 } catch (InterruptedException e) {235 Thread.currentThread().interrupt();236 throw new RuntimeException(e);237 }238 LOG.info("Stopping session: " + sessionId);239 stop(sessionId);240 },241 "Node clean up: " + getId())242 .start();243 }244 return res;245 }246 @Override247 public Session getSession(SessionId id) throws NoSuchSessionException {248 if (!isSessionOwner(id)) {249 throw new NoSuchSessionException("Unable to find session with id: " + id);250 }251 return new Session(252 sessionId,253 getUri(),254 stereotype,255 capabilities,256 sessionStart);257 }258 @Override259 public HttpResponse uploadFile(HttpRequest req, SessionId id) {260 return null;261 }262 @Override263 public void stop(SessionId id) throws NoSuchSessionException {264 LOG.info("Stop has been called: " + id);265 Require.nonNull("Session ID", id);266 if (!isSessionOwner(id)) {267 throw new NoSuchSessionException("Unable to find session " + id);268 }269 LOG.info("Quitting session " + id);270 try {271 driver.quit();272 } catch (Exception e) {273 // It's possible that the driver has already quit.274 }275 events.fire(new SessionClosedEvent(id));276 LOG.info("Firing node drain complete message");277 events.fire(new NodeDrainComplete(getId()));278 }279 @Override280 public boolean isSessionOwner(SessionId id) {281 return driver != null && sessionId.equals(id);282 }283 @Override284 public boolean isSupporting(Capabilities capabilities) {285 return driverInfo.isSupporting(capabilities);286 }287 @Override288 public NodeStatus getStatus() {289 return new NodeStatus(290 getId(),291 getUri(),292 1,293 ImmutableSet.of(294 new Slot(295 new SlotId(getId(), slotId),296 stereotype,297 Instant.EPOCH,298 driver == null ?299 Optional.empty() :300 Optional.of(new Session(sessionId, getUri(), stereotype, capabilities, Instant.now())))),301 isDraining() ? DRAINING : UP,302 heartbeatPeriod,303 getNodeVersion(),304 getOsInfo());305 }306 @Override307 public void drain() {308 events.fire(new NodeDrainStarted(getId()));309 draining = true;310 }311 @Override312 public HealthCheck getHealthCheck() {313 return () -> new HealthCheck.Result(isDraining() ? DRAINING : UP, "Everything is fine");314 }...

Full Screen

Full Screen

Source:GridModel.java Github

copy

Full Screen

...23import org.openqa.selenium.grid.data.NodeId;24import org.openqa.selenium.grid.data.NodeRemovedEvent;25import org.openqa.selenium.grid.data.NodeStatus;26import org.openqa.selenium.grid.data.NodeStatusEvent;27import org.openqa.selenium.grid.data.Session;28import org.openqa.selenium.grid.data.SessionClosedEvent;29import org.openqa.selenium.grid.data.Slot;30import org.openqa.selenium.grid.data.SlotId;31import org.openqa.selenium.grid.security.Secret;32import org.openqa.selenium.internal.Require;33import org.openqa.selenium.remote.SessionId;34import java.time.Instant;35import java.util.HashSet;36import java.util.Iterator;37import java.util.Map;38import java.util.Optional;39import java.util.Set;40import java.util.concurrent.ConcurrentHashMap;41import java.util.concurrent.locks.Lock;42import java.util.concurrent.locks.ReadWriteLock;43import java.util.concurrent.locks.ReentrantReadWriteLock;44import java.util.logging.Logger;45import static org.openqa.selenium.grid.data.Availability.DOWN;46import static org.openqa.selenium.grid.data.Availability.DRAINING;47import static org.openqa.selenium.grid.data.Availability.UP;48public class GridModel {49 private static final Logger LOG = Logger.getLogger(GridModel.class.getName());50 private static final SessionId RESERVED = new SessionId("reserved");51 private final ReadWriteLock lock = new ReentrantReadWriteLock(/* fair */ true);52 private final Map<Availability, Set<NodeStatus>> nodes = new ConcurrentHashMap<>();53 private final EventBus events;54 public GridModel(EventBus events, Secret registrationSecret) {55 this.events = Require.nonNull("Event bus", events);56 Require.nonNull("Registration secret", registrationSecret);57 events.addListener(NodeDrainStarted.listener(nodeId -> setAvailability(nodeId, DRAINING)));58 events.addListener(NodeDrainComplete.listener(this::remove));59 events.addListener(NodeRemovedEvent.listener(this::remove));60 events.addListener(NodeStatusEvent.listener(status -> refresh(status)));61 events.addListener(SessionClosedEvent.listener(this::release));62 }63 public GridModel add(NodeStatus node) {64 Require.nonNull("Node", node);65 Lock writeLock = lock.writeLock();66 writeLock.lock();67 try {68 // If we've already added the node, remove it.69 for (Set<NodeStatus> nodes : nodes.values()) {70 Iterator<NodeStatus> iterator = nodes.iterator();71 while (iterator.hasNext()) {72 NodeStatus next = iterator.next();73 // If the ID is the same, we're re-adding a node. If the URI is the same a node probably restarted74 if (next.getId().equals(node.getId()) || next.getUri().equals(node.getUri())) {75 LOG.info(String.format("Re-adding node with id %s and URI %s.", node.getId(), node.getUri()));76 iterator.remove();77 }78 }79 }80 // Nodes are initially added in the "down" state until something changes their availability81 nodes(DOWN).add(node);82 } finally {83 writeLock.unlock();84 }85 return this;86 }87 public GridModel refresh(NodeStatus status) {88 Require.nonNull("Node status", status);89 Lock writeLock = lock.writeLock();90 writeLock.lock();91 try {92 AvailabilityAndNode availabilityAndNode = findNode(status.getId());93 if (availabilityAndNode == null) {94 return this;95 }96 // if the node was marked as "down", keep it down until a healthcheck passes:97 // just because the node can hit the event bus doesn't mean it's reachable98 if (DOWN.equals(availabilityAndNode.availability)) {99 nodes(DOWN).remove(availabilityAndNode.status);100 nodes(DOWN).add(status);101 return this;102 }103 // But do trust the node if it tells us it's draining104 nodes(availabilityAndNode.availability).remove(availabilityAndNode.status);105 nodes(status.getAvailability()).add(status);106 return this;107 } finally {108 writeLock.unlock();109 }110 }111 public GridModel remove(NodeId id) {112 Require.nonNull("Node ID", id);113 Lock writeLock = lock.writeLock();114 writeLock.lock();115 try {116 AvailabilityAndNode availabilityAndNode = findNode(id);117 if (availabilityAndNode == null) {118 return this;119 }120 nodes(availabilityAndNode.availability).remove(availabilityAndNode.status);121 return this;122 } finally {123 writeLock.unlock();124 }125 }126 public Availability setAvailability(NodeId id, Availability availability) {127 Require.nonNull("Node ID", id);128 Require.nonNull("Availability", availability);129 Lock writeLock = lock.writeLock();130 writeLock.lock();131 try {132 AvailabilityAndNode availabilityAndNode = findNode(id);133 if (availabilityAndNode == null) {134 return DOWN;135 }136 if (availability.equals(availabilityAndNode.availability)) {137 return availability;138 }139 nodes(availabilityAndNode.availability).remove(availabilityAndNode.status);140 nodes(availability).add(availabilityAndNode.status);141 LOG.info(String.format(142 "Switching node %s (uri: %s) from %s to %s",143 id,144 availabilityAndNode.status.getUri(),145 availabilityAndNode.availability,146 availability));147 return availabilityAndNode.availability;148 } finally {149 writeLock.unlock();150 }151 }152 public boolean reserve(SlotId slotId) {153 Lock writeLock = lock.writeLock();154 writeLock.lock();155 try {156 AvailabilityAndNode node = findNode(slotId.getOwningNodeId());157 if (node == null) {158 LOG.warning(String.format("Asked to reserve slot on node %s, but unable to find node", slotId.getOwningNodeId()));159 return false;160 }161 if (!UP.equals(node.availability)) {162 LOG.warning(String.format(163 "Asked to reserve a slot on node %s, but not is %s",164 slotId.getOwningNodeId(),165 node.availability));166 return false;167 }168 Optional<Slot> maybeSlot = node.status.getSlots().stream()169 .filter(slot -> slotId.equals(slot.getId()))170 .findFirst();171 if (!maybeSlot.isPresent()) {172 LOG.warning(String.format(173 "Asked to reserve slot on node %s, but no slot with id %s found",174 node.status.getId(),175 slotId));176 return false;177 }178 reserve(node.status, maybeSlot.get());179 return true;180 } finally {181 writeLock.unlock();182 }183 }184 public Set<NodeStatus> getSnapshot() {185 Lock readLock = this.lock.readLock();186 readLock.lock();187 try {188 ImmutableSet.Builder<NodeStatus> snapshot = ImmutableSet.builder();189 for (Map.Entry<Availability, Set<NodeStatus>> entry : nodes.entrySet()) {190 entry.getValue().stream()191 .map(status -> rewrite(status, entry.getKey()))192 .forEach(snapshot::add);193 }194 return snapshot.build();195 } finally {196 readLock.unlock();197 }198 }199 private Set<NodeStatus> nodes(Availability availability) {200 return nodes.computeIfAbsent(availability, ignored -> new HashSet<>());201 }202 private AvailabilityAndNode findNode(NodeId id) {203 for (Map.Entry<Availability, Set<NodeStatus>> entry : nodes.entrySet()) {204 for (NodeStatus nodeStatus : entry.getValue()) {205 if (id.equals(nodeStatus.getId())) {206 return new AvailabilityAndNode(entry.getKey(), nodeStatus);207 }208 }209 }210 return null;211 }212 private NodeStatus rewrite(NodeStatus status, Availability availability) {213 return new NodeStatus(214 status.getId(),215 status.getUri(),216 status.getMaxSessionCount(),217 status.getSlots(),218 availability);219 }220 private void release(SessionId id) {221 if (id == null) {222 return;223 }224 Lock writeLock = lock.writeLock();225 writeLock.lock();226 try {227 for (Map.Entry<Availability, Set<NodeStatus>> entry : nodes.entrySet()) {228 for (NodeStatus node : entry.getValue()) {229 for (Slot slot : node.getSlots()) {230 if (!slot.getSession().isPresent()) {231 continue;232 }233 if (id.equals(slot.getSession().get().getId())) {234 Slot released = new Slot(235 slot.getId(),236 slot.getStereotype(),237 slot.getLastStarted(),238 Optional.empty());239 amend(entry.getKey(), node, released);240 return;241 }242 }243 }244 }245 } finally {246 writeLock.unlock();247 }248 }249 private void reserve(NodeStatus status, Slot slot) {250 Instant now = Instant.now();251 Slot reserved = new Slot(252 slot.getId(),253 slot.getStereotype(),254 now,255 Optional.of(new Session(256 RESERVED,257 status.getUri(),258 slot.getStereotype(),259 slot.getStereotype(),260 now)));261 amend(UP, status, reserved);262 }263 public void setSession(SlotId slotId, Session session) {264 Require.nonNull("Slot ID", slotId);265 AvailabilityAndNode node = findNode(slotId.getOwningNodeId());266 if (node == null) {267 LOG.warning("Grid model and reality have diverged. Unable to find node " + slotId.getOwningNodeId());268 return;269 }270 Optional<Slot> maybeSlot = node.status.getSlots().stream()271 .filter(slot -> slotId.equals(slot.getId()))272 .findFirst();273 if (!maybeSlot.isPresent()) {274 LOG.warning("Grid model and reality have diverged. Unable to find slot " + slotId);275 return;276 }277 Slot slot = maybeSlot.get();278 Optional<Session> maybeSession = slot.getSession();279 if (!maybeSession.isPresent()) {280 LOG.warning("Grid model and reality have diverged. Slot is not reserved. " + slotId);281 return;282 }283 Session current = maybeSession.get();284 if (!RESERVED.equals(current.getId())) {285 LOG.warning("Gid model and reality have diverged. Slot has session and is not reserved. " + slotId);286 return;287 }288 Slot updated = new Slot(289 slot.getId(),290 slot.getStereotype(),291 session == null ? slot.getLastStarted() : session.getStartTime(),292 Optional.ofNullable(session));293 amend(node.availability, node.status, updated);294 }295 private void amend(Availability availability, NodeStatus status, Slot slot) {296 Set<Slot> newSlots = new HashSet<>(status.getSlots());297 newSlots.removeIf(s -> s.getId().equals(slot.getId()));298 newSlots.add(slot);299 nodes(availability).remove(status);300 nodes(availability).add(new NodeStatus(301 status.getId(),302 status.getUri(),303 status.getMaxSessionCount(),304 newSlots,305 status.getAvailability()));306 }307 private static class AvailabilityAndNode {308 public final Availability availability;309 public final NodeStatus status;310 public AvailabilityAndNode(Availability availability, NodeStatus status) {311 this.availability = availability;312 this.status = status;313 }314 }315}...

Full Screen

Full Screen

Source:LocalDistributor.java Github

copy

Full Screen

...18import com.google.common.collect.ImmutableSet;19import org.openqa.selenium.Beta;20import org.openqa.selenium.Capabilities;21import org.openqa.selenium.ImmutableCapabilities;22import org.openqa.selenium.SessionNotCreatedException;23import org.openqa.selenium.concurrent.Regularly;24import org.openqa.selenium.events.EventBus;25import org.openqa.selenium.grid.config.Config;26import org.openqa.selenium.grid.data.CreateSessionRequest;27import org.openqa.selenium.grid.data.CreateSessionResponse;28import org.openqa.selenium.grid.data.DistributorStatus;29import org.openqa.selenium.grid.data.NodeAddedEvent;30import org.openqa.selenium.grid.data.NodeDrainComplete;31import org.openqa.selenium.grid.data.NodeId;32import org.openqa.selenium.grid.data.NodeRemovedEvent;33import org.openqa.selenium.grid.data.NodeStatus;34import org.openqa.selenium.grid.data.NodeStatusEvent;35import org.openqa.selenium.grid.data.Slot;36import org.openqa.selenium.grid.data.SlotId;37import org.openqa.selenium.grid.distributor.Distributor;38import org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector;39import org.openqa.selenium.grid.log.LoggingOptions;40import org.openqa.selenium.grid.node.HealthCheck;41import org.openqa.selenium.grid.node.Node;42import org.openqa.selenium.grid.node.remote.RemoteNode;43import org.openqa.selenium.grid.security.Secret;44import org.openqa.selenium.grid.server.BaseServerOptions;45import org.openqa.selenium.grid.server.EventBusOptions;46import org.openqa.selenium.grid.server.NetworkOptions;47import org.openqa.selenium.grid.sessionmap.SessionMap;48import org.openqa.selenium.grid.sessionmap.config.SessionMapOptions;49import org.openqa.selenium.internal.Require;50import org.openqa.selenium.remote.http.HttpClient;51import org.openqa.selenium.remote.tracing.Tracer;52import org.openqa.selenium.status.HasReadyState;53import java.time.Duration;54import java.util.ArrayList;55import java.util.HashMap;56import java.util.List;57import java.util.Map;58import java.util.Optional;59import java.util.Set;60import java.util.concurrent.locks.Lock;61import java.util.concurrent.locks.ReadWriteLock;62import java.util.concurrent.locks.ReentrantReadWriteLock;63import java.util.function.Supplier;64import java.util.logging.Level;65import java.util.logging.Logger;66import static com.google.common.collect.ImmutableSet.toImmutableSet;67import static org.openqa.selenium.grid.data.Availability.DOWN;68import static org.openqa.selenium.grid.data.Availability.DRAINING;69public class LocalDistributor extends Distributor {70 private static final Logger LOG = Logger.getLogger(LocalDistributor.class.getName());71 private final Tracer tracer;72 private final EventBus bus;73 private final HttpClient.Factory clientFactory;74 private final SessionMap sessions;75 private final Secret registrationSecret;76 private final Regularly hostChecker = new Regularly("distributor host checker");77 private final Map<NodeId, Runnable> allChecks = new HashMap<>();78 private final ReadWriteLock lock = new ReentrantReadWriteLock(/* fair */ true);79 private final GridModel model;80 private final Map<NodeId, Node> nodes;81 public LocalDistributor(82 Tracer tracer,83 EventBus bus,84 HttpClient.Factory clientFactory,85 SessionMap sessions,86 Secret registrationSecret) {87 super(tracer, clientFactory, new DefaultSlotSelector(), sessions, registrationSecret);88 this.tracer = Require.nonNull("Tracer", tracer);89 this.bus = Require.nonNull("Event bus", bus);90 this.clientFactory = Require.nonNull("HTTP client factory", clientFactory);91 this.sessions = Require.nonNull("Session map", sessions);92 this.model = new GridModel(bus, registrationSecret);93 this.nodes = new HashMap<>();94 this.registrationSecret = Require.nonNull("Registration secret", registrationSecret);95 bus.addListener(NodeStatusEvent.listener(this::register));96 bus.addListener(NodeStatusEvent.listener(model::refresh));97 bus.addListener(NodeDrainComplete.listener(this::remove));98 }99 public static Distributor create(Config config) {100 Tracer tracer = new LoggingOptions(config).getTracer();101 EventBus bus = new EventBusOptions(config).getEventBus();102 HttpClient.Factory clientFactory = new NetworkOptions(config).getHttpClientFactory(tracer);103 SessionMap sessions = new SessionMapOptions(config).getSessionMap();104 BaseServerOptions serverOptions = new BaseServerOptions(config);105 return new LocalDistributor(tracer, bus, clientFactory, sessions, serverOptions.getRegistrationSecret());106 }107 @Override108 public boolean isReady() {109 try {110 return ImmutableSet.of(bus, sessions).parallelStream()111 .map(HasReadyState::isReady)112 .reduce(true, Boolean::logicalAnd);113 } catch (RuntimeException e) {114 return false;115 }116 }117 private void register(NodeStatus status) {118 Require.nonNull("Node", status);119 Lock writeLock = lock.writeLock();120 writeLock.lock();121 try {122 if (nodes.containsKey(status.getId())) {123 return;124 }125 Set<Capabilities> capabilities = status.getSlots().stream()126 .map(Slot::getStereotype)127 .map(ImmutableCapabilities::copyOf)128 .collect(toImmutableSet());129 // A new node! Add this as a remote node, since we've not called add130 RemoteNode remoteNode = new RemoteNode(131 tracer,132 clientFactory,133 status.getId(),134 status.getUri(),135 registrationSecret,136 capabilities);137 add(remoteNode);138 } finally {139 writeLock.unlock();140 }141 }142 @Override143 public LocalDistributor add(Node node) {144 Require.nonNull("Node", node);145 LOG.info(String.format("Added node %s at %s.", node.getId(), node.getUri()));146 nodes.put(node.getId(), node);147 model.add(node.getStatus());148 // Extract the health check149 Runnable runnableHealthCheck = asRunnableHealthCheck(node);150 allChecks.put(node.getId(), runnableHealthCheck);151 hostChecker.submit(runnableHealthCheck, Duration.ofMinutes(5), Duration.ofSeconds(30));152 bus.fire(new NodeAddedEvent(node.getId()));153 return this;154 }155 private Runnable asRunnableHealthCheck(Node node) {156 HealthCheck healthCheck = node.getHealthCheck();157 NodeId id = node.getId();158 return () -> {159 HealthCheck.Result result;160 try {161 result = healthCheck.check();162 } catch (Exception e) {163 LOG.log(Level.WARNING, "Unable to process node " + id, e);164 result = new HealthCheck.Result(DOWN, "Unable to run healthcheck. Assuming down");165 }166 Lock writeLock = lock.writeLock();167 writeLock.lock();168 try {169 model.setAvailability(id, result.getAvailability());170 } finally {171 writeLock.unlock();172 }173 };174 }175 @Override176 public boolean drain(NodeId nodeId) {177 Node node = nodes.get(nodeId);178 if (node == null) {179 LOG.info("Asked to drain unregistered node " + nodeId);180 return false;181 }182 Lock writeLock = lock.writeLock();183 writeLock.lock();184 try {185 node.drain();186 model.setAvailability(nodeId, DRAINING);187 } finally {188 writeLock.unlock();189 }190 return node.isDraining();191 }192 public void remove(NodeId nodeId) {193 Lock writeLock = lock.writeLock();194 writeLock.lock();195 try {196 model.remove(nodeId);197 Runnable runnable = allChecks.remove(nodeId);198 if (runnable != null) {199 hostChecker.remove(runnable);200 }201 } finally {202 writeLock.unlock();203 bus.fire(new NodeRemovedEvent(nodeId));204 }205 }206 @Override207 public DistributorStatus getStatus() {208 Lock readLock = this.lock.readLock();209 readLock.lock();210 try {211 return new DistributorStatus(model.getSnapshot());212 } finally {213 readLock.unlock();214 }215 }216 @Beta217 public void refresh() {218 List<Runnable> allHealthChecks = new ArrayList<>();219 Lock readLock = this.lock.readLock();220 readLock.lock();221 try {222 allHealthChecks.addAll(allChecks.values());223 } finally {224 readLock.unlock();225 }226 allHealthChecks.parallelStream().forEach(Runnable::run);227 }228 @Override229 protected Set<NodeStatus> getAvailableNodes() {230 Lock readLock = this.lock.readLock();231 readLock.lock();232 try {233 return model.getSnapshot().stream()234 .filter(node -> !DOWN.equals(node.getAvailability()))235 .collect(toImmutableSet());236 } finally {237 readLock.unlock();238 }239 }240 @Override241 protected Supplier<CreateSessionResponse> reserve(SlotId slotId, CreateSessionRequest request) {242 Require.nonNull("Slot ID", slotId);243 Require.nonNull("New Session request", request);244 Lock writeLock = this.lock.writeLock();245 writeLock.lock();246 try {247 Node node = nodes.get(slotId.getOwningNodeId());248 if (node == null) {249 return () -> {250 throw new SessionNotCreatedException("Unable to find node");251 };252 }253 model.reserve(slotId);254 return () -> {255 Optional<CreateSessionResponse> response = node.newSession(request);256 if (!response.isPresent()) {257 model.setSession(slotId, null);258 throw new SessionNotCreatedException("Unable to create session for " + request);259 }260 model.setSession(slotId, response.get().getSession());261 return response.get();262 };263 } finally {264 writeLock.unlock();265 }266 }267}...

Full Screen

Full Screen

Source:RemoteNode.java Github

copy

Full Screen

...17package org.openqa.selenium.grid.node.remote;18import com.google.common.collect.ImmutableMap;19import com.google.common.collect.ImmutableSet;20import org.openqa.selenium.Capabilities;21import org.openqa.selenium.NoSuchSessionException;22import org.openqa.selenium.grid.data.CreateSessionRequest;23import org.openqa.selenium.grid.data.CreateSessionResponse;24import org.openqa.selenium.grid.data.NodeId;25import org.openqa.selenium.grid.data.NodeStatus;26import org.openqa.selenium.grid.data.Session;27import org.openqa.selenium.grid.node.HealthCheck;28import org.openqa.selenium.grid.node.Node;29import org.openqa.selenium.grid.security.AddSecretFilter;30import org.openqa.selenium.grid.security.Secret;31import org.openqa.selenium.grid.web.Values;32import org.openqa.selenium.internal.Require;33import org.openqa.selenium.json.Json;34import org.openqa.selenium.json.JsonInput;35import org.openqa.selenium.remote.SessionId;36import org.openqa.selenium.remote.http.Filter;37import org.openqa.selenium.remote.http.HttpClient;38import org.openqa.selenium.remote.http.HttpHandler;39import org.openqa.selenium.remote.http.HttpRequest;40import org.openqa.selenium.remote.http.HttpResponse;41import org.openqa.selenium.remote.tracing.HttpTracing;42import org.openqa.selenium.remote.tracing.Tracer;43import java.io.IOException;44import java.io.Reader;45import java.io.UncheckedIOException;46import java.net.URI;47import java.util.Collection;48import java.util.Map;49import java.util.Objects;50import java.util.Optional;51import java.util.Set;52import static java.net.HttpURLConnection.HTTP_OK;53import static org.openqa.selenium.grid.data.Availability.DOWN;54import static org.openqa.selenium.grid.data.Availability.DRAINING;55import static org.openqa.selenium.grid.data.Availability.UP;56import static org.openqa.selenium.net.Urls.fromUri;57import static org.openqa.selenium.remote.http.Contents.asJson;58import static org.openqa.selenium.remote.http.Contents.reader;59import static org.openqa.selenium.remote.http.HttpMethod.DELETE;60import static org.openqa.selenium.remote.http.HttpMethod.GET;61import static org.openqa.selenium.remote.http.HttpMethod.POST;62public class RemoteNode extends Node {63 public static final Json JSON = new Json();64 private final HttpHandler client;65 private final URI externalUri;66 private final Set<Capabilities> capabilities;67 private final HealthCheck healthCheck;68 private final Filter addSecret;69 public RemoteNode(70 Tracer tracer,71 HttpClient.Factory clientFactory,72 NodeId id,73 URI externalUri,74 Secret registrationSecret,75 Collection<Capabilities> capabilities) {76 super(tracer, id, externalUri, registrationSecret);77 this.externalUri = Require.nonNull("External URI", externalUri);78 this.capabilities = ImmutableSet.copyOf(capabilities);79 this.client = Require.nonNull("HTTP client factory", clientFactory).createClient(fromUri(externalUri));80 this.healthCheck = new RemoteCheck();81 Require.nonNull("Registration secret", registrationSecret);82 this.addSecret = new AddSecretFilter(registrationSecret);83 }84 @Override85 public boolean isReady() {86 try {87 return client.execute(new HttpRequest(GET, "/readyz")).isSuccessful();88 } catch (Exception e) {89 return false;90 }91 }92 @Override93 public boolean isSupporting(Capabilities capabilities) {94 return this.capabilities.stream()95 .anyMatch(caps -> caps.getCapabilityNames().stream()96 .allMatch(name -> Objects.equals(97 caps.getCapability(name),98 capabilities.getCapability(name))));99 }100 @Override101 public Optional<CreateSessionResponse> newSession(CreateSessionRequest sessionRequest) {102 Require.nonNull("Capabilities for session", sessionRequest);103 HttpRequest req = new HttpRequest(POST, "/se/grid/node/session");104 HttpTracing.inject(tracer, tracer.getCurrentContext(), req);105 req.setContent(asJson(sessionRequest));106 HttpResponse res = client.with(addSecret).execute(req);107 return Optional.ofNullable(Values.get(res, CreateSessionResponse.class));108 }109 @Override110 public boolean isSessionOwner(SessionId id) {111 Require.nonNull("Session ID", id);112 HttpRequest req = new HttpRequest(GET, "/se/grid/node/owner/" + id);113 HttpTracing.inject(tracer, tracer.getCurrentContext(), req);114 HttpResponse res = client.with(addSecret).execute(req);115 return Boolean.TRUE.equals(Values.get(res, Boolean.class));116 }117 @Override118 public Session getSession(SessionId id) throws NoSuchSessionException {119 Require.nonNull("Session ID", id);120 HttpRequest req = new HttpRequest(GET, "/se/grid/node/session/" + id);121 HttpTracing.inject(tracer, tracer.getCurrentContext(), req);122 HttpResponse res = client.with(addSecret).execute(req);123 return Values.get(res, Session.class);124 }125 @Override126 public HttpResponse executeWebDriverCommand(HttpRequest req) {127 return client.execute(req);128 }129 @Override130 public HttpResponse uploadFile(HttpRequest req, SessionId id) {131 return client.execute(req);132 }133 @Override134 public void stop(SessionId id) throws NoSuchSessionException {135 Require.nonNull("Session ID", id);136 HttpRequest req = new HttpRequest(DELETE, "/se/grid/node/session/" + id);137 HttpTracing.inject(tracer, tracer.getCurrentContext(), req);138 HttpResponse res = client.with(addSecret).execute(req);139 Values.get(res, Void.class);140 }141 @Override142 public NodeStatus getStatus() {143 HttpRequest req = new HttpRequest(GET, "/status");144 HttpTracing.inject(tracer, tracer.getCurrentContext(), req);145 HttpResponse res = client.execute(req);146 try (Reader reader = reader(res);147 JsonInput in = JSON.newInput(reader)) {148 in.beginObject();149 // Skip everything until we find "value"...

Full Screen

Full Screen

Source:Grid.java Github

copy

Full Screen

...20import org.openqa.selenium.Capabilities;21import org.openqa.selenium.ImmutableCapabilities;22import org.openqa.selenium.grid.data.DistributorStatus;23import org.openqa.selenium.grid.data.NodeStatus;24import org.openqa.selenium.grid.data.SessionRequestCapability;25import org.openqa.selenium.grid.data.Slot;26import org.openqa.selenium.grid.distributor.Distributor;27import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;28import org.openqa.selenium.internal.Require;29import org.openqa.selenium.json.Json;30import java.net.URI;31import java.util.ArrayList;32import java.util.Collection;33import java.util.HashMap;34import java.util.List;35import java.util.Map;36import java.util.Set;37import java.util.function.Supplier;38import java.util.stream.Collectors;39public class Grid {40 private static final Json JSON = new Json();41 private final URI uri;42 private final Supplier<DistributorStatus> distributorStatus;43 private final List<Set<Capabilities>> queueInfoList;44 private final String version;45 public Grid(46 Distributor distributor,47 NewSessionQueue newSessionQueue,48 URI uri,49 String version) {50 Require.nonNull("Distributor", distributor);51 this.uri = Require.nonNull("Grid's public URI", uri);52 NewSessionQueue sessionQueue = Require.nonNull("New session queue", newSessionQueue);53 this.queueInfoList = sessionQueue54 .getQueueContents()55 .stream()56 .map(SessionRequestCapability::getDesiredCapabilities)57 .collect(Collectors.toList());58 this.distributorStatus = Suppliers.memoize(distributor::getStatus);59 this.version = Require.nonNull("Grid's version", version);60 }61 public URI getUri() {62 return uri;63 }64 public String getVersion() {65 return version;66 }67 public List<Node> getNodes() {68 ImmutableList.Builder<Node> toReturn = ImmutableList.builder();69 for (NodeStatus status : distributorStatus.get().getNodes()) {70 Map<Capabilities, Integer> stereotypes = new HashMap<>();71 Map<org.openqa.selenium.grid.data.Session, Slot> sessions = new HashMap<>();72 for (Slot slot : status.getSlots()) {73 slot.getSession().ifPresent(session -> sessions.put(session, slot));74 int count = stereotypes.getOrDefault(slot.getStereotype(), 0);75 count++;76 stereotypes.put(slot.getStereotype(), count);77 }78 OsInfo osInfo = new OsInfo(79 status.getOsInfo().get("arch"),80 status.getOsInfo().get("name"),81 status.getOsInfo().get("version"));82 toReturn.add(new Node(83 status.getId(),84 status.getUri(),85 status.getAvailability(),86 status.getMaxSessionCount(),87 status.getSlots().size(),88 stereotypes,89 sessions,90 status.getVersion(),91 osInfo));92 }93 return toReturn.build();94 }95 public int getNodeCount() {96 return distributorStatus.get().getNodes().size();97 }98 public int getSessionCount() {99 return distributorStatus.get().getNodes().stream()100 .map(NodeStatus::getSlots)101 .flatMap(Collection::stream)102 .filter(slot -> slot.getSession().isPresent())103 .mapToInt(slot -> 1)104 .sum();105 }106 public int getTotalSlots() {107 return distributorStatus.get().getNodes().stream()108 .mapToInt(status -> status.getSlots().size())109 .sum();110 }111 public int getMaxSession() {112 return distributorStatus.get().getNodes().stream()113 .mapToInt(NodeStatus::getMaxSessionCount)114 .sum();115 }116 public int getSessionQueueSize() {117 return queueInfoList.size();118 }119 public List<String> getSessionQueueRequests() {120 // TODO: The Grid UI expects there to be a single capability per new session request, which is not correct121 return queueInfoList.stream()122 .map(set -> set.isEmpty() ? new ImmutableCapabilities() : set.iterator().next())123 .map(JSON::toJson)124 .collect(Collectors.toList());125 }126 public List<Session> getSessions() {127 List<Session> sessions = new ArrayList<>();128 for (NodeStatus status : distributorStatus.get().getNodes()) {129 for (Slot slot : status.getSlots()) {130 if (slot.getSession().isPresent()) {131 org.openqa.selenium.grid.data.Session session = slot.getSession().get();132 sessions.add(133 new org.openqa.selenium.grid.graphql.Session(134 session.getId().toString(),135 session.getCapabilities(),136 session.getStartTime(),137 session.getUri(),138 status.getId().toString(),139 status.getUri(),140 slot)141 );142 }143 }144 }145 return sessions;146 }147}...

Full Screen

Full Screen

Source:SessionData.java Github

copy

Full Screen

...25import org.openqa.selenium.internal.Require;26import java.util.Optional;27import java.util.Set;28import java.util.function.Supplier;29public class SessionData implements DataFetcher {30 private final Supplier<DistributorStatus> distributorStatus;31 public SessionData(Distributor distributor) {32 distributorStatus = Suppliers.memoize(Require.nonNull("Distributor", distributor)::getStatus);33 }34 @Override35 public Object get(DataFetchingEnvironment environment) {36 String sessionId = environment.getArgument("id");37 if (sessionId.isEmpty()) {38 throw new SessionNotFoundException("Session id is empty. A valid session id is required.");39 }40 Set<NodeStatus> nodeStatuses = distributorStatus.get().getNodes();41 SessionInSlot currentSession = findSession(sessionId, nodeStatuses);42 if (currentSession != null) {43 org.openqa.selenium.grid.data.Session session = currentSession.session;44 return new org.openqa.selenium.grid.graphql.Session(45 session.getId().toString(),46 session.getCapabilities(),47 session.getStartTime(),48 session.getUri(),49 currentSession.node.getId().toString(),50 currentSession.node.getUri(),51 currentSession.slot);52 } else {53 throw new SessionNotFoundException("No ongoing session found with the requested session id.",54 sessionId);55 }56 }57 private SessionInSlot findSession(String sessionId, Set<NodeStatus> nodeStatuses) {58 for (NodeStatus status : nodeStatuses) {59 for (Slot slot : status.getSlots()) {60 Optional<org.openqa.selenium.grid.data.Session> session = slot.getSession();61 if (session.isPresent() && sessionId.equals(session.get().getId().toString())) {62 return new SessionInSlot(session.get(), status, slot);63 }64 }65 }66 return null;67 }68 private static class SessionInSlot {69 private final org.openqa.selenium.grid.data.Session session;70 private final NodeStatus node;71 private final Slot slot;72 SessionInSlot(org.openqa.selenium.grid.data.Session session, NodeStatus node, Slot slot) {73 this.session = session;74 this.node = node;75 this.slot = slot;76 }77 }78}...

Full Screen

Full Screen

Session

Using AI Code Generation

copy

Full Screen

1import org.openqa.selenium.grid.data.Session;2import org.openqa.selenium.grid.data.SessionId;3SessionId sessionId = new SessionId("sessionId");4Session session = new Session(sessionId, null, null, null, null, null, null, null, null);5session.getId();6session.getUri();7session.getCapabilities();8session.getStatus();9session.getStartTime();10session.getEndTime();11session.getSlot();12import org.openqa.selenium.grid.data.SessionId;13SessionId sessionId = new SessionId("sessionId");14sessionId.toString();15sessionId.getUuid();16import org.openqa.selenium.grid.data.SessionRequest;17SessionRequest sessionRequest = new SessionRequest(null, null);18sessionRequest.getCapabilities();19sessionRequest.getSlotMatch();20import org.openqa.selenium.grid.data.SessionResponse;21SessionResponse sessionResponse = new SessionResponse(null, null, null);22sessionResponse.getSession();23sessionResponse.getDownstreamDialects();24sessionResponse.getUpstreamDialects();25import org.openqa.selenium.grid.data.Slot;26Slot slot = new Slot(null, null);27slot.getId();28slot.getUri();29slot.getCapabilities();30import org.openqa.selenium.grid.data.SlotId;31SlotId slotId = new SlotId("slotId");32slotId.toString();33slotId.getUuid();34import org.openqa.selenium.grid.data.SlotMatch;35SlotMatch slotMatch = new SlotMatch(null, null);36slotMatch.getSlot();37slotMatch.getScore();38import org.openqa.selenium.grid

Full Screen

Full Screen

Session

Using AI Code Generation

copy

Full Screen

1import org.openqa.selenium.grid.data.Session;2package com.selenium.grid;3import org.openqa.selenium.grid.data.Session;4public class Test {5public static void main(String[] args) {6Session session = new Session();7}8}

Full Screen

Full Screen
copy
1System.setProperty("webdriver.gecko.driver", "D:/geckodriver-v0.16.1-win64/geckodriver.exe");2WebDriver driver = new FirefoxDriver();3driver.get("https://www.lynda.com/Selenium-tutorials/Mastering-Selenium-Testing-Tools/521207-2.html");4
Full Screen
copy
1 @Override2 protected File findDefaultExecutable() {3 return findExecutable(4 "geckodriver", GECKO_DRIVER_EXE_PROPERTY,5 "https://github.com/mozilla/geckodriver",6 "https://github.com/mozilla/geckodriver/releases");7 }8
Full Screen
copy
1webdriver.gecko.driver="/lib/geckodriver-v0.26.0-win64/geckodriver.exe"2
Full Screen

Selenium 4 Tutorial:

LambdaTest’s Selenium 4 tutorial is covering every aspects of Selenium 4 testing with examples and best practices. Here you will learn basics, such as how to upgrade from Selenium 3 to Selenium 4, to some advanced concepts, such as Relative locators and Selenium Grid 4 for Distributed testing. Also will learn new features of Selenium 4, such as capturing screenshots of specific elements, opening a new tab or window on the browser, and new protocol adoptions.

Chapters:

  1. Upgrading From Selenium 3 To Selenium 4?: In this chapter, learn in detail how to update Selenium 3 to Selenium 4 for Java binding. Also, learn how to upgrade while using different build tools such as Maven or Gradle and get comprehensive guidance for upgrading Selenium.

  2. What’s New In Selenium 4 & What’s Being Deprecated? : Get all information about new implementations in Selenium 4, such as W3S protocol adaption, Optimized Selenium Grid, and Enhanced Selenium IDE. Also, learn what is deprecated for Selenium 4, such as DesiredCapabilites and FindsBy methods, etc.

  3. Selenium 4 With Python: Selenium supports all major languages, such as Python, C#, Ruby, and JavaScript. In this chapter, learn how to install Selenium 4 for Python and the features of Python in Selenium 4, such as Relative locators, Browser manipulation, and Chrom DevTool protocol.

  4. Selenium 4 Is Now W3C Compliant: JSON Wireframe protocol is retiring from Selenium 4, and they are adopting W3C protocol to learn in detail about the advantages and impact of these changes.

  5. How To Use Selenium 4 Relative Locator? : Selenium 4 came with new features such as Relative Locators that allow constructing locators with reference and easily located constructors nearby. Get to know its different use cases with examples.

  6. Selenium Grid 4 Tutorial For Distributed Testing: Selenium Grid 4 allows you to perform tests over different browsers, OS, and device combinations. It also enables parallel execution browser testing, reads up on various features of Selenium Grid 4 and how to download it, and runs a test on Selenium Grid 4 with best practices.

  7. Selenium Video Tutorials: Binge on video tutorials on Selenium by industry experts to get step-by-step direction from automating basic to complex test scenarios with Selenium.

Selenium 101 certifications:

LambdaTest also provides certification for Selenium testing to accelerate your career in Selenium automation testing.

Run Selenium automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Test Your Web Or Mobile Apps On 3000+ Browsers

Signup for free

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful