@@ -8850,6 +8850,68 @@ def doit(mock_pr, mock_r):
8850
8850
8851
8851
doit ()
8852
8852
8853
+ def test_prep_resize_fails_unable_to_migrate_to_self (self ):
8854
+ """Asserts that _prep_resize handles UnableToMigrateToSelf when
8855
+ _prep_resize is called on the host on which the instance lives and
8856
+ the flavor is not changing.
8857
+ """
8858
+ instance = fake_instance .fake_instance_obj (
8859
+ self .context , host = self .compute .host ,
8860
+ expected_attrs = ['system_metadata' , 'flavor' ])
8861
+ migration = mock .MagicMock (spec = 'nova.objects.Migration' )
8862
+ with mock .patch .dict (self .compute .driver .capabilities ,
8863
+ {'supports_migrate_to_same_host' : False }):
8864
+ ex = self .assertRaises (
8865
+ exception .InstanceFaultRollback , self .compute ._prep_resize ,
8866
+ self .context , instance .image_meta , instance , instance .flavor ,
8867
+ filter_properties = {}, node = instance .node , migration = migration )
8868
+ self .assertIsInstance (
8869
+ ex .inner_exception , exception .UnableToMigrateToSelf )
8870
+
8871
+ @mock .patch ('nova.compute.utils.notify_usage_exists' )
8872
+ @mock .patch ('nova.compute.manager.ComputeManager.'
8873
+ '_notify_about_instance_usage' )
8874
+ @mock .patch ('nova.compute.utils.notify_about_resize_prep_instance' )
8875
+ @mock .patch ('nova.objects.Instance.save' )
8876
+ @mock .patch ('nova.compute.manager.ComputeManager._revert_allocation' )
8877
+ @mock .patch ('nova.compute.manager.ComputeManager.'
8878
+ '_reschedule_resize_or_reraise' )
8879
+ @mock .patch ('nova.compute.utils.add_instance_fault_from_exc' )
8880
+ def test_prep_resize_fails_rollback (
8881
+ self , add_instance_fault_from_exc , _reschedule_resize_or_reraise ,
8882
+ _revert_allocation , mock_instance_save ,
8883
+ notify_about_resize_prep_instance , _notify_about_instance_usage ,
8884
+ notify_usage_exists ):
8885
+ """Tests that if _prep_resize raises InstanceFaultRollback, the
8886
+ instance.vm_state is reset properly in _error_out_instance_on_exception
8887
+ """
8888
+ instance = fake_instance .fake_instance_obj (
8889
+ self .context , host = self .compute .host , vm_state = vm_states .STOPPED ,
8890
+ expected_attrs = ['system_metadata' , 'flavor' ])
8891
+ migration = mock .MagicMock (spec = 'nova.objects.Migration' )
8892
+ request_spec = mock .MagicMock (spec = 'nova.objects.RequestSpec' )
8893
+ ex = exception .InstanceFaultRollback (
8894
+ inner_exception = exception .UnableToMigrateToSelf (
8895
+ instance_id = instance .uuid , host = instance .host ))
8896
+
8897
+ def fake_reschedule_resize_or_reraise (* args , ** kwargs ):
8898
+ raise ex
8899
+
8900
+ _reschedule_resize_or_reraise .side_effect = (
8901
+ fake_reschedule_resize_or_reraise )
8902
+
8903
+ with mock .patch .object (self .compute , '_prep_resize' , side_effect = ex ):
8904
+ self .assertRaises (
8905
+ # _error_out_instance_on_exception should reraise the
8906
+ # UnableToMigrateToSelf inside InstanceFaultRollback.
8907
+ exception .UnableToMigrateToSelf , self .compute .prep_resize ,
8908
+ self .context , instance .image_meta , instance , instance .flavor ,
8909
+ request_spec , filter_properties = {}, node = instance .node ,
8910
+ clean_shutdown = True , migration = migration , host_list = [])
8911
+ # The instance.vm_state should remain unchanged
8912
+ # (_error_out_instance_on_exception will set to ACTIVE by default).
8913
+ self .assertEqual (vm_states .STOPPED , instance .vm_state )
8914
+
8853
8915
def test_get_updated_nw_info_with_pci_mapping (self ):
8854
8916
old_dev = objects .PciDevice (address = '0000:04:00.2' )
8855
8917
new_dev = objects .PciDevice (address = '0000:05:00.3' )
0 commit comments