Skip to content

Commit d7fb38a

Browse files
committed
server: Redesigning driver factory to check if driver providers can instantiate new drivers.
This is the ground to implement more specific driver providers that can check for presence of executable drivers that are required to run a browser.
1 parent 69ddf29 commit d7fb38a

File tree

6 files changed

+149
-78
lines changed

6 files changed

+149
-78
lines changed

java/server/src/org/openqa/selenium/remote/server/DefaultDriverFactory.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,37 @@
1919

2020
import static com.google.common.base.Preconditions.checkState;
2121

22+
import com.google.common.annotations.VisibleForTesting;
23+
2224
import org.openqa.selenium.Capabilities;
2325
import org.openqa.selenium.WebDriver;
2426

2527
import java.util.Map;
2628
import java.util.concurrent.ConcurrentHashMap;
29+
import java.util.logging.Logger;
2730

2831
public class DefaultDriverFactory implements DriverFactory {
2932

33+
private static final Logger LOG = Logger.getLogger(DefaultDriverFactory.class.getName());
34+
3035
private Map<Capabilities, DriverProvider> capabilitiesToDriverProvider =
3136
new ConcurrentHashMap<Capabilities, DriverProvider>();
3237

33-
public void registerDriver(Capabilities capabilities, Class<? extends WebDriver> implementation) {
34-
registerDriverProvider(capabilities, new DefaultDriverProvider(capabilities, implementation));
35-
}
36-
37-
public void registerDriverProvider(Capabilities capabilities, DriverProvider implementation) {
38-
capabilitiesToDriverProvider.put(capabilities, implementation);
38+
@Deprecated
39+
public void registerDriver(Capabilities capabilities, Class<? extends WebDriver> driverClass) {
40+
registerDriverProvider(new DefaultDriverProvider(capabilities, driverClass));
3941
}
4042

41-
protected Class<? extends WebDriver> getBestMatchFor(Capabilities desired) {
42-
return getProviderMatching(desired).getDriverClass();
43+
public void registerDriverProvider(DriverProvider driverProvider) {
44+
if (driverProvider.canCreateDriverInstances()) {
45+
capabilitiesToDriverProvider.put(driverProvider.getProvidedCapabilities(), driverProvider);
46+
} else {
47+
LOG.info(String.format("Driver provider %s is not registered", driverProvider));
48+
}
4349
}
4450

45-
protected DriverProvider getProviderMatching(Capabilities desired) {
51+
@VisibleForTesting
52+
DriverProvider getProviderMatching(Capabilities desired) {
4653
// We won't be able to make a match if no drivers have been registered.
4754
checkState(!capabilitiesToDriverProvider.isEmpty(),
4855
"No drivers have been registered, will be unable to match %s", desired);

java/server/src/org/openqa/selenium/remote/server/DefaultDriverProvider.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,45 @@ public class DefaultDriverProvider implements DriverProvider {
3030
private static final Logger LOG = Logger.getLogger(DefaultDriverProvider.class.getName());
3131

3232
private Capabilities capabilities;
33-
private Class<? extends WebDriver> implementation;
34-
private String driverClass;
33+
private Class<? extends WebDriver> driverClass;
34+
private String driverClassName;
3535

36-
public DefaultDriverProvider(Capabilities capabilities, Class<? extends WebDriver> implementation) {
36+
public DefaultDriverProvider(Capabilities capabilities, Class<? extends WebDriver> driverClass) {
3737
this.capabilities = capabilities;
38-
this.implementation = implementation;
38+
this.driverClass = driverClass;
3939
}
4040

41-
public DefaultDriverProvider(Capabilities capabilities, String driverClass) {
41+
public DefaultDriverProvider(Capabilities capabilities, String driverClassName) {
4242
this.capabilities = capabilities;
43-
this.driverClass = driverClass;
43+
this.driverClassName = driverClassName;
4444
}
4545

4646
@Override
4747
public Capabilities getProvidedCapabilities() {
4848
return capabilities;
4949
}
5050

51+
@Override
52+
public boolean canCreateDriverInstances() {
53+
return getDriverClass() != null;
54+
}
55+
5156
@Override
5257
public Class<? extends WebDriver> getDriverClass() {
53-
if (implementation != null) {
54-
return implementation;
58+
if (driverClass != null) {
59+
return driverClass;
5560
}
5661
try {
57-
return Class.forName(driverClass).asSubclass(WebDriver.class);
62+
return Class.forName(driverClassName).asSubclass(WebDriver.class);
5863
} catch (ClassNotFoundException e) {
59-
LOG.log(Level.INFO, "Driver class not found: " + driverClass);
60-
throw new WebDriverException("Driver class not found: " + driverClass, e);
64+
LOG.log(Level.INFO, "Driver class not found: " + driverClassName);
65+
return null;
6166
} catch (NoClassDefFoundError e) {
62-
LOG.log(Level.INFO, "Driver class not found: " + driverClass);
63-
throw new WebDriverException("Driver class not found: " + driverClass, e);
67+
LOG.log(Level.INFO, "Driver class not found: " + driverClassName);
68+
return null;
6469
} catch (UnsupportedClassVersionError e) {
65-
LOG.log(Level.INFO, "Driver class is built for higher Java version: " + driverClass);
66-
throw new WebDriverException("Driver class is built for higher Java version: " + driverClass, e);
70+
LOG.log(Level.INFO, "Driver class is built for higher Java version: " + driverClassName);
71+
return null;
6772
}
6873
}
6974

@@ -97,6 +102,6 @@ private WebDriver callConstructor(Class<? extends WebDriver> from, Capabilities
97102

98103
@Override
99104
public String toString() {
100-
return implementation != null ? implementation.toString() : driverClass;
105+
return driverClass != null ? driverClass.toString() : driverClassName;
101106
}
102107
}

java/server/src/org/openqa/selenium/remote/server/DefaultDriverSessions.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,12 @@
2626
import org.openqa.selenium.remote.SessionId;
2727

2828
import java.util.Collections;
29-
import java.util.HashMap;
3029
import java.util.List;
3130
import java.util.Map;
3231
import java.util.ServiceLoader;
3332
import java.util.Set;
3433
import java.util.UUID;
3534
import java.util.concurrent.ConcurrentHashMap;
36-
import java.util.logging.Level;
3735
import java.util.logging.Logger;
3836

3937
public class DefaultDriverSessions implements DriverSessions {
@@ -114,7 +112,7 @@ private void registerDriverProvider(Platform current, DriverProvider provider) {
114112
return;
115113
}
116114

117-
factory.registerDriverProvider(caps, provider);
115+
factory.registerDriverProvider(provider);
118116
}
119117

120118
private boolean platformMatches(Platform current, Capabilities caps) {
@@ -123,9 +121,8 @@ private boolean platformMatches(Platform current, Capabilities caps) {
123121
|| current.is(caps.getPlatform());
124122
}
125123

126-
public void registerDriver(Capabilities capabilities, Class<? extends WebDriver> implementation) {
127-
factory.registerDriverProvider(
128-
capabilities, new DefaultDriverProvider(capabilities, implementation));
124+
public void registerDriver(Capabilities capabilities, Class<? extends WebDriver> driverClass) {
125+
factory.registerDriverProvider(new DefaultDriverProvider(capabilities, driverClass));
129126
}
130127

131128
public SessionId newSession(Capabilities desiredCapabilities) throws Exception {

java/server/src/org/openqa/selenium/remote/server/DriverFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@
2020
import org.openqa.selenium.WebDriver;
2121

2222
public interface DriverFactory {
23+
24+
/**
25+
* @deprecated Use registerDriverProvider instead
26+
*/
27+
@Deprecated
2328
void registerDriver(Capabilities capabilities, Class<? extends WebDriver> implementation);
2429

25-
void registerDriverProvider(Capabilities capabilities, DriverProvider implementation);
30+
void registerDriverProvider(DriverProvider implementation);
2631

2732
WebDriver newInstance(Capabilities capabilities);
2833

java/server/src/org/openqa/selenium/remote/server/DriverProvider.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,50 @@
1919
import org.openqa.selenium.Capabilities;
2020
import org.openqa.selenium.WebDriver;
2121

22+
/**
23+
* Classes that implement this interface are used by {org.openqa.selenium.remote.server.DriverFactory}
24+
* to create new driver instances associated with specific set of capabilities.
25+
*
26+
* When a driver factory registers a driver provider it checks ability of the provider to create
27+
* instances by a call to its isDriverAvailable method. Default driver provide implementation
28+
* checks for presence of the driver class in the classpath. Other driver provider classes may
29+
* perform more sophisiticated verification.
30+
*
31+
* If the driver provides is verified successfully it is registered as the driver provider
32+
* associated with the capabilities returned by getProvidedCapabilities method.
33+
*
34+
* Selenium Server trusts the driver providers, it does not check that a driver provider actually
35+
* creates driver instances that have the specified capabilities.
36+
*/
2237
public interface DriverProvider {
38+
39+
/**
40+
* The provider "promices" that created driver instances will have (at least) this set of
41+
* capabilities. The grid uses this information to match the capabilites requested by the client
42+
* against the capabilities provided by all registered providers to pick the "best" one.
43+
*/
2344
Capabilities getProvidedCapabilities();
2445

46+
/**
47+
* This method was used for testing purposes only and will be removed from the interface soon.
48+
* @deprecated
49+
*/
50+
@Deprecated
2551
Class<? extends WebDriver> getDriverClass();
2652

53+
/**
54+
* Checks if the provider can create driver instances.
55+
*
56+
* @return true if the provider can create driver instances.
57+
*/
58+
boolean canCreateDriverInstances();
59+
60+
/**
61+
* Creates a new driver instance. The specified capabilities are to be passed to the driver
62+
* constructor.
63+
*
64+
* @param capabilities Capabilities are to be passed to the driver constructor.
65+
* @return A new driver instance
66+
*/
2767
WebDriver newInstance(Capabilities capabilities);
2868
}

0 commit comments

Comments
 (0)