Skip to content

Commit fef0953

Browse files
authored
Merge branch 'trunk' into feat-14291/add-jspecify-annotations-to-exception-classes-pt4
2 parents 1f5984a + 29af98d commit fef0953

File tree

6 files changed

+184
-30
lines changed

6 files changed

+184
-30
lines changed

common/repositories.bzl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ def pin_browsers():
1111

1212
http_archive(
1313
name = "linux_firefox",
14-
url = "https://ftp.mozilla.org/pub/firefox/releases/142.0.1/linux-x86_64/en-US/firefox-142.0.1.tar.xz",
15-
sha256 = "8f47a714610a624ad536a652a70242aa894a37f65565fd3103d4366869743b91",
14+
url = "https://ftp.mozilla.org/pub/firefox/releases/143.0/linux-x86_64/en-US/firefox-143.0.tar.xz",
15+
sha256 = "1c87a9de21941a15177384d4820a6aa3c7dacb38d34089c73a621734ebf1ea9a",
1616
build_file_content = """
1717
load("@aspect_rules_js//js:defs.bzl", "js_library")
1818
package(default_visibility = ["//visibility:public"])
@@ -33,8 +33,8 @@ js_library(
3333

3434
dmg_archive(
3535
name = "mac_firefox",
36-
url = "https://ftp.mozilla.org/pub/firefox/releases/142.0.1/mac/en-US/Firefox%20142.0.1.dmg",
37-
sha256 = "de41866c94d064a20cd787d89203c5f646fe0278da13c44605733ce205680965",
36+
url = "https://ftp.mozilla.org/pub/firefox/releases/143.0/mac/en-US/Firefox%20143.0.dmg",
37+
sha256 = "a5c570e277021b61df1295efe77446617ebd768d8ad36a20b309aa382685f6f2",
3838
build_file_content = """
3939
load("@aspect_rules_js//js:defs.bzl", "js_library")
4040
package(default_visibility = ["//visibility:public"])
@@ -50,8 +50,8 @@ js_library(
5050

5151
http_archive(
5252
name = "linux_beta_firefox",
53-
url = "https://ftp.mozilla.org/pub/firefox/releases/143.0b9/linux-x86_64/en-US/firefox-143.0b9.tar.xz",
54-
sha256 = "43ac5d340c5380353987417a06af6c9a0eac3a21f2b81c29e6829ca6792418cf",
53+
url = "https://ftp.mozilla.org/pub/firefox/releases/144.0b1/linux-x86_64/en-US/firefox-144.0b1.tar.xz",
54+
sha256 = "41efaaa6b924cf898b00161818a754cbc7f1e99df61c0d8a6c8ce4d0b30b5a54",
5555
build_file_content = """
5656
load("@aspect_rules_js//js:defs.bzl", "js_library")
5757
package(default_visibility = ["//visibility:public"])
@@ -72,8 +72,8 @@ js_library(
7272

7373
dmg_archive(
7474
name = "mac_beta_firefox",
75-
url = "https://ftp.mozilla.org/pub/firefox/releases/143.0b9/mac/en-US/Firefox%20143.0b9.dmg",
76-
sha256 = "7f0c3edd7987fa64023163e3850a5d71bc1c41c7ef4458bf54c486caa1c158dd",
75+
url = "https://ftp.mozilla.org/pub/firefox/releases/144.0b1/mac/en-US/Firefox%20144.0b1.dmg",
76+
sha256 = "1d378cadf853b9b02e7c61ed85cca4c79933ceb6df50e18fd1ed4e246eef7949",
7777
build_file_content = """
7878
load("@aspect_rules_js//js:defs.bzl", "js_library")
7979
package(default_visibility = ["//visibility:public"])

java/src/org/openqa/selenium/grid/distributor/NodeRegistry.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,14 @@ public interface NodeRegistry extends HasReadyState, Closeable {
8585
DistributorStatus getStatus();
8686

8787
/**
88-
* Gets all available nodes that are not DOWN or DRAINING.
88+
* Get all nodes that are UP.
89+
*
90+
* @return Set of UP node statuses.
91+
*/
92+
Set<NodeStatus> getUpNodes();
93+
94+
/**
95+
* Gets all available nodes that are not DOWN or DRAINING and has free slots.
8996
*
9097
* @return Set of available node statuses.
9198
*/

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

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,8 @@ private SlotId reserveSlot(RequestId requestId, Capabilities caps) {
466466
}
467467

468468
private boolean isNotSupported(Capabilities caps) {
469-
return getAvailableNodes().stream().noneMatch(node -> node.hasCapability(caps, slotMatcher));
469+
return nodeRegistry.getUpNodes().stream()
470+
.noneMatch(node -> node.hasCapability(caps, slotMatcher));
470471
}
471472

472473
private boolean reserve(SlotId id) {
@@ -560,21 +561,28 @@ public void run() {
560561
}
561562

562563
private void checkMatchingSlot(List<SessionRequestCapability> sessionRequests) {
563-
for (SessionRequestCapability request : sessionRequests) {
564-
long unmatchableCount =
565-
request.getDesiredCapabilities().stream()
566-
.filter(LocalDistributor.this::isNotSupported)
567-
.count();
568-
569-
if (unmatchableCount == request.getDesiredCapabilities().size()) {
570-
LOG.info(
571-
"No nodes support the capabilities in the request: "
572-
+ request.getDesiredCapabilities());
573-
SessionNotCreatedException exception =
574-
new SessionNotCreatedException("No nodes support the capabilities in the request");
575-
sessionQueue.complete(request.getRequestId(), Either.left(exception));
576-
}
577-
}
564+
// Get UP nodes once to avoid lock & loop over multiple requests
565+
Set<NodeStatus> upNodes = nodeRegistry.getUpNodes();
566+
// Filter and reject only requests where NO capabilities are supported by ANY UP node
567+
// This prevents rejecting requests when nodes support capabilities but are just busy
568+
sessionRequests.stream()
569+
.filter(
570+
request ->
571+
request.getDesiredCapabilities().stream()
572+
.noneMatch(
573+
caps ->
574+
upNodes.stream()
575+
.anyMatch(node -> node.hasCapability(caps, slotMatcher))))
576+
.forEach(
577+
request -> {
578+
LOG.info(
579+
"No nodes support the capabilities in the request: "
580+
+ request.getDesiredCapabilities());
581+
SessionNotCreatedException exception =
582+
new SessionNotCreatedException(
583+
"No nodes support the capabilities in the request");
584+
sessionQueue.complete(request.getRequestId(), Either.left(exception));
585+
});
578586
}
579587

580588
private void handleNewSessionRequest(SessionRequest sessionRequest) {

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,12 +357,19 @@ public DistributorStatus getStatus() {
357357

358358
@Override
359359
public Set<NodeStatus> getAvailableNodes() {
360+
// Filter nodes are UP and have capacity (available slots)
361+
return getUpNodes().stream()
362+
.filter(NodeStatus::hasCapacity)
363+
.collect(ImmutableSet.toImmutableSet());
364+
}
365+
366+
@Override
367+
public Set<NodeStatus> getUpNodes() {
360368
Lock readLock = this.lock.readLock();
361369
readLock.lock();
362370
try {
363371
return model.getSnapshot().stream()
364-
// Filter nodes are UP and have capacity (available slots)
365-
.filter(node -> UP.equals(node.getAvailability()) && node.hasCapacity())
372+
.filter(node -> UP.equals(node.getAvailability()))
366373
.collect(ImmutableSet.toImmutableSet());
367374
} finally {
368375
readLock.unlock();

java/test/org/openqa/selenium/grid/distributor/local/LocalDistributorTest.java

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,140 @@ void shouldReduceRedundantSlotChecks() throws URISyntaxException {
777777
}
778778
}
779779

780+
@Test
781+
void shouldNotRejectRequestsWhenNodesHaveCapabilityButNoFreeSlots() throws URISyntaxException {
782+
// Create a distributor with rejectUnsupportedCaps enabled
783+
NewSessionQueue queue =
784+
new LocalNewSessionQueue(
785+
tracer,
786+
new DefaultSlotMatcher(),
787+
Duration.ofSeconds(2),
788+
Duration.ofSeconds(2),
789+
Duration.ofSeconds(1),
790+
registrationSecret,
791+
5);
792+
LocalDistributor distributor =
793+
new LocalDistributor(
794+
tracer,
795+
bus,
796+
new PassthroughHttpClient.Factory(localNode),
797+
new LocalSessionMap(tracer, bus),
798+
queue,
799+
new DefaultSlotSelector(),
800+
registrationSecret,
801+
Duration.ofMinutes(5),
802+
true, // Enable rejectUnsupportedCaps
803+
Duration.ofSeconds(5),
804+
newSessionThreadPoolSize,
805+
new DefaultSlotMatcher(),
806+
Duration.ofSeconds(30));
807+
808+
// Create a node that supports Chrome with single slot
809+
URI nodeUri = new URI("http://example:1234");
810+
Node node =
811+
LocalNode.builder(tracer, bus, nodeUri, nodeUri, registrationSecret)
812+
.add(
813+
new ImmutableCapabilities("browserName", "chrome"),
814+
new TestSessionFactory(
815+
(id, c) ->
816+
new Session(id, nodeUri, new ImmutableCapabilities(), c, Instant.now())))
817+
.maximumConcurrentSessions(1)
818+
.build();
819+
distributor.add(node);
820+
821+
// Occupy the node's only slot
822+
SessionRequest sessionRequest =
823+
new SessionRequest(
824+
new RequestId(UUID.randomUUID()),
825+
Instant.now(),
826+
Set.of(W3C),
827+
Set.of(new ImmutableCapabilities("browserName", "chrome")),
828+
Map.of(),
829+
Map.of());
830+
Either<SessionNotCreatedException, CreateSessionResponse> result =
831+
distributor.newSession(sessionRequest);
832+
assertThat(result.isRight()).isTrue(); // Session created successfully
833+
834+
// Verify node has no available capacity but still supports Chrome
835+
assertThat(distributor.getAvailableNodes()).isEmpty(); // No available nodes
836+
837+
// Test that the distributor status shows the node is still UP and supports Chrome
838+
// even though it has no available capacity
839+
DistributorStatus status = distributor.getStatus();
840+
Set<NodeStatus> allNodes = status.getNodes();
841+
assertThat(allNodes).hasSize(1);
842+
843+
NodeStatus nodeStatus = allNodes.iterator().next();
844+
assertThat(nodeStatus.getAvailability()).isEqualTo(UP);
845+
846+
// Verify the node still supports Chrome capability even with no free slots
847+
boolean supportsChrome =
848+
nodeStatus.hasCapability(
849+
new ImmutableCapabilities("browserName", "chrome"), new DefaultSlotMatcher());
850+
assertThat(supportsChrome).isTrue();
851+
852+
// Verify the node has no capacity (all slots occupied)
853+
assertThat(nodeStatus.hasCapacity()).isFalse();
854+
}
855+
856+
@Test
857+
void shouldRejectRequestsWhenNoNodesHaveCapability() throws URISyntaxException {
858+
// Create a distributor with rejectUnsupportedCaps enabled
859+
NewSessionQueue queue =
860+
new LocalNewSessionQueue(
861+
tracer,
862+
new DefaultSlotMatcher(),
863+
Duration.ofSeconds(2),
864+
Duration.ofSeconds(2),
865+
Duration.ofSeconds(1),
866+
registrationSecret,
867+
5);
868+
LocalDistributor distributor =
869+
new LocalDistributor(
870+
tracer,
871+
bus,
872+
new PassthroughHttpClient.Factory(localNode),
873+
new LocalSessionMap(tracer, bus),
874+
queue,
875+
new DefaultSlotSelector(),
876+
registrationSecret,
877+
Duration.ofMinutes(5),
878+
true, // Enable rejectUnsupportedCaps
879+
Duration.ofSeconds(5),
880+
newSessionThreadPoolSize,
881+
new DefaultSlotMatcher(),
882+
Duration.ofSeconds(30));
883+
884+
// Create a node that only supports Chrome
885+
URI nodeUri = new URI("http://example:1234");
886+
Node node =
887+
LocalNode.builder(tracer, bus, nodeUri, nodeUri, registrationSecret)
888+
.add(
889+
new ImmutableCapabilities("browserName", "chrome"),
890+
new TestSessionFactory(
891+
(id, c) ->
892+
new Session(id, nodeUri, new ImmutableCapabilities(), c, Instant.now())))
893+
.build();
894+
distributor.add(node);
895+
896+
// Add a Firefox request to the queue (unsupported capability)
897+
SessionRequest unsupportedRequest =
898+
new SessionRequest(
899+
new RequestId(UUID.randomUUID()),
900+
Instant.now(),
901+
Set.of(W3C),
902+
Set.of(new ImmutableCapabilities("browserName", "firefox")),
903+
Map.of(),
904+
Map.of());
905+
queue.addToQueue(unsupportedRequest);
906+
907+
// Wait for checkMatchingSlot to run and reject the request
908+
wait.until(obj -> queue.getQueueContents().isEmpty());
909+
910+
// The request should be rejected and removed from queue
911+
assertThat(queue.getQueueContents()).isEmpty();
912+
}
913+
780914
@Test
781915
void shouldHandleAllNodesFullyOccupied() throws URISyntaxException {
782916
// Create a distributor

rb/spec/integration/selenium/webdriver/fedcm_spec.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@
2222
module Selenium
2323
module WebDriver
2424
module FedCM
25-
describe FedCM,
26-
exclude: {browser: :chrome, reason: 'https://issues.chromium.org/u/0/issues/425801332'},
27-
exclusive: [{bidi: false, reason: 'Not yet implemented with BiDi'}, {browser: %i[chrome edge]}] do
25+
describe FedCM, exclusive: [{bidi: false, reason: 'Not yet implemented with BiDi'}, {browser: %i[chrome edge]}] do
2826
let(:dialog) { driver.fedcm_dialog }
2927

3028
before { driver.get url_for('fedcm/fedcm.html') }

0 commit comments

Comments
 (0)