org.openqa.grid.selenium.GridLauncherV3 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of selenium-server Show documentation
Show all versions of selenium-server Show documentation
Selenium automates browsers. That's it! What you do with that power is entirely up to you.
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.openqa.grid.selenium;
import com.google.common.collect.ImmutableMap;
import com.beust.jcommander.JCommander;
import org.openqa.grid.common.GridRole;
import org.openqa.grid.common.RegistrationRequest;
import org.openqa.grid.internal.utils.SelfRegisteringRemote;
import org.openqa.grid.internal.utils.configuration.CoreRunnerConfiguration;
import org.openqa.grid.internal.utils.configuration.GridHubConfiguration;
import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration;
import org.openqa.grid.internal.utils.configuration.StandaloneConfiguration;
import org.openqa.grid.shared.CliUtils;
import org.openqa.grid.web.Hub;
import org.openqa.selenium.internal.BuildInfo;
import org.openqa.selenium.remote.server.SeleniumServer;
import org.openqa.selenium.remote.server.log.LoggingOptions;
import org.openqa.selenium.remote.server.log.TerseFormatter;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.function.Supplier;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GridLauncherV3 {
private static final Logger log = Logger.getLogger(GridLauncherV3.class.getName());
private static final String CORE_RUNNER_CLASS =
"org.openqa.selenium.server.htmlrunner.HTMLLauncher";
private static abstract class GridItemLauncher {
protected StandaloneConfiguration configuration;
protected boolean helpRequested;
abstract void setConfiguration(String[] args);
abstract void launch() throws Exception;
void printUsage() {
new JCommander(configuration).usage();
}
}
private static ImmutableMap> LAUNCHERS = buildLaunchers();
public static void main(String[] args) throws Exception {
GridItemLauncher launcher = buildLauncher(args);
if (launcher == null) {
return;
}
if (launcher.helpRequested) {
launcher.printUsage();
return;
}
configureLogging(launcher.configuration);
BuildInfo buildInfo = new BuildInfo();
log.info(String.format(
"Selenium build info: version: '%s', revision: '%s'",
buildInfo.getReleaseLabel(),
buildInfo.getBuildRevision()));
try {
launcher.launch();
} catch (Exception e) {
launcher.printUsage();
e.printStackTrace();
}
}
/**
* From the {@code args}, builds a new {@link GridItemLauncher} and populates it properly.
*
* @return null if no role is found, or a properly populated {@link GridItemLauncher}.
*/
private static GridItemLauncher buildLauncher(String[] args) {
String role = "standalone";
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-htmlSuite")) {
Supplier launcherSupplier = LAUNCHERS.get("corerunner");
if (launcherSupplier == null) {
System.err.println(
"Unable to find the HTML runner. This is normally because you have not downloaded " +
"or made available the 'selenium-leg-rc' jar on the CLASSPATH. Your test will " +
"not be run.");
return null;
}
GridItemLauncher launcher = launcherSupplier.get();
launcher.setConfiguration(args);
return launcher;
}
if (args[i].startsWith("-role=")) {
role = args[i].substring("-role=".length());
} else if (args[i].equals("-role")) {
i++; // Increment, because we're going to need this.
if (i < args.length) {
role = args[i];
} else {
role = null; // Will cause us to print the usage information.
}
}
}
GridRole gridRole = GridRole.get(role);
if (gridRole == null) {
printInfoAboutRoles(role);
return null;
}
Supplier supplier = LAUNCHERS.get(gridRole.toString());
if (supplier == null) {
System.err.println("Unknown role: " + gridRole);
return null;
}
GridItemLauncher toReturn = supplier.get();
toReturn.setConfiguration(args);
return toReturn;
}
private static void printInfoAboutRoles(String roleCommandLineArg) {
if (roleCommandLineArg != null) {
CliUtils.printWrappedLine(
"",
"Error: the role '" + roleCommandLineArg + "' does not match a recognized server role: node/hub/standalone\n");
} else {
CliUtils.printWrappedLine(
"",
"Error: -role option needs to be followed by the value that defines role of this component in the grid\n");
}
System.out.println(
"Selenium server can run in one of the following roles:\n" +
" hub as a hub of a Selenium grid\n" +
" node as a node of a Selenium grid\n" +
" standalone as a standalone server not being a part of a grid\n" +
"\n" +
"If -role option is omitted the server runs standalone\n");
CliUtils.printWrappedLine(
"",
"To get help on the options available for a specific role run the server"
+ " with -help option and the corresponding -role option value");
}
private static void configureLogging(StandaloneConfiguration configuration) {
Level logLevel =
configuration.debug
? Level.FINE
: LoggingOptions.getDefaultLogLevel();
if (logLevel == null) {
logLevel = Level.INFO;
}
Logger.getLogger("").setLevel(logLevel);
Logger.getLogger("org.openqa.jetty").setLevel(Level.WARNING);
String logFilename =
configuration.log != null
? configuration.log
: LoggingOptions.getDefaultLogOutFile();
if (logFilename != null) {
for (Handler handler : Logger.getLogger("").getHandlers()) {
if (handler instanceof ConsoleHandler) {
Logger.getLogger("").removeHandler(handler);
}
}
try {
Handler logFile = new FileHandler(new File(logFilename).getAbsolutePath(), true);
logFile.setFormatter(new TerseFormatter(true));
logFile.setLevel(logLevel);
Logger.getLogger("").addHandler(logFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
for (Handler handler : Logger.getLogger("").getHandlers()) {
if (handler instanceof ConsoleHandler) {
handler.setLevel(logLevel);
handler.setFormatter(new TerseFormatter(configuration.logLongForm));
}
}
}
}
private static ImmutableMap> buildLaunchers() {
ImmutableMap.Builder> launchers =
ImmutableMap.>builder()
.put(GridRole.NOT_GRID.toString(), () -> new GridItemLauncher() {
public void setConfiguration(String[] args) {
configuration = new StandaloneConfiguration();
new JCommander(configuration, args);
helpRequested = configuration.help;
}
public void launch() throws Exception {
log.info("Launching a standalone Selenium Server");
SeleniumServer server = new SeleniumServer(configuration);
server.boot();
log.info("Selenium Server is up and running");
}
})
.put(GridRole.HUB.toString(), () -> new GridItemLauncher() {
public void setConfiguration(String[] args) {
GridHubConfiguration pending = new GridHubConfiguration();
new JCommander(pending, args);
configuration = pending;
//re-parse the args using any -hubConfig specified to init
if (pending.hubConfig != null) {
configuration = GridHubConfiguration.loadFromJSON(pending.hubConfig);
new JCommander(configuration, args); //args take precedence
}
helpRequested = configuration.help;
}
public void launch() throws Exception {
log.info("Launching Selenium Grid hub");
Hub h = new Hub((GridHubConfiguration) configuration);
h.start();
log.info("Nodes should register to " + h.getRegistrationURL());
log.info("Selenium Grid hub is up and running");
}
})
.put(GridRole.NODE.toString(), () -> new GridItemLauncher() {
public void setConfiguration(String[] args) {
GridNodeConfiguration pending = new GridNodeConfiguration();
new JCommander(pending, args);
configuration = pending;
//re-parse the args using any -nodeConfig specified to init
if (pending.nodeConfigFile != null) {
configuration = GridNodeConfiguration.loadFromJSON(pending.nodeConfigFile);
new JCommander(configuration, args); //args take precedence
}
helpRequested = configuration.help;
if (configuration.port == null) {
configuration.port = 5555;
}
}
public void launch() throws Exception {
log.info("Launching a Selenium Grid node");
RegistrationRequest
c =
RegistrationRequest.build((GridNodeConfiguration) configuration);
SelfRegisteringRemote remote = new SelfRegisteringRemote(c);
remote.setRemoteServer(new SeleniumServer(configuration));
remote.startRemoteServer();
log.info("Selenium Grid node is up and ready to register to the hub");
remote.startRegistrationProcess();
}
});
try {
Class.forName(CORE_RUNNER_CLASS, false, GridLauncherV3.class.getClassLoader());
launchers.put("corerunner", () -> new GridItemLauncher() {
@Override
void setConfiguration(String[] args) {
configuration = new CoreRunnerConfiguration();
new JCommander(configuration, args);
helpRequested = configuration.help;
}
@Override
void launch() throws Exception {
Class> coreRunnerClass = Class.forName(CORE_RUNNER_CLASS);
Object coreRunner = coreRunnerClass.newInstance();
Method mainInt = coreRunnerClass.getMethod("mainInt", String[].class);
CoreRunnerConfiguration runnerConfig = (CoreRunnerConfiguration) this.configuration;
String[] args = new String[] {
/* Results file */ runnerConfig.htmlSuite.get(3),
/* suite */ runnerConfig.htmlSuite.get(2),
/* start url */ runnerConfig.htmlSuite.get(1),
/* multi window */ "true",
/* browser string */ runnerConfig.htmlSuite.get(0),
};
Integer result = (Integer) mainInt.invoke(coreRunner, (Object) args);
System.exit(result);
}
});
} catch (ReflectiveOperationException e) {
// Do nothing. It's fine.
}
return launchers.build();
}
}