Skip to content

Commit f79086f

Browse files
authored
Merge branch 'trunk' into rb_bidi_add_request_handler
2 parents 16e552e + 7f4d4bf commit f79086f

File tree

21 files changed

+847
-66
lines changed

21 files changed

+847
-66
lines changed

.github/workflows/ci-python.yml

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ jobs:
100100
fail-fast: false
101101
matrix:
102102
include:
103+
- browser: safari
104+
os: macos
103105
- browser: chrome
104106
os: ubuntu
105107
- browser: edge
@@ -114,21 +116,3 @@ jobs:
114116
run: |
115117
bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:common-${{ matrix.browser }}-bidi
116118
bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-${{ matrix.browser }}
117-
118-
safari-tests:
119-
name: Browser Tests
120-
needs: build
121-
uses: ./.github/workflows/bazel.yml
122-
strategy:
123-
fail-fast: false
124-
matrix:
125-
include:
126-
- browser: safari
127-
os: macos
128-
with:
129-
name: Integration Tests (${{ matrix.browser }}, ${{ matrix.os }})
130-
browser: ${{ matrix.browser }}
131-
os: ${{ matrix.os }}
132-
cache-key: py-browser-${{ matrix.browser }}
133-
run: |
134-
bazel test --local_test_jobs 1 --flaky_test_attempts 3 //py:test-${{ matrix.browser }}

java/spotbugs-excludes.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,9 @@
230230
<Bug pattern="NM_CLASS_NAMING_CONVENTION"/>
231231
</Match>
232232

233+
<Match>
234+
<Class name="org.openqa.selenium.manager.SeleniumManager"/>
235+
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
236+
</Match>
237+
233238
</FindBugsFilter>

java/src/org/openqa/selenium/grid/distributor/local/LocalDistributor.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static org.openqa.selenium.remote.RemoteTags.CAPABILITIES_EVENT;
2828
import static org.openqa.selenium.remote.RemoteTags.SESSION_ID;
2929
import static org.openqa.selenium.remote.RemoteTags.SESSION_ID_EVENT;
30+
import static org.openqa.selenium.remote.http.HttpMethod.DELETE;
3031
import static org.openqa.selenium.remote.tracing.AttributeKey.SESSION_URI;
3132
import static org.openqa.selenium.remote.tracing.Tags.EXCEPTION;
3233

@@ -79,6 +80,7 @@
7980
import org.openqa.selenium.grid.data.NodeStatus;
8081
import org.openqa.selenium.grid.data.NodeStatusEvent;
8182
import org.openqa.selenium.grid.data.RequestId;
83+
import org.openqa.selenium.grid.data.Session;
8284
import org.openqa.selenium.grid.data.SessionRequest;
8385
import org.openqa.selenium.grid.data.SessionRequestCapability;
8486
import org.openqa.selenium.grid.data.Slot;
@@ -109,6 +111,7 @@
109111
import org.openqa.selenium.internal.Require;
110112
import org.openqa.selenium.remote.SessionId;
111113
import org.openqa.selenium.remote.http.HttpClient;
114+
import org.openqa.selenium.remote.http.HttpRequest;
112115
import org.openqa.selenium.remote.tracing.AttributeKey;
113116
import org.openqa.selenium.remote.tracing.AttributeMap;
114117
import org.openqa.selenium.remote.tracing.Span;
@@ -853,21 +856,34 @@ private void handleNewSessionRequest(SessionRequest sessionRequest) {
853856
}
854857
}
855858

856-
// 'complete' will return 'true' if the session has not timed out during the creation
857-
// process: it's still a valid session as it can be used by the client
858859
boolean isSessionValid = sessionQueue.complete(reqId, response);
859-
// If the session request has timed out, tell the Node to remove the session, so that does
860-
// not stall
860+
// terminate invalid sessions to avoid stale sessions
861861
if (!isSessionValid && response.isRight()) {
862862
LOG.log(
863863
Level.INFO,
864-
"Session for request {0} has been created but it has timed out, stopping it to avoid"
865-
+ " stalled browser",
864+
"Session for request {0} has been created but it has timed out or the connection"
865+
+ " dropped, stopping it to avoid stalled browser",
866866
reqId.toString());
867-
URI nodeURI = response.right().getSession().getUri();
868-
Node node = getNodeFromURI(nodeURI);
867+
Session session = response.right().getSession();
868+
Node node = getNodeFromURI(session.getUri());
869869
if (node != null) {
870-
node.stop(response.right().getSession().getId());
870+
boolean deleted;
871+
try {
872+
// Attempt to stop the session
873+
deleted =
874+
node.execute(new HttpRequest(DELETE, "/session/" + session.getId())).getStatus()
875+
== 200;
876+
} catch (Exception e) {
877+
LOG.log(
878+
Level.WARNING,
879+
String.format("Exception while trying to delete session %s", session.getId()),
880+
e);
881+
deleted = false;
882+
}
883+
if (!deleted) {
884+
// Kill the session
885+
node.stop(session.getId());
886+
}
871887
}
872888
}
873889
}

java/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,14 @@ public HttpResponse addToQueue(SessionRequest request) {
220220
result = Either.left(new SessionNotCreatedException("New session request timed out"));
221221
}
222222
} catch (InterruptedException e) {
223+
// the client will never see the session, ensure the session is disposed
224+
data.cancel();
223225
Thread.currentThread().interrupt();
224226
result =
225227
Either.left(new SessionNotCreatedException("Interrupted when creating the session", e));
226228
} catch (RuntimeException e) {
229+
// the client will never see the session, ensure the session is disposed
230+
data.cancel();
227231
result =
228232
Either.left(
229233
new SessionNotCreatedException("An error occurred creating the session", e));
@@ -367,43 +371,30 @@ public List<SessionRequest> getNextAvailable(Map<Capabilities, Long> stereotypes
367371
}
368372
}
369373

370-
/** Returns true if the session is still valid (not timed out) */
374+
/** Returns true if the session is still valid (not timed out and not canceled) */
371375
@Override
372376
public boolean complete(
373377
RequestId reqId, Either<SessionNotCreatedException, CreateSessionResponse> result) {
374378
Require.nonNull("New session request", reqId);
375379
Require.nonNull("Result", result);
376380
TraceContext context = contexts.getOrDefault(reqId, tracer.getCurrentContext());
377381
try (Span ignored = context.createSpan("sessionqueue.completed")) {
378-
Lock readLock = lock.readLock();
379-
readLock.lock();
380382
Data data;
381-
boolean isSessionTimedOut = false;
382-
try {
383-
data = requests.get(reqId);
384-
} finally {
385-
readLock.unlock();
386-
}
387-
388-
if (data == null) {
389-
return false;
390-
} else {
391-
isSessionTimedOut = isTimedOut(Instant.now(), data);
392-
}
393-
394383
Lock writeLock = lock.writeLock();
395384
writeLock.lock();
396385
try {
397-
requests.remove(reqId);
386+
data = requests.remove(reqId);
398387
queue.removeIf(req -> reqId.equals(req.getRequestId()));
399388
contexts.remove(reqId);
400389
} finally {
401390
writeLock.unlock();
402391
}
403392

404-
data.setResult(result);
393+
if (data == null) {
394+
return false;
395+
}
405396

406-
return !isSessionTimedOut;
397+
return data.setResult(result);
407398
}
408399
}
409400

@@ -466,6 +457,7 @@ private class Data {
466457
private final CountDownLatch latch = new CountDownLatch(1);
467458
private Either<SessionNotCreatedException, CreateSessionResponse> result;
468459
private boolean complete;
460+
private boolean canceled;
469461

470462
public Data(Instant enqueued) {
471463
this.endTime = enqueued.plus(requestTimeout);
@@ -476,14 +468,19 @@ public synchronized Either<SessionNotCreatedException, CreateSessionResponse> ge
476468
return result;
477469
}
478470

479-
public synchronized void setResult(
471+
public synchronized void cancel() {
472+
canceled = true;
473+
}
474+
475+
public synchronized boolean setResult(
480476
Either<SessionNotCreatedException, CreateSessionResponse> result) {
481-
if (complete) {
482-
return;
477+
if (complete || canceled) {
478+
return false;
483479
}
484480
this.result = result;
485481
complete = true;
486482
latch.countDown();
483+
return true;
487484
}
488485
}
489486
}

java/src/org/openqa/selenium/manager/SeleniumManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ private synchronized Path getBinary() {
213213
if (!binary.toFile().exists()) {
214214
String binaryPathInJar = String.format("%s/%s%s", folder, SELENIUM_MANAGER, extension);
215215
try (InputStream inputStream = this.getClass().getResourceAsStream(binaryPathInJar)) {
216-
binary.getParent().toFile().mkdirs();
216+
Files.createDirectories(binary.getParent());
217217
Files.copy(inputStream, binary);
218218
}
219219
}

java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ private static Log fromJson(JsonInput input) {
9898
case "message":
9999
message = input.nextString();
100100
break;
101+
102+
default:
103+
input.skipValue();
104+
break;
101105
}
102106
}
103107
input.endObject();

java/test/org/openqa/selenium/grid/router/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ load("//java:version.bzl", "TOOLS_JAVA_VERSION")
44
load("//java/src/org/openqa/selenium/devtools:versions.bzl", "CDP_DEPS")
55

66
LARGE_TESTS = [
7+
"DistributedTest.java",
78
"DistributedCdpTest.java",
89
"NewSessionCreationTest.java",
910
"RemoteWebDriverDownloadTest.java",

0 commit comments

Comments
 (0)