Skip to content

Commit 04ec49d

Browse files
pujaganidiemol
andauthored
[grid] Retry session only when capabilities are found. Add test to confirm session retry due to unexpected error. (#8864)
Co-authored-by: Diego Molina <[email protected]>
1 parent a9a4371 commit 04ec49d

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

java/server/src/org/openqa/selenium/grid/distributor/Distributor.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,11 @@ public Either<SessionNotCreatedException, CreateSessionResponse> newSession(
198198
.anyMatch(nodeStatus -> nodeStatus.hasCapability(firstRequest.getCapabilities()));
199199

200200
if (!hostsWithCaps) {
201-
throw new SessionNotCreatedException(
202-
"No host supports the capabilities required: " + payload.stream()
203-
.map(Capabilities::toString).collect(Collectors.joining(", ")));
201+
String errorMessage = String.format(
202+
"No host supports the capabilities required: %s",
203+
payload.stream().map(Capabilities::toString).collect(Collectors.joining(", ")));
204+
SessionNotCreatedException exception = new SessionNotCreatedException(errorMessage);
205+
return Either.left(exception);
204206
}
205207

206208
// Find a host that supports the capabilities present in the new session

java/server/test/org/openqa/selenium/grid/router/NewSessionCreationTest.java

+79
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
import com.google.common.collect.ImmutableSet;
2323
import org.junit.Before;
2424
import org.junit.Test;
25+
import org.openqa.selenium.Capabilities;
26+
import org.openqa.selenium.ImmutableCapabilities;
27+
import org.openqa.selenium.SessionNotCreatedException;
2528
import org.openqa.selenium.WebDriverInfo;
2629
import org.openqa.selenium.chrome.ChromeDriverInfo;
2730
import org.openqa.selenium.events.EventBus;
@@ -39,10 +42,12 @@
3942
import org.openqa.selenium.grid.server.Server;
4043
import org.openqa.selenium.grid.sessionmap.SessionMap;
4144
import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;
45+
import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;
4246
import org.openqa.selenium.grid.sessionqueue.NewSessionQueuer;
4347
import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;
4448
import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueuer;
4549
import org.openqa.selenium.grid.testing.TestSessionFactory;
50+
import org.openqa.selenium.grid.web.CombinedHandler;
4651
import org.openqa.selenium.grid.web.EnsureSpecCompliantHeaders;
4752
import org.openqa.selenium.netty.server.NettyServer;
4853
import org.openqa.selenium.remote.http.Contents;
@@ -55,15 +60,19 @@
5560
import org.openqa.selenium.remote.tracing.Tracer;
5661
import org.openqa.selenium.testing.drivers.Browser;
5762

63+
import java.net.MalformedURLException;
5864
import java.net.URI;
5965
import java.net.URISyntaxException;
6066
import java.time.Duration;
6167
import java.time.Instant;
68+
import java.util.concurrent.atomic.AtomicInteger;
6269

6370
import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
71+
import static java.net.HttpURLConnection.HTTP_OK;
6472
import static org.assertj.core.api.Assertions.assertThat;
6573
import static org.assertj.core.api.Assumptions.assumeThat;
6674
import static org.openqa.selenium.json.Json.JSON_UTF_8;
75+
import static org.openqa.selenium.remote.http.Contents.asJson;
6776
import static org.openqa.selenium.remote.http.HttpMethod.POST;
6877

6978
public class NewSessionCreationTest {
@@ -157,6 +166,76 @@ public void ensureJsCannotCreateANewSession() throws URISyntaxException {
157166
assertThat(res.isSuccessful()).isTrue();
158167
}
159168

169+
@Test
170+
public void shouldRetryNewSessionRequestOnUnexpectedError() throws
171+
URISyntaxException, MalformedURLException {
172+
Capabilities capabilities = new ImmutableCapabilities("browserName", "cheese");
173+
URI nodeUri = new URI("http://localhost:4444");
174+
CombinedHandler handler = new CombinedHandler();
175+
176+
SessionMap sessions = new LocalSessionMap(tracer, events);
177+
handler.addHandler(sessions);
178+
NewSessionQueue localNewSessionQueue = new LocalNewSessionQueue(
179+
tracer,
180+
events,
181+
Duration.ofSeconds(2),
182+
Duration.ofSeconds(10));
183+
NewSessionQueuer queuer = new LocalNewSessionQueuer(tracer, events, localNewSessionQueue);
184+
handler.addHandler(queuer);
185+
186+
Distributor distributor = new LocalDistributor(
187+
tracer,
188+
events,
189+
clientFactory,
190+
sessions,
191+
queuer,
192+
registrationSecret);
193+
handler.addHandler(distributor);
194+
195+
AtomicInteger count = new AtomicInteger();
196+
197+
// First session creation attempt throws an error.
198+
// Second attempt creates a session.
199+
TestSessionFactory sessionFactory = new TestSessionFactory((id, caps) -> {
200+
if (count.get() == 0) {
201+
count.incrementAndGet();
202+
throw new SessionNotCreatedException("Expected the exception");
203+
} else {
204+
return new Session(
205+
id,
206+
nodeUri,
207+
new ImmutableCapabilities(),
208+
caps,
209+
Instant.now());
210+
}
211+
});
212+
213+
LocalNode localNode = LocalNode.builder(tracer, events, nodeUri, nodeUri, registrationSecret)
214+
.add(capabilities, sessionFactory).build();
215+
handler.addHandler(localNode);
216+
distributor.add(localNode);
217+
218+
Router router = new Router(tracer, clientFactory, sessions, queuer, distributor);
219+
handler.addHandler(router);
220+
221+
Server<?> server = new NettyServer(
222+
new BaseServerOptions(
223+
new MapConfig(ImmutableMap.of())),
224+
handler);
225+
226+
server.start();
227+
228+
HttpRequest request = new HttpRequest(POST, "/session");
229+
request.setContent(asJson(
230+
ImmutableMap.of(
231+
"capabilities", ImmutableMap.of(
232+
"alwaysMatch", capabilities))));
233+
234+
HttpClient client = clientFactory.createClient(server.getUrl());
235+
HttpResponse httpResponse = client.execute(request);
236+
assertThat(httpResponse.getStatus()).isEqualTo(HTTP_OK);
237+
}
238+
160239
private LocalNode.Builder addDriverFactory(
161240
LocalNode.Builder builder,
162241
WebDriverInfo info,

0 commit comments

Comments
 (0)