|
22 | 22 | import com.google.common.collect.ImmutableSet;
|
23 | 23 | import org.junit.Before;
|
24 | 24 | import org.junit.Test;
|
| 25 | +import org.openqa.selenium.Capabilities; |
| 26 | +import org.openqa.selenium.ImmutableCapabilities; |
| 27 | +import org.openqa.selenium.SessionNotCreatedException; |
25 | 28 | import org.openqa.selenium.WebDriverInfo;
|
26 | 29 | import org.openqa.selenium.chrome.ChromeDriverInfo;
|
27 | 30 | import org.openqa.selenium.events.EventBus;
|
|
39 | 42 | import org.openqa.selenium.grid.server.Server;
|
40 | 43 | import org.openqa.selenium.grid.sessionmap.SessionMap;
|
41 | 44 | import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;
|
| 45 | +import org.openqa.selenium.grid.sessionqueue.NewSessionQueue; |
42 | 46 | import org.openqa.selenium.grid.sessionqueue.NewSessionQueuer;
|
43 | 47 | import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;
|
44 | 48 | import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueuer;
|
45 | 49 | import org.openqa.selenium.grid.testing.TestSessionFactory;
|
| 50 | +import org.openqa.selenium.grid.web.CombinedHandler; |
46 | 51 | import org.openqa.selenium.grid.web.EnsureSpecCompliantHeaders;
|
47 | 52 | import org.openqa.selenium.netty.server.NettyServer;
|
48 | 53 | import org.openqa.selenium.remote.http.Contents;
|
|
55 | 60 | import org.openqa.selenium.remote.tracing.Tracer;
|
56 | 61 | import org.openqa.selenium.testing.drivers.Browser;
|
57 | 62 |
|
| 63 | +import java.net.MalformedURLException; |
58 | 64 | import java.net.URI;
|
59 | 65 | import java.net.URISyntaxException;
|
60 | 66 | import java.time.Duration;
|
61 | 67 | import java.time.Instant;
|
| 68 | +import java.util.concurrent.atomic.AtomicInteger; |
62 | 69 |
|
63 | 70 | import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
|
| 71 | +import static java.net.HttpURLConnection.HTTP_OK; |
64 | 72 | import static org.assertj.core.api.Assertions.assertThat;
|
65 | 73 | import static org.assertj.core.api.Assumptions.assumeThat;
|
66 | 74 | import static org.openqa.selenium.json.Json.JSON_UTF_8;
|
| 75 | +import static org.openqa.selenium.remote.http.Contents.asJson; |
67 | 76 | import static org.openqa.selenium.remote.http.HttpMethod.POST;
|
68 | 77 |
|
69 | 78 | public class NewSessionCreationTest {
|
@@ -157,6 +166,76 @@ public void ensureJsCannotCreateANewSession() throws URISyntaxException {
|
157 | 166 | assertThat(res.isSuccessful()).isTrue();
|
158 | 167 | }
|
159 | 168 |
|
| 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 | + |
160 | 239 | private LocalNode.Builder addDriverFactory(
|
161 | 240 | LocalNode.Builder builder,
|
162 | 241 | WebDriverInfo info,
|
|
0 commit comments