Skip to content

Commit 53cca49

Browse files
authored
Make user defined SlotMatcher used everywhere in grid code (#12240)
1 parent 7c54398 commit 53cca49

25 files changed

+209
-72
lines changed

java/src/org/openqa/selenium/chrome/ChromeOptions.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static org.openqa.selenium.remote.Browser.CHROME;
2121

2222
import org.openqa.selenium.Capabilities;
23-
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
2423
import org.openqa.selenium.chromium.ChromiumOptions;
2524
import org.openqa.selenium.internal.Require;
2625
import org.openqa.selenium.remote.CapabilityType;

java/src/org/openqa/selenium/grid/commands/Hub.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ protected Handlers createHandlers(Config config) {
163163
distributorOptions.getHealthCheckInterval(),
164164
distributorOptions.shouldRejectUnsupportedCaps(),
165165
newSessionRequestOptions.getSessionRequestRetryInterval(),
166-
distributorOptions.getNewSessionThreadPoolSize());
166+
distributorOptions.getNewSessionThreadPoolSize(),
167+
distributorOptions.getSlotMatcher());
167168
handler.addHandler(distributor);
168169

169170
Router router = new Router(tracer, clientFactory, sessions, queue, distributor);

java/src/org/openqa/selenium/grid/commands/Standalone.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ protected Handlers createHandlers(Config config) {
167167
distributorOptions.getHealthCheckInterval(),
168168
distributorOptions.shouldRejectUnsupportedCaps(),
169169
newSessionRequestOptions.getSessionRequestRetryInterval(),
170-
distributorOptions.getNewSessionThreadPoolSize());
170+
distributorOptions.getNewSessionThreadPoolSize(),
171+
distributorOptions.getSlotMatcher());
171172
combinedHandler.addHandler(distributor);
172173

173174
Routable router =

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
import org.openqa.selenium.grid.data.Availability;
6868
import org.openqa.selenium.grid.data.CreateSessionRequest;
6969
import org.openqa.selenium.grid.data.CreateSessionResponse;
70-
import org.openqa.selenium.grid.data.DefaultSlotMatcher;
7170
import org.openqa.selenium.grid.data.DistributorStatus;
7271
import org.openqa.selenium.grid.data.NodeAddedEvent;
7372
import org.openqa.selenium.grid.data.NodeDrainComplete;
@@ -81,6 +80,7 @@
8180
import org.openqa.selenium.grid.data.SessionRequestCapability;
8281
import org.openqa.selenium.grid.data.Slot;
8382
import org.openqa.selenium.grid.data.SlotId;
83+
import org.openqa.selenium.grid.data.SlotMatcher;
8484
import org.openqa.selenium.grid.data.TraceSessionRequest;
8585
import org.openqa.selenium.grid.distributor.Distributor;
8686
import org.openqa.selenium.grid.distributor.GridModel;
@@ -135,6 +135,7 @@ public class LocalDistributor extends Distributor implements AutoCloseable {
135135
private final ReadWriteLock lock = new ReentrantReadWriteLock(/* fair */ true);
136136
private final GridModel model;
137137
private final Map<NodeId, Node> nodes;
138+
private final SlotMatcher slotMatcher;
138139

139140
private final ScheduledExecutorService newSessionService =
140141
Executors.newSingleThreadScheduledExecutor(
@@ -180,7 +181,8 @@ public LocalDistributor(
180181
Duration healthcheckInterval,
181182
boolean rejectUnsupportedCaps,
182183
Duration sessionRequestRetryInterval,
183-
int newSessionThreadPoolSize) {
184+
int newSessionThreadPoolSize,
185+
SlotMatcher slotMatcher) {
184186
super(tracer, clientFactory, registrationSecret);
185187
this.tracer = Require.nonNull("Tracer", tracer);
186188
this.bus = Require.nonNull("Event bus", bus);
@@ -193,6 +195,7 @@ public LocalDistributor(
193195
this.model = new GridModel(bus);
194196
this.nodes = new ConcurrentHashMap<>();
195197
this.rejectUnsupportedCaps = rejectUnsupportedCaps;
198+
this.slotMatcher = slotMatcher;
196199
Require.nonNull("Session request interval", sessionRequestRetryInterval);
197200

198201
bus.addListener(NodeStatusEvent.listener(this::register));
@@ -264,7 +267,8 @@ public static Distributor create(Config config) {
264267
distributorOptions.getHealthCheckInterval(),
265268
distributorOptions.shouldRejectUnsupportedCaps(),
266269
newSessionQueueOptions.getSessionRequestRetryInterval(),
267-
distributorOptions.getNewSessionThreadPoolSize());
270+
distributorOptions.getNewSessionThreadPoolSize(),
271+
distributorOptions.getSlotMatcher());
268272
}
269273

270274
@Override
@@ -662,8 +666,7 @@ private SlotId reserveSlot(RequestId requestId, Capabilities caps) {
662666
Lock writeLock = lock.writeLock();
663667
writeLock.lock();
664668
try {
665-
Set<SlotId> slotIds =
666-
slotSelector.selectSlot(caps, getAvailableNodes(), new DefaultSlotMatcher());
669+
Set<SlotId> slotIds = slotSelector.selectSlot(caps, getAvailableNodes(), slotMatcher);
667670
if (slotIds.isEmpty()) {
668671
LOG.log(
669672
getDebugLogLevel(),
@@ -684,8 +687,7 @@ private SlotId reserveSlot(RequestId requestId, Capabilities caps) {
684687
}
685688

686689
private boolean isNotSupported(Capabilities caps) {
687-
return getAvailableNodes().stream()
688-
.noneMatch(node -> node.hasCapability(caps, new DefaultSlotMatcher()));
690+
return getAvailableNodes().stream().noneMatch(node -> node.hasCapability(caps, slotMatcher));
689691
}
690692

691693
private boolean reserve(SlotId id) {

java/src/org/openqa/selenium/grid/node/config/NodeOptions.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.openqa.selenium.WebDriverInfo;
5656
import org.openqa.selenium.grid.config.Config;
5757
import org.openqa.selenium.grid.config.ConfigException;
58+
import org.openqa.selenium.grid.data.SlotMatcher;
5859
import org.openqa.selenium.grid.node.Node;
5960
import org.openqa.selenium.grid.node.SessionFactory;
6061
import org.openqa.selenium.internal.Require;
@@ -83,6 +84,7 @@ public class NodeOptions {
8384
static final int DEFAULT_REGISTER_PERIOD = 120;
8485
static final String DEFAULT_NODE_IMPLEMENTATION =
8586
"org.openqa.selenium.grid.node.local.LocalNodeFactory";
87+
static final String DEFAULT_SLOT_MATCHER = "org.openqa.selenium.grid.data.DefaultSlotMatcher";
8688
private static final Logger LOG = Logger.getLogger(NodeOptions.class.getName());
8789
private static final Json JSON = new Json();
8890
private static final Platform CURRENT_PLATFORM = Platform.getCurrent();
@@ -172,6 +174,10 @@ public Duration getRegisterCycle() {
172174
return Duration.ofSeconds(seconds);
173175
}
174176

177+
public SlotMatcher getSlotMatcher() {
178+
return config.getClass("distributor", "slot-matcher", SlotMatcher.class, DEFAULT_SLOT_MATCHER);
179+
}
180+
175181
public Duration getRegisterPeriod() {
176182
// If the user sets 0 or less, we default to 1s.
177183
int seconds =

java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ public Map<Capabilities, Collection<SessionFactory>> getDockerSessionFactories(
181181
videoImage,
182182
assetsPath,
183183
networkName,
184-
info.isPresent()));
184+
info.isPresent(),
185+
capabilities -> options.getSlotMatcher().matches(caps, capabilities)));
185186
}
186187
LOG.info(
187188
String.format(

java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.util.Map;
4242
import java.util.Optional;
4343
import java.util.TimeZone;
44+
import java.util.function.Predicate;
4445
import java.util.logging.Level;
4546
import java.util.logging.Logger;
4647
import org.openqa.selenium.Capabilities;
@@ -59,8 +60,6 @@
5960
import org.openqa.selenium.docker.Image;
6061
import org.openqa.selenium.docker.Port;
6162
import org.openqa.selenium.grid.data.CreateSessionRequest;
62-
import org.openqa.selenium.grid.data.DefaultSlotMatcher;
63-
import org.openqa.selenium.grid.data.SlotMatcher;
6463
import org.openqa.selenium.grid.node.ActiveSession;
6564
import org.openqa.selenium.grid.node.SessionFactory;
6665
import org.openqa.selenium.internal.Either;
@@ -102,7 +101,7 @@ public class DockerSessionFactory implements SessionFactory {
102101
private final DockerAssetsPath assetsPath;
103102
private final String networkName;
104103
private final boolean runningInDocker;
105-
private final SlotMatcher slotMatcher;
104+
private final Predicate<Capabilities> predicate;
106105

107106
public DockerSessionFactory(
108107
Tracer tracer,
@@ -116,7 +115,8 @@ public DockerSessionFactory(
116115
Image videoImage,
117116
DockerAssetsPath assetsPath,
118117
String networkName,
119-
boolean runningInDocker) {
118+
boolean runningInDocker,
119+
Predicate<Capabilities> predicate) {
120120
this.tracer = Require.nonNull("Tracer", tracer);
121121
this.clientFactory = Require.nonNull("HTTP client", clientFactory);
122122
this.sessionTimeout = Require.nonNull("Session timeout", sessionTimeout);
@@ -129,7 +129,7 @@ public DockerSessionFactory(
129129
this.videoImage = videoImage;
130130
this.assetsPath = assetsPath;
131131
this.runningInDocker = runningInDocker;
132-
this.slotMatcher = new DefaultSlotMatcher();
132+
this.predicate = Require.nonNull("Accepted capabilities predicate", predicate);
133133
}
134134

135135
@Override
@@ -139,7 +139,7 @@ public Capabilities getStereotype() {
139139

140140
@Override
141141
public boolean test(Capabilities capabilities) {
142-
return slotMatcher.matches(stereotype, capabilities);
142+
return predicate.test(capabilities);
143143
}
144144

145145
@Override

java/src/org/openqa/selenium/grid/node/local/LocalNodeFactory.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import java.util.ServiceLoader;
2828
import org.openqa.selenium.ImmutableCapabilities;
2929
import org.openqa.selenium.grid.config.Config;
30-
import org.openqa.selenium.grid.data.DefaultSlotMatcher;
3130
import org.openqa.selenium.grid.data.SlotMatcher;
3231
import org.openqa.selenium.grid.log.LoggingOptions;
3332
import org.openqa.selenium.grid.node.Node;
@@ -78,7 +77,14 @@ public static Node create(Config config) {
7877

7978
nodeOptions
8079
.getSessionFactories(
81-
caps -> createSessionFactory(tracer, clientFactory, sessionTimeout, builders, caps))
80+
caps ->
81+
createSessionFactory(
82+
tracer,
83+
clientFactory,
84+
sessionTimeout,
85+
builders,
86+
caps,
87+
nodeOptions.getSlotMatcher()))
8288
.forEach((caps, factories) -> factories.forEach(factory -> builder.add(caps, factory)));
8389

8490
if (config.getAll("docker", "configs").isPresent()) {
@@ -101,9 +107,9 @@ private static Collection<SessionFactory> createSessionFactory(
101107
HttpClient.Factory clientFactory,
102108
Duration sessionTimeout,
103109
List<DriverService.Builder<?, ?>> builders,
104-
ImmutableCapabilities stereotype) {
110+
ImmutableCapabilities stereotype,
111+
SlotMatcher slotMatcher) {
105112
ImmutableList.Builder<SessionFactory> toReturn = ImmutableList.builder();
106-
SlotMatcher slotMatcher = new DefaultSlotMatcher();
107113
String webDriverExecutablePath =
108114
String.valueOf(stereotype.asMap().getOrDefault("se:webDriverExecutable", ""));
109115

java/test/org/openqa/selenium/chrome/ChromeOptionsTest.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,7 @@ void mergingOptionsWithOptionsAsMutableCapabilities() {
361361
@Test
362362
void isW3CSafe() {
363363
Map<String, Object> converted =
364-
new ChromeOptions()
365-
.setBinary("some/path")
366-
.addArguments("--headless")
367-
.asMap();
364+
new ChromeOptions().setBinary("some/path").addArguments("--headless").asMap();
368365

369366
Predicate<String> badKeys = new AcceptedW3CCapabilityKeys().negate();
370367
Set<String> seen = converted.keySet().stream().filter(badKeys).collect(toSet());

java/test/org/openqa/selenium/grid/distributor/AddingNodesTest.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ void shouldBeAbleToRegisterALocalNode() throws URISyntaxException {
141141
Duration.ofMinutes(5),
142142
false,
143143
Duration.ofSeconds(5),
144-
newSessionThreadPoolSize);
144+
newSessionThreadPoolSize,
145+
new DefaultSlotMatcher());
145146

146147
distributor =
147148
new RemoteDistributor(
@@ -179,7 +180,8 @@ void shouldBeAbleToRegisterACustomNode() throws URISyntaxException {
179180
Duration.ofMinutes(5),
180181
false,
181182
Duration.ofSeconds(5),
182-
newSessionThreadPoolSize)) {
183+
newSessionThreadPoolSize,
184+
new DefaultSlotMatcher())) {
183185

184186
distributor =
185187
new RemoteDistributor(
@@ -217,7 +219,8 @@ void shouldBeAbleToRegisterNodesByListeningForEvents() throws URISyntaxException
217219
Duration.ofMinutes(5),
218220
false,
219221
Duration.ofSeconds(5),
220-
newSessionThreadPoolSize)) {
222+
newSessionThreadPoolSize,
223+
new DefaultSlotMatcher())) {
221224

222225
distributor =
223226
new RemoteDistributor(
@@ -265,7 +268,8 @@ void shouldKeepOnlyOneNodeWhenTwoRegistrationsHaveTheSameUriByListeningForEvents
265268
Duration.ofMinutes(5),
266269
false,
267270
Duration.ofSeconds(5),
268-
newSessionThreadPoolSize)) {
271+
newSessionThreadPoolSize,
272+
new DefaultSlotMatcher())) {
269273

270274
distributor =
271275
new RemoteDistributor(
@@ -306,7 +310,8 @@ void distributorShouldUpdateStateOfExistingNodeWhenNodePublishesStateChange()
306310
Duration.ofMinutes(5),
307311
false,
308312
Duration.ofSeconds(5),
309-
newSessionThreadPoolSize)) {
313+
newSessionThreadPoolSize,
314+
new DefaultSlotMatcher())) {
310315

311316
distributor =
312317
new RemoteDistributor(

0 commit comments

Comments
 (0)