diff --git a/nova/tests/functional/integrated_helpers.py b/nova/tests/functional/integrated_helpers.py index dd058769f6d9..5c8d657d6cc0 100644 --- a/nova/tests/functional/integrated_helpers.py +++ b/nova/tests/functional/integrated_helpers.py @@ -27,6 +27,7 @@ import os_traits from oslo_log import log as logging from oslo_utils.fixture import uuidsentinel as uuids +from nova.compute import instance_actions from nova.compute import utils as compute_utils import nova.conf from nova import context @@ -309,12 +310,21 @@ class InstanceHelperMixin(object): """ if api is None: api = self.api - completion_event = None + return self._wait_for_instance_action_event( + api, server, expected_action, event_name, event_result='error') + + def _wait_for_instance_action_event( + self, api, server, action_name, event_name, event_result): + """Polls the instance action events for the given instance, action, + event, and event result until it finds the event. + """ + actions = [] + events = [] for attempt in range(10): actions = api.get_instance_actions(server['id']) - # Look for the migrate action. + # The API returns the newest event first for action in actions: - if action['action'] == expected_action: + if action['action'] == action_name: events = ( api.api_get( '/servers/%s/os-instance-actions/%s' % @@ -322,21 +332,18 @@ class InstanceHelperMixin(object): ).body['instanceAction']['events']) # Look for the action event being in error state. for event in events: + result = event['result'] if (event['event'] == event_name and - event['result'] is not None and - event['result'].lower() == 'error'): - completion_event = event - # Break out of the events loop. - break - if completion_event: - # Break out of the actions loop. - break + result is not None and + result.lower() == event_result.lower()): + return event # We didn't find the completion event yet, so wait a bit. time.sleep(0.5) - if completion_event is None: - self.fail('Timed out waiting for %s failure event. Current ' - 'instance actions: %s' % (event_name, actions)) + self.fail( + 'Timed out waiting for %s instance action event. Current instance ' + 'actions: %s. Events in the last matching action: %s' + % (event_name, actions, events)) def _wait_for_migration_status(self, server, expected_statuses): """Waits for a migration record with the given statuses to be found @@ -912,3 +919,11 @@ class ProviderUsageBaseTestCase(test.TestCase, InstanceHelperMixin): # Account for reserved_host_cpus. expected_vcpu_usage = CONF.reserved_host_cpus + flavor['vcpus'] self.assertEqual(expected_vcpu_usage, hypervisor['vcpus_used']) + + def _confirm_resize(self, server): + self.api.post_server_action(server['id'], {'confirmResize': None}) + server = self._wait_for_state_change(self.api, server, 'ACTIVE') + self._wait_for_instance_action_event( + self.api, server, instance_actions.CONFIRM_RESIZE, + 'compute_confirm_resize', 'success') + return server diff --git a/nova/tests/functional/test_servers.py b/nova/tests/functional/test_servers.py index 7f99754d1bcc..914129258688 100644 --- a/nova/tests/functional/test_servers.py +++ b/nova/tests/functional/test_servers.py @@ -1811,10 +1811,7 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): source_rp_uuid, dest_rp_uuid) # Confirm the resize and check the usages - post = {'confirmResize': None} - self.api.post_server_action( - server['id'], post, check_response_status=[204]) - self._wait_for_state_change(self.api, server, 'ACTIVE') + self._confirm_resize(server) # After confirming, we should have an allocation only on the # destination host @@ -1889,10 +1886,7 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): server, self.flavor2, self.flavor3, rp_uuid) # Confirm the resize and check the usages - post = {'confirmResize': None} - self.api.post_server_action( - server['id'], post, check_response_status=[204]) - self._wait_for_state_change(self.api, server, 'ACTIVE') + self._confirm_resize(server) self._run_periodics() @@ -2020,8 +2014,7 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): dest_rp_uuid, self.flavor2, volume_backed=False) # Now confirm the resize and check hypervisor usage again. - self.api.post_server_action(server['id'], {'confirmResize': None}) - self._wait_for_state_change(self.api, server, 'ACTIVE') + self._confirm_resize(server) # There should no resource usage for flavor1 on the source host. self.assert_hypervisor_usage( @@ -3125,11 +3118,7 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): self._wait_for_state_change(self.api, created_server, 'VERIFY_RESIZE') # Confirm the resize - post = {'confirmResize': None} - self.api.post_server_action( - created_server['id'], post, check_response_status=[204]) - new_server = self._wait_for_state_change(self.api, created_server, - 'ACTIVE') + new_server = self._confirm_resize(created_server) inst_dest_host = new_server["OS-EXT-SRV-ATTR:host"] self.assertEqual(dest_hostname, inst_dest_host) @@ -3300,10 +3289,7 @@ class ServerMovingTests(integrated_helpers.ProviderUsageBaseTestCase): server, self.flavor1, source_rp_uuid, dest_rp_uuid) # Confirm the move and check the usages - post = {'confirmResize': None} - self.api.post_server_action( - server['id'], post, check_response_status=[204]) - self._wait_for_state_change(self.api, server, 'ACTIVE') + self._confirm_resize(server) def _check_allocation(): # the target host usage should be according to the flavor @@ -3951,8 +3937,7 @@ class VolumeBackedServerTest(integrated_helpers.ProviderUsageBaseTestCase): self.admin_api, server, 'VERIFY_RESIZE') self.assertEqual('host2', server['OS-EXT-SRV-ATTR:host']) # Confirm the cold migration and check usage and the request spec. - self.api.post_server_action(server['id'], {'confirmResize': None}) - self._wait_for_state_change(self.api, server, 'ACTIVE') + self._confirm_resize(server) reqspec = objects.RequestSpec.get_by_instance_uuid(ctxt, server['id']) # Make sure it's set. self.assertTrue(reqspec.is_bfv) @@ -6552,9 +6537,7 @@ class ServerMoveWithPortResourceRequestTest( server, compute3_rp_uuid, non_qos_port, qos_port, migration_uuid, source_compute_rp_uuid=self.compute1_rp_uuid) - self.api.post_server_action(server['id'], {'confirmResize': None}) - self._wait_for_migration_status(server, ['confirmed']) - + self._confirm_resize(server) # check that allocation is still OK self._check_allocation( server, compute3_rp_uuid, non_qos_port, qos_port) @@ -6585,8 +6568,7 @@ class ServerMoveWithPortResourceRequestTest( server, self.compute2_rp_uuid, non_qos_port, qos_port, migration_uuid, source_compute_rp_uuid=self.compute1_rp_uuid) - self.api.post_server_action(server['id'], {'confirmResize': None}) - self._wait_for_migration_status(server, ['confirmed']) + self._confirm_resize(server) # check that allocation is still OK self._check_allocation(