Added functionality to wait for port creation
Added a waiter that compares the current status
of the port to a target value and returns the port
when that is achieved.
Closes-Bug: 1845486
Change-Id: Ibc5434244f3758c60ddefa96d78476948a47ed13
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index f207066..55b39ad 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -584,6 +584,22 @@
raise lib_exc.TimeoutException()
+def wait_for_port_status(client, port_id, status):
+ """Wait for a port reach a certain status : ["BUILD" | "DOWN" | "ACTIVE"]
+ :param client: The network client to use when querying the port's
+ status
+ :param status: A string to compare the current port status-to.
+ :param port_id: The uuid of the port we would like queried for status.
+ """
+ start_time = time.time()
+ while (time.time() - start_time <= client.build_timeout):
+ result = client.show_port(port_id)
+ if result['port']['status'].lower() == status.lower():
+ return result
+ time.sleep(client.build_interval)
+ raise lib_exc.TimeoutException
+
+
def wait_for_ssh(ssh_client, timeout=30):
"""Waits for SSH connection to become usable"""
start_time = int(time.time())
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 2843498..bf3f62f 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -145,6 +145,7 @@
- 'binding:vnic_type' - defaults to CONF.network.port_vnic_type
- 'binding:profile' - defaults to CONF.network.port_profile
"""
+
if not client:
client = self.ports_client
name = data_utils.rand_name(
@@ -158,10 +159,12 @@
network_id=network_id,
**kwargs)
self.assertIsNotNone(result, 'Unable to allocate port')
- port = result['port']
+ port_id = result['port']['id']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- client.delete_port, port['id'])
- return port
+ client.delete_port, port_id)
+ port = waiters.wait_for_port_status(
+ client=client, port_id=port_id, status="DOWN")
+ return port["port"]
def create_keypair(self, client=None, **kwargs):
"""Creates keypair
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index 1d0ee77..662030e 100755
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -21,6 +21,7 @@
from tempest import exceptions
from tempest.lib import exceptions as lib_exc
from tempest.lib.services.compute import servers_client
+from tempest.lib.services.network import ports_client
from tempest.lib.services.volume.v2 import volumes_client
from tempest.tests import base
import tempest.tests.utils as utils
@@ -588,6 +589,48 @@
)
+class TestPortCreationWaiter(base.TestCase):
+ def test_wait_for_port_status(self):
+ """Test that the waiter replies with the port before the timeout"""
+
+ def client_response(self):
+ """Mock client response, replies with the final status after
+ 2 calls
+ """
+ if mock_client.call_count >= 2:
+ return mock_port
+ else:
+ mock_client.call_count += 1
+ return mock_port_build
+
+ mock_port = {'port': {'id': '1234', 'status': "DOWN"}}
+ mock_port_build = {'port': {'id': '1234', 'status': "BUILD"}}
+ mock_client = mock.Mock(
+ spec=ports_client.PortsClient,
+ build_timeout=30, build_interval=1,
+ show_port=client_response)
+ fake_port_id = "1234"
+ fake_status = "DOWN"
+ self.assertEqual(mock_port, waiters.wait_for_port_status(
+ mock_client, fake_port_id, fake_status))
+
+ def test_wait_for_port_status_timeout(self):
+ """Negative test - checking that a timeout
+ presented by a small 'fake_timeout' and a static status of
+ 'BUILD' in the mock will raise a timeout exception
+ """
+ mock_port = {'port': {'id': '1234', 'status': "BUILD"}}
+ mock_client = mock.Mock(
+ spec=ports_client.PortsClient,
+ build_timeout=2, build_interval=1,
+ show_port=lambda id: mock_port)
+ fake_port_id = "1234"
+ fake_status = "ACTIVE"
+ self.assertRaises(lib_exc.TimeoutException,
+ waiters.wait_for_port_status, mock_client,
+ fake_port_id, fake_status)
+
+
class TestServerFloatingIPWaiters(base.TestCase):
def test_wait_for_server_floating_ip_associate_timeout(self):