def test_reassign_vm(self, mrapi): volume = mfactory.VolumeFactory() vm = volume.machine another_project = "another_project" with mocked_quotaholder(): vm = servers.reassign(vm.id, another_project, False, credentials=self.credentials) self.assertEqual(vm.project, another_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertNotEqual(vol.project, another_project) volume = mfactory.VolumeFactory() volume.index = 0 volume.save() vm = volume.machine another_project = "another_project" with mocked_quotaholder(): vm = servers.reassign(vm.id, another_project, True, credentials=self.credentials) self.assertEqual(vm.project, another_project) self.assertEqual(vm.shared_to_project, True) vol = vm.volumes.get(id=volume.id) self.assertEqual(vol.project, another_project) self.assertEqual(vol.shared_to_project, True)
def test_list_attachments(self, mrapi): # Test default volume vol = mfactory.VolumeFactory() vm = vol.machine response = self.myget("servers/%d/os-volume_attachments" % vm.id, vm.userid) self.assertSuccess(response) attachments = json.loads(response.content) self.assertEqual(len(attachments), 1) self.assertEqual(attachments["volumeAttachments"][0], { "volumeId": vol.id, "serverId": vm.id, "id": vol.id, "device": "" }) # Test deleted Volume dvol = mfactory.VolumeFactory(machine=vm, deleted=True) response = self.myget("servers/%d/os-volume_attachments" % vm.id, vm.userid) self.assertSuccess(response) attachments = json.loads(response.content)["volumeAttachments"] self.assertEqual(len([d for d in attachments if d["id"] == dvol.id]), 0)
def test_detach(self, mrapi): """Test the detach functionality.""" # Fail to detach a non-detachable volume vol = mf.VolumeFactory(volume_type=self.file_vt, machine=self.file_vm, userid=self.userid, status="IN_USE") message = "Volume type '{}' is not detachable".format( self.file_vt.disk_template) with self.assertRaisesMessage(faults.BadRequest, message): volumes.detach(vol.id, self.credentials) # Fail to detach a volume that has never been attached to any server vol = mf.VolumeFactory(userid=self.userid, volume_type=self.archip_vt, machine=None) message = "Volume is already detached" with self.assertRaisesMessage(faults.BadRequest, message): volumes.detach(vol.id, self.credentials) # Fail to detach a volume that is not in use vol = mf.VolumeFactory(userid=self.userid, volume_type=self.archip_vt) vol.machine = self.archip_vm vol.status = "CREATING" vol.save() message = "Cannot detach volume while volume is in '{}' status".format( vol.status) with self.assertRaisesMessage(faults.BadRequest, message): volumes.detach(vol.id, self.credentials) # Fail to detach the root volume of a vm vol.status = "IN_USE" vol.index = 0 vol.save() message = "Cannot detach the root volume of server {}.".format( self.archip_vm) with self.assertRaisesMessage(faults.BadRequest, message): volumes.detach(vol.id, self.credentials) # Detach a volume from a server vol.userid = self.userid vol.index = 1 vol.save() mrapi().ModifyInstance.return_value = 42 with mocked_quotaholder() as m: volumes.detach(vol.id, self.credentials) # Assert that the VM has just one volume, the volume has an appropriate # status and that no commission was sent. self.assertEqual(self.archip_vm.volumes.all().count(), 1) vol = Volume.objects.get(pk=vol.id) self.assertEqual(vol.status, "DETACHING") self.assertNoCommission(m) # Assert that Ganeti was instructed to keep the disks and that the # ModifyInstance command corresponds to the target volume and server. gnt_args = self.get_ganeti_args(mrapi) self.assertIn("keep_disks", gnt_args) disk_args = self.get_ganeti_disk_args(mrapi) self.assertEqual(disk_args[0], "remove") self.assertEqual(disk_args[1], vol.backend_volume_uuid) self.assertEqual(disk_args[2], {})
def test_vm_holdings(self): flavor = mfactory.FlavorFactory(cpu=24, ram=8192, disk=20) mfactory.VirtualMachineFactory(userid="user1", deleted=True) mfactory.VirtualMachineFactory(flavor=flavor, userid="user1", operstate="BUILD") mfactory.VolumeFactory(userid="user1", size=20, machine=None) user_holdings = { "user1": { "user1": { "cyclades.vm": 1, "cyclades.total_cpu": 24, "cyclades.cpu": 24, "cyclades.disk": 20 << 30, "cyclades.total_ram": 8192 << 20, "cyclades.ram": 8192 << 20 } } } holdings = util.get_db_holdings(user="******") self.assertEqual(holdings, user_holdings) holdings = util.get_db_holdings() self.assertEqual(holdings["user1"], user_holdings["user1"]) mfactory.VirtualMachineFactory(flavor=flavor, userid="user1") ## mfactory.VirtualMachineFactory(flavor=flavor, userid="user2", operstate="STARTED") mfactory.VolumeFactory(userid="user2", size=30, machine=None) user_holdings = { "user2": { "user2": { "cyclades.vm": 1, "cyclades.total_cpu": 24, "cyclades.cpu": 24, "cyclades.disk": 30 << 30, "cyclades.total_ram": 8192 << 20, "cyclades.ram": 8192 << 20 } } } holdings = util.get_db_holdings(user="******") self.assertEqual(holdings, user_holdings) mfactory.VirtualMachineFactory(flavor=flavor, userid="user3", operstate="STOPPED") user_holdings = { "user3": { "user3": { "cyclades.vm": 1, "cyclades.total_cpu": 24, "cyclades.total_ram": 8589934592 } } } holdings = util.get_db_holdings(user="******") self.assertEqual(holdings, user_holdings)
def test_remove(self, client): vm = mfactory.VirtualMachineFactory(flavor__cpu=1, flavor__ram=128) mfactory.VolumeFactory(userid=vm.userid, machine=vm, size=1) mfactory.VolumeFactory(userid=vm.userid, machine=vm, size=3) # Also create a NIC ip = mfactory.IPv4AddressFactory(nic__machine=vm) nic = ip.nic with transaction.atomic(): nic.network.get_ip_pools()[0].reserve(nic.ipv4_address) msg = self.create_msg(operation='OP_INSTANCE_REMOVE', instance=vm.backend_vm_id) with mocked_quotaholder() as m: update_db(client, msg) self.assertTrue(client.basic_ack.called) db_vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(db_vm.operstate, 'DESTROYED') self.assertTrue(db_vm.deleted) # Check that nics are deleted self.assertFalse(db_vm.nics.all()) with transaction.atomic(): self.assertTrue(nic.network.get_ip_pools()[0].is_available(ip.address)) # Check that volumes are deleted self.assertFalse(db_vm.volumes.filter(deleted=False)) # Check quotas name, args, kwargs = m.mock_calls[0] for (userid, res), value in args[1].items(): if res == 'cyclades.disk': self.assertEqual(value, -4 << 30) elif res == 'cyclades.cpu': self.assertEqual(value, -1) elif res == 'cyclades.ram': self.assertEqual(value, -128 << 20) vm2 = mfactory.VirtualMachineFactory() fp1 = mfactory.IPv4AddressFactory(nic__machine=vm2, floating_ip=True, network__floating_ip_pool=True) network = fp1.network nic1 = mfactory.NetworkInterfaceFactory(machine=vm2) fp1.nic = nic1 fp1.save() with transaction.atomic(): pool = network.get_ip_pools()[0] pool.reserve(fp1.address) pool.save() msg = self.create_msg(operation='OP_INSTANCE_REMOVE', instance=vm2.backend_vm_id) with mocked_quotaholder(): update_db(client, msg) self.assertEqual(2, client.basic_ack.call_count) db_vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(db_vm.operstate, 'DESTROYED') self.assertTrue(db_vm.deleted) self.assertEqual(IPAddress.objects.get(id=fp1.id).nic, None) with transaction.atomic(): pool = network.get_ip_pools()[0] # Test that floating ips are not released self.assertFalse(pool.is_available(fp1.address))
def test_attach_detach_volume(self, mrapi): vol = mfactory.VolumeFactory(status="AVAILABLE") vm = vol.machine volume_type = vm.flavor.volume_type # Test that we cannot detach the root volume response = self.mydelete( "servers/%d/os-volume_attachments/%d" % (vm.id, vol.id), vm.userid) self.assertBadRequest(response) # Test that we cannot attach a used volume vol1 = mfactory.VolumeFactory(status="IN_USE", volume_type=volume_type, userid=vm.userid) request = json.dumps({"volumeAttachment": {"volumeId": vol1.id}}) response = self.mypost("servers/%d/os-volume_attachments" % vm.id, vm.userid, request, "json") self.assertBadRequest(response) vol1.status = "AVAILABLE" # We cannot attach a volume of different disk template volume_type_2 = mfactory.VolumeTypeFactory(disk_template="lalalal") vol1.volume_type = volume_type_2 vol1.save() response = self.mypost("servers/%d/os-volume_attachments/" % vm.id, vm.userid, request, "json") self.assertBadRequest(response) vol1.volume_type = volume_type vol1.save() mrapi().ModifyInstance.return_value = 43 response = self.mypost("servers/%d/os-volume_attachments" % vm.id, vm.userid, request, "json") self.assertEqual(response.status_code, 202, response.content) attachment = json.loads(response.content)["volumeAttachment"] self.assertEqual(attachment, { "volumeId": vol1.id, "serverId": vm.id, "id": vol1.id, "device": "" }) # And we delete it...will fail because of status response = self.mydelete( "servers/%d/os-volume_attachments/%d" % (vm.id, vol1.id), vm.userid) self.assertBadRequest(response) vm.task = None vm.save() vm.volumes.all().update(status="IN_USE") response = self.mydelete( "servers/%d/os-volume_attachments/%d" % (vm.id, vol1.id), vm.userid) self.assertEqual(response.status_code, 202, response.content)
def test_assign_to_server(self): """Test if volume assignment to server works properly.""" vm = mf.VirtualMachineFactory() # Assign a volume to a server with no volumes. vol1 = mf.VolumeFactory() util.assign_volume_to_server(vm, vol1) # Assert that the volume is associated with the server and that its # index is 0. self.assertEqual(vol1.machine, vm) self.assertItemsEqual(vm.volumes.all(), [vol1]) self.assertEqual(vol1.index, 0) # Assign a volume to a server with a volume. vol2 = mf.VolumeFactory() util.assign_volume_to_server(vm, vol2) # Assert that the volume is associated with the server and that its # index is 1. self.assertEqual(vol2.machine, vm) self.assertItemsEqual(vm.volumes.all(), [vol1, vol2]) self.assertEqual(vol2.index, 1) # Assign a volume to a server with more than one volume and set its # index to a custom value (e.g. 9) vol3 = mf.VolumeFactory() util.assign_volume_to_server(vm, vol3, index=9) # Assert that the volume is associated with the server and that its # index is set to 9. self.assertEqual(vol3.machine, vm) self.assertItemsEqual(vm.volumes.all(), [vol1, vol2, vol3]) self.assertEqual(vol3.index, 9) # Assign a volume to a server with a volume whose index is 1 and a # deleted volume whose index is 9. vol1.machine = None vol1.save() vol3.deleted = True vol3.save() vol4 = mf.VolumeFactory() util.assign_volume_to_server(vm, vol4) # Assert that the volume is associated with the server and that its # index is 2. self.assertEqual(vol4.machine, vm) self.assertItemsEqual(vm.volumes.filter(deleted=False), [vol2, vol4]) self.assertEqual(vol4.index, 2) # Assert that the same index cannot be assigned to a different volume. vol5 = mf.VolumeFactory() with self.assertRaisesMessage(faults.BadRequest, self.wrong_msg.format(vol5, 2, vm)): util.assign_volume_to_server(vm, vol5, index=2)
def test_delete(self, mrapi): # We can not deleted detached volumes vol = mf.VolumeFactory(machine=None, status="AVAILABLE") self.assertRaises(faults.BadRequest, volumes.delete, vol) vm = mf.VirtualMachineFactory(userid=vol.userid) # Also we cannot delete root volume vol.index = 0 vol.machine = vm vol.status = "IN_USE" vol.save() self.assertRaises(faults.BadRequest, volumes.delete, vol) # We can delete everything else vol.index = 1 mrapi().ModifyInstance.return_value = 42 with mocked_quotaholder(): volumes.delete(vol) self.assertEqual(vol.backendjobid, 42) args, kwargs = mrapi().ModifyInstance.call_args self.assertEqual(kwargs["instance"], vm.backend_vm_id) self.assertEqual(kwargs["disks"][0], ("remove", vol.backend_volume_uuid, {}))
def test_delete_attached(self, mrapi): # Test that we cannot delete root volume vm = mf.VirtualMachineFactory(userid=self.userid) vol = mf.VolumeFactory(machine=vm, userid=self.userid, status="IN_USE", index=0, size=self.size) self.assertRaises(faults.BadRequest, volumes.delete, vol.id, credentials=self.credentials) # We can delete everything else vol.index = 1 vol.save() mrapi().ModifyInstance.return_value = 42 with mocked_quotaholder() as m: volumes.delete(vol.id, credentials=self.credentials) vol = Volume.objects.get(id=vol.id) self.assertEqual(vol.backendjobid, 42) args, kwargs = mrapi().ModifyInstance.call_args expected_commission = { (self.userid, "cyclades.disk"): -(self.size << 30) } self.assertCommissionEqual(m, expected_commission) self.assertEqual(vol.status, "DELETING") self.assertEqual(kwargs["instance"], vm.backend_vm_id) self.assertEqual(kwargs["disks"][0], ("remove", vol.backend_volume_uuid, {}))
def test_reassign_vm_backends(self, mrapi): volume = mfactory.VolumeFactory() vm = volume.machine original_project = vm.project another_project = "another_project" with mocked_quotaholder(): servers.reassign(vm, another_project, False) self.assertEqual(vm.project, another_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertNotEqual(vol.project, another_project) backend = vm.backend backend.public = False backend.save() with mocked_quotaholder(): self.assertRaises(faults.BadRequest, servers.reassign, vm, original_project, False) self.assertEqual(vm.project, another_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertNotEqual(vol.project, another_project) mfactory.ProjectBackendFactory(project=original_project, backend=backend) with mocked_quotaholder(): servers.reassign(vm, original_project, False) self.assertEqual(vm.project, original_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertEqual(vol.project, original_project)
def test_attach_wait_for_sync(self, mrapi): """Test wait_for_sync when attaching volume to instance. """ volume = mfactory.VolumeFactory() vm = volume.machine # Test Started VM vm.operstate = "STARTED" vm.save() mrapi().ModifyInstance.return_value = 1 for sync in [True, False]: with override_settings(settings, GANETI_DISKS_WAIT_FOR_SYNC=sync): jobid = backend.attach_volume(vm, volume) self.assertEqual(jobid, 1) name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1] self.assertEqual(kwargs['wait_for_sync'], sync) # Test Stopped VM. We do not pass wait_for_sync. vm.operstate = "STOPPED" vm.save() mrapi().ModifyInstance.return_value = 1 for sync in [True, False]: with override_settings(settings, GANETI_DISKS_WAIT_FOR_SYNC=sync): jobid = backend.attach_volume(vm, volume) self.assertEqual(jobid, 1) name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1] self.assertFalse('wait_for_sync' in kwargs)
def test_attach_volume_type_specs(self, mrapi): """Test volume type spces propagation when attaching a volume to an instance """ vlmt = mfactory.VolumeTypeFactory(disk_template='ext_archipelago') # Generate 4 specs. 2 prefixed with GNT_EXTP_VOLTYPESPEC_PREFIX # and 2 with an other prefix that should be omitted volume_type_specs = [ mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='%sbar' % GNT_EXTP_VOLTYPESPEC_PREFIX), mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='%sfoo' % GNT_EXTP_VOLTYPESPEC_PREFIX), mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='other-prefx-baz'), mfactory.VolumeTypeSpecsFactory(volume_type=vlmt, key='another-prefix-biz'), ] gnt_prefixed_specs = filter( lambda s: s.key.startswith(GNT_EXTP_VOLTYPESPEC_PREFIX), volume_type_specs) volume = mfactory.VolumeFactory(volume_type=vlmt, size=1) vm = volume.machine osettings = { "GANETI_DISK_PROVIDER_KWARGS": { "archipelago": { "foo": "mpaz", "lala": "lolo" } } } with override_settings(settings, **osettings): mrapi().ModifyInstance.return_value = 1 jobid = backend.attach_volume(vm, volume) self.assertEqual(jobid, 1) name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1] disk_kwargs = { "provider": "archipelago", "name": vm.volumes.all()[0].backend_volume_uuid, "reuse_data": 'False', "foo": "mpaz", "lala": "lolo", "size": 1024 } disk_kwargs.update({ spec.key[len(GNT_EXTP_VOLTYPESPEC_PREFIX):]: spec.value for spec in gnt_prefixed_specs }) # Should be "disks": [('add', '-1', {disk_kwargs}), ] disk = kwargs["disks"][0] self.assertEqual(disk[0], 'add') self.assertEqual(disk[1], '-1') self.assertEqual(disk[2], disk_kwargs)
def test_create_from_volume(self, mrapi): svol = mf.VolumeFactory(userid=self.userid, status="IN_USE", volume_type=self.vm.flavor.volume_type) kwargs = deepcopy(self.kwargs) kwargs["size"] = svol.size self.assertRaises(faults.BadRequest, volumes.create, source_volume_id=svol.id, **self.kwargs)
def test_reassign_vm(self, mrapi): volume = mfactory.VolumeFactory() vm = volume.machine another_project = "another_project" with mocked_quotaholder(): servers.reassign(vm, another_project) self.assertEqual(vm.project, another_project) vol = vm.volumes.get(id=volume.id) self.assertNotEqual(vol.project, another_project) volume = mfactory.VolumeFactory() volume.index = 0 volume.save() vm = volume.machine another_project = "another_project" with mocked_quotaholder(): servers.reassign(vm, another_project) self.assertEqual(vm.project, another_project) vol = vm.volumes.get(id=volume.id) self.assertEqual(vol.project, another_project)
def test_attach(self, mrapi): """Test the attach functionality.""" # Fail to attach a non-detachable volume vol = mf.VolumeFactory(userid=self.userid, volume_type=self.file_vt, machine=None, backendjobid="1134", status="AVAILABLE") message = "Volume type '{}' is not detachable".format( self.file_vt.disk_template) with self.assertRaisesMessage(faults.BadRequest, message): volumes.attach(self.archip_vm.id, vol.id, self.credentials) # Fail to attach a volume that is in use vol.volume_type = self.archip_vt vol.userid = "test_user" vol.status = "IN_USE" vol.save() message = "Cannot attach volume while volume is in '{}' status".format( vol.status) with self.assertRaisesMessage(faults.BadRequest, message): volumes.attach(self.archip_vm.id, vol.id, self.credentials) # Fail to attach a volume to a server with a different volume type message = "Volume and server must have the same volume template" vol.status = "AVAILABLE" vol.save() with self.assertRaises(faults.BadRequest) as e: volumes.attach(self.file_vm.id, vol.id, self.credentials) self.assertIn(message, e.exception.message) # Attach a volume to a server mrapi().ModifyInstance.return_value = 42 with mocked_quotaholder() as m: volumes.attach(self.archip_vm.id, vol.id, self.credentials) # Assert that the volume is assigned to the VM, it has an appropriate # status and that no commission was sent. self.archip_vm = VirtualMachine.objects.get(pk=self.archip_vm.id) vol = Volume.objects.get(pk=vol.id) self.assertEqual(vol.machine, self.archip_vm) self.assertEqual(vol.volume_type, self.archip_vm.flavor.volume_type) self.assertEqual(self.archip_vm.volumes.filter().count(), 1) self.assertEqual(vol.index, 0) self.assertEqual(vol.status, "ATTACHING") self.assertNoCommission(m) disk_args = self.get_ganeti_disk_args(mrapi) self.assertEqual(disk_args[0], "add") self.assertEqual(disk_args[1], '-1') disk_kwargs = disk_args[2] self.assertEqual(disk_kwargs["reuse_data"], "True") self.assertEqual(disk_kwargs["name"], vol.backend_volume_uuid) self.assertEqual(disk_kwargs["size"], vol.size << 10)
def setUp(self): """Common setUp for all AdminTestCases. This setUp method will create and approve a project as well as add several Cyclades model instances using Cyclades' model_factory. """ ProjectAPITest.setUp(self) # Create a simple project. h_owner = {"HTTP_X_AUTH_TOKEN": self.user1.auth_token} app1 = { "name": "test.pr", "description": u"δεσκρίπτιον", "end_date": "2113-5-5T20:20:20Z", "join_policy": "auto", "max_members": 5, "resources": { u"σέρβις1.ρίσορς11": { "project_capacity": 1024, "member_capacity": 512 } } } status, body = self.create(app1, h_owner) # Ensure that the project application has been created. self.assertEqual(status, 201) project_id = body["id"] app_id = body["application"] # Approve the application. with transaction.atomic(): self.project = approve_application(app_id, project_id) self.assertIsNotNone(self.project) # Alias owner user with a generic name self.user = self.user1 # Create cyclades models. self.vm = mf.VirtualMachineFactory() self.volume = mf.VolumeFactory() self.network = mf.NetworkFactory() self.ipv4 = mf.IPv4AddressFactory(address="1.2.3.4") self.ipv6 = mf.IPv6AddressFactory(address="::1")
def test_delete_detached(self, mrapi): """Test the deletion of a detached volume.""" vol = mf.VolumeFactory(machine=None, status="AVAILABLE", userid=self.userid, backendjobid=42, volume_type=self.archip_vt) vm = mf.VirtualMachineFactory(userid=self.userid, helper=True, operstate="STOPPED", flavor__volume_type=self.archip_vt) mrapi().ModifyInstance.return_value = 42 with mocked_quotaholder() as m: vol = volumes.delete(vol.id, credentials=self.credentials) self.assertNoCommission(m) self.assertEqual(vol.machine, vm) self.assertEqual(vol.status, "DELETING") self.assertEqual(vol.deleted, False)
def test_reassign_vm_flavors(self, mrapi): volume = mfactory.VolumeFactory() vm = volume.machine vm_id = vm.id original_project = vm.project another_project = "another_project" with mocked_quotaholder(): servers.reassign(vm_id, another_project, False, credentials=self.credentials) vm = models.VirtualMachine.objects.get(id=vm_id) self.assertEqual(vm.project, another_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertNotEqual(vol.project, another_project) vm = models.VirtualMachine.objects.get(id=vm_id) flavor = vm.flavor flavor.public = False flavor.save() with mocked_quotaholder(): self.assertRaises(faults.Forbidden, servers.reassign, vm_id, original_project, False, self.credentials) vm = models.VirtualMachine.objects.get(id=vm_id) self.assertEqual(vm.project, another_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertNotEqual(vol.project, another_project) mfactory.FlavorAccessFactory(project=original_project, flavor=flavor) with mocked_quotaholder(): servers.reassign(vm_id, original_project, False, credentials=self.credentials) vm = models.VirtualMachine.objects.get(id=vm_id) self.assertEqual(vm.project, original_project) self.assertEqual(vm.shared_to_project, False) vol = vm.volumes.get(id=volume.id) self.assertEqual(vol.project, original_project)
def test_unsynced_flavor(self, mrapi): flavor1 = mfactory.FlavorFactory(cpu=2, ram=1024, disk=1, volume_type__disk_template="drbd") flavor2 = mfactory.FlavorFactory(cpu=4, ram=2048, disk=1, volume_type__disk_template="drbd") vm1 = mfactory.VirtualMachineFactory(backend=self.backend, deleted=False, flavor=flavor1, operstate="STARTED") v1 = mfactory.VolumeFactory(machine=vm1, size=flavor1.disk, volume_type=flavor1.volume_type) mrapi().GetInstances.return_value =\ [{"name": vm1.backend_vm_id, "beparams": {"maxmem": 2048, "minmem": 2048, "vcpus": 4}, "oper_state": True, "mtime": time(), "disk.sizes": [1024], "disk.names": [v1.backend_volume_uuid], "disk.uuids": [v1.backend_disk_uuid], "nic.ips": [], "nic.names": [], "nic.macs": [], "nic.networks.names": [], "tags": []}] with mocked_quotaholder(): self.reconciler.reconcile() vm1 = VirtualMachine.objects.get(id=vm1.id) self.assertEqual(vm1.flavor, flavor2) self.assertEqual(vm1.operstate, "STARTED")
def test_delete_uninitialized(self, mrapi): """Test if we can delete an uninitialized volume.""" # We cannot delete an uninitialized volume in invalid state vol = mf.VolumeFactory(machine=None, status="DELETING", userid=self.userid, size=self.size) message = "Volume is in invalid state: %s" % vol.status with self.assertRaisesMessage(faults.BadRequest, message): volumes.delete(vol.id, credentials=self.credentials) # Test if the deletion and quota logic works as expected vol.status = "AVAILABLE" vol.save() with mocked_quotaholder() as m: vol = volumes.delete(vol.id, credentials=self.credentials) expected_commission = { (self.userid, "cyclades.disk"): -(self.size << 30) } self.assertCommissionEqual(m, expected_commission) self.assertAcceptedSerial(m, vol.serial) self.assertEqual(vol.machine, None) self.assertEqual(vol.status, "DELETED") self.assertEqual(vol.deleted, True)
def test_commissions(self): flavor = mfactory.FlavorFactory(cpu=2, ram=1024, disk=20) vm = mfactory.VirtualMachineFactory(flavor=flavor) mfactory.VolumeFactory(size=20, machine=vm, deleted=False, status="IN_USE", delete_on_termination=True) vm.volumes.update(project=vm.project) #commission = quotas.get_commission_info(vm, "BUILD") #self.assertEqual({"cyclades.vm": 1, # "cyclades.cpu": 2, # "cyclades.cpu": 2, # "cyclades.ram": 1048576 * 1024, # "cyclades.ram": 1048576 * 1024, # "cyclades.disk": 1073741824 * 20}, commission) vm.operstate = "STARTED" vm.save() project = vm.project commission = quotas.get_commission_info(vm, "STOP") self.assertEqual( { (project, "cyclades.cpu"): -2, (project, "cyclades.ram"): 1048576 * -1024 }, commission) # Check None quotas if vm is already stopped vm.operstate = "STOPPED" vm.save() commission = quotas.get_commission_info(vm, "STOP") self.assertEqual(None, commission) commission = quotas.get_commission_info(vm, "START") self.assertEqual( { (project, "cyclades.cpu"): 2, (project, "cyclades.ram"): 1048576 * 1024 }, commission) vm.operstate = "STARTED" vm.save() commission = quotas.get_commission_info(vm, "DESTROY") self.assertEqual( { (project, "cyclades.vm"): -1, (project, "cyclades.total_cpu"): -2, (project, "cyclades.cpu"): -2, (project, "cyclades.total_ram"): 1048576 * -1024, (project, "cyclades.ram"): 1048576 * -1024, (project, "cyclades.disk"): 1073741824 * -20 }, commission) vm.operstate = "STOPPED" vm.save() commission = quotas.get_commission_info(vm, "DESTROY") self.assertEqual( { (project, "cyclades.vm"): -1, (project, "cyclades.total_cpu"): -2, (project, "cyclades.total_ram"): -1024 << 20, (project, "cyclades.disk"): -20 << 30 }, commission) commission = quotas.get_commission_info(vm, "RESIZE") self.assertTrue((commission is None) or (not commission.keys())) commission = quotas.get_commission_info( vm, "RESIZE", {"beparams": { "vcpus": 4, "maxmem": 2048 }}) self.assertEqual( { (project, "cyclades.total_cpu"): 2, (project, "cyclades.total_ram"): 1048576 * 1024 }, commission) vm.operstate = "STOPPED" vm.save() commission = quotas.get_commission_info(vm, "REBOOT") self.assertEqual( { (project, "cyclades.cpu"): 2, (project, "cyclades.ram"): 1048576 * 1024 }, commission) vm.operstate = "STARTED" vm.save() commission = quotas.get_commission_info(vm, "REBOOT") self.assertEqual(None, commission)