Reputation: 1585
I'm using selenium grid for distributed testing on remote machine. There are two projects running on this machine and I want to set up selenium hub and nodes for each of the projects separately. However, if one of the hubs is not available I'd like to pass the tests to available one.
webdriver_hub = '/wd/hub'
PORT.nil? ? port = ':4444' : port =':' + PORT
@driver = Selenium::WebDriver.for(
:remote,
:url => 'http://' + SELENIUM_HUB + port + webdriver_hub,
:desired_capabilities => caps,
:http_client => client
)
The default port is ":4444". Instead having static default port, I want to be able to assign it dynamically depending on available hub. Is there a way to get available hub before the test run?
Upvotes: 1
Views: 2783
Reputation: 1529
I am not sure exactly what you are looking for, so I will attempt to explain how I think you may be able to get what you are looking for.
There are two scenarios where a specific hub may be "not available". The first is when the hub is not running. The hub has either been shutdown manually or through an error or it was just not started (perhaps after a reboot).
The other case is when the hub is available, but there are no nodes currently available to service the request. This may occur if there is only one node which can service all requests and it is currently running the maximum number of requests.
The first scenario is the easiest to look for. Simply attempt to connect to the remote server to determine if it has a server listening on it.
/// <summary>
/// Will test to verify that a Selenium Hub is running by checking a URL
/// </summary>
/// <param name="defaultURL">The url to test.</param>
/// <returns>true if the hub is running. false if it is not running.</returns>
/// <example>IsHubRunning(new Uri("http://localhost:4444/wd/status"));</example>
static public bool IsHubRunning(Uri defaultURL)
{
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(defaultURL);
httpReq.AllowAutoRedirect = false;
HttpWebResponse httpRes;
try
{
httpRes = (HttpWebResponse)httpReq.GetResponse();
if (httpRes.StatusCode != HttpStatusCode.OK)
{
return false;
}
}
catch (WebException ex)
{
// Inspect the exection. An exception of 500 in the case
// of Selenium may NOT be a problem. This means a server is listening.
if (ex.Response == null || ex.Status == WebExceptionStatus.ConnectFailure)
{
return false;
}
// Did it return the expected content type.
if(ex.Response.ContentType != "application/json;charset=UTF-8")
{
return false;
}
if (ex.Response.ContentLength <= 0)
{
return false;
}
}
return true;
}
The above C# code will make a request to the Uri passed in. It will perform a GET request and then inspect the status code returned. It also tests for exceptions which may be reported depending on the specific Uri you request. If you request the /wd/status, you should get an "OK" response.
This will tell you if a hub is running. It will NOT tell you if there is a node available to service the specific request. You could also inspect additional properties of the response such as the Server property to determine if the response is from a Selenium grid hub.
The second scenario is a little more involved. If you want to know if a specific set of capabilities can be supported then you could perform a similar query to the /grid/console Uri. This will return information about nodes and their capabilities.
To determine what nodes are available to a hub simply parse the information returned from the above Uri. This however requires a lot of work on the part of your test client just to determine if a specific node is available on the requested hub.
A better way would be to verify which hub is up and running. Then attempt to create a connection requesting a specific set of capabilities from that hub. If the hub you make the request from indicates it cannot service the request then you try the next hub.
Here is some C# code that can be used to determine if a specific set of capabilities is available from a hub.
/// <summary>
/// Determines if the hub can provide the capabilities requested.
/// The specified hub is used.
/// </summary>
/// <param name="dc">The capabilities being requested.</param>
/// <param name="hub">The hub to make the request to.</param>
/// <returns>true if the requested capabilities are available, otherwise false;</returns>
static public bool IsRemoteDriverAvailable(DesiredCapabilities dc, Uri hub)
{
bool isAvailable = false;
// Verify that valid capabilities were requested.
if (dc == null)
{
return isAvailable;
}
try
{
IWebDriver driver = new RemoteWebDriver(hub, dc);
driver.Quit();
isAvailable = true;
}
catch (Exception ex)
{
Console.WriteLine("Error {0}", ex.Message);
}
return isAvailable;
}
Hope that helps.
Upvotes: 0
Reputation: 21
That's what HUB is for, to use available resources when they are. You should only specify the port of the NODES in the configuration, not for the test execution. Test execution should connect the the HUB, with the browser/platform/version you want it to be executed against, nothing else.
Upvotes: 2