Merge "VNC harcoded server name removed" into mcp/queens
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 08e2a12..4f3afc5 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -14,6 +14,7 @@
 import time
 
 from oslo_log import log as logging
+import six
 
 from tempest.common import image as common_image
 from tempest import config
@@ -265,13 +266,16 @@
 
 
 def wait_for_interface_status(client, server_id, port_id, status):
-    """Waits for an interface to reach a given status."""
+    """Waits for an interface to reach a (one of) given status(es)."""
+    if isinstance(status, six.string_types):
+        status = [status]
+
     body = (client.show_interface(server_id, port_id)
             ['interfaceAttachment'])
     interface_status = body['port_state']
     start = int(time.time())
 
-    while(interface_status != status):
+    while(interface_status not in status):
         time.sleep(client.build_interval)
         body = (client.show_interface(server_id, port_id)
                 ['interfaceAttachment'])
@@ -279,8 +283,8 @@
 
         timed_out = int(time.time()) - start >= client.build_timeout
 
-        if interface_status != status and timed_out:
-            message = ('Interface %s failed to reach %s status '
+        if interface_status not in status and timed_out:
+            message = ('Interface %s failed to reach either of %s statuses '
                        '(current %s) within the required time (%s s).' %
                        (port_id, status, interface_status,
                         client.build_timeout))
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 0b38761..ef49adc 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -773,8 +773,14 @@
         ports = self.os_admin.ports_client.list_ports(
             device_id=server['id'], fixed_ip=ip_addr)['ports']
         # A port can have more than one IP address in some cases.
-        # If the network is dual-stack (IPv4 + IPv6), this port is associated
-        # with 2 subnets
+        # If the network is dual-stack (IPv4 + IPv6), this port
+        # is associated with 2 subnets
+        port_map = [{"id": p["id"],
+                     "ip": fxip["ip_address"],
+                     "status": p["status"]}
+                    for p in ports
+                    for fxip in p["fixed_ips"]
+                    if netutils.is_valid_ipv4(fxip["ip_address"])]
         p_status = ['ACTIVE']
         # NOTE(vsaienko) With Ironic, instances live on separate hardware
         # servers. Neutron does not bind ports for Ironic instances, as a
@@ -782,22 +788,31 @@
         # TODO(vsaienko) remove once bug: #1599836 is resolved.
         if getattr(CONF.service_available, 'ironic', False):
             p_status.append('DOWN')
-        port_map = [(p["id"], fxip["ip_address"])
-                    for p in ports
-                    for fxip in p["fixed_ips"]
-                    if (netutils.is_valid_ipv4(fxip["ip_address"]) and
-                        p['status'] in p_status)]
-        inactive = [p for p in ports if p['status'] != 'ACTIVE']
+        # TODO(pas-ha) add a new waiter that will wait for all/at least one
+        # port on instance at once, and use it here
+        for pm in port_map:
+            try:
+                port = waiters.wait_for_interface_status(self.interface_client,
+                                                         server['id'],
+                                                         pm["id"], p_status)
+                pm["status"] = port['port_state']
+            except lib_exc.TimeoutException:
+                # NOTE(pas-ha) as server might have several IPv4 ports
+                # we need at least one of them to be in appropriate state
+                # so just ignore timeouts and deal with it later
+                pass
+        port_map = [p for p in port_map if p["status"] in p_status]
+        inactive = [p for p in port_map if p["status"] != 'ACTIVE']
         if inactive:
-            LOG.warning("Instance has ports that are not ACTIVE: %s", inactive)
-
+            LOG.warning("Instance has port that are not ACTIVE: %s", inactive)
         self.assertNotEmpty(port_map,
                             "No IPv4 addresses found in: %s" % ports)
         self.assertEqual(len(port_map), 1,
                          "Found multiple IPv4 addresses: %s. "
                          "Unable to determine which port to target."
                          % port_map)
-        return port_map[0]
+
+        return port_map[0]["id"], port_map[0]["ip"]
 
     def _get_network_by_name(self, network_name):
         net = self.os_admin.networks_client.list_networks(