@@ -3923,7 +3923,8 @@ def fake_get_node(context, host, node):
3923
3923
# both instance_1 and instance_2 is destroyed in the driver
3924
3924
destroy .assert_has_calls (
3925
3925
[mock .call (self .context , instance_1 , None , {}, True ),
3926
- mock .call (self .context , instance_2 , None , {}, True )])
3926
+ mock .call (self .context , instance_2 , None , {}, True )],
3927
+ any_order = True )
3927
3928
3928
3929
# but only instance_2 is deallocated as the compute node for
3929
3930
# instance_1 is already deleted
@@ -3932,6 +3933,91 @@ def fake_get_node(context, host, node):
3932
3933
3933
3934
self .assertEqual (2 , get_node .call_count )
3934
3935
3936
+ def test_destroy_evacuated_instances_not_on_hypervisor (self ):
3937
+ our_host = self .compute .host
3938
+ flavor = objects .Flavor ()
3939
+ instance_1 = objects .Instance (self .context , flavor = flavor )
3940
+ instance_1 .uuid = uuids .instance_1
3941
+ instance_1 .task_state = None
3942
+ instance_1 .vm_state = vm_states .ACTIVE
3943
+ instance_1 .host = 'not-' + our_host
3944
+ instance_1 .user_id = uuids .user_id
3945
+ instance_1 .project_id = uuids .project_id
3946
+ instance_1 .deleted = False
3947
+
3948
+ migration_1 = objects .Migration (instance_uuid = instance_1 .uuid )
3949
+ migration_1 .status = 'done'
3950
+ migration_1 .source_node = 'our-node'
3951
+
3952
+ our_node = objects .ComputeNode (
3953
+ host = our_host , uuid = uuids .our_node_uuid )
3954
+
3955
+ with test .nested (
3956
+ mock .patch .object (self .compute , '_get_instances_on_driver' ,
3957
+ return_value = []),
3958
+ mock .patch .object (self .compute .driver , 'destroy' ),
3959
+ mock .patch ('nova.objects.MigrationList.get_by_filters' ),
3960
+ mock .patch ('nova.objects.Migration.save' ),
3961
+ mock .patch ('nova.objects.ComputeNode.get_by_host_and_nodename' ),
3962
+ mock .patch ('nova.scheduler.utils.resources_from_flavor' ),
3963
+ mock .patch .object (self .compute .reportclient ,
3964
+ 'remove_provider_tree_from_instance_allocation' ),
3965
+ mock .patch ('nova.objects.Instance.get_by_uuid' )
3966
+ ) as (_get_intances_on_driver , destroy , migration_list , migration_save ,
3967
+ get_node , get_resources , remove_allocation ,
3968
+ instance_get_by_uuid ):
3969
+ migration_list .return_value = [migration_1 ]
3970
+ instance_get_by_uuid .return_value = instance_1
3971
+ get_node .return_value = our_node
3972
+ get_resources .return_value = mock .sentinel .resources
3973
+
3974
+ self .compute ._destroy_evacuated_instances (self .context )
3975
+
3976
+ # nothing to be destroyed as the driver returned no instances on
3977
+ # the hypervisor
3978
+ self .assertFalse (destroy .called )
3979
+
3980
+ # but our only instance still cleaned up in placement
3981
+ remove_allocation .assert_called_once_with (
3982
+ self .context , instance_1 .uuid , uuids .our_node_uuid )
3983
+ instance_get_by_uuid .assert_called_once_with (
3984
+ self .context , instance_1 .uuid )
3985
+ get_node .assert_called_once_with (
3986
+ self .context , our_host , 'our-node' )
3987
+
3988
+ def test_destroy_evacuated_instances_not_on_hyp_and_instance_deleted (self ):
3989
+ migration_1 = objects .Migration (instance_uuid = uuids .instance_1 )
3990
+ migration_1 .status = 'done'
3991
+ migration_1 .source_node = 'our-node'
3992
+
3993
+ with test .nested (
3994
+ mock .patch .object (self .compute , '_get_instances_on_driver' ,
3995
+ return_value = []),
3996
+ mock .patch .object (self .compute .driver , 'destroy' ),
3997
+ mock .patch ('nova.objects.MigrationList.get_by_filters' ),
3998
+ mock .patch ('nova.objects.Migration.save' ),
3999
+ mock .patch ('nova.scheduler.utils.resources_from_flavor' ),
4000
+ mock .patch .object (self .compute .reportclient ,
4001
+ 'remove_provider_tree_from_instance_allocation' ),
4002
+ mock .patch ('nova.objects.Instance.get_by_uuid' )
4003
+ ) as (_get_instances_on_driver ,
4004
+ destroy , migration_list , migration_save , get_resources ,
4005
+ remove_allocation , instance_get_by_uuid ):
4006
+ migration_list .return_value = [migration_1 ]
4007
+ instance_get_by_uuid .side_effect = exception .InstanceNotFound (
4008
+ instance_id = uuids .instance_1 )
4009
+
4010
+ self .compute ._destroy_evacuated_instances (self .context )
4011
+
4012
+ # nothing to be destroyed as the driver returned no instances on
4013
+ # the hypervisor
4014
+ self .assertFalse (destroy .called )
4015
+
4016
+ instance_get_by_uuid .assert_called_once_with (
4017
+ self .context , uuids .instance_1 )
4018
+ # nothing to be cleaned as the instance was deleted already
4019
+ self .assertFalse (remove_allocation .called )
4020
+
3935
4021
@mock .patch ('nova.compute.manager.ComputeManager.'
3936
4022
'_destroy_evacuated_instances' )
3937
4023
@mock .patch ('nova.compute.manager.LOG' )
0 commit comments