From aa8d42c51d2a1ce122b9b515f1300769583e1617 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 13 Nov 2024 07:21:46 -0800 Subject: [PATCH] Allow wait_for_image_status() to have multiple This lets us wait for one of multiple target states so we can more effectively avoid race conditions where we miss an intermediate state and first poll the final one. Change-Id: If12c35d38c03fa329ebbf536e2fcd3ff2bd136de --- .../image-wait-multiple-79c55305b584b1ba.yaml | 6 ++++++ tempest/common/waiters.py | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/image-wait-multiple-79c55305b584b1ba.yaml diff --git a/releasenotes/notes/image-wait-multiple-79c55305b584b1ba.yaml b/releasenotes/notes/image-wait-multiple-79c55305b584b1ba.yaml new file mode 100644 index 0000000000..6f63ebd3f3 --- /dev/null +++ b/releasenotes/notes/image-wait-multiple-79c55305b584b1ba.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The wait_for_image_status() waiter now allows a list of status values + instead of just a string, and returns the state the image was in when we + stopped waiting. diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py index 9e97f4797e..85006930ae 100644 --- a/tempest/common/waiters.py +++ b/tempest/common/waiters.py @@ -154,13 +154,21 @@ def wait_for_server_termination(client, server_id, ignore_error=False, def wait_for_image_status(client, image_id, status): - """Waits for an image to reach a given status. + """Waits for an image to reach a given status (or list of them). The client should have a show_image(image_id) method to get the image. The client should also have build_interval and build_timeout attributes. + + status can be either a string or a list of strings that constitute a + terminal state that we will return. """ show_image = client.show_image + if isinstance(status, str): + terminal_status = [status] + else: + terminal_status = status + current_status = 'An unknown status' start = int(time.time()) while int(time.time()) - start < client.build_timeout: @@ -171,8 +179,8 @@ def wait_for_image_status(client, image_id, status): image = image['image'] current_status = image['status'] - if current_status == status: - return + if current_status in terminal_status: + return current_status if current_status.lower() == 'killed': raise exceptions.ImageKilledException(image_id=image_id, status=status) @@ -184,7 +192,7 @@ def wait_for_image_status(client, image_id, status): message = ('Image %(image_id)s failed to reach %(status)s state ' '(current state %(current_status)s) within the required ' 'time (%(timeout)s s).' % {'image_id': image_id, - 'status': status, + 'status': ','.join(terminal_status), 'current_status': current_status, 'timeout': client.build_timeout}) caller = test_utils.find_test_caller()