def test_find(self): rp = resource_provider.ResourceProvider( self.context, uuid=uuids.rp_uuid) inv_list = [ inventory.Inventory( resource_provider=rp, resource_class=orc.VCPU, total=24), inventory.Inventory( resource_provider=rp, resource_class=orc.MEMORY_MB, total=10240), ] found = inventory.find(inv_list, orc.MEMORY_MB) self.assertIsNotNone(found) self.assertEqual(10240, found.total) found = inventory.find(inv_list, orc.VCPU) self.assertIsNotNone(found) self.assertEqual(24, found.total) found = inventory.find(inv_list, orc.DISK_GB) self.assertIsNone(found) # Try an integer resource class identifier... self.assertRaises(ValueError, inventory.find, inv_list, VCPU_ID) # Use an invalid string... self.assertIsNone(inventory.find(inv_list, 'HOUSE'))
def get_inventory(req): """GET one inventory. On success return a 200 an application/json body representing one inventory. """ context = req.environ['placement.context'] context.can(policies.SHOW) uuid = util.wsgi_path_item(req.environ, 'uuid') resource_class = util.wsgi_path_item(req.environ, 'resource_class') try: rp = rp_obj.ResourceProvider.get_by_uuid(context, uuid) except exception.NotFound as exc: raise webob.exc.HTTPNotFound( _("No resource provider with uuid %(uuid)s found : %(error)s") % {'uuid': uuid, 'error': exc}) inv_list = inv_obj.get_all_by_resource_provider(context, rp) inventory = inv_obj.find(inv_list, resource_class) if not inventory: raise webob.exc.HTTPNotFound( _('No inventory of class %(class)s for %(rp_uuid)s') % {'class': resource_class, 'rp_uuid': uuid}) return _send_inventory(req, rp, inventory)
def _update_inventory_for_provider(ctx, rp, inv_list, to_update): """Updates existing inventory records for the supplied resource provider. :param ctx: `placement.context.RequestContext` that contains an oslo_db Session :param rp: Resource provider on which to update inventory. :param inv_list: List of Inventory objects :param to_update: set() containing resource class IDs to search inv_list for updating in resource provider. :returns: A list of (uuid, class) tuples that have exceeded their capacity after this inventory update. """ exceeded = [] for rc_id in to_update: rc_str = ctx.rc_cache.string_from_id(rc_id) inv_record = inv_obj.find(inv_list, rc_str) allocation_query = sa.select( [func.sum(_ALLOC_TBL.c.used).label('usage')]) allocation_query = allocation_query.where( sa.and_( _ALLOC_TBL.c.resource_provider_id == rp.id, _ALLOC_TBL.c.resource_class_id == rc_id)) allocations = ctx.session.execute(allocation_query).first() if (allocations and allocations['usage'] is not None and allocations['usage'] > inv_record.capacity): exceeded.append((rp.uuid, rc_str)) upd_stmt = _INV_TBL.update().where( sa.and_( _INV_TBL.c.resource_provider_id == rp.id, _INV_TBL.c.resource_class_id == rc_id) ).values( total=inv_record.total, reserved=inv_record.reserved, min_unit=inv_record.min_unit, max_unit=inv_record.max_unit, step_size=inv_record.step_size, allocation_ratio=inv_record.allocation_ratio) res = ctx.session.execute(upd_stmt) if not res.rowcount: raise exception.InventoryWithResourceClassNotFound( resource_class=rc_str) return exceeded
def _add_inventory_to_provider(ctx, rp, inv_list, to_add): """Inserts new inventory records for the supplied resource provider. :param ctx: `placement.context.RequestContext` that contains an oslo_db Session :param rp: Resource provider to add inventory to. :param inv_list: List of Inventory objects :param to_add: set() containing resource class IDs to search inv_list for adding to resource provider. """ for rc_id in to_add: rc_str = ctx.rc_cache.string_from_id(rc_id) inv_record = inv_obj.find(inv_list, rc_str) ins_stmt = _INV_TBL.insert().values( resource_provider_id=rp.id, resource_class_id=rc_id, total=inv_record.total, reserved=inv_record.reserved, min_unit=inv_record.min_unit, max_unit=inv_record.max_unit, step_size=inv_record.step_size, allocation_ratio=inv_record.allocation_ratio) ctx.session.execute(ins_stmt)
def test_provider_modify_inventory(self): rp = self._create_provider(uuidsentinel.rp_name) saved_generation = rp.generation disk_inv = tb.add_inventory(rp, orc.DISK_GB, 1024, reserved=15, min_unit=10, max_unit=100, step_size=10) vcpu_inv = tb.add_inventory(rp, orc.VCPU, 12, allocation_ratio=16.0) # generation has bumped once for each add self.assertEqual(saved_generation + 2, rp.generation) saved_generation = rp.generation new_inv_list = inv_obj.get_all_by_resource_provider(self.ctx, rp) self.assertEqual(2, len(new_inv_list)) resource_classes = [inv.resource_class for inv in new_inv_list] self.assertIn(orc.VCPU, resource_classes) self.assertIn(orc.DISK_GB, resource_classes) # reset inventory to just disk_inv rp.set_inventory([disk_inv]) # generation has bumped self.assertEqual(saved_generation + 1, rp.generation) saved_generation = rp.generation new_inv_list = inv_obj.get_all_by_resource_provider(self.ctx, rp) self.assertEqual(1, len(new_inv_list)) resource_classes = [inv.resource_class for inv in new_inv_list] self.assertNotIn(orc.VCPU, resource_classes) self.assertIn(orc.DISK_GB, resource_classes) self.assertEqual(1024, new_inv_list[0].total) # update existing disk inv to new settings disk_inv = inv_obj.Inventory( resource_provider=rp, resource_class=orc.DISK_GB, total=2048, reserved=15, min_unit=10, max_unit=100, step_size=10, allocation_ratio=1.0) rp.update_inventory(disk_inv) # generation has bumped self.assertEqual(saved_generation + 1, rp.generation) saved_generation = rp.generation new_inv_list = inv_obj.get_all_by_resource_provider(self.ctx, rp) self.assertEqual(1, len(new_inv_list)) self.assertEqual(2048, new_inv_list[0].total) # delete inventory rp.delete_inventory(orc.DISK_GB) # generation has bumped self.assertEqual(saved_generation + 1, rp.generation) saved_generation = rp.generation new_inv_list = inv_obj.get_all_by_resource_provider(self.ctx, rp) result = inv_obj.find(new_inv_list, orc.DISK_GB) self.assertIsNone(result) self.assertRaises(exception.NotFound, rp.delete_inventory, orc.DISK_GB) # check inventory list is empty inv_list = inv_obj.get_all_by_resource_provider(self.ctx, rp) self.assertEqual(0, len(inv_list)) # add some inventory rp.add_inventory(vcpu_inv) inv_list = inv_obj.get_all_by_resource_provider(self.ctx, rp) self.assertEqual(1, len(inv_list)) # generation has bumped self.assertEqual(saved_generation + 1, rp.generation) saved_generation = rp.generation # add same inventory again self.assertRaises(db_exc.DBDuplicateEntry, rp.add_inventory, vcpu_inv) # generation has not bumped self.assertEqual(saved_generation, rp.generation) # fail when generation wrong rp.generation = rp.generation - 1 self.assertRaises(exception.ConcurrentUpdateDetected, rp.set_inventory, inv_list)