Merge "Remove ResourceProviderList class"
This commit is contained in:
commit
7a4151e4f0
placement
handlers
objects
tests/functional/db
@ -321,10 +321,9 @@ def _resource_providers_by_uuid(ctx, rp_uuids):
|
||||
# TODO(jaypipes): Clearly, this is not efficient to do one query for
|
||||
# each resource provider UUID in the allocations instead of doing a
|
||||
# single query for all the UUIDs. However, since
|
||||
# ResourceProviderList.get_all_by_filters() is way too complicated for
|
||||
# rp_obj.get_all_by_filters() is way too complicated for
|
||||
# this purpose and doesn't raise NotFound anyway, we'll do this.
|
||||
# Perhaps consider adding a ResourceProviderList.get_all_by_uuids()
|
||||
# later on?
|
||||
# Perhaps consider adding a rp_obj.get_all_by_uuids() later on?
|
||||
try:
|
||||
res[rp_uuid] = rp_obj.ResourceProvider.get_by_uuid(ctx, rp_uuid)
|
||||
except exception.NotFound:
|
||||
|
@ -236,8 +236,7 @@ def list_resource_providers(req):
|
||||
value, allow_forbidden=allow_forbidden)
|
||||
filters[attr] = value
|
||||
try:
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
context, filters)
|
||||
resource_providers = rp_obj.get_all_by_filters(context, filters)
|
||||
except exception.ResourceClassNotFound as exc:
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
_('Invalid resource class in resources parameter: %(error)s') %
|
||||
|
@ -1,38 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
class ObjectList(object):
|
||||
# For FooList, ITEM_CLS = Foo
|
||||
ITEM_CLS = None
|
||||
|
||||
"""Provide listiness for objects which are a list of other objects."""
|
||||
def __init__(self, objects=None):
|
||||
self.objects = objects or []
|
||||
|
||||
def __len__(self):
|
||||
"""List length is a proxy for truthiness."""
|
||||
return len(self.objects)
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.objects[index]
|
||||
|
||||
def __repr__(self):
|
||||
strings = [repr(x) for x in self.objects]
|
||||
return "%s[%s]" % (self.__class__.__name__, ", ".join(strings))
|
||||
|
||||
@classmethod
|
||||
def _set_objects(cls, context, db_list):
|
||||
list_obj = cls()
|
||||
for db_item in db_list:
|
||||
list_obj.objects.append(cls.ITEM_CLS(context, **db_item))
|
||||
return list_obj
|
@ -34,7 +34,6 @@ from placement.db.sqlalchemy import models
|
||||
from placement import db_api
|
||||
from placement import exception
|
||||
from placement.i18n import _
|
||||
from placement.objects import common as common_obj
|
||||
from placement.objects import inventory as inv_obj
|
||||
from placement.objects import rp_candidates
|
||||
from placement.objects import trait as trait_obj
|
||||
@ -1089,9 +1088,8 @@ class ResourceProvider(object):
|
||||
# However as the RP's current parent is None the above
|
||||
# condition is the same as "the new parent cannot be any RP
|
||||
# from the current RP tree".
|
||||
same_tree = ResourceProviderList.get_all_by_filters(
|
||||
context,
|
||||
filters={'in_tree': self.uuid})
|
||||
same_tree = get_all_by_filters(
|
||||
context, filters={'in_tree': self.uuid})
|
||||
rp_uuids_in_the_same_tree = [rp.uuid for rp in same_tree]
|
||||
if parent_uuid in rp_uuids_in_the_same_tree:
|
||||
raise exception.ObjectActionError(
|
||||
@ -1282,206 +1280,202 @@ def get_providers_with_shared_capacity(ctx, rc_id, amount, member_of=None):
|
||||
return [r[0] for r in ctx.session.execute(sel)]
|
||||
|
||||
|
||||
class ResourceProviderList(common_obj.ObjectList):
|
||||
ITEM_CLS = ResourceProvider
|
||||
@db_api.placement_context_manager.reader
|
||||
def _get_all_by_filters_from_db(context, filters):
|
||||
# Eg. filters can be:
|
||||
# filters = {
|
||||
# 'name': <name>,
|
||||
# 'uuid': <uuid>,
|
||||
# 'member_of': [[<aggregate_uuid>, <aggregate_uuid>],
|
||||
# [<aggregate_uuid>]]
|
||||
# 'resources': {
|
||||
# 'VCPU': 1,
|
||||
# 'MEMORY_MB': 1024
|
||||
# },
|
||||
# 'in_tree': <uuid>,
|
||||
# 'required': [<trait_name>, ...]
|
||||
# }
|
||||
if not filters:
|
||||
filters = {}
|
||||
else:
|
||||
# Since we modify the filters, copy them so that we don't modify
|
||||
# them in the calling program.
|
||||
filters = copy.deepcopy(filters)
|
||||
name = filters.pop('name', None)
|
||||
uuid = filters.pop('uuid', None)
|
||||
member_of = filters.pop('member_of', [])
|
||||
required = set(filters.pop('required', []))
|
||||
forbidden = set([trait for trait in required
|
||||
if trait.startswith('!')])
|
||||
required = required - forbidden
|
||||
forbidden = set([trait.lstrip('!') for trait in forbidden])
|
||||
|
||||
@staticmethod
|
||||
@db_api.placement_context_manager.reader
|
||||
def _get_all_by_filters_from_db(context, filters):
|
||||
# Eg. filters can be:
|
||||
# filters = {
|
||||
# 'name': <name>,
|
||||
# 'uuid': <uuid>,
|
||||
# 'member_of': [[<aggregate_uuid>, <aggregate_uuid>],
|
||||
# [<aggregate_uuid>]]
|
||||
# 'resources': {
|
||||
# 'VCPU': 1,
|
||||
# 'MEMORY_MB': 1024
|
||||
# },
|
||||
# 'in_tree': <uuid>,
|
||||
# 'required': [<trait_name>, ...]
|
||||
# }
|
||||
if not filters:
|
||||
filters = {}
|
||||
else:
|
||||
# Since we modify the filters, copy them so that we don't modify
|
||||
# them in the calling program.
|
||||
filters = copy.deepcopy(filters)
|
||||
name = filters.pop('name', None)
|
||||
uuid = filters.pop('uuid', None)
|
||||
member_of = filters.pop('member_of', [])
|
||||
required = set(filters.pop('required', []))
|
||||
forbidden = set([trait for trait in required
|
||||
if trait.startswith('!')])
|
||||
required = required - forbidden
|
||||
forbidden = set([trait.lstrip('!') for trait in forbidden])
|
||||
resources = filters.pop('resources', {})
|
||||
# NOTE(sbauza): We want to key the dict by the resource class IDs
|
||||
# and we want to make sure those class names aren't incorrect.
|
||||
resources = {rc_cache.RC_CACHE.id_from_string(r_name): amount
|
||||
for r_name, amount in resources.items()}
|
||||
rp = sa.alias(_RP_TBL, name="rp")
|
||||
root_rp = sa.alias(_RP_TBL, name="root_rp")
|
||||
parent_rp = sa.alias(_RP_TBL, name="parent_rp")
|
||||
|
||||
resources = filters.pop('resources', {})
|
||||
# NOTE(sbauza): We want to key the dict by the resource class IDs
|
||||
# and we want to make sure those class names aren't incorrect.
|
||||
resources = {rc_cache.RC_CACHE.id_from_string(r_name): amount
|
||||
for r_name, amount in resources.items()}
|
||||
rp = sa.alias(_RP_TBL, name="rp")
|
||||
root_rp = sa.alias(_RP_TBL, name="root_rp")
|
||||
parent_rp = sa.alias(_RP_TBL, name="parent_rp")
|
||||
cols = [
|
||||
rp.c.id,
|
||||
rp.c.uuid,
|
||||
rp.c.name,
|
||||
rp.c.generation,
|
||||
rp.c.updated_at,
|
||||
rp.c.created_at,
|
||||
root_rp.c.uuid.label("root_provider_uuid"),
|
||||
parent_rp.c.uuid.label("parent_provider_uuid"),
|
||||
]
|
||||
|
||||
cols = [
|
||||
rp.c.id,
|
||||
rp.c.uuid,
|
||||
rp.c.name,
|
||||
rp.c.generation,
|
||||
rp.c.updated_at,
|
||||
rp.c.created_at,
|
||||
root_rp.c.uuid.label("root_provider_uuid"),
|
||||
parent_rp.c.uuid.label("parent_provider_uuid"),
|
||||
]
|
||||
# TODO(jaypipes): Convert this to an inner join once all
|
||||
# root_provider_id values are NOT NULL
|
||||
rp_to_root = sa.outerjoin(
|
||||
rp, root_rp,
|
||||
rp.c.root_provider_id == root_rp.c.id)
|
||||
rp_to_parent = sa.outerjoin(
|
||||
rp_to_root, parent_rp,
|
||||
rp.c.parent_provider_id == parent_rp.c.id)
|
||||
|
||||
# TODO(jaypipes): Convert this to an inner join once all
|
||||
# root_provider_id values are NOT NULL
|
||||
rp_to_root = sa.outerjoin(
|
||||
rp, root_rp,
|
||||
rp.c.root_provider_id == root_rp.c.id)
|
||||
rp_to_parent = sa.outerjoin(
|
||||
rp_to_root, parent_rp,
|
||||
rp.c.parent_provider_id == parent_rp.c.id)
|
||||
query = sa.select(cols).select_from(rp_to_parent)
|
||||
|
||||
query = sa.select(cols).select_from(rp_to_parent)
|
||||
|
||||
if name:
|
||||
query = query.where(rp.c.name == name)
|
||||
if uuid:
|
||||
query = query.where(rp.c.uuid == uuid)
|
||||
if 'in_tree' in filters:
|
||||
# The 'in_tree' parameter is the UUID of a resource provider that
|
||||
# the caller wants to limit the returned providers to only those
|
||||
# within its "provider tree". So, we look up the resource provider
|
||||
# having the UUID specified by the 'in_tree' parameter and grab the
|
||||
# root_provider_id value of that record. We can then ask for only
|
||||
# those resource providers having a root_provider_id of that value.
|
||||
tree_uuid = filters.pop('in_tree')
|
||||
tree_ids = provider_ids_from_uuid(context, tree_uuid)
|
||||
if tree_ids is None:
|
||||
# List operations should simply return an empty list when a
|
||||
# non-existing resource provider UUID is given.
|
||||
return []
|
||||
root_id = tree_ids.root_id
|
||||
# TODO(jaypipes): Remove this OR condition when root_provider_id
|
||||
# is not nullable in the database and all resource provider records
|
||||
# have populated the root provider ID.
|
||||
where_cond = sa.or_(
|
||||
rp.c.id == root_id,
|
||||
rp.c.root_provider_id == root_id)
|
||||
query = query.where(where_cond)
|
||||
|
||||
# Get the provider IDs matching any specified traits and/or aggregates
|
||||
rp_ids, forbidden_rp_ids = get_provider_ids_for_traits_and_aggs(
|
||||
context, required, forbidden, member_of)
|
||||
if rp_ids is None:
|
||||
# If no providers match the traits/aggs, we can short out
|
||||
if name:
|
||||
query = query.where(rp.c.name == name)
|
||||
if uuid:
|
||||
query = query.where(rp.c.uuid == uuid)
|
||||
if 'in_tree' in filters:
|
||||
# The 'in_tree' parameter is the UUID of a resource provider that
|
||||
# the caller wants to limit the returned providers to only those
|
||||
# within its "provider tree". So, we look up the resource provider
|
||||
# having the UUID specified by the 'in_tree' parameter and grab the
|
||||
# root_provider_id value of that record. We can then ask for only
|
||||
# those resource providers having a root_provider_id of that value.
|
||||
tree_uuid = filters.pop('in_tree')
|
||||
tree_ids = provider_ids_from_uuid(context, tree_uuid)
|
||||
if tree_ids is None:
|
||||
# List operations should simply return an empty list when a
|
||||
# non-existing resource provider UUID is given.
|
||||
return []
|
||||
if rp_ids:
|
||||
query = query.where(rp.c.id.in_(rp_ids))
|
||||
# forbidden providers, if found, are mutually exclusive with matching
|
||||
# providers above, so we only need to include this clause if we didn't
|
||||
# use the positive filter above.
|
||||
elif forbidden_rp_ids:
|
||||
query = query.where(~rp.c.id.in_(forbidden_rp_ids))
|
||||
root_id = tree_ids.root_id
|
||||
# TODO(jaypipes): Remove this OR condition when root_provider_id
|
||||
# is not nullable in the database and all resource provider records
|
||||
# have populated the root provider ID.
|
||||
where_cond = sa.or_(
|
||||
rp.c.id == root_id,
|
||||
rp.c.root_provider_id == root_id)
|
||||
query = query.where(where_cond)
|
||||
|
||||
if not resources:
|
||||
# Returns quickly the list in case we don't need to check the
|
||||
# resource usage
|
||||
res = context.session.execute(query).fetchall()
|
||||
return [dict(r) for r in res]
|
||||
|
||||
# NOTE(sbauza): In case we want to look at the resource criteria, then
|
||||
# the SQL generated from this case looks something like:
|
||||
# SELECT
|
||||
# rp.*
|
||||
# FROM resource_providers AS rp
|
||||
# JOIN inventories AS inv
|
||||
# ON rp.id = inv.resource_provider_id
|
||||
# LEFT JOIN (
|
||||
# SELECT resource_provider_id, resource_class_id, SUM(used) AS used
|
||||
# FROM allocations
|
||||
# WHERE resource_class_id IN ($RESOURCE_CLASSES)
|
||||
# GROUP BY resource_provider_id, resource_class_id
|
||||
# ) AS usage
|
||||
# ON inv.resource_provider_id = usage.resource_provider_id
|
||||
# AND inv.resource_class_id = usage.resource_class_id
|
||||
# AND (inv.resource_class_id = $X AND (used + $AMOUNT_X <= (
|
||||
# total - reserved) * inv.allocation_ratio) AND
|
||||
# inv.min_unit <= $AMOUNT_X AND inv.max_unit >= $AMOUNT_X AND
|
||||
# $AMOUNT_X % inv.step_size == 0)
|
||||
# OR (inv.resource_class_id = $Y AND (used + $AMOUNT_Y <= (
|
||||
# total - reserved) * inv.allocation_ratio) AND
|
||||
# inv.min_unit <= $AMOUNT_Y AND inv.max_unit >= $AMOUNT_Y AND
|
||||
# $AMOUNT_Y % inv.step_size == 0)
|
||||
# OR (inv.resource_class_id = $Z AND (used + $AMOUNT_Z <= (
|
||||
# total - reserved) * inv.allocation_ratio) AND
|
||||
# inv.min_unit <= $AMOUNT_Z AND inv.max_unit >= $AMOUNT_Z AND
|
||||
# $AMOUNT_Z % inv.step_size == 0))
|
||||
# GROUP BY rp.id
|
||||
# HAVING
|
||||
# COUNT(DISTINCT(inv.resource_class_id)) == len($RESOURCE_CLASSES)
|
||||
#
|
||||
# with a possible additional WHERE clause for the name and uuid that
|
||||
# comes from the above filters
|
||||
|
||||
# First JOIN between inventories and RPs is here
|
||||
inv_join = sa.join(
|
||||
rp_to_parent,
|
||||
_INV_TBL,
|
||||
rp.c.id == _INV_TBL.c.resource_provider_id)
|
||||
|
||||
# Now, below is the LEFT JOIN for getting the allocations usage
|
||||
usage = _usage_select(list(resources))
|
||||
usage_join = sa.outerjoin(
|
||||
inv_join, usage, sa.and_(
|
||||
usage.c.resource_provider_id == (
|
||||
_INV_TBL.c.resource_provider_id),
|
||||
usage.c.resource_class_id == _INV_TBL.c.resource_class_id))
|
||||
|
||||
# And finally, we verify for each resource class if the requested
|
||||
# amount isn't more than the left space (considering the allocation
|
||||
# ratio, the reserved space and the min and max amount possible sizes)
|
||||
where_clauses = [
|
||||
sa.and_(
|
||||
_INV_TBL.c.resource_class_id == r_idx,
|
||||
_capacity_check_clause(amount, usage)
|
||||
)
|
||||
for (r_idx, amount) in resources.items()]
|
||||
query = query.select_from(usage_join)
|
||||
query = query.where(sa.or_(*where_clauses))
|
||||
query = query.group_by(rp.c.id, root_rp.c.uuid, parent_rp.c.uuid)
|
||||
# NOTE(sbauza): Only RPs having all the asked resources can be provided
|
||||
query = query.having(sql.func.count(
|
||||
sa.distinct(_INV_TBL.c.resource_class_id)) == len(resources))
|
||||
# Get the provider IDs matching any specified traits and/or aggregates
|
||||
rp_ids, forbidden_rp_ids = get_provider_ids_for_traits_and_aggs(
|
||||
context, required, forbidden, member_of)
|
||||
if rp_ids is None:
|
||||
# If no providers match the traits/aggs, we can short out
|
||||
return []
|
||||
if rp_ids:
|
||||
query = query.where(rp.c.id.in_(rp_ids))
|
||||
# forbidden providers, if found, are mutually exclusive with matching
|
||||
# providers above, so we only need to include this clause if we didn't
|
||||
# use the positive filter above.
|
||||
elif forbidden_rp_ids:
|
||||
query = query.where(~rp.c.id.in_(forbidden_rp_ids))
|
||||
|
||||
if not resources:
|
||||
# Returns quickly the list in case we don't need to check the
|
||||
# resource usage
|
||||
res = context.session.execute(query).fetchall()
|
||||
return [dict(r) for r in res]
|
||||
|
||||
@classmethod
|
||||
def get_all_by_filters(cls, context, filters=None):
|
||||
"""Returns a list of `ResourceProvider` objects that have sufficient
|
||||
resources in their inventories to satisfy the amounts specified in the
|
||||
`filters` parameter.
|
||||
# NOTE(sbauza): In case we want to look at the resource criteria, then
|
||||
# the SQL generated from this case looks something like:
|
||||
# SELECT
|
||||
# rp.*
|
||||
# FROM resource_providers AS rp
|
||||
# JOIN inventories AS inv
|
||||
# ON rp.id = inv.resource_provider_id
|
||||
# LEFT JOIN (
|
||||
# SELECT resource_provider_id, resource_class_id, SUM(used) AS used
|
||||
# FROM allocations
|
||||
# WHERE resource_class_id IN ($RESOURCE_CLASSES)
|
||||
# GROUP BY resource_provider_id, resource_class_id
|
||||
# ) AS usage
|
||||
# ON inv.resource_provider_id = usage.resource_provider_id
|
||||
# AND inv.resource_class_id = usage.resource_class_id
|
||||
# AND (inv.resource_class_id = $X AND (used + $AMOUNT_X <= (
|
||||
# total - reserved) * inv.allocation_ratio) AND
|
||||
# inv.min_unit <= $AMOUNT_X AND inv.max_unit >= $AMOUNT_X AND
|
||||
# $AMOUNT_X % inv.step_size == 0)
|
||||
# OR (inv.resource_class_id = $Y AND (used + $AMOUNT_Y <= (
|
||||
# total - reserved) * inv.allocation_ratio) AND
|
||||
# inv.min_unit <= $AMOUNT_Y AND inv.max_unit >= $AMOUNT_Y AND
|
||||
# $AMOUNT_Y % inv.step_size == 0)
|
||||
# OR (inv.resource_class_id = $Z AND (used + $AMOUNT_Z <= (
|
||||
# total - reserved) * inv.allocation_ratio) AND
|
||||
# inv.min_unit <= $AMOUNT_Z AND inv.max_unit >= $AMOUNT_Z AND
|
||||
# $AMOUNT_Z % inv.step_size == 0))
|
||||
# GROUP BY rp.id
|
||||
# HAVING
|
||||
# COUNT(DISTINCT(inv.resource_class_id)) == len($RESOURCE_CLASSES)
|
||||
#
|
||||
# with a possible additional WHERE clause for the name and uuid that
|
||||
# comes from the above filters
|
||||
|
||||
If no resource providers can be found, the function will return an
|
||||
empty list.
|
||||
# First JOIN between inventories and RPs is here
|
||||
inv_join = sa.join(
|
||||
rp_to_parent,
|
||||
_INV_TBL,
|
||||
rp.c.id == _INV_TBL.c.resource_provider_id)
|
||||
|
||||
:param context: `placement.context.RequestContext` that may be used to
|
||||
grab a DB connection.
|
||||
:param filters: Can be `name`, `uuid`, `member_of`, `in_tree` or
|
||||
`resources` where `member_of` is a list of list of
|
||||
aggregate UUIDs, `in_tree` is a UUID of a resource
|
||||
provider that we can use to find the root provider ID
|
||||
of the tree of providers to filter results by and
|
||||
`resources` is a dict of amounts keyed by resource
|
||||
classes.
|
||||
:type filters: dict
|
||||
"""
|
||||
resource_providers = cls._get_all_by_filters_from_db(context, filters)
|
||||
return cls._set_objects(context, resource_providers)
|
||||
# Now, below is the LEFT JOIN for getting the allocations usage
|
||||
usage = _usage_select(list(resources))
|
||||
usage_join = sa.outerjoin(
|
||||
inv_join, usage, sa.and_(
|
||||
usage.c.resource_provider_id == (
|
||||
_INV_TBL.c.resource_provider_id),
|
||||
usage.c.resource_class_id == _INV_TBL.c.resource_class_id))
|
||||
|
||||
# And finally, we verify for each resource class if the requested
|
||||
# amount isn't more than the left space (considering the allocation
|
||||
# ratio, the reserved space and the min and max amount possible sizes)
|
||||
where_clauses = [
|
||||
sa.and_(
|
||||
_INV_TBL.c.resource_class_id == r_idx,
|
||||
_capacity_check_clause(amount, usage)
|
||||
)
|
||||
for (r_idx, amount) in resources.items()]
|
||||
query = query.select_from(usage_join)
|
||||
query = query.where(sa.or_(*where_clauses))
|
||||
query = query.group_by(rp.c.id, root_rp.c.uuid, parent_rp.c.uuid)
|
||||
# NOTE(sbauza): Only RPs having all the asked resources can be provided
|
||||
query = query.having(sql.func.count(
|
||||
sa.distinct(_INV_TBL.c.resource_class_id)) == len(resources))
|
||||
|
||||
res = context.session.execute(query).fetchall()
|
||||
return [dict(r) for r in res]
|
||||
|
||||
|
||||
def get_all_by_filters(context, filters=None):
|
||||
"""Returns a list of `ResourceProvider` objects that have sufficient
|
||||
resources in their inventories to satisfy the amounts specified in the
|
||||
`filters` parameter.
|
||||
|
||||
If no resource providers can be found, the function will return an
|
||||
empty list.
|
||||
|
||||
:param context: `placement.context.RequestContext` that may be used to
|
||||
grab a DB connection.
|
||||
:param filters: Can be `name`, `uuid`, `member_of`, `in_tree` or
|
||||
`resources` where `member_of` is a list of list of
|
||||
aggregate UUIDs, `in_tree` is a UUID of a resource
|
||||
provider that we can use to find the root provider ID
|
||||
of the tree of providers to filter results by and
|
||||
`resources` is a dict of amounts keyed by resource
|
||||
classes.
|
||||
:type filters: dict
|
||||
"""
|
||||
resource_providers = _get_all_by_filters_from_db(context, filters)
|
||||
return [ResourceProvider(context, **rp) for rp in resource_providers]
|
||||
|
||||
|
||||
@db_api.placement_context_manager.reader
|
||||
|
@ -186,7 +186,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
# Check the new-style providers remains in a tree,
|
||||
# which means the root provider ids are not changed
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.root_rp,
|
||||
@ -282,7 +282,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
tb.add_inventory(grandchild_rp, orc.VCPU, 1)
|
||||
|
||||
# Check all providers returned when getting by root UUID
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.root_rp,
|
||||
@ -291,7 +291,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
self.assertEqual(3, len(rps))
|
||||
|
||||
# Check all providers returned when getting by child UUID
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.child_rp,
|
||||
@ -300,7 +300,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
self.assertEqual(3, len(rps))
|
||||
|
||||
# Check all providers returned when getting by grandchild UUID
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.grandchild_rp,
|
||||
@ -313,7 +313,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
# No aggregate associations yet, so expect no records when adding a
|
||||
# member_of filter
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'member_of': [[uuidsentinel.agg]],
|
||||
@ -326,7 +326,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
# the grandchild is returned when asking for the grandchild's tree
|
||||
# along with the aggregate as member_of
|
||||
grandchild_rp.set_aggregates([uuidsentinel.agg])
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'member_of': [[uuidsentinel.agg]],
|
||||
@ -337,7 +337,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
self.assertEqual(uuidsentinel.grandchild_rp, rps[0].uuid)
|
||||
|
||||
# Try filtering on an unknown UUID and verify no results
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'uuid': uuidsentinel.unknown_rp,
|
||||
@ -348,7 +348,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
# And now check that filtering for just the child's UUID along with the
|
||||
# tree produces just a single provider (the child)
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'uuid': uuidsentinel.child_rp,
|
||||
@ -361,7 +361,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
# Ensure that the resources filter also continues to work properly with
|
||||
# the in_tree filter. Request resources that none of the providers
|
||||
# currently have and ensure no providers are returned
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.grandchild_rp,
|
||||
@ -373,7 +373,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
self.assertEqual(0, len(rps))
|
||||
|
||||
# And now ask for one VCPU, which should only return us the grandchild
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.grandchild_rp,
|
||||
@ -387,7 +387,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
# Finally, verify we still get the grandchild if filtering on the
|
||||
# parent's UUID as in_tree
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.child_rp,
|
||||
@ -426,13 +426,13 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
"""
|
||||
# Passing a non-existing resource provider UUID should return an empty
|
||||
# list
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.rp1,
|
||||
}
|
||||
)
|
||||
self.assertEqual([], rps.objects)
|
||||
self.assertEqual([], rps)
|
||||
|
||||
rp_tbl = rp_obj._RP_TBL
|
||||
conn = self.placement_db.get_engine().connect()
|
||||
@ -454,7 +454,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||
# don't have any migrations messing with the end result.
|
||||
with mock.patch('placement.objects.resource_provider.'
|
||||
'_set_root_provider_id'):
|
||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'in_tree': uuidsentinel.rp1,
|
||||
@ -796,13 +796,13 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
'rp_name_' + rp_i,
|
||||
uuid=getattr(uuidsentinel, 'rp_uuid_' + rp_i))
|
||||
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx)
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, filters={'name': u'rp_name_1'})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, filters={'uuid': uuidsentinel.rp_uuid_2})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
self.assertEqual('rp_name_2', resource_providers[0].name)
|
||||
@ -824,55 +824,55 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
# Both RPs should accept that request given the only current allocation
|
||||
# for the first RP is leaving one VCPU
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.VCPU: 1}})
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
# Now, when asking for 2 VCPUs, only the second RP should accept that
|
||||
# given the current allocation for the first RP
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.VCPU: 2}})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
# Adding a second resource request should be okay for the 2nd RP
|
||||
# given it has enough disk but we also need to make sure that the
|
||||
# first RP is not acceptable because of the VCPU request
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.VCPU: 2, orc.DISK_GB: 1022}})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
# Now, we are asking for both disk and VCPU resources that all the RPs
|
||||
# can't accept (as the 2nd RP is having a reserved size)
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.VCPU: 2, orc.DISK_GB: 1024}})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
|
||||
# We also want to verify that asking for a specific RP can also be
|
||||
# checking the resource usage.
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'name': u'rp_name_1',
|
||||
'resources': {orc.VCPU: 1}})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
|
||||
# Let's verify that the min and max units are checked too
|
||||
# Case 1: amount is in between min and max and modulo step_size
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.MEMORY_MB: 2}})
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
# Case 2: amount is less than min_unit
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.MEMORY_MB: 1}})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
# Case 3: amount is more than min_unit
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.MEMORY_MB: 5}})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
# Case 4: amount is not modulo step_size
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, {'resources': {orc.MEMORY_MB: 3}})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
|
||||
def test_get_all_by_filters_with_resources_not_existing(self):
|
||||
self.assertRaises(
|
||||
exception.ResourceClassNotFound,
|
||||
rp_obj.ResourceProviderList.get_all_by_filters,
|
||||
rp_obj.get_all_by_filters,
|
||||
self.ctx, {'resources': {'FOOBAR': 3}})
|
||||
|
||||
def test_get_all_by_filters_aggregate(self):
|
||||
@ -882,7 +882,7 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
'rp_name_' + str(rp_i), *aggs,
|
||||
uuid=getattr(uuidsentinel, 'rp_uuid_' + str(rp_i)))
|
||||
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx, filters={'member_of': [[uuidsentinel.agg_a]]})
|
||||
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
@ -892,24 +892,24 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
self.assertNotIn('rp_name_2', names)
|
||||
self.assertNotIn('rp_name_4', names)
|
||||
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={'member_of': [[uuidsentinel.agg_a, uuidsentinel.agg_b]]})
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={'member_of': [[uuidsentinel.agg_a, uuidsentinel.agg_b]],
|
||||
'name': u'rp_name_1'})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={'member_of': [[uuidsentinel.agg_a, uuidsentinel.agg_b]],
|
||||
'name': u'barnabas'})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
|
||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
resource_providers = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={'member_of': [[uuidsentinel.agg_1, uuidsentinel.agg_2]]})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
@ -931,7 +931,7 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
tb.set_traits(rp, *traits)
|
||||
|
||||
# Three rps (1, 2, 3) should have CUSTOM_TRAIT_A
|
||||
custom_a_rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
custom_a_rps = rp_obj.get_all_by_filters(
|
||||
self.ctx, filters={'required': ['CUSTOM_TRAIT_A']})
|
||||
self.assertEqual(3, len(custom_a_rps))
|
||||
rp_names = [a_rp.name for a_rp in custom_a_rps]
|
||||
@ -940,7 +940,7 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
# One rp (rp 1) if we forbid CUSTOM_TRAIT_B, with a single trait of
|
||||
# CUSTOM_TRAIT_A
|
||||
custom_a_rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||
custom_a_rps = rp_obj.get_all_by_filters(
|
||||
self.ctx,
|
||||
filters={'required': ['CUSTOM_TRAIT_A', '!CUSTOM_TRAIT_B']})
|
||||
self.assertEqual(1, len(custom_a_rps))
|
||||
|
Loading…
x
Reference in New Issue
Block a user