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") mrapi().GetInstances.return_value =\ [{"name": vm1.backend_vm_id, "beparams": {"maxmem": 2048, "minmem": 2048, "vcpus": 4}, "oper_state": True, "mtime": time(), "disk.sizes": [], "disk.names": [], "disk.uuids": [], "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_invalid_operstate_for_action(self, mrapi): vm = mfactory.VirtualMachineFactory(operstate="STARTED") self.assertRaises(faults.BadRequest, servers.start, vm) vm = mfactory.VirtualMachineFactory(operstate="STOPPED") self.assertRaises(faults.BadRequest, servers.stop, vm) vm = mfactory.VirtualMachineFactory(operstate="STARTED") flavor = mfactory.FlavorFactory() self.assertRaises(faults.BadRequest, servers.resize, vm, flavor) # Check that connect/disconnect is allowed only in STOPPED vms # if hotplug is disabled. vm = mfactory.VirtualMachineFactory(operstate="STARTED") network = mfactory.NetworkFactory(state="ACTIVE") with override_settings(settings, GANETI_USE_HOTPLUG=False): self.assertRaises(faults.BadRequest, servers.connect, vm, network) self.assertRaises(faults.BadRequest, servers.disconnect, vm, network) #test valid vm = mfactory.VirtualMachineFactory(operstate="STOPPED") mrapi().StartupInstance.return_value = 1 with mocked_quotaholder(): servers.start(vm) vm.task = None vm.task_job_id = None vm.save() with mocked_quotaholder(): quotas.accept_resource_serial(vm) mrapi().RebootInstance.return_value = 1 with mocked_quotaholder(): servers.reboot(vm, "HARD")
def test_flavor_name(self): """Test a flavor object name method.""" flavor = mfact.FlavorFactory(cpu=1, ram=1024, disk=40, disk_template="temp") self.assertEqual( flavor.name, "C1R1024D40temp", "flavor.name is not" " generated correctly. Name is %s instead of C1R1024D40temp" % flavor.name)
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 setUp(self): self.allocators = [cls() for cls in AllocatorBase.__subclasses__()] self.backend = models_factory.BackendFactory() flavor = models_factory.FlavorFactory() disk = flavor.disk * 1024 ram = flavor.ram cpu = flavor.cpu self.vm = {'ram': ram, 'disk': disk, 'cpu': cpu}
def test_vm_holdings(self): flavor = mfactory.FlavorFactory(cpu=24, ram=8192, disk=20, disk_template='drbd') mfactory.VirtualMachineFactory() mfactory.VirtualMachineFactory(flavor=flavor, userid="user1", operstate="BUILD") user_holdings = { "user1": { "cyclades.vm": 1, "cyclades.total_cpu": 24, "cyclades.cpu": 24, "cyclades.disk": 21474836480, "cyclades.total_ram": 8589934592, "cyclades.ram": 8589934592 } } 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") user_holdings = { "user2": { "cyclades.vm": 1, "cyclades.total_cpu": 24, "cyclades.cpu": 24, "cyclades.disk": 21474836480, "cyclades.total_ram": 8589934592, "cyclades.ram": 8589934592 } } holdings = util.get_db_holdings(user="******") self.assertEqual(holdings, user_holdings) mfactory.VirtualMachineFactory(flavor=flavor, userid="user3", operstate="STOPPED") user_holdings = { "user3": { "cyclades.vm": 1, "cyclades.total_cpu": 24, "cyclades.disk": 21474836480, "cyclades.total_ram": 8589934592 } } holdings = util.get_db_holdings(user="******") self.assertEqual(holdings, user_holdings)
def test_create_server(self, mrapi, mimage): """Test if the create server call returns the expected response if a valid request has been speficied.""" mimage.return_value = { 'location': 'pithos://foo', 'checksum': '1234', "id": 1, "name": "test_image", 'disk_format': 'diskdump' } mrapi().CreateInstance.return_value = 12 flavor = mfactory.FlavorFactory() # Create public network and backend network = mfactory.NetworkFactory(public=True) backend = mfactory.BackendFactory() mfactory.BackendNetworkFactory(network=network, backend=backend) request = { "server": { "name": "new-server-test", "userid": "test_user", "imageRef": 1, "flavorRef": flavor.id, "metadata": { "My Server Name": "Apache1" }, "personality": [] } } with mocked_quotaholder(): response = self.mypost('servers', 'test_user', json.dumps(request), 'json') self.assertEqual(response.status_code, 202) mrapi().CreateInstance.assert_called_once() api_server = json.loads(response.content)['server'] self.assertEqual(api_server['status'], "BUILD") self.assertEqual(api_server['progress'], 0) self.assertEqual(api_server['metadata'], {"My Server Name": "Apache1"}) self.assertTrue('adminPass' in api_server) db_vm = VirtualMachine.objects.get(userid='test_user') self.assertEqual(api_server['name'], db_vm.name) self.assertEqual(api_server['status'], db_vm.operstate) # Test drained flag in Network: network.drained = True network.save() with mocked_quotaholder(): response = self.mypost('servers', 'test_user', json.dumps(request), 'json') self.assertEqual(response.status_code, 503, "serviceUnavailable")
def test_create_server_wrong_flavor(self, mrapi): # Test with a flavor that does not exist request = deepcopy(self.request) request["server"]["flavorRef"] = 42 with override_settings(settings, **self.network_settings): with mocked_quotaholder(): response = self.mypost('servers', 'test_user', json.dumps(request), 'json') self.assertItemNotFound(response) # Test with an flavor that is not allowed flavor = mfactory.FlavorFactory(allow_create=False) request["server"]["flavorRef"] = flavor.id with override_settings(settings, **self.network_settings): with mocked_quotaholder(): response = self.mypost('servers', 'test_user', json.dumps(request), 'json') self.assertEqual(response.status_code, 403)
def test_resize_vm(self, mrapi, mimage): flavor = mfactory.FlavorFactory(cpu=1, ram=1024) # Check building VM vm = self.get_vm(flavor=flavor, operstate="BUILD") request = {'resize': {'flavorRef': flavor.id}} response = self.mypost('servers/%d/action' % vm.id, vm.userid, json.dumps(request), 'json') self.assertFault(response, 409, "buildInProgress") # Check same Flavor vm = self.get_vm(flavor=flavor, operstate="STOPPED") request = {'resize': {'flavorRef': flavor.id}} response = self.mypost('servers/%d/action' % vm.id, vm.userid, json.dumps(request), 'json') self.assertBadRequest(response) # Check flavor with different disk flavor2 = mfactory.FlavorFactory(disk=1024) flavor3 = mfactory.FlavorFactory(disk=2048) vm = self.get_vm(flavor=flavor2, operstate="STOPPED") request = {'resize': {'flavorRef': flavor3.id}} response = self.mypost('servers/%d/action' % vm.id, vm.userid, json.dumps(request), 'json') self.assertBadRequest(response) # Check flavor with different volume type flavor2 = mfactory.FlavorFactory(volume_type__disk_template="foo") flavor3 = mfactory.FlavorFactory(volume_type__disk_template="baz") vm = self.get_vm(flavor=flavor2, operstate="STOPPED") request = {'resize': {'flavorRef': flavor3.id}} response = self.mypost('servers/%d/action' % vm.id, vm.userid, json.dumps(request), 'json') self.assertBadRequest(response) # Check success vm = self.get_vm(flavor=flavor, operstate="STOPPED") flavor4 = mfactory.FlavorFactory(volume_type=vm.flavor.volume_type, disk=flavor.disk, cpu=4, ram=2048) request = {'resize': {'flavorRef': flavor4.id}} mrapi().ModifyInstance.return_value = 42 response = self.mypost('servers/%d/action' % vm.id, vm.userid, json.dumps(request), 'json') self.assertEqual(response.status_code, 202) vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(vm.task_job_id, 42) name, args, kwargs = mrapi().ModifyInstance.mock_calls[0] self.assertEqual(kwargs["beparams"]["vcpus"], 4) self.assertEqual(kwargs["beparams"]["minmem"], 2048) self.assertEqual(kwargs["beparams"]["maxmem"], 2048)
def setUp(self): self.flavor = mfactory.FlavorFactory() self.backend = mfactory.BackendFactory() self.request = { "server": { "name": u"Server in the \u2601", "userid": "test_user", "imageRef": 1, "flavorRef": self.flavor.id, "metadata": { u"Meta \u2601": u"Meta in the \u2601" }, "personality": [] } } # Create dummy public IPv6 network sub6 = mfactory.IPv6SubnetFactory(network__public=True) self.net6 = sub6.network self.network_settings = { "CYCLADES_DEFAULT_SERVER_NETWORKS": [], "CYCLADES_FORCED_SERVER_NETWORKS": ["SNF:ANY_PUBLIC_IPV6"] }
def test_create(self, mrapi): flavor = mfactory.FlavorFactory() kwargs = { "userid": "test", "name": "test_vm", "password": "******", "flavor": flavor, "image_id": "safs", "networks": [], "metadata": { "foo": "bar" }, "personality": [], } # no backend! mfactory.BackendFactory(offline=True) self.assertRaises(faults.ServiceUnavailable, servers.create, **kwargs) self.assertEqual(models.VirtualMachine.objects.count(), 0) mfactory.IPv4SubnetFactory(network__public=True) mfactory.IPv6SubnetFactory(network__public=True) backend = mfactory.BackendFactory() # error in nics req = deepcopy(kwargs) req["networks"] = [{"uuid": 42}] self.assertRaises(faults.ItemNotFound, servers.create, **req) self.assertEqual(models.VirtualMachine.objects.count(), 0) # error in enqueue. check the vm is deleted and resources released mrapi().CreateInstance.side_effect = Exception("ganeti is down") with mocked_quotaholder(): servers.create(**kwargs) vm = models.VirtualMachine.objects.get() self.assertFalse(vm.deleted) self.assertEqual(vm.operstate, "ERROR") for nic in vm.nics.all(): self.assertEqual(nic.state, "ERROR") # test ext settings: req = deepcopy(kwargs) ext_flavor = mfactory.FlavorFactory( volume_type__disk_template="ext_archipelago", disk=1) req["flavor"] = ext_flavor mrapi().CreateInstance.return_value = 42 backend.disk_templates = ["ext"] backend.save() osettings = { "GANETI_DISK_PROVIDER_KWARGS": { "archipelago": { "foo": "mpaz", "lala": "lolo" } } } with mocked_quotaholder(): with override_settings(settings, **osettings): vm = servers.create(**req) name, args, kwargs = mrapi().CreateInstance.mock_calls[-1] self.assertEqual( kwargs["disks"][0], { "provider": "archipelago", "origin": "test_mapfile", "origin_size": 1000, "name": vm.volumes.all()[0].backend_volume_uuid, "foo": "mpaz", "lala": "lolo", "size": 1024 })
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)
def test_resize_msg(self, client): vm = mfactory.VirtualMachineFactory() # Test empty beparams for status in ["success", "error"]: msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', instance=vm.backend_vm_id, job_fields={"beparams": {}}, status=status) client.reset_mock() with mocked_quotaholder(): update_db(client, msg) self.assertTrue(client.basic_ack.called) db_vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(db_vm.operstate, vm.operstate) # Test intermediate states vm.operstate = "STOPPED" vm.save() for status in ["queued", "waiting", "running"]: beparams = {"vcpus": 4, "minmem": 2048, "maxmem": 2048} msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', instance=vm.backend_vm_id, job_fields={"beparams": beparams}, status=status) client.reset_mock() update_db(client, msg) self.assertTrue(client.basic_ack.called) db_vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(db_vm.operstate, "STOPPED") # Test operstate after error msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', instance=vm.backend_vm_id, beparams={"vcpus": 4}, status="error") client.reset_mock() with mocked_quotaholder(): update_db(client, msg) self.assertTrue(client.basic_ack.called) db_vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(db_vm.operstate, "STOPPED") # Test success f1 = mfactory.FlavorFactory(cpu=4, ram=1024, volume_type__disk_template="drbd", disk=1024) vm.flavor = f1 vm.save() f2 = mfactory.FlavorFactory(cpu=8, ram=2048, volume_type__disk_template="drbd", disk=1024) beparams = {"vcpus": 8, "minmem": 2048, "maxmem": 2048} msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', instance=vm.backend_vm_id, job_fields={"beparams": beparams}, status="success") client.reset_mock() with mocked_quotaholder(): update_db(client, msg) self.assertTrue(client.basic_ack.called) db_vm = VirtualMachine.objects.get(id=vm.id) self.assertEqual(db_vm.operstate, "STOPPED") self.assertEqual(db_vm.flavor, f2) beparams = {"vcpus": 100, "minmem": 2048, "maxmem": 2048} msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS', instance=vm.backend_vm_id, job_fields={"beparams": beparams}, status="success") client.reset_mock() with mocked_quotaholder(): update_db(client, msg) self.assertTrue(client.basic_reject.called)
def test_create(self, mrapi): flavor = mfactory.FlavorFactory() kwargs = { "credentials": self.credentials, "name": "test_vm", "password": "******", "flavor": flavor, "image_id": "safs", "networks": [], "metadata": { "foo": "bar" }, "personality": [], } # no backend! mfactory.BackendFactory(offline=True) self.assertRaises(faults.ServiceUnavailable, servers.create, **kwargs) self.assertEqual(models.VirtualMachine.objects.count(), 0) mfactory.IPv4SubnetFactory(network__public=True) mfactory.IPv6SubnetFactory(network__public=True) backend = mfactory.BackendFactory() # error in nics req = deepcopy(kwargs) req["networks"] = [{"uuid": 42}] self.assertRaises(faults.ItemNotFound, servers.create, **req) self.assertEqual(models.VirtualMachine.objects.count(), 0) # error in enqueue. check the vm is deleted and resources released mrapi().CreateInstance.side_effect = Exception("ganeti is down") with mocked_quotaholder(): servers.create(**kwargs) vm = models.VirtualMachine.objects.get() self.assertFalse(vm.deleted) self.assertEqual(vm.operstate, "ERROR") for nic in vm.nics.all(): self.assertEqual(nic.state, "ERROR") # test ext settings: req = deepcopy(kwargs) 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) ext_flavor = mfactory.FlavorFactory(volume_type=vlmt, disk=1) req["flavor"] = ext_flavor mrapi().CreateInstance.return_value = 42 backend.disk_templates = ["ext"] backend.save() osettings = { "GANETI_DISK_PROVIDER_KWARGS": { "archipelago": { "foo": "mpaz", "lala": "lolo" } } } with mocked_quotaholder(): with override_settings(settings, **osettings): with patch( 'synnefo.logic.backend_allocator.update_backends_disk_templates' # noqa E265 ) as update_disk_templates_mock: # Check that between the `get_available_backends` call # and the `update_backend_disk_templates` call # the backend doesn't change. update_disk_templates_mock.return_value = [backend] vm = servers.create(**req) update_disk_templates_mock.assert_called_once_with([backend]) name, args, kwargs = mrapi().CreateInstance.mock_calls[-1] disk_kwargs = { "provider": "archipelago", "origin": "test_mapfile", "origin_size": 1000, "name": vm.volumes.all()[0].backend_volume_uuid, "foo": "mpaz", "lala": "lolo", "size": 1024 } disk_kwargs.update({ spec.key[len(GNT_EXTP_VOLTYPESPEC_PREFIX):]: spec.value for spec in gnt_prefixed_specs }) self.assertEqual(kwargs["disks"][0], disk_kwargs)
def test_commissions(self): flavor = mfactory.FlavorFactory(cpu=2, ram=1024, disk=20) vm = mfactory.VirtualMachineFactory(flavor=flavor) #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() commission = quotas.get_commission_info(vm, "STOP") self.assertEqual({ "cyclades.cpu": -2, "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({ "cyclades.cpu": 2, "cyclades.ram": 1048576 * 1024 }, commission) vm.operstate = "STARTED" vm.save() commission = quotas.get_commission_info(vm, "DESTROY") self.assertEqual( { "cyclades.vm": -1, "cyclades.total_cpu": -2, "cyclades.cpu": -2, "cyclades.total_ram": 1048576 * -1024, "cyclades.ram": 1048576 * -1024, "cyclades.disk": 1073741824 * -20 }, commission) vm.operstate = "STOPPED" vm.save() commission = quotas.get_commission_info(vm, "DESTROY") self.assertEqual( { "cyclades.vm": -1, "cyclades.total_cpu": -2, "cyclades.total_ram": 1048576 * -1024, "cyclades.disk": 1073741824 * -20 }, commission) commission = quotas.get_commission_info(vm, "RESIZE") self.assertEqual(None, commission) commission = quotas.get_commission_info( vm, "RESIZE", {"beparams": { "vcpus": 4, "maxmem": 2048 }}) self.assertEqual( { "cyclades.total_cpu": 2, "cyclades.total_ram": 1048576 * 1024 }, commission) vm.operstate = "STOPPED" vm.save() commission = quotas.get_commission_info(vm, "REBOOT") self.assertEqual({ "cyclades.cpu": 2, "cyclades.ram": 1048576 * 1024 }, commission) vm.operstate = "STARTED" vm.save() commission = quotas.get_commission_info(vm, "REBOOT") self.assertEqual(None, commission)