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

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

Run Selenium automation tests on LambdaTest cloud grid

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

copy
1// Licensed to the Software Freedom Conservancy (SFC) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The SFC licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18package org.openqa.selenium.grid.distributor;
19
20import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.ImmutableSet;
22import org.junit.Before;
23import org.junit.Test;
24import org.openqa.selenium.Capabilities;
25import org.openqa.selenium.ImmutableCapabilities;
26import org.openqa.selenium.NoSuchSessionException;
27import org.openqa.selenium.SessionNotCreatedException;
28import org.openqa.selenium.WebDriverException;
29import org.openqa.selenium.events.EventBus;
30import org.openqa.selenium.events.local.GuavaEventBus;
31import org.openqa.selenium.grid.data.CreateSessionRequest;
32import org.openqa.selenium.grid.data.CreateSessionResponse;
33import org.openqa.selenium.grid.data.DefaultSlotMatcher;
34import org.openqa.selenium.grid.data.NodeId;
35import org.openqa.selenium.grid.data.NodeStatus;
36import org.openqa.selenium.grid.data.NodeStatusEvent;
37import org.openqa.selenium.grid.data.Session;
38import org.openqa.selenium.grid.data.SessionClosedEvent;
39import org.openqa.selenium.grid.data.Slot;
40import org.openqa.selenium.grid.data.SlotId;
41import org.openqa.selenium.grid.distributor.local.LocalDistributor;
42import org.openqa.selenium.grid.distributor.remote.RemoteDistributor;
43import org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector;
44import org.openqa.selenium.grid.node.CapabilityResponseEncoder;
45import org.openqa.selenium.grid.node.HealthCheck;
46import org.openqa.selenium.grid.node.Node;
47import org.openqa.selenium.grid.node.local.LocalNode;
48import org.openqa.selenium.grid.security.Secret;
49import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;
50import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;
51import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;
52import org.openqa.selenium.grid.testing.TestSessionFactory;
53import org.openqa.selenium.grid.web.CombinedHandler;
54import org.openqa.selenium.grid.web.RoutableHttpClientFactory;
55import org.openqa.selenium.internal.Either;
56import org.openqa.selenium.remote.SessionId;
57import org.openqa.selenium.remote.http.HttpClient;
58import org.openqa.selenium.remote.http.HttpRequest;
59import org.openqa.selenium.remote.http.HttpResponse;
60import org.openqa.selenium.remote.tracing.DefaultTestTracer;
61import org.openqa.selenium.remote.tracing.Tracer;
62import org.openqa.selenium.support.ui.FluentWait;
63import org.openqa.selenium.support.ui.Wait;
64
65import java.net.MalformedURLException;
66import java.net.URI;
67import java.net.URISyntaxException;
68import java.net.URL;
69import java.time.Duration;
70import java.time.Instant;
71import java.util.HashMap;
72import java.util.Map;
73import java.util.Objects;
74import java.util.Optional;
75import java.util.Set;
76import java.util.UUID;
77import java.util.function.Function;
78
79import static com.google.common.collect.Iterables.getOnlyElement;
80import static org.junit.Assert.assertEquals;
81import static org.openqa.selenium.grid.data.Availability.UP;
82import static org.openqa.selenium.remote.Dialect.W3C;
83
84public class AddingNodesTest {
85
86  private static final Capabilities CAPS = new ImmutableCapabilities("cheese", "gouda");
87  private static final Secret registrationSecret = new Secret("caerphilly");
88
89  private Distributor distributor;
90  private Tracer tracer;
91  private EventBus bus;
92  private Wait<Object> wait;
93  private URL externalUrl;
94  private CombinedHandler handler;
95  private Capabilities stereotype;
96
97  @Before
98  public void setUpDistributor() throws MalformedURLException {
99    tracer = DefaultTestTracer.createTracer();
100    bus = new GuavaEventBus();
101
102    handler = new CombinedHandler();
103    externalUrl = new URL("http://example.com");
104    HttpClient.Factory clientFactory = new RoutableHttpClientFactory(
105      externalUrl,
106      handler,
107      HttpClient.Factory.createDefault());
108
109    LocalSessionMap sessions = new LocalSessionMap(tracer, bus);
110    NewSessionQueue queue = new LocalNewSessionQueue(
111      tracer,
112      bus,
113      new DefaultSlotMatcher(),
114      Duration.ofSeconds(2),
115      Duration.ofSeconds(2),
116      registrationSecret);
117    Distributor local = new LocalDistributor(
118      tracer,
119      bus,
120      clientFactory,
121      sessions,
122      queue,
123      new DefaultSlotSelector(),
124      registrationSecret,
125      Duration.ofMinutes(5),
126      false);
127
128    handler.addHandler(local);
129    distributor = new RemoteDistributor(tracer, clientFactory, externalUrl, registrationSecret);
130
131    stereotype = new ImmutableCapabilities("browserName", "gouda");
132
133    wait = new FluentWait<>(
134      new Object()).ignoring(Throwable.class).withTimeout(Duration.ofSeconds(2));
135  }
136
137  @Test
138  public void shouldBeAbleToRegisterALocalNode() throws URISyntaxException {
139    URI sessionUri = new URI("http://example:1234");
140    Node node = LocalNode
141      .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)
142        .add(
143          CAPS,
144          new TestSessionFactory(
145            (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))
146        .build();
147    handler.addHandler(node);
148
149    distributor.add(node);
150
151    wait.until(obj -> distributor.getStatus().hasCapacity());
152
153    NodeStatus status = getOnlyElement(distributor.getStatus().getNodes());
154    assertEquals(1, getStereotypes(status).get(CAPS).intValue());
155  }
156
157  @Test
158  public void shouldBeAbleToRegisterACustomNode() throws URISyntaxException {
159    URI sessionUri = new URI("http://example:1234");
160    Node node = new CustomNode(
161        bus,
162        new NodeId(UUID.randomUUID()),
163        externalUrl.toURI(),
164        c -> new Session(
165          new SessionId(UUID.randomUUID()), sessionUri, stereotype, c, Instant.now()));
166    handler.addHandler(node);
167
168    distributor.add(node);
169
170    wait.until(obj -> distributor.getStatus().hasCapacity());
171
172    NodeStatus status = getOnlyElement(distributor.getStatus().getNodes());
173    assertEquals(1, getStereotypes(status).get(CAPS).intValue());
174  }
175
176  @Test
177  public void shouldBeAbleToRegisterNodesByListeningForEvents() throws URISyntaxException {
178    URI sessionUri = new URI("http://example:1234");
179    Node node = LocalNode
180      .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)
181        .add(
182          CAPS,
183          new TestSessionFactory(
184            (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))
185        .build();
186    handler.addHandler(node);
187
188    bus.fire(new NodeStatusEvent(node.getStatus()));
189
190    wait.until(obj -> distributor.getStatus().hasCapacity());
191
192    NodeStatus status = getOnlyElement(distributor.getStatus().getNodes());
193    assertEquals(1, getStereotypes(status).get(CAPS).intValue());
194  }
195
196  @Test
197  public void shouldKeepOnlyOneNodeWhenTwoRegistrationsHaveTheSameUriByListeningForEvents()
198    throws URISyntaxException {
199    URI sessionUri = new URI("http://example:1234");
200    Node firstNode = LocalNode
201      .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    Node secondNode = LocalNode
208      .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)
209      .add(
210        CAPS,
211        new TestSessionFactory(
212          (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))
213      .build();
214    handler.addHandler(firstNode);
215    handler.addHandler(secondNode);
216
217    bus.fire(new NodeStatusEvent(firstNode.getStatus()));
218    bus.fire(new NodeStatusEvent(secondNode.getStatus()));
219
220    wait.until(obj -> distributor.getStatus());
221
222    Set<NodeStatus> nodes = distributor.getStatus().getNodes();
223
224    assertEquals(1, nodes.size());
225  }
226
227  @Test
228  public void distributorShouldUpdateStateOfExistingNodeWhenNodePublishesStateChange()
229      throws URISyntaxException {
230    URI sessionUri = new URI("http://example:1234");
231    Node node = LocalNode
232      .builder(tracer, bus, externalUrl.toURI(), externalUrl.toURI(), registrationSecret)
233        .add(
234          CAPS,
235          new TestSessionFactory(
236            (id, caps) -> new Session(id, sessionUri, stereotype, caps, Instant.now())))
237        .build();
238    handler.addHandler(node);
239
240    bus.fire(new NodeStatusEvent(node.getStatus()));
241
242    // Start empty
243    wait.until(obj -> distributor.getStatus().hasCapacity());
244
245    NodeStatus nodeStatus = getOnlyElement(distributor.getStatus().getNodes());
246    assertEquals(1, getStereotypes(nodeStatus).get(CAPS).intValue());
247
248    // Craft a status that makes it look like the node is busy, and post it on the bus.
249    NodeStatus status = node.getStatus();
250    NodeStatus crafted = new NodeStatus(
251      status.getId(),
252      status.getUri(),
253      status.getMaxSessionCount(),
254      ImmutableSet.of(
255        new Slot(
256          new SlotId(status.getId(), UUID.randomUUID()),
257          CAPS,
258          Instant.now(),
259          Optional.of(new Session(
260            new SessionId(UUID.randomUUID()), sessionUri, CAPS, CAPS, Instant.now())))),
261      UP,
262      Duration.ofSeconds(10),
263      status.getVersion(),
264      status.getOsInfo());
265
266    bus.fire(new NodeStatusEvent(crafted));
267
268    // We claimed the only slot is filled. Life is good.
269    wait.until(obj -> !distributor.getStatus().hasCapacity());
270  }
271
272  private Map<Capabilities, Integer> getStereotypes(NodeStatus status) {
273    Map<Capabilities, Integer> stereotypes = new HashMap<>();
274
275    for (Slot slot : status.getSlots()) {
276      int count = stereotypes.getOrDefault(slot.getStereotype(), 0);
277      count++;
278      stereotypes.put(slot.getStereotype(), count);
279    }
280
281    return ImmutableMap.copyOf(stereotypes);
282  }
283
284  static class CustomNode extends Node {
285
286    private final EventBus bus;
287    private final Function<Capabilities, Session> factory;
288    private Session running;
289
290    protected CustomNode(
291        EventBus bus,
292        NodeId nodeId,
293        URI uri,
294        Function<Capabilities, Session> factory) {
295      super(DefaultTestTracer.createTracer(), nodeId, uri, registrationSecret);
296
297      this.bus = bus;
298      this.factory = Objects.requireNonNull(factory);
299    }
300
301    @Override
302    public boolean isReady() {
303      return true;
304    }
305
306    @Override
307    public Either<WebDriverException, CreateSessionResponse> newSession(CreateSessionRequest sessionRequest) {
308      Objects.requireNonNull(sessionRequest);
309
310      if (running != null) {
311        return Either.left(new SessionNotCreatedException("Session already exists"));
312      }
313      Session session = factory.apply(sessionRequest.getDesiredCapabilities());
314      running = session;
315      return Either.right(
316        new CreateSessionResponse(
317          session,
318          CapabilityResponseEncoder.getEncoder(W3C).apply(session)));
319    }
320
321    @Override
322    public HttpResponse executeWebDriverCommand(HttpRequest req) {
323      throw new UnsupportedOperationException("executeWebDriverCommand");
324    }
325
326    @Override
327    public HttpResponse uploadFile(HttpRequest req, SessionId id) {
328      throw new UnsupportedOperationException("uploadFile");
329    }
330
331    @Override
332    public Session getSession(SessionId id) throws NoSuchSessionException {
333      if (running == null || !running.getId().equals(id)) {
334        throw new NoSuchSessionException();
335      }
336
337      return running;
338    }
339
340    @Override
341    public void stop(SessionId id) throws NoSuchSessionException {
342      getSession(id);
343      running = null;
344
345      bus.fire(new SessionClosedEvent(id));
346    }
347
348    @Override
349    public boolean isSessionOwner(SessionId id) {
350      return running != null && running.getId().equals(id);
351    }
352
353    @Override
354    public boolean isSupporting(Capabilities capabilities) {
355      return Objects.equals("cake", capabilities.getCapability("cheese"));
356    }
357
358    @Override
359    public NodeStatus getStatus() {
360      Session sess = null;
361      if (running != null) {
362        try {
363          sess = new Session(
364            running.getId(),
365            new URI("http://localhost:14568"),
366            CAPS,
367            running.getCapabilities(),
368            Instant.now());
369        } catch (URISyntaxException e) {
370          throw new RuntimeException(e);
371        }
372      }
373
374      return new NodeStatus(
375        getId(),
376        getUri(),
377        1,
378        ImmutableSet.of(
379          new Slot(
380            new SlotId(getId(), UUID.randomUUID()),
381            CAPS,
382            Instant.now(),
383            Optional.ofNullable(sess))),
384        UP,
385        Duration.ofSeconds(10),
386        getNodeVersion(),
387        getOsInfo());
388    }
389
390    @Override
391    public HealthCheck getHealthCheck() {
392      return () -> new HealthCheck.Result(UP, "tl;dr");
393    }
394
395    @Override
396    public void drain() {
397    }
398  }
399
400}
401
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

...Most popular Stackoverflow questions on NodeStatusEvent

    No relevant questions found for this class 😞

Most used methods in NodeStatusEvent

Run Selenium Automation Tests on LambdaTest Cloud Grid

Trigger Selenium automation tests on a cloud-based Grid of 3000+ real browsers and operating systems.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)