示例#1
0
 def _make_allocation(self, rp_uuid=None):
     rp_uuid = rp_uuid or uuidsentinel.allocation_resource_provider
     rp = objects.ResourceProvider(context=self.context,
                                   uuid=rp_uuid,
                                   name=rp_uuid)
     rp.create()
     alloc = objects.Allocation(self.context,
                                resource_provider=rp,
                                **DISK_ALLOCATION)
     alloc.create()
     return rp, alloc
示例#2
0
    def test_get_allocations(self, mock_get_allocations_from_db,
                             mock_ensure_cache):
        rp = objects.ResourceProvider(id=_RESOURCE_PROVIDER_ID,
                                      uuid=uuids.resource_provider)
        allocations = objects.AllocationList.get_all_by_resource_provider_uuid(
            self.context, rp.uuid)

        self.assertEqual(1, len(allocations))
        mock_get_allocations_from_db.assert_called_once_with(
            self.context, resource_provider_uuid=uuids.resource_provider)
        self.assertEqual(_ALLOCATION_DB['used'], allocations[0].used)
示例#3
0
 def test_create(self, mock_db_create):
     obj = objects.ResourceProvider(context=self.context,
                                    uuid=_RESOURCE_PROVIDER_UUID,
                                    name=_RESOURCE_PROVIDER_NAME)
     obj.create()
     self.assertEqual(_RESOURCE_PROVIDER_UUID, obj.uuid)
     self.assertIsInstance(obj.id, int)
     mock_db_create.assert_called_once_with(self.context, {
         'uuid': _RESOURCE_PROVIDER_UUID,
         'name': _RESOURCE_PROVIDER_NAME
     })
示例#4
0
    def test_get_by_uuid_from_db(self):
        rp = objects.ResourceProvider(context=self.context,
                                      uuid=_RESOURCE_PROVIDER_UUID)
        rp.create()
        retrieved_rp = objects.ResourceProvider._get_by_uuid_from_db(
            self.context, _RESOURCE_PROVIDER_UUID)
        self.assertEqual(rp.uuid, retrieved_rp.uuid)

        self.assertRaises(exception.NotFound,
                          objects.ResourceProvider._get_by_uuid_from_db,
                          self.context, uuids.missing)
示例#5
0
 def _make_allocation(self, rp_uuid=None):
     rp_uuid = rp_uuid or uuidsentinel.allocation_resource_provider
     db_rp = objects.ResourceProvider(context=self.context,
                                      uuid=rp_uuid,
                                      name=rp_uuid)
     db_rp.create()
     updates = dict(DISK_ALLOCATION,
                    resource_class_id=RESOURCE_CLASS_ID,
                    resource_provider_id=db_rp.id)
     db_allocation = objects.Allocation._create_in_db(self.context, updates)
     return db_rp, db_allocation
示例#6
0
    def start_fixture(self):
        super(AllocationFixture, self).start_fixture()
        self.context = context.get_admin_context()
        # Stealing from the super
        rp_name = os.environ['RP_NAME']
        rp_uuid = os.environ['RP_UUID']
        rp = objects.ResourceProvider(
            self.context, name=rp_name, uuid=rp_uuid)
        rp.create()

        # Create some DISK_GB inventory and allocations.
        inventory = objects.Inventory(
            self.context, resource_provider=rp,
            resource_class='DISK_GB', total=2048,
            step_size=10, min_unit=10, max_unit=600)
        inventory.obj_set_defaults()
        rp.add_inventory(inventory)
        allocation = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='DISK_GB',
            consumer_id=uuidutils.generate_uuid(),
            used=512)
        allocation.create()
        allocation = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='DISK_GB',
            consumer_id=uuidutils.generate_uuid(),
            used=512)
        allocation.create()

        # Create some VCPU inventory and allocations.
        inventory = objects.Inventory(
            self.context, resource_provider=rp,
            resource_class='VCPU', total=8,
            max_unit=4)
        inventory.obj_set_defaults()
        rp.add_inventory(inventory)
        allocation = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='VCPU',
            consumer_id=uuidutils.generate_uuid(),
            used=2)
        allocation.create()
        allocation = objects.Allocation(
            self.context, resource_provider=rp,
            resource_class='VCPU',
            consumer_id=uuidutils.generate_uuid(),
            used=4)
        allocation.create()

        # The ALT_RP_XXX variables are for a resource provider that has
        # not been created in the Allocation fixture
        os.environ['ALT_RP_UUID'] = uuidutils.generate_uuid()
        os.environ['ALT_RP_NAME'] = uuidutils.generate_uuid()
示例#7
0
 def _create_resource_provider(self, inventory):
     """Helper method to create a resource provider with inventory"""
     ctxt = context.get_admin_context()
     rp_uuid = uuidutils.generate_uuid()
     rp = objects.ResourceProvider(context=ctxt, name=rp_uuid, uuid=rp_uuid)
     rp.create()
     inventory = objects.Inventory(context=ctxt,
                                   resource_provider=rp,
                                   **inventory)
     inventory.create()
     return rp
 def test_save_resource_provider(self):
     created_resource_provider = objects.ResourceProvider(
         context=self.context,
         uuid=uuidsentinel.fake_resource_provider,
         name=uuidsentinel.fake_resource_name,
     )
     created_resource_provider.create()
     created_resource_provider.name = 'new-name'
     created_resource_provider.save()
     retrieved_resource_provider = objects.ResourceProvider.get_by_uuid(
         self.context, uuidsentinel.fake_resource_provider)
     self.assertEqual('new-name', retrieved_resource_provider.name)
示例#9
0
 def test_create_requires_created_resource_provider(self):
     rp = objects.ResourceProvider(context=self.context,
                                   uuid=uuids.inventory_resource_provider)
     inventory_dict = dict(_INVENTORY_DB)
     inventory_dict.pop('id')
     inventory_dict.pop('resource_provider_id')
     inventory_dict.pop('resource_class_id')
     inventory_dict['resource_provider'] = rp
     inventory = objects.Inventory(context=self.context, **inventory_dict)
     error = self.assertRaises(exception.ObjectActionError,
                               inventory.create)
     self.assertIn('resource_provider required', str(error))
示例#10
0
 def test_update_inventory_not_found(self):
     rp = objects.ResourceProvider(context=self.context,
                                   uuid=uuidsentinel.rp_uuid,
                                   name=uuidsentinel.rp_name)
     rp.create()
     disk_inv = objects.Inventory(resource_provider=rp,
                                  resource_class='DISK_GB',
                                  total=2048)
     disk_inv.obj_set_defaults()
     error = self.assertRaises(exception.NotFound, rp.update_inventory,
                               disk_inv)
     self.assertIn('No inventory of class DISK_GB found', str(error))
 def test_create_inventory_with_uncreated_provider(self):
     resource_provider = objects.ResourceProvider(
         context=self.context,
         uuid=uuidsentinel.inventory_resource_provider
     )
     disk_inventory = objects.Inventory(
         context=self.context,
         resource_provider=resource_provider,
         **DISK_INVENTORY
     )
     self.assertRaises(exception.ObjectActionError,
                       disk_inventory.create)
示例#12
0
 def test_create(self, mock_db_create, mock_ensure_cache):
     rp = objects.ResourceProvider(id=_RESOURCE_PROVIDER_ID,
                                   uuid=uuids.resource_provider)
     obj = objects.Allocation(context=self.context,
                              resource_provider=rp,
                              resource_class=_RESOURCE_CLASS_NAME,
                              consumer_id=uuids.fake_instance,
                              used=8)
     obj.create()
     self.assertEqual(_ALLOCATION_ID, obj.id)
     expected = dict(_ALLOCATION_DB)
     expected.pop('id')
     mock_db_create.assert_called_once_with(self.context, expected)
示例#13
0
 def _make_rp_and_inventory(self, **kwargs):
     # Create one resource provider and set some inventory
     rp_name = uuidsentinel.rp_name
     rp_uuid = uuidsentinel.rp_uuid
     rp = objects.ResourceProvider(
         self.context, name=rp_name, uuid=rp_uuid)
     rp.create()
     inv = objects.Inventory(resource_provider=rp,
                             total=1024, allocation_ratio=1,
                             reserved=0, **kwargs)
     inv.obj_set_defaults()
     rp.set_inventory(objects.InventoryList(objects=[inv]))
     return rp
 def test_destroy_resource_provider(self):
     created_resource_provider = objects.ResourceProvider(
         context=self.context,
         uuid=uuidsentinel.fake_resource_provider,
         name=uuidsentinel.fake_resource_name,
     )
     created_resource_provider.create()
     created_resource_provider.destroy()
     self.assertRaises(exception.NotFound,
                       objects.ResourceProvider.get_by_uuid, self.context,
                       uuidsentinel.fake_resource_provider)
     self.assertRaises(exception.NotFound,
                       created_resource_provider.destroy)
示例#15
0
    def test_compute_node_inventory(self):
        # This is for making sure we only check once the I/O so we can directly
        # call this helper method for the next tests.
        uuid = uuids.compute_node
        name = 'computehost'
        compute_node = objects.ComputeNode(uuid=uuid,
                                           hypervisor_hostname=name,
                                           vcpus=2,
                                           cpu_allocation_ratio=16.0,
                                           memory_mb=1024,
                                           ram_allocation_ratio=1.5,
                                           local_gb=10,
                                           disk_allocation_ratio=1.0)
        rp = objects.ResourceProvider(uuid=uuid, name=name, generation=42)
        self.client._resource_providers[uuid] = rp

        self.flags(reserved_host_memory_mb=1000)
        self.flags(reserved_host_disk_mb=2000)

        result = self.client._compute_node_inventory(compute_node)

        expected_inventories = {
            'VCPU': {
                'total': compute_node.vcpus,
                'reserved': 0,
                'min_unit': 1,
                'max_unit': 1,
                'step_size': 1,
                'allocation_ratio': compute_node.cpu_allocation_ratio,
            },
            'MEMORY_MB': {
                'total': compute_node.memory_mb,
                'reserved': CONF.reserved_host_memory_mb,
                'min_unit': 1,
                'max_unit': 1,
                'step_size': 1,
                'allocation_ratio': compute_node.ram_allocation_ratio,
            },
            'DISK_GB': {
                'total': compute_node.local_gb,
                'reserved': CONF.reserved_host_disk_mb * 1024,
                'min_unit': 1,
                'max_unit': 1,
                'step_size': 1,
                'allocation_ratio': compute_node.disk_allocation_ratio,
            },
        }
        expected = {
            'inventories': expected_inventories,
        }
        self.assertEqual(expected, result)
示例#16
0
    def test_update_inventory_conflicts_and_then_succeeds(self, ensure_mock):
        # Ensure _update_inventory() fails if we have a conflict when updating
        # but retries correctly.
        uuid = uuids.compute_node
        name = 'computehost'
        compute_node = objects.ComputeNode(uuid=uuid,
                                           hypervisor_hostname=name,
                                           vcpus=2,
                                           cpu_allocation_ratio=16.0,
                                           memory_mb=1024,
                                           ram_allocation_ratio=1.5,
                                           local_gb=10,
                                           disk_allocation_ratio=1.0)
        rp = objects.ResourceProvider(uuid=uuid, name=name, generation=42)

        # Make sure the ResourceProvider exists for preventing to call the API
        def fake_ensure_rp(uuid, name=None):
            self.client._resource_providers[uuid] = rp

        ensure_mock.side_effect = fake_ensure_rp

        self.client._resource_providers[uuid] = rp

        # Make sure we store the original generation bit before it's updated
        original_generation = rp.generation
        expected_payload = self.client._compute_node_inventory(compute_node)
        expected_output = mock.sentinel.inventories

        conflict_mock = mock.Mock(status_code=409)
        success_mock = mock.Mock(status_code=200, json=lambda: expected_output)
        self.ks_sess_mock.put.side_effect = (conflict_mock, success_mock)

        result = self.client._update_inventory(compute_node)

        expected_url = '/resource_providers/' + uuid + '/inventories'
        self.ks_sess_mock.put.assert_has_calls([
            mock.call(expected_url,
                      endpoint_filter=mock.ANY,
                      json=expected_payload,
                      raise_exc=False),
            mock.call(expected_url,
                      endpoint_filter=mock.ANY,
                      json=expected_payload,
                      raise_exc=False),
        ])

        self.assertTrue(result)
        # Make sure the generation bit has been incremented
        rp = self.client._resource_providers[compute_node.uuid]
        self.assertEqual(original_generation + 1, rp.generation)
示例#17
0
    def test_set_defaults(self):
        rp = objects.ResourceProvider(id=_RESOURCE_PROVIDER_ID,
                                      uuid=_RESOURCE_PROVIDER_UUID)
        kwargs = dict(resource_provider=rp,
                      resource_class=_RESOURCE_CLASS_NAME,
                      total=16)
        inv = objects.Inventory(self.context, **kwargs)

        inv.obj_set_defaults()
        self.assertEqual(0, inv.reserved)
        self.assertEqual(1, inv.min_unit)
        self.assertEqual(1, inv.max_unit)
        self.assertEqual(1, inv.step_size)
        self.assertEqual(1.0, inv.allocation_ratio)
示例#18
0
 def test_non_negative_handling(self):
     # NOTE(cdent): Just checking, useless to be actually
     # comprehensive here.
     rp = objects.ResourceProvider(id=_RESOURCE_PROVIDER_ID,
                                   uuid=_RESOURCE_PROVIDER_UUID)
     kwargs = dict(resource_provider=rp,
                   resource_class=_RESOURCE_CLASS_NAME,
                   total=16,
                   reserved=2,
                   min_unit=1,
                   max_unit=-8,
                   step_size=1,
                   allocation_ratio=1.0)
     self.assertRaises(ValueError, objects.Inventory, **kwargs)
示例#19
0
    def _ensure_resource_provider(self):
        shortname = self.host.split('.')[0]
        rp_name = 'compute-%s-%s' % (shortname, self.uuid)
        rp = objects.ResourceProvider(context=self._context,
                                      uuid=self.uuid,
                                      name=rp_name)
        try:
            rp.create()
        except db_exc.DBDuplicateEntry:
            rp = objects.ResourceProvider.get_by_uuid(self._context, self.uuid)
            if rp.name != rp_name:
                rp.name = rp_name
                rp.save()

        return rp
示例#20
0
    def test_capacity(self):
        rp = objects.ResourceProvider(id=_RESOURCE_PROVIDER_ID,
                                      uuid=_RESOURCE_PROVIDER_UUID)
        kwargs = dict(resource_provider=rp,
                      resource_class=_RESOURCE_CLASS_NAME,
                      total=16,
                      reserved=16)
        inv = objects.Inventory(self.context, **kwargs)
        inv.obj_set_defaults()

        self.assertEqual(0, inv.capacity)
        inv.reserved = 15
        self.assertEqual(1, inv.capacity)
        inv.allocation_ratio = 2.0
        self.assertEqual(2, inv.capacity)
示例#21
0
    def test_get_all_by_filters(self):
        for rp_i in ['1', '2']:
            uuid = getattr(uuidsentinel, 'rp_uuid_' + rp_i)
            name = 'rp_name_' + rp_i
            rp = objects.ResourceProvider(self.context, name=name, uuid=uuid)
            rp.create()

        resource_providers = objects.ResourceProviderList.get_all_by_filters(
            self.context)
        self.assertEqual(2, len(resource_providers))
        resource_providers = objects.ResourceProviderList.get_all_by_filters(
            self.context, filters={'name': 'rp_name_1'})
        self.assertEqual(1, len(resource_providers))
        resource_providers = objects.ResourceProviderList.get_all_by_filters(
            self.context, filters={'can_host': 1})
        self.assertEqual(0, len(resource_providers))
示例#22
0
    def create_inventory(self):
        """Create the initial inventory objects for this compute node.

        This is only ever called once, either for the first time when a compute
        is created, or after an upgrade where the required services have
        reached the required version.
        """
        rp = objects.ResourceProvider(context=self._context, uuid=self.uuid)
        rp.create()

        cpu = objects.Inventory(context=self._context,
                                resource_provider=rp,
                                resource_class=fields.ResourceClass.VCPU,
                                total=self.vcpus,
                                reserved=0,
                                min_unit=1,
                                max_unit=1,
                                step_size=1,
                                allocation_ratio=self.cpu_allocation_ratio)
        cpu.create()

        mem = objects.Inventory(context=self._context,
                                resource_provider=rp,
                                resource_class=fields.ResourceClass.MEMORY_MB,
                                total=self.memory_mb,
                                reserved=0,
                                min_unit=1,
                                max_unit=1,
                                step_size=1,
                                allocation_ratio=self.ram_allocation_ratio)
        mem.create()

        # FIXME(danms): Eventually we want to not write this record
        # if the compute host is on shared storage. We'll need some
        # indication from it to that effect, so for now we always
        # write it so that we can make all the usual machinery depend
        # on these records instead of the legacy columns.
        disk = objects.Inventory(context=self._context,
                                 resource_provider=rp,
                                 resource_class=fields.ResourceClass.DISK_GB,
                                 total=self.local_gb,
                                 reserved=0,
                                 min_unit=1,
                                 max_unit=1,
                                 step_size=1,
                                 allocation_ratio=self.disk_allocation_ratio)
        disk.create()
示例#23
0
    def test_delete_inventory_already_no_inventory(self, mock_get, mock_put,
                                                   mock_extract):
        cn = self.compute_node
        rp = objects.ResourceProvider(uuid=cn.uuid, generation=42)
        # Make sure the ResourceProvider exists for preventing to call the API
        self.client._resource_providers[cn.uuid] = rp

        mock_get.return_value.json.return_value = {
            'resource_provider_generation': 1,
            'inventories': {}
        }
        result = self.client._delete_inventory(cn.uuid)
        self.assertIsNone(result)
        self.assertFalse(mock_put.called)
        self.assertFalse(mock_extract.called)
        new_gen = self.client._resource_providers[cn.uuid].generation
        self.assertEqual(1, new_gen)
示例#24
0
    def test_update_inventory_unknown_response(self, mock_put, mock_get):
        # Ensure _update_inventory() returns a list of Inventories objects
        # after creating or updating the existing values
        uuid = uuids.compute_node
        compute_node = self.compute_node
        rp = objects.ResourceProvider(uuid=uuid, name='foo', generation=42)
        # Make sure the ResourceProvider exists for preventing to call the API
        self.client._resource_providers[uuid] = rp

        mock_get.return_value = {}
        mock_put.return_value.status_code = 234

        result = self.client._update_inventory_attempt(compute_node)
        self.assertFalse(result)

        # No cache invalidation
        self.assertIn(uuid, self.client._resource_providers)
示例#25
0
 def test_create(self, mock_db_create):
     rp = objects.ResourceProvider(id=_RESOURCE_PROVIDER_ID,
                                   uuid=_RESOURCE_PROVIDER_UUID)
     obj = objects.Inventory(context=self.context,
                             resource_provider=rp,
                             resource_class=_RESOURCE_CLASS_NAME,
                             total=16,
                             reserved=2,
                             min_unit=1,
                             max_unit=8,
                             step_size=1,
                             allocation_ratio=1.0)
     obj.create()
     self.assertEqual(_INVENTORY_ID, obj.id)
     expected = dict(_INVENTORY_DB)
     expected.pop('id')
     mock_db_create.assert_called_once_with(self.context, expected)
 def test_add_invalid_inventory(self):
     rp = objects.ResourceProvider(context=self.context,
                                   uuid=uuidsentinel.rp_uuid,
                                   name=uuidsentinel.rp_name)
     rp.create()
     disk_inv = objects.Inventory(
         resource_provider=rp,
         resource_class=fields.ResourceClass.DISK_GB,
         total=1024, reserved=2048)
     disk_inv.obj_set_defaults()
     error = self.assertRaises(exception.InvalidInventoryCapacity,
                               rp.add_inventory,
                               disk_inv)
     self.assertIn("Invalid inventory for '%s'"
                   % fields.ResourceClass.DISK_GB, str(error))
     self.assertIn("on resource provider '%s'."
                   % rp.uuid, str(error))
示例#27
0
    def _create_resource_provider(self, uuid, name):
        """Calls the placement API to create a new resource provider record.

        Returns an `objects.ResourceProvider` object representing the
        newly-created resource provider object.

        :param uuid: UUID of the new resource provider
        :param name: Name of the resource provider
        """
        url = "/resource_providers"
        payload = {
            'uuid': uuid,
            'name': name,
        }
        resp = self.post(url, payload)
        if resp.status_code == 201:
            msg = _LI("Created resource provider record via placement API "
                      "for resource provider with UUID {0} and name {1}.")
            msg = msg.format(uuid, name)
            LOG.info(msg)
            return objects.ResourceProvider(
                uuid=uuid,
                name=name,
                generation=1,
            )
        elif resp.status_code == 409:
            # Another thread concurrently created a resource provider with the
            # same UUID. Log a warning and then just return the resource
            # provider object from _get_resource_provider()
            msg = _LI("Another thread already created a resource provider "
                      "with the UUID {0}. Grabbing that record from "
                      "the placement API.")
            msg = msg.format(uuid)
            LOG.info(msg)
            return self._get_resource_provider(uuid)
        else:
            msg = _LE("Failed to create resource provider record in "
                      "placement API for UUID %(uuid)s. "
                      "Got %(status_code)d: %(err_text)s.")
            args = {
                'uuid': uuid,
                'status_code': resp.status_code,
                'err_text': resp.text,
            }
            LOG.error(msg, args)
    def test_set_inventory_over_capacity(self, mock_log):
        rp = objects.ResourceProvider(context=self.context,
                                      uuid=uuidsentinel.rp_uuid,
                                      name=uuidsentinel.rp_name)
        rp.create()

        disk_inv = objects.Inventory(
            resource_provider=rp,
            resource_class=fields.ResourceClass.DISK_GB,
            total=1024,
            reserved=15,
            min_unit=10,
            max_unit=100,
            step_size=10,
            allocation_ratio=1.0)
        vcpu_inv = objects.Inventory(resource_provider=rp,
                                     resource_class=fields.ResourceClass.VCPU,
                                     total=12,
                                     reserved=0,
                                     min_unit=1,
                                     max_unit=12,
                                     step_size=1,
                                     allocation_ratio=16.0)

        inv_list = objects.InventoryList(objects=[disk_inv, vcpu_inv])
        rp.set_inventory(inv_list)
        self.assertFalse(mock_log.warning.called)

        # Allocate something reasonable for the above inventory
        alloc = objects.Allocation(context=self.context,
                                   resource_provider=rp,
                                   consumer_id=uuidsentinel.consumer,
                                   resource_class='DISK_GB',
                                   used=512)
        alloc.create()

        # Update our inventory to over-subscribe us after the above allocation
        disk_inv.total = 400
        rp.set_inventory(inv_list)

        # We should succeed, but have logged a warning for going over on disk
        mock_log.warning.assert_called_once_with(mock.ANY, {
            'uuid': rp.uuid,
            'resource': 'DISK_GB'
        })
    def test_get_inventory_no_allocation(self):
        db_rp = objects.ResourceProvider(self.context,
                                         name=uuidsentinel.rp_no_inv,
                                         uuid=uuidsentinel.rp_no_inv)
        db_rp.create()
        inv = objects.Inventory(resource_provider=db_rp,
                                resource_class=fields.ResourceClass.DISK_GB,
                                total=1024)
        inv.obj_set_defaults()
        inv_list = objects.InventoryList(objects=[inv])
        db_rp.set_inventory(inv_list)

        usage_list = objects.UsageList.get_all_by_resource_provider_uuid(
            self.context, db_rp.uuid)
        self.assertEqual(1, len(usage_list))
        self.assertEqual(0, usage_list[0].usage)
        self.assertEqual(fields.ResourceClass.DISK_GB,
                         usage_list[0].resource_class)
 def test_destroy_resource_provider_destroy_inventory(self):
     resource_provider = objects.ResourceProvider(
         context=self.context,
         uuid=uuidsentinel.fake_resource_provider,
         name=uuidsentinel.fake_resource_name,
     )
     resource_provider.create()
     disk_inventory = objects.Inventory(context=self.context,
                                        resource_provider=resource_provider,
                                        **DISK_INVENTORY)
     disk_inventory.create()
     inventories = objects.InventoryList.get_all_by_resource_provider_uuid(
         self.context, resource_provider.uuid)
     self.assertEqual(1, len(inventories))
     resource_provider.destroy()
     inventories = objects.InventoryList.get_all_by_resource_provider_uuid(
         self.context, resource_provider.uuid)
     self.assertEqual(0, len(inventories))