From 3c24cca240123b30fa3293928d9d518d7ae0b704 Mon Sep 17 00:00:00 2001 From: Alex Rodionov Date: Wed, 14 Oct 2015 18:22:33 +0600 Subject: [PATCH] rb: Allow to start mutliple IE drivers in parallel --- rb/lib/selenium/webdriver/ie/bridge.rb | 2 +- rb/lib/selenium/webdriver/ie/server.rb | 48 ++++++++++++++----- .../selenium/webdriver/ie/driver_spec.rb | 32 +++++++++++++ 3 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 rb/spec/integration/selenium/webdriver/ie/driver_spec.rb diff --git a/rb/lib/selenium/webdriver/ie/bridge.rb b/rb/lib/selenium/webdriver/ie/bridge.rb index 96092716a97c2..b5816774a8088 100644 --- a/rb/lib/selenium/webdriver/ie/bridge.rb +++ b/rb/lib/selenium/webdriver/ie/bridge.rb @@ -34,7 +34,7 @@ class Bridge < Remote::Bridge def initialize(opts = {}) caps = opts.delete(:desired_capabilities) { Remote::Capabilities.internet_explorer } timeout = opts.delete(:timeout) { DEFAULT_TIMEOUT } - port = opts.delete(:port) { PortProber.above(DEFAULT_PORT) } + port = opts.delete(:port) { DEFAULT_PORT } http_client = opts.delete(:http_client) ignore_mode = opts.delete(:introduce_flakiness_by_ignoring_security_domains) native_events = opts.delete(:native_events) != false diff --git a/rb/lib/selenium/webdriver/ie/server.rb b/rb/lib/selenium/webdriver/ie/server.rb index 45b3795096abe..1a672206dd923 100644 --- a/rb/lib/selenium/webdriver/ie/server.rb +++ b/rb/lib/selenium/webdriver/ie/server.rb @@ -20,9 +20,16 @@ module Selenium module WebDriver module IE + + # + # @api private + # + class Server - STOP_TIMEOUT = 5 + STOP_TIMEOUT = 5 + SOCKET_LOCK_TIMEOUT = 45 + MISSING_TEXT = "Unable to find standalone executable. Please download the IEDriverServer from http://selenium-release.storage.googleapis.com/index.html and place the executable on your PATH." def self.get(opts = {}) binary = IE.driver_path || Platform.find_binary("IEDriverServer") @@ -30,8 +37,7 @@ def self.get(opts = {}) if binary new binary, opts else - raise Error::WebDriverError, - "Unable to find standalone executable. Please download the IEDriverServer from http://selenium-release.storage.googleapis.com/index.html and place the executable on your PATH." + raise Error::WebDriverError, MISSING_TEXT end end @@ -52,23 +58,19 @@ def initialize(binary_path, opts = {}) unless opts.empty? raise ArgumentError, "invalid option#{'s' if opts.size != 1}: #{opts.inspect}" end - end def start(port, timeout) return @port if running? @port = port - - @process = ChildProcess.new(@binary_path, *server_args) - @process.io.inherit! if $DEBUG - @process.start - - unless SocketPoller.new(Platform.localhost, @port, timeout).connected? - raise Error::WebDriverError, "unable to connect to IE server within #{timeout} seconds" + socket_lock.locked do + find_free_port + start_process + connect_until_stable(timeout) end - Platform.exit_hook { stop } + Platform.exit_hook { stop } # make sure we don't leave the server running @port end @@ -103,6 +105,28 @@ def server_args args end + def find_free_port + @port = PortProber.above @port + end + + def start_process + @process = ChildProcess.new(@binary_path, *server_args) + @process.io.inherit! if $DEBUG + @process.start + end + + def connect_until_stable(timeout) + socket_poller = SocketPoller.new Platform.localhost, @port, timeout + + unless socket_poller.connected? + raise Error::WebDriverError, "unable to connect to IE server within #{timeout} seconds" + end + end + + def socket_lock + @socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT) + end + end # Server end # IE end # WebDriver diff --git a/rb/spec/integration/selenium/webdriver/ie/driver_spec.rb b/rb/spec/integration/selenium/webdriver/ie/driver_spec.rb new file mode 100644 index 0000000000000..ec86cefed4ecf --- /dev/null +++ b/rb/spec/integration/selenium/webdriver/ie/driver_spec.rb @@ -0,0 +1,32 @@ +# encoding: utf-8 +# +# 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. + +require File.expand_path("../../spec_helper", __FILE__) + +module Selenium + module WebDriver + module IE + + describe Driver do + it_behaves_like "driver that can be started concurrently", :ie + end + + end # IE + end # WebDriver +end # Selenium