From da48e4ee3d61088b6087adccbd0a70a8fd966231 Mon Sep 17 00:00:00 2001 From: Artom Lifshitz Date: Mon, 22 Nov 2021 15:59:15 -0500 Subject: [PATCH] wait_for_server_status(): report original request ID if failure If waiting for a server to reach a particular status fails - for example, a server never reaches ACTIVE after boot - the most useful piece of information when debugging the failure is the orignal request ID - in our example, the request ID of the original POST /servers request. This patch makes create_server() remember the original server boot request ID, and wires that value up into wait_for_server_status(), so that the latter can log it if the wait fails. Because we have to remain compatible with calls to wait_for_server_status() that do not pass a request_id, there's some conditional logic to only log it if it was passed in. Similar mechanics can, in the future, be added to other areas where tests can fail, for example for live migration or resizing, or attaching a port to an server. Change-Id: I3d5aa41d96f7fa4fc860ed9d1076a247d5fa7bf6 --- tempest/common/compute.py | 4 +++- tempest/common/waiters.py | 14 +++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tempest/common/compute.py b/tempest/common/compute.py index a062f6f0f3..2443a67530 100644 --- a/tempest/common/compute.py +++ b/tempest/common/compute.py @@ -197,6 +197,7 @@ def create_test_server(clients, validatable=False, validation_resources=None, body = clients.servers_client.create_server(name=name, imageRef=image_id, flavorRef=flavor, **kwargs) + request_id = body.response['x-openstack-request-id'] # handle the case of multiple servers if multiple_create_request: @@ -234,7 +235,8 @@ def create_test_server(clients, validatable=False, validation_resources=None, for server in servers: try: waiters.wait_for_server_status( - clients.servers_client, server['id'], wait_until) + clients.servers_client, server['id'], wait_until, + request_id=request_id) # Multiple validatable servers are not supported for now. Their # creation will fail with the condition above. diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py index 33ed1532cf..b34bfac61c 100644 --- a/tempest/common/waiters.py +++ b/tempest/common/waiters.py @@ -32,7 +32,8 @@ def _get_task_state(body): # NOTE(afazekas): This function needs to know a token and a subject. def wait_for_server_status(client, server_id, status, ready_wait=True, - extra_timeout=0, raise_on_error=True): + extra_timeout=0, raise_on_error=True, + request_id=None): """Waits for a server to reach a given status.""" # NOTE(afazekas): UNKNOWN status possible on ERROR @@ -71,11 +72,12 @@ def wait_for_server_status(client, server_id, status, ready_wait=True, '/'.join((server_status, str(task_state))), time.time() - start_time) if (server_status == 'ERROR') and raise_on_error: + details = '' if 'fault' in body: - raise exceptions.BuildErrorException(body['fault'], - server_id=server_id) - else: - raise exceptions.BuildErrorException(server_id=server_id) + details += 'Fault: %s.' % body['fault'] + if request_id: + details += ' Server boot request ID: %s.' % request_id + raise exceptions.BuildErrorException(details, server_id=server_id) timed_out = int(time.time()) - start_time >= timeout @@ -88,6 +90,8 @@ def wait_for_server_status(client, server_id, status, ready_wait=True, 'status': status, 'expected_task_state': expected_task_state, 'timeout': timeout}) + if request_id: + message += ' Server boot request ID: %s.' % request_id message += ' Current status: %s.' % server_status message += ' Current task state: %s.' % task_state caller = test_utils.find_test_caller()