Merge "Add floating IP waiter"
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 33ed153..1b69349 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -541,3 +541,45 @@
server_id)
return
time.sleep(client.build_interval)
+
+
+def wait_for_server_floating_ip(servers_client, server, floating_ip,
+ wait_for_disassociate=False):
+ """Wait for floating IP association or disassociation.
+
+ :param servers_client: The servers client to use when querying the server's
+ floating IPs.
+ :param server: The server JSON dict on which to wait.
+ :param floating_ip: The floating IP JSON dict on which to wait.
+ :param wait_for_disassociate: Boolean indiating whether to wait for
+ disassociation instead of association.
+ """
+
+ def _get_floating_ip_in_server_addresses(floating_ip, server):
+ for addresses in server['addresses'].values():
+ for address in addresses:
+ if (
+ address['OS-EXT-IPS:type'] == 'floating' and
+ address['addr'] == floating_ip['floating_ip_address']
+ ):
+ return address
+ return None
+
+ start_time = int(time.time())
+ while True:
+ server = servers_client.show_server(server['id'])['server']
+ address = _get_floating_ip_in_server_addresses(floating_ip, server)
+ if address is None and wait_for_disassociate:
+ return None
+ if not wait_for_disassociate and address:
+ return address
+
+ if int(time.time()) - start_time >= servers_client.build_timeout:
+ if wait_for_disassociate:
+ msg = ('Floating ip %s failed to disassociate from server %s '
+ 'in time.' % (floating_ip, server['id']))
+ else:
+ msg = ('Floating ip %s failed to associate with server %s '
+ 'in time.' % (floating_ip, server['id']))
+ raise lib_exc.TimeoutException(msg)
+ time.sleep(servers_client.build_interval)
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 2c981c8..5aac19c 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -96,13 +96,6 @@
'%s' % (secgroup['id'], server['id']))
raise exceptions.TimeoutException(msg)
- def _get_floating_ip_in_server_addresses(self, floating_ip, server):
- for addresses in server['addresses'].values():
- for address in addresses:
- if (address['OS-EXT-IPS:type'] == 'floating' and
- address['addr'] == floating_ip['floating_ip_address']):
- return address
-
@decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
@utils.services('compute', 'volume', 'image', 'network')
def test_minimum_basic_scenario(self):
@@ -132,15 +125,8 @@
fip = self.create_floating_ip(server)
floating_ip = self.associate_floating_ip(
fip, server)
- # fetch the server again to make sure the addresses were refreshed
- # after associating the floating IP
- server = self.servers_client.show_server(server['id'])['server']
- address = self._get_floating_ip_in_server_addresses(
- floating_ip, server)
- self.assertIsNotNone(
- address,
- "Failed to find floating IP '%s' in server addresses: %s" %
- (floating_ip['floating_ip_address'], server['addresses']))
+ waiters.wait_for_server_floating_ip(self.servers_client,
+ server, floating_ip)
ssh_ip = floating_ip['floating_ip_address']
else:
ssh_ip = self.get_server_ip(server)
@@ -165,19 +151,6 @@
if floating_ip:
# delete the floating IP, this should refresh the server addresses
self.disassociate_floating_ip(floating_ip)
-
- def is_floating_ip_detached_from_server():
- server_info = self.servers_client.show_server(
- server['id'])['server']
- address = self._get_floating_ip_in_server_addresses(
- floating_ip, server_info)
- return (not address)
-
- if not test_utils.call_until_true(
- is_floating_ip_detached_from_server,
- CONF.compute.build_timeout,
- CONF.compute.build_interval):
- msg = ("Floating IP '%s' should not be in server addresses: %s"
- % (floating_ip['floating_ip_address'],
- server['addresses']))
- raise exceptions.TimeoutException(msg)
+ waiters.wait_for_server_floating_ip(
+ self.servers_client, server, floating_ip,
+ wait_for_disassociate=True)
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index a5016e2..b76a263 100755
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -552,3 +552,37 @@
# Assert that list_volume_attachments was actually called
mock_list_volume_attachments.assert_called_once_with(
mock.sentinel.server_id)
+
+
+class TestServerFloatingIPWaiters(base.TestCase):
+
+ def test_wait_for_server_floating_ip_associate_timeout(self):
+ mock_server = {'server': {'id': 'fake_uuid', 'addresses': {}}}
+ mock_client = mock.Mock(
+ spec=servers_client.ServersClient,
+ build_timeout=1, build_interval=1,
+ show_server=lambda id: mock_server)
+
+ fake_server = {'id': 'fake-uuid'}
+ fake_fip = {'floating_ip_address': 'fake_address'}
+ self.assertRaises(
+ lib_exc.TimeoutException,
+ waiters.wait_for_server_floating_ip, mock_client, fake_server,
+ fake_fip)
+
+ def test_wait_for_server_floating_ip_disassociate_timeout(self):
+ mock_addresses = {'shared': [{'OS-EXT-IPS:type': 'floating',
+ 'addr': 'fake_address'}]}
+ mock_server = {'server': {'id': 'fake_uuid',
+ 'addresses': mock_addresses}}
+ mock_client = mock.Mock(
+ spec=servers_client.ServersClient,
+ build_timeout=1, build_interval=1,
+ show_server=lambda id: mock_server)
+
+ fake_server = {'id': 'fake-uuid'}
+ fake_fip = {'floating_ip_address': 'fake_address'}
+ self.assertRaises(
+ lib_exc.TimeoutException,
+ waiters.wait_for_server_floating_ip, mock_client, fake_server,
+ fake_fip, wait_for_disassociate=True)