mhardin / SeleniumGridScaler

Selenium Grid auto scaling plugin utilizing AWS
GNU General Public License v2.0
111 stars 51 forks source link

SeleniumGridScaler Build Status


Overview

A Selenium Grid plugin for integrating your project with AWS (Amazon Web Services) to allow for resources (EC2 'nodes') to dynamically spin up/down (autoscale) depending on current test load. The jar should be pulled down and installed to serve as a hub for the desired Selenium Grid setup.

Details

New nodes will be started as needed depending on the browser requested:

AWS bills by rounding up to the next hour, so if you leave a machine on for 5 minutes, you get billed for the full hour (60 minutes). Based on this logic, SeleniumGridScaler's automatic termination logic will terminate nodes at the end of the current billing cycle, taking into account current test load. So if there is enough test load, say 12 tests running and only 12 threads are online (2 chrome instances each capable of running 6 for a total of 12), all of the nodes will stay on. If the current time crosses into the next billing cycle (e.g. they're on for 1 hour and 5 minutes), SeleniumGridScaler will not attempt to terminate them until the end of that next billing cycle (will attempt to terminate at 1 hour and 55 minutes instead of prematurely terminating paid for resources).

Requirements

A Java 8 or later runtime is required in order to run this application

Installation/Startup

Download the automation-grid jar file. To start up the hub process, start the jar with the java jar command like so. Note, you must register the Scaler servlet (AutomationTestRunServlet) with GridLauncher.

java -DawsAccessKey=foo -DawsSecretKey=bar -DipAddress="10.10.28.205" -cp automation-grid.jar org.openqa.grid.selenium.GridLauncher -role hub -servlets "com.rmn.qa.servlet.AutomationTestRunServlet","com.rmn.qa.servlet.StatusServlet" -hubConfig hub.json

The -hubConfig configuration key and value are optional to specify Selenium Hub configuration information. Please see the 'Selenium Configuration' section below for more information. After starting the hub process, you should be able to run your tests against the hub in the Running Your Tests section below

Installation/Startup w/Docker

Clone source code repository, and build target jars with:

mvn install

After building target jars, build docker image:

docker build -t selenium-grid-ec2

After the docker image has been built, you can start a new docker container with it:

docker run -d -p 4444:4444 -e AWS_ACCESS_KEY={REPLACE_WITH_YOUR_KEY} -e AWS_SECRET_KEY={REPLACE_WITH_SECRET_KEY selenium-grid-ec2

Startup Configuration

Certain configuration values can be passed in to change the default behavior of SeleniumGridScaler

System properties

More information can be found here on AWS Access

Running Your Tests

In your test run, you must send a GET HTTP request to the servlet, with the required query string parameters, to ensure the requested resources are available.

If you wanted to do a test run with 10 threads in chrome with a test run UUID of 'testRun1', the HTTP request would look something like this

http://hubIpAddress:4444/grid/admin/AutomationTestRunServlet?uuid=testRun1&threadCount=10&browser=chrome

Possible response codes:

After a successful response code (201 or 202), you should be able to run your test run against the hub end point like so. Note that the test run UUID used in the API call above must be passed in via a desired capability or you may run into unintended side effects

    URL url = null;
    try {
        url = new URL("http://servername:4444/wd/hub");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    capabilities.setBrowserName("chrome");
    // The test run UUID associated with the test needs to be passed in
    // so SeleniumGridScaler can associate in progress tests with test runs
    capabilities.setCapability("uuid","testRun1");
    WebDriver driver = new RemoteWebDriver(url,capabilities);

Selenium Configuration

Note that on top of the SeleniumGridScaler configuration, you can use all existing configurations for Selenium. Available selenium configurations values can be found here and an example of passing them in can be seen in the Running Your Tests section above

Test Access

If you're trying to test against a website thats not publicly available on the internet, such as a private testing environment behind a firewall, you will need to setup up some sort of solution to allow your nodes have to access your test environment(s). Two ways of granting access have been included below.

Logging

Logging will be saved to a log file found in in /log/automation.log. If you would like to change the location, you can override the directory and log file name with the 'logLocation' system property (e.g. -DlogLocation=/log/myLogName.log) The current logging levels is set to INFO or higher.

Installation to Develop Locally

The SeleniumGridScaler is a Maven project, which means when you have downloaded it and opened it in your favorite Maven-enabled IDE, you should be able to run "mvn install", and a SNAPSHOT jar file will be deployed to your local Maven repo.

Once the jar has been deployed, you should be able to include a small snippet in your project pom file to point to your installed SNAPSHOT to develop and test any changes you may want to make:

<dependency>
    <groupId>com.retailmenot</groupId>
    <artifactId>selenium-grid-scaler</artifactId>
    <version>1.1-SNAPSHOT</version>
</dependency>

If you're currently using Maven, and your repos, paths, and IDE are all set up correctly, you should be able to address the classes in this project immediately (you may need to update your Maven dependencies).

If you would prefer to simply build a jar file and include it into your classpath, run "mvn package", and the jar file should appear in the target folder under the main folder and then you can add it to your sources for your project.

AWS Customization

If you would like to specify custom attributes for the instances that will be started in AWS, you can do so by creating a .properties file and passing it in via a system property 'propertyFileLocation' for the file location (e.g. -DpropertyFileLocation=/myPath/customAws.properties). Please see aws.properties.sample for an idea of how the format should look. Possible values to override/implement:

Current Issues

Currently Windows is not supported. There was an AMI I built out but forgot to make public before changing jobs. So, if you want to run in Windows, you'll basically need to mimic the startup/configuration logic done in ~/grid/grid_start_node.sh on the linux AMI included in aws.properties.default

Contributing

All pull requests are greatly appreciated! This project is intended for end users of Selenium Grid, but we've only implemented functionality we've needed to handle our current needs. If you need new features, open an issue on github, or better yet, contribute your own features!

The SeleniumGridScaler is a Maven/Java project, using JUnit for unit tests, Cobertura for coverage checks, and Selenium for web browser interaction.

Contact

For any questions, concerns, or problems, please feel free to contact the author Matthew Hardin at mhardin.github@gmail.com

License

This project has been released under the GPL license. Please see the license.txt file for more details.