diff --git a/horizon/test/firefox_binary.py b/horizon/test/firefox_binary.py index ba67c7d10e..93cb955914 100644 --- a/horizon/test/firefox_binary.py +++ b/horizon/test/firefox_binary.py @@ -11,10 +11,13 @@ # 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. +import errno import platform import shutil +import socket import subprocess import tempfile +import time from selenium.common import exceptions as selenium_exceptions from selenium.webdriver.common import desired_capabilities as dc @@ -62,6 +65,9 @@ class WebDriver(firefox.webdriver.WebDriver): """Workarounds selenium firefox issues.""" TEMPDIR = tempfile.mkdtemp(dir="/tmp") + CONNREFUSED_RETRY_COUNT = 3 + CONNREFUSED_RETRY_INTERVAL = 5 + def __init__(self, firefox_profile=None, firefox_binary=None, timeout=30, desired_capabilities=dc.DesiredCapabilities.FIREFOX, proxy=None): @@ -69,9 +75,27 @@ class WebDriver(firefox.webdriver.WebDriver): if firefox_profile is None: firefox_profile = firefox.webdriver.FirefoxProfile() self.setup_profile(firefox_profile) - super(WebDriver, self).__init__( - firefox_profile, FirefoxBinary(), timeout, - desired_capabilities, proxy) + + # NOTE(amotoki): workaround for bug 1626643 + # Connection refused error happens randomly in integration tests. + # When a connection refused exception is raised from start_session + # called from WebDriver.__init__, retry __init__. + for i in range(self.CONNREFUSED_RETRY_COUNT + 1): + try: + super(WebDriver, self).__init__( + firefox_profile, FirefoxBinary(), timeout, + desired_capabilities, proxy) + if i > 0: + # i==0 is normal behavior without connection refused. + print('NOTE: Retried %s time(s) due to ' + 'connection refused.' % i) + break + except socket.error as socket_error: + if (socket_error.errno == errno.ECONNREFUSED + and i < self.CONNREFUSED_RETRY_COUNT): + time.sleep(self.CONNREFUSED_RETRY_INTERVAL) + continue + raise except selenium_exceptions.WebDriverException: # If we can't start, cleanup profile shutil.rmtree(self.profile.path) diff --git a/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py b/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py index f23144205b..5a1ccfbe0b 100644 --- a/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py +++ b/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py @@ -9,6 +9,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +import netaddr + from openstack_dashboard.test.integration_tests.pages import basepage from openstack_dashboard.test.integration_tests.regions import forms from openstack_dashboard.test.integration_tests.regions import tables @@ -156,4 +158,6 @@ class InstancesPage(basepage.BaseNavigationPage): def get_fixed_ipv4(self, name): row = self._get_row_with_instance_name(name) ips = row.cells[self.INSTANCES_TABLE_IP_COLUMN].text - return ips.split()[0] + for ip in ips.split(): + if netaddr.valid_ipv4(ip): + return ip