From 8ec0b4390401ce62cab0ea9b3786dc487e26c9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Vancsics?= Date: Wed, 19 Jul 2017 11:48:17 +0200 Subject: [PATCH] Transform instance.resize_confirm notification The instance.resize_confirm.start and instance.resize_confirm.end notifications are transformed to the versioned framework. Change-Id: I6a51542216340299d250576714e303f74e0ceb0f Co-Authored-By: Takashi Natsume Co-Authored-By: stewie925 Co-Authored-By: MikeG451 Implements: bp versioned-notification-transformation-queens --- .../instance-resize_confirm-end.json | 18 +++++++++ .../instance-resize_confirm-start.json | 19 ++++++++++ nova/compute/manager.py | 6 +++ nova/notifications/objects/instance.py | 4 +- nova/tests/functional/api/client.py | 2 +- .../test_instance.py | 32 ++++++++++++++-- nova/tests/unit/compute/test_compute.py | 37 +++++++++++++++++-- 7 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 doc/notification_samples/instance-resize_confirm-end.json create mode 100644 doc/notification_samples/instance-resize_confirm-start.json diff --git a/doc/notification_samples/instance-resize_confirm-end.json b/doc/notification_samples/instance-resize_confirm-end.json new file mode 100644 index 000000000000..c333bb15918a --- /dev/null +++ b/doc/notification_samples/instance-resize_confirm-end.json @@ -0,0 +1,18 @@ +{ + "event_type":"instance.resize_confirm.end", + "payload": { + "$ref": "common_payloads/InstanceActionPayload.json#", + "nova_object.data": { + "flavor": { + "nova_object.data": { + "flavorid": "2", + "memory_mb": 2048, + "name": "m1.small", + "root_gb":20 + } + } + } + }, + "priority":"INFO", + "publisher_id":"nova-compute:compute" +} diff --git a/doc/notification_samples/instance-resize_confirm-start.json b/doc/notification_samples/instance-resize_confirm-start.json new file mode 100644 index 000000000000..2d440b0b4bc6 --- /dev/null +++ b/doc/notification_samples/instance-resize_confirm-start.json @@ -0,0 +1,19 @@ +{ + "event_type":"instance.resize_confirm.start", + "payload": { + "$ref": "common_payloads/InstanceActionPayload.json#", + "nova_object.data": { + "flavor": { + "nova_object.data": { + "flavorid": "2", + "memory_mb": 2048, + "name": "m1.small", + "root_gb":20 + } + }, + "state": "resized" + } + }, + "priority":"INFO", + "publisher_id":"nova-compute:compute" +} diff --git a/nova/compute/manager.py b/nova/compute/manager.py index a3f5ed69ae03..c0b75e5cb1ed 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -3685,6 +3685,9 @@ class ComputeManager(manager.Manager): """Destroys the source instance.""" self._notify_about_instance_usage(context, instance, "resize.confirm.start") + compute_utils.notify_about_instance_action(context, instance, + self.host, action=fields.NotificationAction.RESIZE_CONFIRM, + phase=fields.NotificationPhase.START) with self._error_out_instance_on_exception(context, instance): # NOTE(danms): delete stashed migration information @@ -3739,6 +3742,9 @@ class ComputeManager(manager.Manager): self._notify_about_instance_usage( context, instance, "resize.confirm.end", network_info=network_info) + compute_utils.notify_about_instance_action(context, instance, + self.host, action=fields.NotificationAction.RESIZE_CONFIRM, + phase=fields.NotificationPhase.END) def _delete_allocation_after_move(self, context, instance, migration, flavor, nodename): diff --git a/nova/notifications/objects/instance.py b/nova/notifications/objects/instance.py index 7e05f2488006..817a509d9bb2 100644 --- a/nova/notifications/objects/instance.py +++ b/nova/notifications/objects/instance.py @@ -455,8 +455,8 @@ class InstanceStateUpdatePayload(base.NotificationPayloadBase): @base.notification_sample('instance-rebuild-error.json') @base.notification_sample('instance-interface_detach-start.json') @base.notification_sample('instance-interface_detach-end.json') -# @base.notification_sample('instance-resize_confirm-start.json') -# @base.notification_sample('instance-resize_confirm-end.json') +@base.notification_sample('instance-resize_confirm-start.json') +@base.notification_sample('instance-resize_confirm-end.json') # @base.notification_sample('instance-resize_prep-start.json') @base.notification_sample('instance-resize_revert-start.json') @base.notification_sample('instance-resize_revert-end.json') diff --git a/nova/tests/functional/api/client.py b/nova/tests/functional/api/client.py index b44423a26bcf..11cbf2d2e483 100644 --- a/nova/tests/functional/api/client.py +++ b/nova/tests/functional/api/client.py @@ -220,7 +220,7 @@ class TestOpenStackClient(object): headers['Content-Type'] = 'application/json' kwargs['body'] = jsonutils.dumps(body) - kwargs.setdefault('check_response_status', [200, 201, 202]) + kwargs.setdefault('check_response_status', [200, 201, 202, 204]) return APIResponse(self.api_request(relative_uri, **kwargs)) def api_put(self, relative_uri, body, **kwargs): diff --git a/nova/tests/functional/notification_sample_tests/test_instance.py b/nova/tests/functional/notification_sample_tests/test_instance.py index 524672177bfc..35516c11ea08 100644 --- a/nova/tests/functional/notification_sample_tests/test_instance.py +++ b/nova/tests/functional/notification_sample_tests/test_instance.py @@ -257,7 +257,6 @@ class TestInstanceNotificationSample( self._test_shelve_and_shelve_offload_server, self._test_unshelve_server, self._test_resize_and_revert_server, - self._test_resize_confirm_server, self._test_snapshot_server, self._test_reboot_server, self._test_reboot_server_error, @@ -1155,8 +1154,35 @@ class TestInstanceNotificationSample( 'uuid': server['id']}, actual=fake_notifier.VERSIONED_NOTIFICATIONS[6]) - def _test_resize_confirm_server(self, server): - pass + def test_resize_confirm_server(self): + server = self._boot_a_server( + extra_params={'networks': [{'port': self.neutron.port_1['id']}]}) + self._attach_volume_to_server(server, self.cinder.SWAP_OLD_VOL) + self.admin_api.post_extra_spec( + '2', {"extra_specs": {"hw:watchdog_action": "disabled"}}) + self.flags(allow_resize_to_same_host=True) + post = {'resize': {'flavorRef': '2'}} + self.api.post_server_action(server['id'], post) + self._wait_for_state_change(self.api, server, 'VERIFY_RESIZE') + fake_notifier.reset() + + post = {'confirmResize': None} + self.api.post_server_action(server['id'], post) + self._wait_for_state_change(self.api, server, 'ACTIVE') + + self.assertEqual(2, len(fake_notifier.VERSIONED_NOTIFICATIONS)) + self._verify_notification( + 'instance-resize_confirm-start', + replacements={ + 'reservation_id': server['reservation_id'], + 'uuid': server['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[0]) + self._verify_notification( + 'instance-resize_confirm-end', + replacements={ + 'reservation_id': server['reservation_id'], + 'uuid': server['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) def _test_trigger_crash_dump(self, server): post = {'trigger_crash_dump': None} diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 71e02ba7f3d5..a3aa9a4c6fe5 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -5473,7 +5473,10 @@ class ComputeTestCase(BaseTestCase, def test_resize_instance_forced_shutdown(self): self._test_resize_instance(clean_shutdown=False) - def _test_confirm_resize(self, power_on, numa_topology=None): + @mock.patch.object(objects.BlockDeviceMappingList, 'get_by_instance_uuid') + @mock.patch.object(nova.compute.utils, 'notify_about_instance_action') + def _test_confirm_resize(self, mock_notify, mock_get_by_instance_uuid, + power_on, numa_topology=None): # Common test case method for confirm_resize def fake(*args, **kwargs): pass @@ -5482,6 +5485,9 @@ class ComputeTestCase(BaseTestCase, # Confirm the instance uses the new type in finish_resize self.assertEqual('3', instance.flavor.flavorid) + expected_bdm = objects.BlockDeviceMappingList(objects=[]) + mock_get_by_instance_uuid.return_value = expected_bdm + old_vm_state = None p_state = None if power_on: @@ -5573,15 +5579,38 @@ class ComputeTestCase(BaseTestCase, # Finally, confirm the resize and verify the new flavor is applied instance.task_state = None instance.save() - self.compute.confirm_resize(self.context, instance=instance, - reservations=[], - migration=migration) + + with mock.patch.object(objects.Instance, 'get_by_uuid', + return_value=instance) as mock_get_by_uuid: + self.compute.confirm_resize(self.context, instance=instance, + reservations=[], + migration=migration) + mock_get_by_uuid.assert_called_once_with( + self.context, instance.uuid, + expected_attrs=['metadata', 'system_metadata', 'flavor']) # Resources from the migration (based on initial flavor) should # be freed now self.assertEqual(self.rt.compute_nodes[NODENAME].memory_mb_used, memory_mb_used + new_instance_type_ref.memory_mb) + mock_notify.assert_has_calls([ + mock.call(self.context, instance, + 'fake-mini', action='resize', bdms=expected_bdm, + phase='start'), + mock.call(self.context, instance, + 'fake-mini', action='resize', bdms=expected_bdm, + phase='end'), + mock.call(self.context, instance, + 'fake-mini', action='resize_finish', bdms=expected_bdm, + phase='start'), + mock.call(self.context, instance, + 'fake-mini', action='resize_finish', bdms=expected_bdm, + phase='end'), + mock.call(self.context, instance, + 'fake-mini', action='resize_confirm', phase='start'), + mock.call(self.context, instance, + 'fake-mini', action='resize_confirm', phase='end')]) instance.refresh() flavor = objects.Flavor.get_by_id(self.context,