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