Skip to content

Commit

Permalink
Functional test from VM remove event
Browse files Browse the repository at this point in the history
Depends-On: I87cf8f4ab6d6b584b406f6240e51896324f18174
Change-Id: Ie08a50b91b7d2f9ccc5d1b8e885bfbd33bff3289
Partial-Bug: #1776434
  • Loading branch information
krzysztofg256 authored and aszc-dev committed Jul 23, 2018
1 parent dd1cc56 commit 882ef9d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 4 deletions.
3 changes: 3 additions & 0 deletions cvm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ def get_available(self):
def free(self, vlan_id):
self._available_ids.append(vlan_id)

def is_available(self, vlan_id):
return vlan_id in self._available_ids


class VCenterPort(object):
def __init__(self, device):
Expand Down
9 changes: 6 additions & 3 deletions cvm/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,12 @@ def _delete_from_vnc(self, vmi_model):
self._vnc_api_client.delete_vmi(vmi_model.uuid)

def _restore_vlan_id(self, vmi_model):
self._restore_vcenter_vlan_id(vmi_model)
self._vlan_id_pool.free(vmi_model.vcenter_port.vlan_id)

def _restore_vcenter_vlan_id(self, vmi_model):
with self._vcenter_api_client:
self._vcenter_api_client.restore_vlan_id(vmi_model.vcenter_port)
self._vlan_id_pool.free(vmi_model.vcenter_port.vlan_id)
vmi_model.vcenter_port.vlan_id = None

def _delete_vrouter_port(self, uuid):
self._database.ports_to_delete.append(uuid)
Expand All @@ -303,7 +305,8 @@ def remove_vmis_for_vm_model(self, vm_name):
for vmi_model in vmi_models:
if self._can_modify_in_vnc(vmi_model.vnc_vmi):
self._delete_from_vnc(vmi_model)
self._restore_vlan_id(vmi_model)
self._restore_vcenter_vlan_id(vmi_model)
self._vlan_id_pool.free(vmi_model.vcenter_port.vlan_id)
self._database.delete_vmi_model(vmi_model.uuid)
self._delete_vrouter_port(vmi_model.uuid)

Expand Down
11 changes: 10 additions & 1 deletion tests/functional/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

from cvm.controllers import (GuestNetHandler, UpdateHandler,
VmReconfiguredHandler, VmRenamedHandler,
VmUpdatedHandler, VmwareController, PowerStateHandler, VmwareToolsStatusHandler)
VmUpdatedHandler, VmwareController, PowerStateHandler,
VmwareToolsStatusHandler, VmRemovedHandler)
from cvm.database import Database
from cvm.models import VlanIdPool
from cvm.services import (VirtualMachineInterfaceService,
Expand Down Expand Up @@ -84,6 +85,13 @@ def vm_created_update(vmware_vm_1):
return wrap_into_update_set(event=event)


@pytest.fixture()
def vm_removed_update():
event = Mock(spec=vim.event.VmRemovedEvent())
event.vm.name = 'VM1'
return wrap_into_update_set(event=event)


@pytest.fixture()
def vm_renamed_update():
event = Mock(spec=vim.event.VmRenamedEvent())
Expand Down Expand Up @@ -225,6 +233,7 @@ def controller(vm_service, vn_service, vmi_service, vrouter_port_service, lock):
VmUpdatedHandler(vm_service, vn_service, vmi_service, vrouter_port_service),
VmRenamedHandler(vm_service, vmi_service, vrouter_port_service),
VmReconfiguredHandler(vm_service, vn_service, vmi_service, vrouter_port_service),
VmRemovedHandler(vm_service, vmi_service, vrouter_port_service),
GuestNetHandler(vmi_service, vrouter_port_service),
PowerStateHandler(vm_service, vrouter_port_service),
VmwareToolsStatusHandler(vm_service)
Expand Down
118 changes: 118 additions & 0 deletions tests/functional/test_vm_removed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from mock import Mock, patch

from tests.utils import reserve_vlan_ids


@patch('cvm.services.VirtualMachineService._can_modify_in_vnc', Mock(return_value=True))
@patch('cvm.services.VirtualMachineInterfaceService._can_modify_in_vnc', Mock(return_value=True))
def test_full_remove_vm(controller, database, vcenter_api_client, vnc_api_client, vrouter_api_client,
vm_created_update, vm_removed_update, vn_model_1, vlan_id_pool):
# Virtual Networks are already created for us and after synchronization,
# their models are stored in our database
database.save(vn_model_1)

# Some vlan ids should be already reserved
vcenter_api_client.get_vlan_id.return_value = None
reserve_vlan_ids(vlan_id_pool, [0, 1, 2, 3])

# A new update containing VmCreatedEvent arrives and is being handled by the controller
controller.handle_update(vm_created_update)

# After VmCreatedEvent has been handled
# proper VM model should exists
vm_model = database.get_vm_model_by_uuid('12345678-1234-1234-1234-123456789012')
assert vm_model is not None
# And associated VMI model
vmi_models = vm_model.vmi_models
assert len(vmi_models) == 1
vmi_model = vmi_models[0]
assert vmi_model is not None
# And proper VLAN ID should be acquired
assert not vlan_id_pool.is_available(4)

# Then VmRemovedEvent is being handled
controller.handle_update(vm_removed_update)

# Check that VM Model has been removed from Database:
assert database.get_vm_model_by_uuid(vm_model.uuid) is None

# Check that VM has been removed from VNC
vnc_api_client.delete_vm.assert_called_once_with(vm_model.uuid)

# Check that VMI Model which was associated with removed VM has been removed
# from Database
vmi_models = database.get_vmi_models_by_vm_uuid(vm_model.uuid)
assert len(vmi_models) == 0

# from VNC
vnc_api_client.delete_vmi.assert_called_with(vmi_model.uuid)

# Check that VMI's vRouter Port has been deleted:
vrouter_api_client.delete_port.assert_called_with(vmi_model.uuid)
assert vrouter_api_client.delete_port.call_count == 2
assert vrouter_api_client.add_port.call_count == 1

# Check that VLAN ID has been released
vcenter_api_client.restore_vlan_id.assert_called_once_with(vmi_model.vcenter_port)
assert vlan_id_pool.is_available(4)


@patch('cvm.services.VirtualMachineService._can_modify_in_vnc', Mock(return_value=False))
@patch('cvm.services.VirtualMachineInterfaceService._can_modify_in_vnc', Mock(return_value=False))
def test_vm_removed_local_remove(controller, database, vcenter_api_client, vnc_api_client, vrouter_api_client,
vm_created_update, vm_removed_update, vn_model_1, vlan_id_pool):
"""
Same situation as in test_full_remove_vm, but between VmCreatedEvent and VmDeletedEvent VM
changed its ESXi host. It happens during vMotion. So we have to remove that VM and its associated objects
from database and vRouter. But cannot remove them from VNC and vCenter
"""
# Virtual Networks are already created for us and after synchronization,
# their models are stored in our database
database.save(vn_model_1)

# Some vlan ids should be already reserved
vcenter_api_client.get_vlan_id.return_value = None
reserve_vlan_ids(vlan_id_pool, [0, 1, 2, 3])

# A new update containing VmCreatedEvent arrives and is being handled by the controller
controller.handle_update(vm_created_update)

# After VmCreatedEvent has been handled
# proper VM model should exists
vm_model = database.get_vm_model_by_uuid('12345678-1234-1234-1234-123456789012')
assert vm_model is not None
# And associated VMI model
vmi_models = vm_model.vmi_models
assert len(vmi_models) == 1
vmi_model = vmi_models[0]
assert vmi_model is not None
# And proper VLAN ID should be acquired
assert not vlan_id_pool.is_available(4)

# Then VmRemovedEvent is being handled
controller.handle_update(vm_removed_update)

# Check that VM Model has been removed from Database:
assert database.get_vm_model_by_uuid(vm_model.uuid) is None

# Cannot remove VM from VNC
vnc_api_client.delete_vm.assert_not_called()

# Check that VMI Model which was associated with removed VM has been removed
# from Database
vmi_models = database.get_vmi_models_by_vm_uuid(vm_model.uuid)
assert len(vmi_models) == 0

# Cannot remove VMI from VNC
vnc_api_client.delete_vmi.assert_not_called()

# Check that VMI's vRouter Port has been deleted:
vrouter_api_client.delete_port.assert_called_with(vmi_model.uuid)
assert vrouter_api_client.delete_port.call_count == 2
assert vrouter_api_client.add_port.call_count == 1

# Cannot remove VLAN ID from vCenter
vcenter_api_client.restore_vlan_id.assert_not_called()

# Check that VLAN ID has been restored to local pool
assert vlan_id_pool.is_available(4)

0 comments on commit 882ef9d

Please sign in to comment.