From 211e9b1961a14e22b39194fdd90e40738fc27202 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Thu, 5 Oct 2017 19:19:36 -0400 Subject: [PATCH] Implement power_off/power_on for the FakeDriver When trying to recreate hundreds of instance action events for scale testing with the FakeDriver, a nice simple way to do that is by stopping those instances and starting them again. However, since power_off/on aren't implemented, once you "stop" them the sync_instance_power_state periodic task in the compute manager thinks they are still running on the "hypervisor" and will stop them again via the API, which records yet another instance action and set of events. This just toggles the power state bit on the fake instance in the FakeDriver to make the periodic task do the right thing. As a result, we also have more realistic API and notification samples. Change-Id: Ie621686053ad774c4ae4f22bb2a455f98900b611 --- doc/api_samples/os-rescue/server-get-resp-rescue.json | 2 +- .../os-rescue/server-get-resp-unrescue.json | 2 +- doc/notification_samples/instance-power_on-start.json | 2 +- doc/notification_samples/instance-shelve-end.json | 2 +- .../instance-shelve_offload-end.json | 2 +- .../instance-shelve_offload-start.json | 2 +- doc/notification_samples/instance-unshelve-start.json | 2 +- .../os-rescue/server-get-resp-rescue.json.tpl | 2 +- .../os-rescue/server-get-resp-unrescue.json.tpl | 2 +- .../notification_sample_tests/test_instance.py | 1 - nova/tests/unit/compute/test_compute.py | 9 ++++++--- nova/virt/fake.py | 10 ++++++++-- 12 files changed, 23 insertions(+), 15 deletions(-) diff --git a/doc/api_samples/os-rescue/server-get-resp-rescue.json b/doc/api_samples/os-rescue/server-get-resp-rescue.json index 62e741a43408..8780bc668d31 100644 --- a/doc/api_samples/os-rescue/server-get-resp-rescue.json +++ b/doc/api_samples/os-rescue/server-get-resp-rescue.json @@ -58,7 +58,7 @@ "OS-EXT-SRV-ATTR:host": "b8b357f7100d4391828f2177c922ef93", "OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini", "OS-EXT-SRV-ATTR:instance_name": "instance-00000001", - "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:power_state": 4, "OS-EXT-STS:task_state": null, "OS-EXT-STS:vm_state": "rescued", "os-extended-volumes:volumes_attached": [], diff --git a/doc/api_samples/os-rescue/server-get-resp-unrescue.json b/doc/api_samples/os-rescue/server-get-resp-unrescue.json index a8c9f271aaf7..0dd02e07fa47 100644 --- a/doc/api_samples/os-rescue/server-get-resp-unrescue.json +++ b/doc/api_samples/os-rescue/server-get-resp-unrescue.json @@ -59,7 +59,7 @@ "OS-EXT-SRV-ATTR:host": "b8b357f7100d4391828f2177c922ef93", "OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini", "OS-EXT-SRV-ATTR:instance_name": "instance-00000001", - "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:power_state": 4, "OS-EXT-STS:task_state": null, "OS-EXT-STS:vm_state": "active", "os-extended-volumes:volumes_attached": [], diff --git a/doc/notification_samples/instance-power_on-start.json b/doc/notification_samples/instance-power_on-start.json index d11174083521..4da4d3e3bac8 100644 --- a/doc/notification_samples/instance-power_on-start.json +++ b/doc/notification_samples/instance-power_on-start.json @@ -50,7 +50,7 @@ "reservation_id":"r-npxv0e40", "state":"stopped", "task_state":"powering-on", - "power_state":"running", + "power_state":"shutdown", "tenant_id":"6f70656e737461636b20342065766572", "terminated_at":null, "auto_disk_config":"MANUAL", diff --git a/doc/notification_samples/instance-shelve-end.json b/doc/notification_samples/instance-shelve-end.json index d4fa1637e21c..7a6afb9f25e0 100644 --- a/doc/notification_samples/instance-shelve-end.json +++ b/doc/notification_samples/instance-shelve-end.json @@ -50,7 +50,7 @@ "reservation_id":"r-npxv0e40", "state":"shelved", "task_state":null, - "power_state":"running", + "power_state":"shutdown", "tenant_id":"6f70656e737461636b20342065766572", "terminated_at":null, "auto_disk_config":"MANUAL", diff --git a/doc/notification_samples/instance-shelve_offload-end.json b/doc/notification_samples/instance-shelve_offload-end.json index b82bf474747d..2a8ae4b4e929 100644 --- a/doc/notification_samples/instance-shelve_offload-end.json +++ b/doc/notification_samples/instance-shelve_offload-end.json @@ -50,7 +50,7 @@ "reservation_id":"r-npxv0e40", "state":"shelved_offloaded", "task_state":null, - "power_state":"running", + "power_state":"shutdown", "tenant_id":"6f70656e737461636b20342065766572", "terminated_at":null, "auto_disk_config":"MANUAL", diff --git a/doc/notification_samples/instance-shelve_offload-start.json b/doc/notification_samples/instance-shelve_offload-start.json index 4a1bccc07a7d..4376b8391f60 100644 --- a/doc/notification_samples/instance-shelve_offload-start.json +++ b/doc/notification_samples/instance-shelve_offload-start.json @@ -50,7 +50,7 @@ "reservation_id":"r-npxv0e40", "state":"shelved", "task_state":"shelving_offloading", - "power_state":"running", + "power_state":"shutdown", "tenant_id":"6f70656e737461636b20342065766572", "terminated_at":null, "auto_disk_config":"MANUAL", diff --git a/doc/notification_samples/instance-unshelve-start.json b/doc/notification_samples/instance-unshelve-start.json index 3ef368d922b2..da1637cc40c7 100644 --- a/doc/notification_samples/instance-unshelve-start.json +++ b/doc/notification_samples/instance-unshelve-start.json @@ -50,7 +50,7 @@ "reservation_id":"r-npxv0e40", "state":"shelved_offloaded", "task_state":"unshelving", - "power_state":"running", + "power_state":"shutdown", "tenant_id":"6f70656e737461636b20342065766572", "terminated_at":null, "auto_disk_config":"MANUAL", diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-rescue.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-rescue.json.tpl index bcd663f275a0..8f1ae997c0fe 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-rescue.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-rescue.json.tpl @@ -58,7 +58,7 @@ "OS-EXT-SRV-ATTR:host": "%(compute_host)s", "OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s", "OS-EXT-SRV-ATTR:instance_name": "%(instance_name)s", - "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:power_state": 4, "OS-EXT-STS:task_state": null, "OS-EXT-STS:vm_state": "rescued", "os-extended-volumes:volumes_attached": [], diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-unrescue.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-unrescue.json.tpl index 3240c49372ab..dcf8c453b8f6 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-unrescue.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-rescue/server-get-resp-unrescue.json.tpl @@ -59,7 +59,7 @@ "OS-EXT-SRV-ATTR:host": "%(compute_host)s", "OS-EXT-SRV-ATTR:hypervisor_hostname": "%(hypervisor_hostname)s", "OS-EXT-SRV-ATTR:instance_name": "%(instance_name)s", - "OS-EXT-STS:power_state": 1, + "OS-EXT-STS:power_state": 4, "OS-EXT-STS:task_state": null, "OS-EXT-STS:vm_state": "active", "os-extended-volumes:volumes_attached": [], diff --git a/nova/tests/functional/notification_sample_tests/test_instance.py b/nova/tests/functional/notification_sample_tests/test_instance.py index c824587506d2..1356433ea5db 100644 --- a/nova/tests/functional/notification_sample_tests/test_instance.py +++ b/nova/tests/functional/notification_sample_tests/test_instance.py @@ -425,7 +425,6 @@ class TestInstanceNotificationSample( 'instance-power_off-end', replacements={ 'reservation_id': server['reservation_id'], - 'power_state': 'running', 'uuid': server['id']}, actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 0f427068bc5e..b26c9b9baeb3 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -2407,9 +2407,10 @@ class ComputeTestCase(BaseTestCase, self.compute.terminate_instance(self.context, instance, [], []) + @mock.patch.object(fake.FakeDriver, 'power_off') @mock.patch.object(fake.FakeDriver, 'rescue') @mock.patch.object(compute_manager.ComputeManager, '_get_rescue_image') - def test_rescue_handle_err(self, mock_get, mock_rescue): + def test_rescue_handle_err(self, mock_get, mock_rescue, mock_power_off): # If the driver fails to rescue, instance state should got to ERROR # and the exception should be converted to InstanceNotRescuable inst_obj = self._create_fake_instance_obj() @@ -2432,8 +2433,9 @@ class ComputeTestCase(BaseTestCase, mock.ANY, 'password') @mock.patch.object(image_api.API, "get") + @mock.patch.object(fake.FakeDriver, 'power_off') @mock.patch.object(nova.virt.fake.FakeDriver, "rescue") - def test_rescue_with_image_specified(self, mock_rescue, + def test_rescue_with_image_specified(self, mock_rescue, mock_power_off, mock_image_get): image_ref = uuids.image_instance rescue_image_meta = {} @@ -2457,9 +2459,10 @@ class ComputeTestCase(BaseTestCase, self.compute.terminate_instance(ctxt, instance, [], []) @mock.patch.object(image_api.API, "get") + @mock.patch.object(fake.FakeDriver, 'power_off') @mock.patch.object(nova.virt.fake.FakeDriver, "rescue") def test_rescue_with_base_image_when_image_not_specified(self, - mock_rescue, mock_image_get): + mock_rescue, mock_power_off, mock_image_get): image_ref = FAKE_IMAGE_REF system_meta = {"image_base_image_ref": image_ref} rescue_image_meta = {} diff --git a/nova/virt/fake.py b/nova/virt/fake.py index c86ed093d644..a2f57507bc49 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -244,11 +244,17 @@ class FakeDriver(driver.ComputeDriver): pass def power_off(self, instance, timeout=0, retry_interval=0): - pass + if instance.uuid in self.instances: + self.instances[instance.uuid].state = power_state.SHUTDOWN + else: + raise exception.InstanceNotFound(instance_id=instance.uuid) def power_on(self, context, instance, network_info, block_device_info=None): - pass + if instance.uuid in self.instances: + self.instances[instance.uuid].state = power_state.RUNNING + else: + raise exception.InstanceNotFound(instance_id=instance.uuid) def trigger_crash_dump(self, instance): pass