org.openqa.grid.selenium.GridLauncherV3.java Source code

Java tutorial

Introduction

Here is the source code for org.openqa.grid.selenium.GridLauncherV3.java

Source

// 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.base.Joiner;
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<String, Supplier<GridItemLauncher>> 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<GridItemLauncher> launcherSupplier = LAUNCHERS.get("corerunner");
                if (launcherSupplier == null) {
                    System.err.println(Joiner.on("\n").join(
                            "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.",
                            "Download the Selenium HTML Runner from http://www.seleniumhq.org/download/ and",
                            "use that in place of the selenium-server-standalone.jar for the simplest way of",
                            "running your HTML suite."));
                    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<GridItemLauncher> 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<String, Supplier<GridItemLauncher>> buildLaunchers() {
        ImmutableMap.Builder<String, Supplier<GridItemLauncher>> launchers = ImmutableMap
                .<String, Supplier<GridItemLauncher>>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();
    }
}