Merge "Use os-resource-classes in placement"
This commit is contained in:
commit
1e213276bb
|
@ -41,6 +41,7 @@ mox3==0.20.0
|
||||||
msgpack-python==0.5.6
|
msgpack-python==0.5.6
|
||||||
netaddr==0.7.18
|
netaddr==0.7.18
|
||||||
netifaces==0.10.4
|
netifaces==0.10.4
|
||||||
|
os-resource-classes==0.1.0
|
||||||
os-client-config==1.29.0
|
os-client-config==1.29.0
|
||||||
os-service-types==1.2.0
|
os-service-types==1.2.0
|
||||||
os-traits==0.4.0
|
os-traits==0.4.0
|
||||||
|
|
|
@ -97,6 +97,7 @@ def update_database():
|
||||||
"""
|
"""
|
||||||
ctx = db_api.DbContext()
|
ctx = db_api.DbContext()
|
||||||
resource_provider.ensure_trait_sync(ctx)
|
resource_provider.ensure_trait_sync(ctx)
|
||||||
|
resource_provider.ensure_resource_classes_sync(ctx)
|
||||||
resource_provider.ensure_rc_cache(ctx)
|
resource_provider.ensure_rc_cache(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import random
|
||||||
# not be registered and there is no need to express VERSIONs nor handle
|
# not be registered and there is no need to express VERSIONs nor handle
|
||||||
# obj_make_compatible.
|
# obj_make_compatible.
|
||||||
|
|
||||||
|
import os_resource_classes as orc
|
||||||
import os_traits
|
import os_traits
|
||||||
from oslo_concurrency import lockutils
|
from oslo_concurrency import lockutils
|
||||||
from oslo_db import api as oslo_db_api
|
from oslo_db import api as oslo_db_api
|
||||||
|
@ -43,7 +44,6 @@ from placement.i18n import _
|
||||||
from placement.objects import consumer as consumer_obj
|
from placement.objects import consumer as consumer_obj
|
||||||
from placement.objects import project as project_obj
|
from placement.objects import project as project_obj
|
||||||
from placement.objects import user as user_obj
|
from placement.objects import user as user_obj
|
||||||
from placement import rc_fields
|
|
||||||
from placement import resource_class_cache as rc_cache
|
from placement import resource_class_cache as rc_cache
|
||||||
|
|
||||||
_TRAIT_TBL = models.Trait.__table__
|
_TRAIT_TBL = models.Trait.__table__
|
||||||
|
@ -59,6 +59,8 @@ _PROJECT_TBL = models.Project.__table__
|
||||||
_USER_TBL = models.User.__table__
|
_USER_TBL = models.User.__table__
|
||||||
_CONSUMER_TBL = models.Consumer.__table__
|
_CONSUMER_TBL = models.Consumer.__table__
|
||||||
_RC_CACHE = None
|
_RC_CACHE = None
|
||||||
|
_RESOURCE_CLASSES_LOCK = 'resource_classes_sync'
|
||||||
|
_RESOURCE_CLASSES_SYNCED = False
|
||||||
_TRAIT_LOCK = 'trait_sync'
|
_TRAIT_LOCK = 'trait_sync'
|
||||||
_TRAITS_SYNCED = False
|
_TRAITS_SYNCED = False
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ def ensure_rc_cache(ctx):
|
||||||
@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True)
|
@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True)
|
||||||
# Bug #1760322: If the caller raises an exception, we don't want the trait
|
# Bug #1760322: If the caller raises an exception, we don't want the trait
|
||||||
# sync rolled back; so use an .independent transaction
|
# sync rolled back; so use an .independent transaction
|
||||||
@db_api.placement_context_manager.writer.independent
|
@db_api.placement_context_manager.writer
|
||||||
def _trait_sync(ctx):
|
def _trait_sync(ctx):
|
||||||
"""Sync the os_traits symbols to the database.
|
"""Sync the os_traits symbols to the database.
|
||||||
|
|
||||||
|
@ -145,6 +147,47 @@ def ensure_trait_sync(ctx):
|
||||||
_TRAITS_SYNCED = True
|
_TRAITS_SYNCED = True
|
||||||
|
|
||||||
|
|
||||||
|
@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True)
|
||||||
|
@db_api.placement_context_manager.writer
|
||||||
|
def _resource_classes_sync(ctx):
|
||||||
|
# Create a set of all resource class in the os_resource_classes library.
|
||||||
|
sel = sa.select([_RC_TBL.c.name])
|
||||||
|
res = ctx.session.execute(sel).fetchall()
|
||||||
|
db_classes = [r[0] for r in res if not orc.is_custom(r[0])]
|
||||||
|
LOG.debug("Found existing resource classes in db: %s", db_classes)
|
||||||
|
# Determine those resource clases which are in os_resource_classes but not
|
||||||
|
# currently in the database, and insert them.
|
||||||
|
batch_args = [{'name': six.text_type(name), 'id': index}
|
||||||
|
for index, name in enumerate(orc.STANDARDS)
|
||||||
|
if name not in db_classes]
|
||||||
|
ins = _RC_TBL.insert()
|
||||||
|
if batch_args:
|
||||||
|
conn = ctx.session.connection()
|
||||||
|
if conn.engine.dialect.name == 'mysql':
|
||||||
|
# We need to do a literal insert of 0 to preserve the order
|
||||||
|
# of the resource class ids from the previous style of
|
||||||
|
# managing them. In some mysql settings a 0 is the same as
|
||||||
|
# "give me a default key".
|
||||||
|
conn.execute("SET SESSION SQL_MODE='NO_AUTO_VALUE_ON_ZERO'")
|
||||||
|
try:
|
||||||
|
ctx.session.execute(ins, batch_args)
|
||||||
|
LOG.info("Synced resource_classes from os_resource_classes: %s",
|
||||||
|
batch_args)
|
||||||
|
except db_exc.DBDuplicateEntry:
|
||||||
|
pass # some other process sync'd, just ignore
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_resource_classes_sync(ctx):
|
||||||
|
global _RESOURCE_CLASSES_SYNCED
|
||||||
|
# If another thread is doing this work, wait for it to complete.
|
||||||
|
# When that thread is done _RESOURCE_CLASSES_SYNCED will be true in this
|
||||||
|
# thread and we'll simply return.
|
||||||
|
with lockutils.lock(_RESOURCE_CLASSES_LOCK):
|
||||||
|
if not _RESOURCE_CLASSES_SYNCED:
|
||||||
|
_resource_classes_sync(ctx)
|
||||||
|
_RESOURCE_CLASSES_SYNCED = True
|
||||||
|
|
||||||
|
|
||||||
def _usage_select(rc_ids):
|
def _usage_select(rc_ids):
|
||||||
usage = sa.select([_ALLOC_TBL.c.resource_provider_id,
|
usage = sa.select([_ALLOC_TBL.c.resource_provider_id,
|
||||||
_ALLOC_TBL.c.resource_class_id,
|
_ALLOC_TBL.c.resource_class_id,
|
||||||
|
@ -310,7 +353,7 @@ def _add_inventory(context, rp, inventory):
|
||||||
"""Add one Inventory that wasn't already on the provider.
|
"""Add one Inventory that wasn't already on the provider.
|
||||||
|
|
||||||
:raises `exception.ResourceClassNotFound` if inventory.resource_class
|
:raises `exception.ResourceClassNotFound` if inventory.resource_class
|
||||||
cannot be found in either the standard classes or the DB.
|
cannot be found in the DB.
|
||||||
"""
|
"""
|
||||||
rc_id = _RC_CACHE.id_from_string(inventory.resource_class)
|
rc_id = _RC_CACHE.id_from_string(inventory.resource_class)
|
||||||
inv_list = InventoryList(objects=[inventory])
|
inv_list = InventoryList(objects=[inventory])
|
||||||
|
@ -324,7 +367,7 @@ def _update_inventory(context, rp, inventory):
|
||||||
"""Update an inventory already on the provider.
|
"""Update an inventory already on the provider.
|
||||||
|
|
||||||
:raises `exception.ResourceClassNotFound` if inventory.resource_class
|
:raises `exception.ResourceClassNotFound` if inventory.resource_class
|
||||||
cannot be found in either the standard classes or the DB.
|
cannot be found in the DB.
|
||||||
"""
|
"""
|
||||||
rc_id = _RC_CACHE.id_from_string(inventory.resource_class)
|
rc_id = _RC_CACHE.id_from_string(inventory.resource_class)
|
||||||
inv_list = InventoryList(objects=[inventory])
|
inv_list = InventoryList(objects=[inventory])
|
||||||
|
@ -339,7 +382,7 @@ def _delete_inventory(context, rp, resource_class):
|
||||||
"""Delete up to one Inventory of the given resource_class string.
|
"""Delete up to one Inventory of the given resource_class string.
|
||||||
|
|
||||||
:raises `exception.ResourceClassNotFound` if resource_class
|
:raises `exception.ResourceClassNotFound` if resource_class
|
||||||
cannot be found in either the standard classes or the DB.
|
cannot be found in the DB.
|
||||||
"""
|
"""
|
||||||
rc_id = _RC_CACHE.id_from_string(resource_class)
|
rc_id = _RC_CACHE.id_from_string(resource_class)
|
||||||
if not _delete_inventory_from_provider(context, rp, [rc_id]):
|
if not _delete_inventory_from_provider(context, rp, [rc_id]):
|
||||||
|
@ -365,8 +408,7 @@ def _set_inventory(context, rp, inv_list):
|
||||||
allocations in between the time when this object was originally
|
allocations in between the time when this object was originally
|
||||||
read and the call to set the inventory.
|
read and the call to set the inventory.
|
||||||
:raises `exception.ResourceClassNotFound` if any resource class in any
|
:raises `exception.ResourceClassNotFound` if any resource class in any
|
||||||
inventory in inv_list cannot be found in either the standard
|
inventory in inv_list cannot be found in the DB.
|
||||||
classes or the DB.
|
|
||||||
:raises `exception.InventoryInUse` if we attempt to delete inventory
|
:raises `exception.InventoryInUse` if we attempt to delete inventory
|
||||||
from a provider that has allocations for that resource class.
|
from a provider that has allocations for that resource class.
|
||||||
"""
|
"""
|
||||||
|
@ -1558,7 +1600,7 @@ class Inventory(base.VersionedObject, base.TimestampedObject):
|
||||||
fields = {
|
fields = {
|
||||||
'id': fields.IntegerField(read_only=True),
|
'id': fields.IntegerField(read_only=True),
|
||||||
'resource_provider': fields.ObjectField('ResourceProvider'),
|
'resource_provider': fields.ObjectField('ResourceProvider'),
|
||||||
'resource_class': rc_fields.ResourceClassField(read_only=True),
|
'resource_class': fields.StringField(read_only=True),
|
||||||
'total': fields.NonNegativeIntegerField(),
|
'total': fields.NonNegativeIntegerField(),
|
||||||
'reserved': fields.NonNegativeIntegerField(default=0),
|
'reserved': fields.NonNegativeIntegerField(default=0),
|
||||||
'min_unit': fields.NonNegativeIntegerField(default=1),
|
'min_unit': fields.NonNegativeIntegerField(default=1),
|
||||||
|
@ -1643,7 +1685,7 @@ class Allocation(base.VersionedObject, base.TimestampedObject):
|
||||||
'id': fields.IntegerField(),
|
'id': fields.IntegerField(),
|
||||||
'resource_provider': fields.ObjectField('ResourceProvider'),
|
'resource_provider': fields.ObjectField('ResourceProvider'),
|
||||||
'consumer': fields.ObjectField('Consumer', nullable=False),
|
'consumer': fields.ObjectField('Consumer', nullable=False),
|
||||||
'resource_class': rc_fields.ResourceClassField(),
|
'resource_class': fields.StringField(),
|
||||||
'used': fields.IntegerField(),
|
'used': fields.IntegerField(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2008,8 +2050,7 @@ class AllocationList(base.ObjectListBase, base.VersionedObject):
|
||||||
If there is not we roll back the entire set.
|
If there is not we roll back the entire set.
|
||||||
|
|
||||||
:raises `exception.ResourceClassNotFound` if any resource class in any
|
:raises `exception.ResourceClassNotFound` if any resource class in any
|
||||||
allocation in allocs cannot be found in either the standard
|
allocation in allocs cannot be found in either the DB.
|
||||||
classes or the DB.
|
|
||||||
:raises `exception.InvalidAllocationCapacityExceeded` if any inventory
|
:raises `exception.InvalidAllocationCapacityExceeded` if any inventory
|
||||||
would be exhausted by the allocation.
|
would be exhausted by the allocation.
|
||||||
:raises `InvalidAllocationConstraintsViolated` if any of the
|
:raises `InvalidAllocationConstraintsViolated` if any of the
|
||||||
|
@ -2225,7 +2266,7 @@ class AllocationList(base.ObjectListBase, base.VersionedObject):
|
||||||
class Usage(base.VersionedObject):
|
class Usage(base.VersionedObject):
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'resource_class': rc_fields.ResourceClassField(read_only=True),
|
'resource_class': fields.StringField(read_only=True),
|
||||||
'usage': fields.NonNegativeIntegerField(),
|
'usage': fields.NonNegativeIntegerField(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2321,7 +2362,7 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject):
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'id': fields.IntegerField(read_only=True),
|
'id': fields.IntegerField(read_only=True),
|
||||||
'name': rc_fields.ResourceClassField(nullable=False),
|
'name': fields.StringField(nullable=False),
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -2355,7 +2396,7 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject):
|
||||||
"""
|
"""
|
||||||
query = context.session.query(func.max(models.ResourceClass.id))
|
query = context.session.query(func.max(models.ResourceClass.id))
|
||||||
max_id = query.one()[0]
|
max_id = query.one()[0]
|
||||||
if not max_id:
|
if not max_id or max_id < ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID:
|
||||||
return ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID
|
return ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID
|
||||||
else:
|
else:
|
||||||
return max_id + 1
|
return max_id + 1
|
||||||
|
@ -2367,14 +2408,13 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject):
|
||||||
if 'name' not in self:
|
if 'name' not in self:
|
||||||
raise exception.ObjectActionError(action='create',
|
raise exception.ObjectActionError(action='create',
|
||||||
reason='name is required')
|
reason='name is required')
|
||||||
if self.name in rc_fields.ResourceClass.STANDARD:
|
if self.name in orc.STANDARDS:
|
||||||
raise exception.ResourceClassExists(resource_class=self.name)
|
raise exception.ResourceClassExists(resource_class=self.name)
|
||||||
|
|
||||||
if not self.name.startswith(rc_fields.ResourceClass.CUSTOM_NAMESPACE):
|
if not self.name.startswith(orc.CUSTOM_NAMESPACE):
|
||||||
raise exception.ObjectActionError(
|
raise exception.ObjectActionError(
|
||||||
action='create',
|
action='create',
|
||||||
reason='name must start with ' +
|
reason='name must start with ' + orc.CUSTOM_NAMESPACE)
|
||||||
rc_fields.ResourceClass.CUSTOM_NAMESPACE)
|
|
||||||
|
|
||||||
updates = self.obj_get_changes()
|
updates = self.obj_get_changes()
|
||||||
# There is the possibility of a race when adding resource classes, as
|
# There is the possibility of a race when adding resource classes, as
|
||||||
|
@ -2420,9 +2460,8 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject):
|
||||||
if 'id' not in self:
|
if 'id' not in self:
|
||||||
raise exception.ObjectActionError(action='destroy',
|
raise exception.ObjectActionError(action='destroy',
|
||||||
reason='ID attribute not found')
|
reason='ID attribute not found')
|
||||||
# Never delete any standard resource class, since the standard resource
|
# Never delete any standard resource class.
|
||||||
# classes don't even exist in the database table anyway.
|
if self.id < ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID:
|
||||||
if self.id in (rc['id'] for rc in _RC_CACHE.STANDARDS):
|
|
||||||
raise exception.ResourceClassCannotDeleteStandard(
|
raise exception.ResourceClassCannotDeleteStandard(
|
||||||
resource_class=self.name)
|
resource_class=self.name)
|
||||||
|
|
||||||
|
@ -2449,9 +2488,8 @@ class ResourceClass(base.VersionedObject, base.TimestampedObject):
|
||||||
raise exception.ObjectActionError(action='save',
|
raise exception.ObjectActionError(action='save',
|
||||||
reason='ID attribute not found')
|
reason='ID attribute not found')
|
||||||
updates = self.obj_get_changes()
|
updates = self.obj_get_changes()
|
||||||
# Never update any standard resource class, since the standard resource
|
# Never update any standard resource class.
|
||||||
# classes don't even exist in the database table anyway.
|
if self.id < ResourceClass.MIN_CUSTOM_RESOURCE_CLASS_ID:
|
||||||
if self.id in (rc['id'] for rc in _RC_CACHE.STANDARDS):
|
|
||||||
raise exception.ResourceClassCannotUpdateStandard(
|
raise exception.ResourceClassCannotUpdateStandard(
|
||||||
resource_class=self.name)
|
resource_class=self.name)
|
||||||
self._save(self._context, self.id, self.name, updates)
|
self._save(self._context, self.id, self.name, updates)
|
||||||
|
@ -2479,8 +2517,7 @@ class ResourceClassList(base.ObjectListBase, base.VersionedObject):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@db_api.placement_context_manager.reader
|
@db_api.placement_context_manager.reader
|
||||||
def _get_all(context):
|
def _get_all(context):
|
||||||
customs = list(context.session.query(models.ResourceClass).all())
|
return list(context.session.query(models.ResourceClass).all())
|
||||||
return _RC_CACHE.STANDARDS + customs
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all(cls, context):
|
def get_all(cls, context):
|
||||||
|
@ -2631,7 +2668,7 @@ class AllocationRequestResource(base.VersionedObject):
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'resource_provider': fields.ObjectField('ResourceProvider'),
|
'resource_provider': fields.ObjectField('ResourceProvider'),
|
||||||
'resource_class': rc_fields.ResourceClassField(read_only=True),
|
'resource_class': fields.StringField(read_only=True),
|
||||||
'amount': fields.NonNegativeIntegerField(),
|
'amount': fields.NonNegativeIntegerField(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2671,7 +2708,7 @@ class AllocationRequest(base.VersionedObject):
|
||||||
class ProviderSummaryResource(base.VersionedObject):
|
class ProviderSummaryResource(base.VersionedObject):
|
||||||
|
|
||||||
fields = {
|
fields = {
|
||||||
'resource_class': rc_fields.ResourceClassField(read_only=True),
|
'resource_class': fields.StringField(read_only=True),
|
||||||
'capacity': fields.NonNegativeIntegerField(),
|
'capacity': fields.NonNegativeIntegerField(),
|
||||||
'used': fields.NonNegativeIntegerField(),
|
'used': fields.NonNegativeIntegerField(),
|
||||||
# Internal use only; not included when the object is serialized for
|
# Internal use only; not included when the object is serialized for
|
||||||
|
|
|
@ -1,71 +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.
|
|
||||||
"""Standard Resource Class Fields."""
|
|
||||||
|
|
||||||
# NOTE(cdent): This is kept as its own independent file as it is used by
|
|
||||||
# both the placement and nova sides of the placement interaction. On the
|
|
||||||
# placement side we don't want to import all the nova fields, nor all the
|
|
||||||
# nova objects (which are automatically loaded and registered if the
|
|
||||||
# nova.objects package is imported).
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from oslo_versionedobjects import fields
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceClass(fields.StringField):
|
|
||||||
"""Classes of resources provided to consumers."""
|
|
||||||
|
|
||||||
CUSTOM_NAMESPACE = 'CUSTOM_'
|
|
||||||
"""All non-standard resource classes must begin with this string."""
|
|
||||||
|
|
||||||
VCPU = 'VCPU'
|
|
||||||
MEMORY_MB = 'MEMORY_MB'
|
|
||||||
DISK_GB = 'DISK_GB'
|
|
||||||
PCI_DEVICE = 'PCI_DEVICE'
|
|
||||||
SRIOV_NET_VF = 'SRIOV_NET_VF'
|
|
||||||
NUMA_SOCKET = 'NUMA_SOCKET'
|
|
||||||
NUMA_CORE = 'NUMA_CORE'
|
|
||||||
NUMA_THREAD = 'NUMA_THREAD'
|
|
||||||
NUMA_MEMORY_MB = 'NUMA_MEMORY_MB'
|
|
||||||
IPV4_ADDRESS = 'IPV4_ADDRESS'
|
|
||||||
VGPU = 'VGPU'
|
|
||||||
VGPU_DISPLAY_HEAD = 'VGPU_DISPLAY_HEAD'
|
|
||||||
# Standard resource class for network bandwidth egress measured in
|
|
||||||
# kilobits per second.
|
|
||||||
NET_BW_EGR_KILOBIT_PER_SEC = 'NET_BW_EGR_KILOBIT_PER_SEC'
|
|
||||||
# Standard resource class for network bandwidth ingress measured in
|
|
||||||
# kilobits per second.
|
|
||||||
NET_BW_IGR_KILOBIT_PER_SEC = 'NET_BW_IGR_KILOBIT_PER_SEC'
|
|
||||||
|
|
||||||
# The ordering here is relevant. If you must add a value, only
|
|
||||||
# append.
|
|
||||||
STANDARD = (VCPU, MEMORY_MB, DISK_GB, PCI_DEVICE, SRIOV_NET_VF,
|
|
||||||
NUMA_SOCKET, NUMA_CORE, NUMA_THREAD, NUMA_MEMORY_MB,
|
|
||||||
IPV4_ADDRESS, VGPU, VGPU_DISPLAY_HEAD,
|
|
||||||
NET_BW_EGR_KILOBIT_PER_SEC, NET_BW_IGR_KILOBIT_PER_SEC)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def normalize_name(cls, rc_name):
|
|
||||||
if rc_name is None:
|
|
||||||
return None
|
|
||||||
# Replace non-alphanumeric characters with underscores
|
|
||||||
norm_name = re.sub('[^0-9A-Za-z]+', '_', rc_name)
|
|
||||||
# Bug #1762789: Do .upper after replacing non alphanumerics.
|
|
||||||
norm_name = norm_name.upper()
|
|
||||||
norm_name = cls.CUSTOM_NAMESPACE + norm_name
|
|
||||||
return norm_name
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceClassField(fields.AutoTypedField):
|
|
||||||
AUTO_TYPE = ResourceClass()
|
|
|
@ -16,7 +16,6 @@ import sqlalchemy as sa
|
||||||
from placement.db.sqlalchemy import models
|
from placement.db.sqlalchemy import models
|
||||||
from placement import db_api
|
from placement import db_api
|
||||||
from placement import exception
|
from placement import exception
|
||||||
from placement import rc_fields as fields
|
|
||||||
|
|
||||||
_RC_TBL = models.ResourceClass.__table__
|
_RC_TBL = models.ResourceClass.__table__
|
||||||
_LOCKNAME = 'rc_cache'
|
_LOCKNAME = 'rc_cache'
|
||||||
|
@ -24,28 +23,21 @@ _LOCKNAME = 'rc_cache'
|
||||||
|
|
||||||
@db_api.placement_context_manager.reader
|
@db_api.placement_context_manager.reader
|
||||||
def _refresh_from_db(ctx, cache):
|
def _refresh_from_db(ctx, cache):
|
||||||
"""Grabs all custom resource classes from the DB table and populates the
|
"""Grabs all resource classes from the DB table and populates the
|
||||||
supplied cache object's internal integer and string identifier dicts.
|
supplied cache object's internal integer and string identifier dicts.
|
||||||
|
|
||||||
:param cache: ResourceClassCache object to refresh.
|
:param cache: ResourceClassCache object to refresh.
|
||||||
"""
|
"""
|
||||||
with db_api.placement_context_manager.reader.connection.using(ctx) as conn:
|
sel = sa.select([_RC_TBL.c.id, _RC_TBL.c.name, _RC_TBL.c.updated_at,
|
||||||
sel = sa.select([_RC_TBL.c.id, _RC_TBL.c.name, _RC_TBL.c.updated_at,
|
_RC_TBL.c.created_at])
|
||||||
_RC_TBL.c.created_at])
|
res = ctx.session.execute(sel).fetchall()
|
||||||
res = conn.execute(sel).fetchall()
|
cache.id_cache = {r[1]: r[0] for r in res}
|
||||||
cache.id_cache = {r[1]: r[0] for r in res}
|
cache.str_cache = {r[0]: r[1] for r in res}
|
||||||
cache.str_cache = {r[0]: r[1] for r in res}
|
cache.all_cache = {r[1]: r for r in res}
|
||||||
cache.all_cache = {r[1]: r for r in res}
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceClassCache(object):
|
class ResourceClassCache(object):
|
||||||
"""A cache of integer and string lookup values for resource classes."""
|
"""A cache of integer and string lookup values for resource classes."""
|
||||||
|
|
||||||
# List of dict of all standard resource classes, where every list item
|
|
||||||
# have a form {'id': <ID>, 'name': <NAME>}
|
|
||||||
STANDARDS = [{'id': fields.ResourceClass.STANDARD.index(s), 'name': s,
|
|
||||||
'updated_at': None, 'created_at': None}
|
|
||||||
for s in fields.ResourceClass.STANDARD]
|
|
||||||
|
|
||||||
def __init__(self, ctx):
|
def __init__(self, ctx):
|
||||||
"""Initialize the cache of resource class identifiers.
|
"""Initialize the cache of resource class identifiers.
|
||||||
|
@ -66,29 +58,23 @@ class ResourceClassCache(object):
|
||||||
|
|
||||||
def id_from_string(self, rc_str):
|
def id_from_string(self, rc_str):
|
||||||
"""Given a string representation of a resource class -- e.g. "DISK_GB"
|
"""Given a string representation of a resource class -- e.g. "DISK_GB"
|
||||||
or "IRON_SILVER" -- return the integer code for the resource class. For
|
or "CUSTOM_IRON_SILVER" -- return the integer code for the resource
|
||||||
standard resource classes, this integer code will match the list of
|
class by doing a DB lookup into the resource_classes table; however,
|
||||||
resource classes on the fields.ResourceClass field type. Other custom
|
the results of these DB lookups are cached since the lookups are so
|
||||||
resource classes will cause a DB lookup into the resource_classes
|
frequent.
|
||||||
table, however the results of these DB lookups are cached since the
|
|
||||||
lookups are so frequent.
|
|
||||||
|
|
||||||
:param rc_str: The string representation of the resource class to look
|
:param rc_str: The string representation of the resource class to look
|
||||||
up a numeric identifier for.
|
up a numeric identifier for.
|
||||||
:returns integer identifier for the resource class, or None, if no such
|
:returns Integer identifier for the resource class.
|
||||||
resource class was found in the list of standard resource
|
|
||||||
classes or the resource_classes database table.
|
|
||||||
:raises `exception.ResourceClassNotFound` if rc_str cannot be found in
|
:raises `exception.ResourceClassNotFound` if rc_str cannot be found in
|
||||||
either the standard classes or the DB.
|
the DB.
|
||||||
"""
|
"""
|
||||||
# First check the standard resource classes
|
rc_id = self.id_cache.get(rc_str)
|
||||||
if rc_str in fields.ResourceClass.STANDARD:
|
if rc_id is not None:
|
||||||
return fields.ResourceClass.STANDARD.index(rc_str)
|
return rc_id
|
||||||
|
|
||||||
|
# Otherwise, check the database table
|
||||||
with lockutils.lock(_LOCKNAME):
|
with lockutils.lock(_LOCKNAME):
|
||||||
if rc_str in self.id_cache:
|
|
||||||
return self.id_cache[rc_str]
|
|
||||||
# Otherwise, check the database table
|
|
||||||
_refresh_from_db(self.ctx, self)
|
_refresh_from_db(self.ctx, self)
|
||||||
if rc_str in self.id_cache:
|
if rc_str in self.id_cache:
|
||||||
return self.id_cache[rc_str]
|
return self.id_cache[rc_str]
|
||||||
|
@ -101,22 +87,17 @@ class ResourceClassCache(object):
|
||||||
:param rc_str: The string representation of the resource class for
|
:param rc_str: The string representation of the resource class for
|
||||||
which to look up a resource_class.
|
which to look up a resource_class.
|
||||||
:returns: dict representing the resource class fields, if the
|
:returns: dict representing the resource class fields, if the
|
||||||
resource class was found in the list of standard
|
resource class was found in the resource_classes database
|
||||||
resource classes or the resource_classes database table.
|
table.
|
||||||
:raises: `exception.ResourceClassNotFound` if rc_str cannot be found in
|
:raises: `exception.ResourceClassNotFound` if rc_str cannot be found in
|
||||||
either the standard classes or the DB.
|
the DB.
|
||||||
"""
|
"""
|
||||||
# First check the standard resource classes
|
rc_id_str = self.all_cache.get(rc_str)
|
||||||
if rc_str in fields.ResourceClass.STANDARD:
|
if rc_id_str is not None:
|
||||||
return {'id': fields.ResourceClass.STANDARD.index(rc_str),
|
return rc_id_str
|
||||||
'name': rc_str,
|
|
||||||
'updated_at': None,
|
|
||||||
'created_at': None}
|
|
||||||
|
|
||||||
|
# Otherwise, check the database table
|
||||||
with lockutils.lock(_LOCKNAME):
|
with lockutils.lock(_LOCKNAME):
|
||||||
if rc_str in self.all_cache:
|
|
||||||
return self.all_cache[rc_str]
|
|
||||||
# Otherwise, check the database table
|
|
||||||
_refresh_from_db(self.ctx, self)
|
_refresh_from_db(self.ctx, self)
|
||||||
if rc_str in self.all_cache:
|
if rc_str in self.all_cache:
|
||||||
return self.all_cache[rc_str]
|
return self.all_cache[rc_str]
|
||||||
|
@ -125,29 +106,21 @@ class ResourceClassCache(object):
|
||||||
def string_from_id(self, rc_id):
|
def string_from_id(self, rc_id):
|
||||||
"""The reverse of the id_from_string() method. Given a supplied numeric
|
"""The reverse of the id_from_string() method. Given a supplied numeric
|
||||||
identifier for a resource class, we look up the corresponding string
|
identifier for a resource class, we look up the corresponding string
|
||||||
representation, either in the list of standard resource classes or via
|
representation, via a DB lookup. The results of these DB lookups are
|
||||||
a DB lookup. The results of these DB lookups are cached since the
|
cached since the lookups are so frequent.
|
||||||
lookups are so frequent.
|
|
||||||
|
|
||||||
:param rc_id: The numeric representation of the resource class to look
|
:param rc_id: The numeric representation of the resource class to look
|
||||||
up a string identifier for.
|
up a string identifier for.
|
||||||
:returns: string identifier for the resource class, or None, if no such
|
:returns: String identifier for the resource class.
|
||||||
resource class was found in the list of standard resource
|
|
||||||
classes or the resource_classes database table.
|
|
||||||
:raises `exception.ResourceClassNotFound` if rc_id cannot be found in
|
:raises `exception.ResourceClassNotFound` if rc_id cannot be found in
|
||||||
either the standard classes or the DB.
|
the DB.
|
||||||
"""
|
"""
|
||||||
# First check the fields.ResourceClass.STANDARD values
|
rc_str = self.str_cache.get(rc_id)
|
||||||
try:
|
if rc_str is not None:
|
||||||
return fields.ResourceClass.STANDARD[rc_id]
|
return rc_str
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
# Otherwise, check the database table
|
||||||
with lockutils.lock(_LOCKNAME):
|
with lockutils.lock(_LOCKNAME):
|
||||||
if rc_id in self.str_cache:
|
|
||||||
return self.str_cache[rc_id]
|
|
||||||
|
|
||||||
# Otherwise, check the database table
|
|
||||||
_refresh_from_db(self.ctx, self)
|
_refresh_from_db(self.ctx, self)
|
||||||
if rc_id in self.str_cache:
|
if rc_id in self.str_cache:
|
||||||
return self.str_cache[rc_id]
|
return self.str_cache[rc_id]
|
||||||
|
|
|
@ -64,12 +64,15 @@ class Database(test_fixtures.GeneratesSchema, test_fixtures.AdHocDbFixture):
|
||||||
engine)
|
engine)
|
||||||
self.addCleanup(_reset_facade)
|
self.addCleanup(_reset_facade)
|
||||||
|
|
||||||
|
# Make sure db flags are correct at both the start and finish
|
||||||
|
# of the test.
|
||||||
self.addCleanup(self.cleanup)
|
self.addCleanup(self.cleanup)
|
||||||
resource_provider._TRAITS_SYNCED = False
|
self.cleanup()
|
||||||
resource_provider._RC_CACHE = None
|
|
||||||
|
# Sync traits and resource classes.
|
||||||
deploy.update_database()
|
deploy.update_database()
|
||||||
self.addCleanup(self.cleanup)
|
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
resource_provider._TRAITS_SYNCED = False
|
resource_provider._TRAITS_SYNCED = False
|
||||||
|
resource_provider._RESOURCE_CLASSES_SYNCED = False
|
||||||
resource_provider._RC_CACHE = None
|
resource_provider._RC_CACHE = None
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import os_resource_classes as orc
|
||||||
from oslo_utils.fixture import uuidsentinel as uuids
|
from oslo_utils.fixture import uuidsentinel as uuids
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
@ -19,7 +20,6 @@ from placement.objects import consumer as consumer_obj
|
||||||
from placement.objects import project as project_obj
|
from placement.objects import project as project_obj
|
||||||
from placement.objects import resource_provider as rp_obj
|
from placement.objects import resource_provider as rp_obj
|
||||||
from placement.objects import user as user_obj
|
from placement.objects import user as user_obj
|
||||||
from placement import rc_fields as fields
|
|
||||||
from placement.tests.functional import base
|
from placement.tests.functional import base
|
||||||
from placement.tests.functional.db import test_base as tb
|
from placement.tests.functional.db import test_base as tb
|
||||||
|
|
||||||
|
@ -263,24 +263,24 @@ class DeleteConsumerIfNoAllocsTestCase(tb.PlacementDbBaseTestCase):
|
||||||
|
|
||||||
# Create some inventory that we will allocate
|
# Create some inventory that we will allocate
|
||||||
cn1 = self._create_provider('cn1')
|
cn1 = self._create_provider('cn1')
|
||||||
tb.add_inventory(cn1, fields.ResourceClass.VCPU, 8)
|
tb.add_inventory(cn1, orc.VCPU, 8)
|
||||||
tb.add_inventory(cn1, fields.ResourceClass.MEMORY_MB, 2048)
|
tb.add_inventory(cn1, orc.MEMORY_MB, 2048)
|
||||||
tb.add_inventory(cn1, fields.ResourceClass.DISK_GB, 2000)
|
tb.add_inventory(cn1, orc.DISK_GB, 2000)
|
||||||
|
|
||||||
# Now allocate some of that inventory to two different consumers
|
# Now allocate some of that inventory to two different consumers
|
||||||
allocs = [
|
allocs = [
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
self.ctx, consumer=c1, resource_provider=cn1,
|
self.ctx, consumer=c1, resource_provider=cn1,
|
||||||
resource_class=fields.ResourceClass.VCPU, used=1),
|
resource_class=orc.VCPU, used=1),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
self.ctx, consumer=c1, resource_provider=cn1,
|
self.ctx, consumer=c1, resource_provider=cn1,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB, used=512),
|
resource_class=orc.MEMORY_MB, used=512),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
self.ctx, consumer=c2, resource_provider=cn1,
|
self.ctx, consumer=c2, resource_provider=cn1,
|
||||||
resource_class=fields.ResourceClass.VCPU, used=1),
|
resource_class=orc.VCPU, used=1),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
self.ctx, consumer=c2, resource_provider=cn1,
|
self.ctx, consumer=c2, resource_provider=cn1,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB, used=512),
|
resource_class=orc.MEMORY_MB, used=512),
|
||||||
]
|
]
|
||||||
alloc_list = rp_obj.AllocationList(self.ctx, objects=allocs)
|
alloc_list = rp_obj.AllocationList(self.ctx, objects=allocs)
|
||||||
alloc_list.replace_all()
|
alloc_list.replace_all()
|
||||||
|
@ -297,10 +297,10 @@ class DeleteConsumerIfNoAllocsTestCase(tb.PlacementDbBaseTestCase):
|
||||||
allocs = [
|
allocs = [
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
self.ctx, consumer=c2, resource_provider=cn1,
|
self.ctx, consumer=c2, resource_provider=cn1,
|
||||||
resource_class=fields.ResourceClass.VCPU, used=0),
|
resource_class=orc.VCPU, used=0),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
self.ctx, consumer=c2, resource_provider=cn1,
|
self.ctx, consumer=c2, resource_provider=cn1,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB, used=0),
|
resource_class=orc.MEMORY_MB, used=0),
|
||||||
]
|
]
|
||||||
alloc_list = rp_obj.AllocationList(self.ctx, objects=allocs)
|
alloc_list = rp_obj.AllocationList(self.ctx, objects=allocs)
|
||||||
alloc_list.replace_all()
|
alloc_list.replace_all()
|
||||||
|
|
|
@ -16,66 +16,38 @@ import mock
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
|
|
||||||
from placement import exception
|
from placement import exception
|
||||||
from placement import rc_fields as fields
|
|
||||||
from placement import resource_class_cache as rc_cache
|
from placement import resource_class_cache as rc_cache
|
||||||
from placement.tests.functional import base
|
from placement.tests.functional import base
|
||||||
|
|
||||||
|
|
||||||
class TestResourceClassCache(base.TestCase):
|
class TestResourceClassCache(base.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def test_rc_cache_std_db(self):
|
||||||
super(TestResourceClassCache, self).setUp()
|
|
||||||
db = self.placement_db
|
|
||||||
self.context = mock.Mock()
|
|
||||||
sess_mock = mock.Mock()
|
|
||||||
sess_mock.connection.side_effect = db.get_engine().connect
|
|
||||||
self.context.session = sess_mock
|
|
||||||
|
|
||||||
@mock.patch('sqlalchemy.select')
|
|
||||||
def test_rc_cache_std_no_db(self, sel_mock):
|
|
||||||
"""Test that looking up either an ID or a string in the resource class
|
"""Test that looking up either an ID or a string in the resource class
|
||||||
cache for a standardized resource class does not result in a DB
|
cache for a standardized resource class doesn't result in a DB call
|
||||||
call.
|
once the cache is initialized
|
||||||
"""
|
"""
|
||||||
cache = rc_cache.ResourceClassCache(self.context)
|
cache = rc_cache.ResourceClassCache(self.context)
|
||||||
|
rc_cache._refresh_from_db(self.context, cache)
|
||||||
|
|
||||||
self.assertEqual('VCPU', cache.string_from_id(0))
|
with mock.patch('sqlalchemy.select') as sel_mock:
|
||||||
self.assertEqual('MEMORY_MB', cache.string_from_id(1))
|
self.assertEqual('VCPU', cache.string_from_id(0))
|
||||||
self.assertEqual(0, cache.id_from_string('VCPU'))
|
self.assertEqual('MEMORY_MB', cache.string_from_id(1))
|
||||||
self.assertEqual(1, cache.id_from_string('MEMORY_MB'))
|
self.assertEqual(0, cache.id_from_string('VCPU'))
|
||||||
|
self.assertEqual(1, cache.id_from_string('MEMORY_MB'))
|
||||||
|
|
||||||
self.assertFalse(sel_mock.called)
|
self.assertFalse(sel_mock.called)
|
||||||
|
|
||||||
def test_standards(self):
|
|
||||||
cache = rc_cache.ResourceClassCache(self.context)
|
|
||||||
standards = cache.STANDARDS
|
|
||||||
|
|
||||||
self.assertEqual(len(standards), len(fields.ResourceClass.STANDARD))
|
|
||||||
names = (rc['name'] for rc in standards)
|
|
||||||
for name in fields.ResourceClass.STANDARD:
|
|
||||||
self.assertIn(name, names)
|
|
||||||
|
|
||||||
cache = rc_cache.ResourceClassCache(self.context)
|
|
||||||
standards2 = cache.STANDARDS
|
|
||||||
self.assertEqual(id(standards), id(standards2))
|
|
||||||
|
|
||||||
def test_standards_have_time_fields(self):
|
|
||||||
cache = rc_cache.ResourceClassCache(self.context)
|
|
||||||
standards = cache.STANDARDS
|
|
||||||
|
|
||||||
first_standard = standards[0]
|
|
||||||
self.assertIn('updated_at', first_standard)
|
|
||||||
self.assertIn('created_at', first_standard)
|
|
||||||
self.assertIsNone(first_standard['updated_at'])
|
|
||||||
self.assertIsNone(first_standard['created_at'])
|
|
||||||
|
|
||||||
def test_standard_has_time_fields(self):
|
def test_standard_has_time_fields(self):
|
||||||
cache = rc_cache.ResourceClassCache(self.context)
|
cache = rc_cache.ResourceClassCache(self.context)
|
||||||
|
|
||||||
vcpu_class = cache.all_from_string('VCPU')
|
vcpu_class = dict(cache.all_from_string('VCPU'))
|
||||||
expected = {'id': 0, 'name': 'VCPU', 'updated_at': None,
|
expected = {'id': 0, 'name': 'VCPU', 'updated_at': None,
|
||||||
'created_at': None}
|
'created_at': None}
|
||||||
self.assertEqual(expected, vcpu_class)
|
expected_fields = sorted(expected.keys())
|
||||||
|
self.assertEqual(expected_fields, sorted(vcpu_class.keys()))
|
||||||
|
self.assertEqual(0, vcpu_class['id'])
|
||||||
|
self.assertEqual('VCPU', vcpu_class['name'])
|
||||||
|
|
||||||
def test_rc_cache_custom(self):
|
def test_rc_cache_custom(self):
|
||||||
"""Test that non-standard, custom resource classes hit the database and
|
"""Test that non-standard, custom resource classes hit the database and
|
||||||
|
@ -92,7 +64,7 @@ class TestResourceClassCache(base.TestCase):
|
||||||
cache.id_from_string, "IRON_NFV")
|
cache.id_from_string, "IRON_NFV")
|
||||||
|
|
||||||
# Now add to the database and verify appropriate results...
|
# Now add to the database and verify appropriate results...
|
||||||
with self.context.session.connection() as conn:
|
with self.placement_db.get_engine().connect() as conn:
|
||||||
ins_stmt = rc_cache._RC_TBL.insert().values(
|
ins_stmt = rc_cache._RC_TBL.insert().values(
|
||||||
id=1001,
|
id=1001,
|
||||||
name='IRON_NFV'
|
name='IRON_NFV'
|
||||||
|
@ -117,8 +89,8 @@ class TestResourceClassCache(base.TestCase):
|
||||||
self.assertIsInstance(iron_nfv_class['created_at'], datetime.datetime)
|
self.assertIsInstance(iron_nfv_class['created_at'], datetime.datetime)
|
||||||
|
|
||||||
# Update IRON_NFV (this is a no-op but will set updated_at)
|
# Update IRON_NFV (this is a no-op but will set updated_at)
|
||||||
with self.context.session.connection() as conn:
|
with self.placement_db.get_engine().connect() as conn:
|
||||||
# NOTE(cdent): When using explicit SQL that names columns,
|
# NOTE(cdent): When using explict SQL that names columns,
|
||||||
# the automatic timestamp handling provided by the oslo_db
|
# the automatic timestamp handling provided by the oslo_db
|
||||||
# TimestampMixin is not provided. created_at is a default
|
# TimestampMixin is not provided. created_at is a default
|
||||||
# but updated_at is an onupdate.
|
# but updated_at is an onupdate.
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import mock
|
import mock
|
||||||
|
import os_resource_classes as orc
|
||||||
import os_traits
|
import os_traits
|
||||||
from oslo_db import exception as db_exc
|
from oslo_db import exception as db_exc
|
||||||
from oslo_utils.fixture import uuidsentinel
|
from oslo_utils.fixture import uuidsentinel
|
||||||
|
@ -23,7 +24,6 @@ from placement.db.sqlalchemy import models
|
||||||
from placement import exception
|
from placement import exception
|
||||||
from placement.objects import consumer as consumer_obj
|
from placement.objects import consumer as consumer_obj
|
||||||
from placement.objects import resource_provider as rp_obj
|
from placement.objects import resource_provider as rp_obj
|
||||||
from placement import rc_fields as fields
|
|
||||||
from placement.tests.functional.db import test_base as tb
|
from placement.tests.functional.db import test_base as tb
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,13 +34,13 @@ DISK_INVENTORY = dict(
|
||||||
max_unit=5,
|
max_unit=5,
|
||||||
step_size=1,
|
step_size=1,
|
||||||
allocation_ratio=1.0,
|
allocation_ratio=1.0,
|
||||||
resource_class=fields.ResourceClass.DISK_GB
|
resource_class=orc.DISK_GB
|
||||||
)
|
)
|
||||||
|
|
||||||
DISK_ALLOCATION = dict(
|
DISK_ALLOCATION = dict(
|
||||||
consumer_id=uuidsentinel.disk_consumer,
|
consumer_id=uuidsentinel.disk_consumer,
|
||||||
used=2,
|
used=2,
|
||||||
resource_class=fields.ResourceClass.DISK_GB
|
resource_class=orc.DISK_GB
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
# Create some inventory in the grandchild, allocate some consumers to
|
# Create some inventory in the grandchild, allocate some consumers to
|
||||||
# the grandchild and then attempt to delete the root provider and child
|
# the grandchild and then attempt to delete the root provider and child
|
||||||
# provider, both of which should fail.
|
# provider, both of which should fail.
|
||||||
tb.add_inventory(grandchild_rp, fields.ResourceClass.VCPU, 1)
|
tb.add_inventory(grandchild_rp, orc.VCPU, 1)
|
||||||
|
|
||||||
# Check all providers returned when getting by root UUID
|
# Check all providers returned when getting by root UUID
|
||||||
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
rps = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
|
@ -362,7 +362,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
self.assertEqual(uuidsentinel.grandchild_rp, rps[0].uuid)
|
self.assertEqual(uuidsentinel.grandchild_rp, rps[0].uuid)
|
||||||
|
|
||||||
alloc_list = self.allocate_from_provider(
|
alloc_list = self.allocate_from_provider(
|
||||||
grandchild_rp, fields.ResourceClass.VCPU, 1)
|
grandchild_rp, orc.VCPU, 1)
|
||||||
|
|
||||||
self.assertRaises(exception.CannotDeleteParentResourceProvider,
|
self.assertRaises(exception.CannotDeleteParentResourceProvider,
|
||||||
root_rp.destroy)
|
root_rp.destroy)
|
||||||
|
@ -557,12 +557,12 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
def test_set_inventory_over_capacity(self, mock_log):
|
def test_set_inventory_over_capacity(self, mock_log):
|
||||||
rp = self._create_provider(uuidsentinel.rp_name)
|
rp = self._create_provider(uuidsentinel.rp_name)
|
||||||
|
|
||||||
disk_inv = tb.add_inventory(rp, fields.ResourceClass.DISK_GB, 2048,
|
disk_inv = tb.add_inventory(rp, orc.DISK_GB, 2048,
|
||||||
reserved=15,
|
reserved=15,
|
||||||
min_unit=10,
|
min_unit=10,
|
||||||
max_unit=600,
|
max_unit=600,
|
||||||
step_size=10)
|
step_size=10)
|
||||||
vcpu_inv = tb.add_inventory(rp, fields.ResourceClass.VCPU, 12,
|
vcpu_inv = tb.add_inventory(rp, orc.VCPU, 12,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
|
|
||||||
self.assertFalse(mock_log.warning.called)
|
self.assertFalse(mock_log.warning.called)
|
||||||
|
@ -582,13 +582,13 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
rp = self._create_provider(uuidsentinel.rp_name)
|
rp = self._create_provider(uuidsentinel.rp_name)
|
||||||
saved_generation = rp.generation
|
saved_generation = rp.generation
|
||||||
|
|
||||||
disk_inv = tb.add_inventory(rp, fields.ResourceClass.DISK_GB, 1024,
|
disk_inv = tb.add_inventory(rp, orc.DISK_GB, 1024,
|
||||||
reserved=15,
|
reserved=15,
|
||||||
min_unit=10,
|
min_unit=10,
|
||||||
max_unit=100,
|
max_unit=100,
|
||||||
step_size=10)
|
step_size=10)
|
||||||
|
|
||||||
vcpu_inv = tb.add_inventory(rp, fields.ResourceClass.VCPU, 12,
|
vcpu_inv = tb.add_inventory(rp, orc.VCPU, 12,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
|
|
||||||
# generation has bumped once for each add
|
# generation has bumped once for each add
|
||||||
|
@ -599,8 +599,8 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
self.ctx, rp)
|
self.ctx, rp)
|
||||||
self.assertEqual(2, len(new_inv_list))
|
self.assertEqual(2, len(new_inv_list))
|
||||||
resource_classes = [inv.resource_class for inv in new_inv_list]
|
resource_classes = [inv.resource_class for inv in new_inv_list]
|
||||||
self.assertIn(fields.ResourceClass.VCPU, resource_classes)
|
self.assertIn(orc.VCPU, resource_classes)
|
||||||
self.assertIn(fields.ResourceClass.DISK_GB, resource_classes)
|
self.assertIn(orc.DISK_GB, resource_classes)
|
||||||
|
|
||||||
# reset list to just disk_inv
|
# reset list to just disk_inv
|
||||||
inv_list = rp_obj.InventoryList(objects=[disk_inv])
|
inv_list = rp_obj.InventoryList(objects=[disk_inv])
|
||||||
|
@ -614,14 +614,14 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
self.ctx, rp)
|
self.ctx, rp)
|
||||||
self.assertEqual(1, len(new_inv_list))
|
self.assertEqual(1, len(new_inv_list))
|
||||||
resource_classes = [inv.resource_class for inv in new_inv_list]
|
resource_classes = [inv.resource_class for inv in new_inv_list]
|
||||||
self.assertNotIn(fields.ResourceClass.VCPU, resource_classes)
|
self.assertNotIn(orc.VCPU, resource_classes)
|
||||||
self.assertIn(fields.ResourceClass.DISK_GB, resource_classes)
|
self.assertIn(orc.DISK_GB, resource_classes)
|
||||||
self.assertEqual(1024, new_inv_list[0].total)
|
self.assertEqual(1024, new_inv_list[0].total)
|
||||||
|
|
||||||
# update existing disk inv to new settings
|
# update existing disk inv to new settings
|
||||||
disk_inv = rp_obj.Inventory(
|
disk_inv = rp_obj.Inventory(
|
||||||
resource_provider=rp,
|
resource_provider=rp,
|
||||||
resource_class=fields.ResourceClass.DISK_GB,
|
resource_class=orc.DISK_GB,
|
||||||
total=2048,
|
total=2048,
|
||||||
reserved=15,
|
reserved=15,
|
||||||
min_unit=10,
|
min_unit=10,
|
||||||
|
@ -640,7 +640,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
self.assertEqual(2048, new_inv_list[0].total)
|
self.assertEqual(2048, new_inv_list[0].total)
|
||||||
|
|
||||||
# delete inventory
|
# delete inventory
|
||||||
rp.delete_inventory(fields.ResourceClass.DISK_GB)
|
rp.delete_inventory(orc.DISK_GB)
|
||||||
|
|
||||||
# generation has bumped
|
# generation has bumped
|
||||||
self.assertEqual(saved_generation + 1, rp.generation)
|
self.assertEqual(saved_generation + 1, rp.generation)
|
||||||
|
@ -648,10 +648,10 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
|
|
||||||
new_inv_list = rp_obj.InventoryList.get_all_by_resource_provider(
|
new_inv_list = rp_obj.InventoryList.get_all_by_resource_provider(
|
||||||
self.ctx, rp)
|
self.ctx, rp)
|
||||||
result = new_inv_list.find(fields.ResourceClass.DISK_GB)
|
result = new_inv_list.find(orc.DISK_GB)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
self.assertRaises(exception.NotFound, rp.delete_inventory,
|
self.assertRaises(exception.NotFound, rp.delete_inventory,
|
||||||
fields.ResourceClass.DISK_GB)
|
orc.DISK_GB)
|
||||||
|
|
||||||
# check inventory list is empty
|
# check inventory list is empty
|
||||||
inv_list = rp_obj.InventoryList.get_all_by_resource_provider(
|
inv_list = rp_obj.InventoryList.get_all_by_resource_provider(
|
||||||
|
@ -718,7 +718,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
new_total = 1
|
new_total = 1
|
||||||
disk_inv = rp_obj.Inventory(
|
disk_inv = rp_obj.Inventory(
|
||||||
resource_provider=rp,
|
resource_provider=rp,
|
||||||
resource_class=fields.ResourceClass.DISK_GB, total=new_total)
|
resource_class=orc.DISK_GB, total=new_total)
|
||||||
disk_inv.obj_set_defaults()
|
disk_inv.obj_set_defaults()
|
||||||
rp.update_inventory(disk_inv)
|
rp.update_inventory(disk_inv)
|
||||||
|
|
||||||
|
@ -748,7 +748,7 @@ class ResourceProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
for rp in (rp1, rp2):
|
for rp in (rp1, rp2):
|
||||||
tb.add_inventory(rp, DISK_INVENTORY['resource_class'],
|
tb.add_inventory(rp, DISK_INVENTORY['resource_class'],
|
||||||
DISK_INVENTORY['total'])
|
DISK_INVENTORY['total'])
|
||||||
tb.add_inventory(rp, fields.ResourceClass.IPV4_ADDRESS, 10,
|
tb.add_inventory(rp, orc.IPV4_ADDRESS, 10,
|
||||||
max_unit=2)
|
max_unit=2)
|
||||||
|
|
||||||
# Get inventories for the first resource provider and validate
|
# Get inventories for the first resource provider and validate
|
||||||
|
@ -780,65 +780,65 @@ class ResourceProviderListTestCase(tb.PlacementDbBaseTestCase):
|
||||||
def test_get_all_by_filters_with_resources(self):
|
def test_get_all_by_filters_with_resources(self):
|
||||||
for rp_i in ['1', '2']:
|
for rp_i in ['1', '2']:
|
||||||
rp = self._create_provider('rp_name_' + rp_i)
|
rp = self._create_provider('rp_name_' + rp_i)
|
||||||
tb.add_inventory(rp, fields.ResourceClass.VCPU, 2)
|
tb.add_inventory(rp, orc.VCPU, 2)
|
||||||
tb.add_inventory(rp, fields.ResourceClass.DISK_GB, 1024,
|
tb.add_inventory(rp, orc.DISK_GB, 1024,
|
||||||
reserved=2)
|
reserved=2)
|
||||||
# Write a specific inventory for testing min/max units and steps
|
# Write a specific inventory for testing min/max units and steps
|
||||||
tb.add_inventory(rp, fields.ResourceClass.MEMORY_MB, 1024,
|
tb.add_inventory(rp, orc.MEMORY_MB, 1024,
|
||||||
reserved=2, min_unit=2, max_unit=4, step_size=2)
|
reserved=2, min_unit=2, max_unit=4, step_size=2)
|
||||||
|
|
||||||
# Create the VCPU allocation only for the first RP
|
# Create the VCPU allocation only for the first RP
|
||||||
if rp_i != '1':
|
if rp_i != '1':
|
||||||
continue
|
continue
|
||||||
self.allocate_from_provider(rp, fields.ResourceClass.VCPU, used=1)
|
self.allocate_from_provider(rp, orc.VCPU, used=1)
|
||||||
|
|
||||||
# Both RPs should accept that request given the only current allocation
|
# Both RPs should accept that request given the only current allocation
|
||||||
# for the first RP is leaving one VCPU
|
# for the first RP is leaving one VCPU
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.VCPU: 1}})
|
self.ctx, {'resources': {orc.VCPU: 1}})
|
||||||
self.assertEqual(2, len(resource_providers))
|
self.assertEqual(2, len(resource_providers))
|
||||||
# Now, when asking for 2 VCPUs, only the second RP should accept that
|
# Now, when asking for 2 VCPUs, only the second RP should accept that
|
||||||
# given the current allocation for the first RP
|
# given the current allocation for the first RP
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.VCPU: 2}})
|
self.ctx, {'resources': {orc.VCPU: 2}})
|
||||||
self.assertEqual(1, len(resource_providers))
|
self.assertEqual(1, len(resource_providers))
|
||||||
# Adding a second resource request should be okay for the 2nd RP
|
# 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
|
# given it has enough disk but we also need to make sure that the
|
||||||
# first RP is not acceptable because of the VCPU request
|
# first RP is not acceptable because of the VCPU request
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.VCPU: 2,
|
self.ctx, {'resources': {orc.VCPU: 2,
|
||||||
fields.ResourceClass.DISK_GB: 1022}})
|
orc.DISK_GB: 1022}})
|
||||||
self.assertEqual(1, len(resource_providers))
|
self.assertEqual(1, len(resource_providers))
|
||||||
# Now, we are asking for both disk and VCPU resources that all the RPs
|
# 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)
|
# 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.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.VCPU: 2,
|
self.ctx, {'resources': {orc.VCPU: 2,
|
||||||
fields.ResourceClass.DISK_GB: 1024}})
|
orc.DISK_GB: 1024}})
|
||||||
self.assertEqual(0, len(resource_providers))
|
self.assertEqual(0, len(resource_providers))
|
||||||
|
|
||||||
# We also want to verify that asking for a specific RP can also be
|
# We also want to verify that asking for a specific RP can also be
|
||||||
# checking the resource usage.
|
# checking the resource usage.
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'name': u'rp_name_1',
|
self.ctx, {'name': u'rp_name_1',
|
||||||
'resources': {fields.ResourceClass.VCPU: 1}})
|
'resources': {orc.VCPU: 1}})
|
||||||
self.assertEqual(1, len(resource_providers))
|
self.assertEqual(1, len(resource_providers))
|
||||||
|
|
||||||
# Let's verify that the min and max units are checked too
|
# 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
|
# 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.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.MEMORY_MB: 2}})
|
self.ctx, {'resources': {orc.MEMORY_MB: 2}})
|
||||||
self.assertEqual(2, len(resource_providers))
|
self.assertEqual(2, len(resource_providers))
|
||||||
# Case 2: amount is less than min_unit
|
# Case 2: amount is less than min_unit
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.MEMORY_MB: 1}})
|
self.ctx, {'resources': {orc.MEMORY_MB: 1}})
|
||||||
self.assertEqual(0, len(resource_providers))
|
self.assertEqual(0, len(resource_providers))
|
||||||
# Case 3: amount is more than min_unit
|
# Case 3: amount is more than min_unit
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.MEMORY_MB: 5}})
|
self.ctx, {'resources': {orc.MEMORY_MB: 5}})
|
||||||
self.assertEqual(0, len(resource_providers))
|
self.assertEqual(0, len(resource_providers))
|
||||||
# Case 4: amount is not modulo step_size
|
# Case 4: amount is not modulo step_size
|
||||||
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
resource_providers = rp_obj.ResourceProviderList.get_all_by_filters(
|
||||||
self.ctx, {'resources': {fields.ResourceClass.MEMORY_MB: 3}})
|
self.ctx, {'resources': {orc.MEMORY_MB: 3}})
|
||||||
self.assertEqual(0, len(resource_providers))
|
self.assertEqual(0, len(resource_providers))
|
||||||
|
|
||||||
def test_get_all_by_filters_with_resources_not_existing(self):
|
def test_get_all_by_filters_with_resources_not_existing(self):
|
||||||
|
@ -1153,9 +1153,9 @@ class TestAllocation(tb.PlacementDbBaseTestCase):
|
||||||
|
|
||||||
# Add same inventory to both source and destination host
|
# Add same inventory to both source and destination host
|
||||||
for cn in (cn_source, cn_dest):
|
for cn in (cn_source, cn_dest):
|
||||||
tb.add_inventory(cn, fields.ResourceClass.VCPU, 24,
|
tb.add_inventory(cn, orc.VCPU, 24,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
tb.add_inventory(cn, fields.ResourceClass.MEMORY_MB, 1024,
|
tb.add_inventory(cn, orc.MEMORY_MB, 1024,
|
||||||
min_unit=64,
|
min_unit=64,
|
||||||
max_unit=1024,
|
max_unit=1024,
|
||||||
step_size=64,
|
step_size=64,
|
||||||
|
@ -1176,25 +1176,25 @@ class TestAllocation(tb.PlacementDbBaseTestCase):
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=cn_source,
|
resource_provider=cn_source,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=1),
|
used=1),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=cn_source,
|
resource_provider=cn_source,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=256),
|
used=256),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=cn_dest,
|
resource_provider=cn_dest,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=1),
|
used=1),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=cn_dest,
|
resource_provider=cn_dest,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=256),
|
used=256),
|
||||||
])
|
])
|
||||||
alloc_list.replace_all()
|
alloc_list.replace_all()
|
||||||
|
@ -1226,13 +1226,13 @@ class TestAllocation(tb.PlacementDbBaseTestCase):
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=cn_dest,
|
resource_provider=cn_dest,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=1),
|
used=1),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=cn_dest,
|
resource_provider=cn_dest,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=256),
|
used=256),
|
||||||
])
|
])
|
||||||
new_alloc_list.replace_all()
|
new_alloc_list.replace_all()
|
||||||
|
@ -1288,10 +1288,10 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
# Create one resource provider with 2 classes
|
# Create one resource provider with 2 classes
|
||||||
rp1_name = uuidsentinel.rp1_name
|
rp1_name = uuidsentinel.rp1_name
|
||||||
rp1_uuid = uuidsentinel.rp1_uuid
|
rp1_uuid = uuidsentinel.rp1_uuid
|
||||||
rp1_class = fields.ResourceClass.DISK_GB
|
rp1_class = orc.DISK_GB
|
||||||
rp1_used = 6
|
rp1_used = 6
|
||||||
|
|
||||||
rp2_class = fields.ResourceClass.IPV4_ADDRESS
|
rp2_class = orc.IPV4_ADDRESS
|
||||||
rp2_used = 2
|
rp2_used = 2
|
||||||
|
|
||||||
rp1 = self._create_provider(rp1_name, uuid=rp1_uuid)
|
rp1 = self._create_provider(rp1_name, uuid=rp1_uuid)
|
||||||
|
@ -1341,12 +1341,12 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
# Create two resource providers
|
# Create two resource providers
|
||||||
rp1_name = uuidsentinel.rp1_name
|
rp1_name = uuidsentinel.rp1_name
|
||||||
rp1_uuid = uuidsentinel.rp1_uuid
|
rp1_uuid = uuidsentinel.rp1_uuid
|
||||||
rp1_class = fields.ResourceClass.DISK_GB
|
rp1_class = orc.DISK_GB
|
||||||
rp1_used = 6
|
rp1_used = 6
|
||||||
|
|
||||||
rp2_name = uuidsentinel.rp2_name
|
rp2_name = uuidsentinel.rp2_name
|
||||||
rp2_uuid = uuidsentinel.rp2_uuid
|
rp2_uuid = uuidsentinel.rp2_uuid
|
||||||
rp2_class = fields.ResourceClass.IPV4_ADDRESS
|
rp2_class = orc.IPV4_ADDRESS
|
||||||
rp2_used = 2
|
rp2_used = 2
|
||||||
|
|
||||||
rp1 = self._create_provider(rp1_name, uuid=rp1_uuid)
|
rp1 = self._create_provider(rp1_name, uuid=rp1_uuid)
|
||||||
|
@ -1452,7 +1452,7 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
|
|
||||||
def _check_create_allocations(self, inventory_kwargs,
|
def _check_create_allocations(self, inventory_kwargs,
|
||||||
bad_used, good_used):
|
bad_used, good_used):
|
||||||
rp_class = fields.ResourceClass.DISK_GB
|
rp_class = orc.DISK_GB
|
||||||
rp = self._make_rp_and_inventory(resource_class=rp_class,
|
rp = self._make_rp_and_inventory(resource_class=rp_class,
|
||||||
**inventory_kwargs)
|
**inventory_kwargs)
|
||||||
|
|
||||||
|
@ -1500,7 +1500,7 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
project=self.project_obj)
|
project=self.project_obj)
|
||||||
inst_consumer.create()
|
inst_consumer.create()
|
||||||
|
|
||||||
rp_class = fields.ResourceClass.DISK_GB
|
rp_class = orc.DISK_GB
|
||||||
target_rp = self._make_rp_and_inventory(resource_class=rp_class,
|
target_rp = self._make_rp_and_inventory(resource_class=rp_class,
|
||||||
max_unit=500)
|
max_unit=500)
|
||||||
|
|
||||||
|
@ -1628,9 +1628,9 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
full_rp = self._create_provider('full_rp')
|
full_rp = self._create_provider('full_rp')
|
||||||
|
|
||||||
for rp in (empty_rp, full_rp):
|
for rp in (empty_rp, full_rp):
|
||||||
tb.add_inventory(rp, fields.ResourceClass.VCPU, 24,
|
tb.add_inventory(rp, orc.VCPU, 24,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
tb.add_inventory(rp, fields.ResourceClass.MEMORY_MB, 1024,
|
tb.add_inventory(rp, orc.MEMORY_MB, 1024,
|
||||||
min_unit=64,
|
min_unit=64,
|
||||||
max_unit=1024,
|
max_unit=1024,
|
||||||
step_size=64)
|
step_size=64)
|
||||||
|
@ -1648,13 +1648,13 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=full_rp,
|
resource_provider=full_rp,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=12),
|
used=12),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=full_rp,
|
resource_provider=full_rp,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=1024)
|
used=1024)
|
||||||
])
|
])
|
||||||
alloc_list.replace_all()
|
alloc_list.replace_all()
|
||||||
|
@ -1673,25 +1673,25 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst2_consumer,
|
consumer=inst2_consumer,
|
||||||
resource_provider=empty_rp,
|
resource_provider=empty_rp,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=12),
|
used=12),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst2_consumer,
|
consumer=inst2_consumer,
|
||||||
resource_provider=empty_rp,
|
resource_provider=empty_rp,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=512),
|
used=512),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst2_consumer,
|
consumer=inst2_consumer,
|
||||||
resource_provider=full_rp,
|
resource_provider=full_rp,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=12),
|
used=12),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst2_consumer,
|
consumer=inst2_consumer,
|
||||||
resource_provider=full_rp,
|
resource_provider=full_rp,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=512),
|
used=512),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -1714,9 +1714,9 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
|
|
||||||
# Create a single resource provider and give it some inventory.
|
# Create a single resource provider and give it some inventory.
|
||||||
rp1 = self._create_provider('rp1')
|
rp1 = self._create_provider('rp1')
|
||||||
tb.add_inventory(rp1, fields.ResourceClass.VCPU, 24,
|
tb.add_inventory(rp1, orc.VCPU, 24,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
tb.add_inventory(rp1, fields.ResourceClass.MEMORY_MB, 1024,
|
tb.add_inventory(rp1, orc.MEMORY_MB, 1024,
|
||||||
min_unit=64,
|
min_unit=64,
|
||||||
max_unit=1024,
|
max_unit=1024,
|
||||||
step_size=64)
|
step_size=64)
|
||||||
|
@ -1737,13 +1737,13 @@ class TestAllocationListCreateDelete(tb.PlacementDbBaseTestCase):
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=rp1,
|
resource_provider=rp1,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
used=12),
|
used=12),
|
||||||
rp_obj.Allocation(
|
rp_obj.Allocation(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
consumer=inst_consumer,
|
consumer=inst_consumer,
|
||||||
resource_provider=rp1,
|
resource_provider=rp1,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
used=1024)
|
used=1024)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -1806,7 +1806,7 @@ class UsageListTestCase(tb.PlacementDbBaseTestCase):
|
||||||
def test_get_all_one_allocation(self):
|
def test_get_all_one_allocation(self):
|
||||||
db_rp, _ = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
db_rp, _ = self._make_allocation(DISK_INVENTORY, DISK_ALLOCATION)
|
||||||
inv = rp_obj.Inventory(resource_provider=db_rp,
|
inv = rp_obj.Inventory(resource_provider=db_rp,
|
||||||
resource_class=fields.ResourceClass.DISK_GB,
|
resource_class=orc.DISK_GB,
|
||||||
total=1024)
|
total=1024)
|
||||||
inv.obj_set_defaults()
|
inv.obj_set_defaults()
|
||||||
inv_list = rp_obj.InventoryList(objects=[inv])
|
inv_list = rp_obj.InventoryList(objects=[inv])
|
||||||
|
@ -1816,24 +1816,24 @@ class UsageListTestCase(tb.PlacementDbBaseTestCase):
|
||||||
self.ctx, db_rp.uuid)
|
self.ctx, db_rp.uuid)
|
||||||
self.assertEqual(1, len(usage_list))
|
self.assertEqual(1, len(usage_list))
|
||||||
self.assertEqual(2, usage_list[0].usage)
|
self.assertEqual(2, usage_list[0].usage)
|
||||||
self.assertEqual(fields.ResourceClass.DISK_GB,
|
self.assertEqual(orc.DISK_GB,
|
||||||
usage_list[0].resource_class)
|
usage_list[0].resource_class)
|
||||||
|
|
||||||
def test_get_inventory_no_allocation(self):
|
def test_get_inventory_no_allocation(self):
|
||||||
db_rp = self._create_provider('rp_no_inv')
|
db_rp = self._create_provider('rp_no_inv')
|
||||||
tb.add_inventory(db_rp, fields.ResourceClass.DISK_GB, 1024)
|
tb.add_inventory(db_rp, orc.DISK_GB, 1024)
|
||||||
|
|
||||||
usage_list = rp_obj.UsageList.get_all_by_resource_provider_uuid(
|
usage_list = rp_obj.UsageList.get_all_by_resource_provider_uuid(
|
||||||
self.ctx, db_rp.uuid)
|
self.ctx, db_rp.uuid)
|
||||||
self.assertEqual(1, len(usage_list))
|
self.assertEqual(1, len(usage_list))
|
||||||
self.assertEqual(0, usage_list[0].usage)
|
self.assertEqual(0, usage_list[0].usage)
|
||||||
self.assertEqual(fields.ResourceClass.DISK_GB,
|
self.assertEqual(orc.DISK_GB,
|
||||||
usage_list[0].resource_class)
|
usage_list[0].resource_class)
|
||||||
|
|
||||||
def test_get_all_multiple_inv(self):
|
def test_get_all_multiple_inv(self):
|
||||||
db_rp = self._create_provider('rp_no_inv')
|
db_rp = self._create_provider('rp_no_inv')
|
||||||
tb.add_inventory(db_rp, fields.ResourceClass.DISK_GB, 1024)
|
tb.add_inventory(db_rp, orc.DISK_GB, 1024)
|
||||||
tb.add_inventory(db_rp, fields.ResourceClass.VCPU, 24)
|
tb.add_inventory(db_rp, orc.VCPU, 24)
|
||||||
|
|
||||||
usage_list = rp_obj.UsageList.get_all_by_resource_provider_uuid(
|
usage_list = rp_obj.UsageList.get_all_by_resource_provider_uuid(
|
||||||
self.ctx, db_rp.uuid)
|
self.ctx, db_rp.uuid)
|
||||||
|
@ -1848,7 +1848,7 @@ class ResourceClassListTestCase(tb.PlacementDbBaseTestCase):
|
||||||
classes.
|
classes.
|
||||||
"""
|
"""
|
||||||
rcs = rp_obj.ResourceClassList.get_all(self.ctx)
|
rcs = rp_obj.ResourceClassList.get_all(self.ctx)
|
||||||
self.assertEqual(len(fields.ResourceClass.STANDARD), len(rcs))
|
self.assertEqual(len(orc.STANDARDS), len(rcs))
|
||||||
|
|
||||||
def test_get_all_with_custom(self):
|
def test_get_all_with_custom(self):
|
||||||
"""Test that if we add some custom resource classes, that we get a list
|
"""Test that if we add some custom resource classes, that we get a list
|
||||||
|
@ -1866,7 +1866,7 @@ class ResourceClassListTestCase(tb.PlacementDbBaseTestCase):
|
||||||
conn.execute(ins)
|
conn.execute(ins)
|
||||||
|
|
||||||
rcs = rp_obj.ResourceClassList.get_all(self.ctx)
|
rcs = rp_obj.ResourceClassList.get_all(self.ctx)
|
||||||
expected_count = len(fields.ResourceClass.STANDARD) + len(customs)
|
expected_count = (len(orc.STANDARDS) + len(customs))
|
||||||
self.assertEqual(expected_count, len(rcs))
|
self.assertEqual(expected_count, len(rcs))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1875,13 +1875,11 @@ class ResourceClassTestCase(tb.PlacementDbBaseTestCase):
|
||||||
def test_get_by_name(self):
|
def test_get_by_name(self):
|
||||||
rc = rp_obj.ResourceClass.get_by_name(
|
rc = rp_obj.ResourceClass.get_by_name(
|
||||||
self.ctx,
|
self.ctx,
|
||||||
fields.ResourceClass.VCPU
|
orc.VCPU
|
||||||
)
|
|
||||||
vcpu_id = fields.ResourceClass.STANDARD.index(
|
|
||||||
fields.ResourceClass.VCPU
|
|
||||||
)
|
)
|
||||||
|
vcpu_id = orc.STANDARDS.index(orc.VCPU)
|
||||||
self.assertEqual(vcpu_id, rc.id)
|
self.assertEqual(vcpu_id, rc.id)
|
||||||
self.assertEqual(fields.ResourceClass.VCPU, rc.name)
|
self.assertEqual(orc.VCPU, rc.name)
|
||||||
|
|
||||||
def test_get_by_name_not_found(self):
|
def test_get_by_name_not_found(self):
|
||||||
self.assertRaises(exception.ResourceClassNotFound,
|
self.assertRaises(exception.ResourceClassNotFound,
|
||||||
|
@ -1913,7 +1911,7 @@ class ResourceClassTestCase(tb.PlacementDbBaseTestCase):
|
||||||
def test_create_duplicate_standard(self):
|
def test_create_duplicate_standard(self):
|
||||||
rc = rp_obj.ResourceClass(
|
rc = rp_obj.ResourceClass(
|
||||||
context=self.ctx,
|
context=self.ctx,
|
||||||
name=fields.ResourceClass.VCPU,
|
name=orc.VCPU,
|
||||||
)
|
)
|
||||||
self.assertRaises(exception.ResourceClassExists, rc.create)
|
self.assertRaises(exception.ResourceClassExists, rc.create)
|
||||||
|
|
||||||
|
@ -2326,10 +2324,10 @@ class SharedProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _requested_resources(self):
|
def _requested_resources(self):
|
||||||
STANDARDS = fields.ResourceClass.STANDARD
|
STANDARDS = orc.STANDARDS
|
||||||
VCPU_ID = STANDARDS.index(fields.ResourceClass.VCPU)
|
VCPU_ID = STANDARDS.index(orc.VCPU)
|
||||||
MEMORY_MB_ID = STANDARDS.index(fields.ResourceClass.MEMORY_MB)
|
MEMORY_MB_ID = STANDARDS.index(orc.MEMORY_MB)
|
||||||
DISK_GB_ID = STANDARDS.index(fields.ResourceClass.DISK_GB)
|
DISK_GB_ID = STANDARDS.index(orc.DISK_GB)
|
||||||
# The resources we will request
|
# The resources we will request
|
||||||
resources = {
|
resources = {
|
||||||
VCPU_ID: 1,
|
VCPU_ID: 1,
|
||||||
|
@ -2352,15 +2350,15 @@ class SharedProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
# DISK_GB. Both should be excluded from the result (one doesn't have
|
# DISK_GB. Both should be excluded from the result (one doesn't have
|
||||||
# the requested resource; but neither is a sharing provider).
|
# the requested resource; but neither is a sharing provider).
|
||||||
for cn in (cn1, cn2):
|
for cn in (cn1, cn2):
|
||||||
tb.add_inventory(cn, fields.ResourceClass.VCPU, 24,
|
tb.add_inventory(cn, orc.VCPU, 24,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
tb.add_inventory(cn, fields.ResourceClass.MEMORY_MB, 32768,
|
tb.add_inventory(cn, orc.MEMORY_MB, 32768,
|
||||||
min_unit=64,
|
min_unit=64,
|
||||||
max_unit=32768,
|
max_unit=32768,
|
||||||
step_size=64,
|
step_size=64,
|
||||||
allocation_ratio=1.5)
|
allocation_ratio=1.5)
|
||||||
if cn is cn1:
|
if cn is cn1:
|
||||||
tb.add_inventory(cn, fields.ResourceClass.DISK_GB, 2000,
|
tb.add_inventory(cn, orc.DISK_GB, 2000,
|
||||||
min_unit=10,
|
min_unit=10,
|
||||||
max_unit=100,
|
max_unit=100,
|
||||||
step_size=10)
|
step_size=10)
|
||||||
|
@ -2369,7 +2367,7 @@ class SharedProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
ss = self._create_provider('shared storage')
|
ss = self._create_provider('shared storage')
|
||||||
|
|
||||||
# Give the shared storage pool some inventory of DISK_GB
|
# Give the shared storage pool some inventory of DISK_GB
|
||||||
tb.add_inventory(ss, fields.ResourceClass.DISK_GB, 2000,
|
tb.add_inventory(ss, orc.DISK_GB, 2000,
|
||||||
min_unit=10,
|
min_unit=10,
|
||||||
max_unit=100,
|
max_unit=100,
|
||||||
step_size=10)
|
step_size=10)
|
||||||
|
@ -2382,7 +2380,7 @@ class SharedProviderTestCase(tb.PlacementDbBaseTestCase):
|
||||||
# the shared storage pool when we ask for DISK_GB
|
# the shared storage pool when we ask for DISK_GB
|
||||||
got_ids = rp_obj._get_providers_with_shared_capacity(
|
got_ids = rp_obj._get_providers_with_shared_capacity(
|
||||||
self.ctx,
|
self.ctx,
|
||||||
fields.ResourceClass.STANDARD.index(fields.ResourceClass.DISK_GB),
|
orc.STANDARDS.index(orc.DISK_GB),
|
||||||
100,
|
100,
|
||||||
)
|
)
|
||||||
self.assertEqual([ss.id], got_ids)
|
self.assertEqual([ss.id], got_ids)
|
||||||
|
|
|
@ -14,6 +14,7 @@ from __future__ import absolute_import
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from gabbi import fixture
|
from gabbi import fixture
|
||||||
|
import os_resource_classes as orc
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_config import fixture as config_fixture
|
from oslo_config import fixture as config_fixture
|
||||||
from oslo_log.fixture import logging_error
|
from oslo_log.fixture import logging_error
|
||||||
|
@ -30,7 +31,6 @@ from placement.objects import project as project_obj
|
||||||
from placement.objects import resource_provider as rp_obj
|
from placement.objects import resource_provider as rp_obj
|
||||||
from placement.objects import user as user_obj
|
from placement.objects import user as user_obj
|
||||||
from placement import policies
|
from placement import policies
|
||||||
from placement import rc_fields as fields
|
|
||||||
from placement.tests import fixtures
|
from placement.tests import fixtures
|
||||||
from placement.tests.functional.db import test_base as tb
|
from placement.tests.functional.db import test_base as tb
|
||||||
from placement.tests.functional.fixtures import capture
|
from placement.tests.functional.fixtures import capture
|
||||||
|
@ -257,21 +257,21 @@ class SharedStorageFixture(APIFixture):
|
||||||
|
|
||||||
# Populate compute node inventory for VCPU and RAM
|
# Populate compute node inventory for VCPU and RAM
|
||||||
for cn in (cn1, cn2):
|
for cn in (cn1, cn2):
|
||||||
tb.add_inventory(cn, fields.ResourceClass.VCPU, 24,
|
tb.add_inventory(cn, orc.VCPU, 24,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
tb.add_inventory(cn, fields.ResourceClass.MEMORY_MB, 128 * 1024,
|
tb.add_inventory(cn, orc.MEMORY_MB, 128 * 1024,
|
||||||
allocation_ratio=1.5)
|
allocation_ratio=1.5)
|
||||||
tb.set_traits(cn1, 'HW_CPU_X86_SSE', 'HW_CPU_X86_SSE2')
|
tb.set_traits(cn1, 'HW_CPU_X86_SSE', 'HW_CPU_X86_SSE2')
|
||||||
|
|
||||||
# Populate shared storage provider with DISK_GB inventory and
|
# Populate shared storage provider with DISK_GB inventory and
|
||||||
# mark it shared among any provider associated via aggregate
|
# mark it shared among any provider associated via aggregate
|
||||||
tb.add_inventory(ss, fields.ResourceClass.DISK_GB, 2000,
|
tb.add_inventory(ss, orc.DISK_GB, 2000,
|
||||||
reserved=100, allocation_ratio=1.0)
|
reserved=100, allocation_ratio=1.0)
|
||||||
tb.set_traits(ss, 'MISC_SHARES_VIA_AGGREGATE')
|
tb.set_traits(ss, 'MISC_SHARES_VIA_AGGREGATE')
|
||||||
|
|
||||||
# Populate PF inventory for VF
|
# Populate PF inventory for VF
|
||||||
for pf in (pf1_1, pf1_2, pf2_1, pf2_2):
|
for pf in (pf1_1, pf1_2, pf2_1, pf2_2):
|
||||||
tb.add_inventory(pf, fields.ResourceClass.SRIOV_NET_VF,
|
tb.add_inventory(pf, orc.SRIOV_NET_VF,
|
||||||
8, allocation_ratio=1.0)
|
8, allocation_ratio=1.0)
|
||||||
|
|
||||||
|
|
||||||
|
@ -343,13 +343,13 @@ class NUMAAggregateFixture(APIFixture):
|
||||||
|
|
||||||
# Populate compute node inventory for VCPU and RAM
|
# Populate compute node inventory for VCPU and RAM
|
||||||
for numa in (numa1_1, numa1_2, numa2_1, numa2_2):
|
for numa in (numa1_1, numa1_2, numa2_1, numa2_2):
|
||||||
tb.add_inventory(numa, fields.ResourceClass.VCPU, 24,
|
tb.add_inventory(numa, orc.VCPU, 24,
|
||||||
allocation_ratio=16.0)
|
allocation_ratio=16.0)
|
||||||
|
|
||||||
# Populate shared storage provider with DISK_GB inventory and
|
# Populate shared storage provider with DISK_GB inventory and
|
||||||
# mark it shared among any provider associated via aggregate
|
# mark it shared among any provider associated via aggregate
|
||||||
for ss in (ss1, ss2):
|
for ss in (ss1, ss2):
|
||||||
tb.add_inventory(ss, fields.ResourceClass.DISK_GB, 2000,
|
tb.add_inventory(ss, orc.DISK_GB, 2000,
|
||||||
reserved=100, allocation_ratio=1.0)
|
reserved=100, allocation_ratio=1.0)
|
||||||
tb.set_traits(ss, 'MISC_SHARES_VIA_AGGREGATE')
|
tb.set_traits(ss, 'MISC_SHARES_VIA_AGGREGATE')
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
import os_resource_classes as orc
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_config import fixture as config_fixture
|
from oslo_config import fixture as config_fixture
|
||||||
from oslo_utils.fixture import uuidsentinel as uuids
|
from oslo_utils.fixture import uuidsentinel as uuids
|
||||||
|
@ -22,15 +23,14 @@ from placement import conf
|
||||||
from placement import context
|
from placement import context
|
||||||
from placement import exception
|
from placement import exception
|
||||||
from placement.objects import resource_provider
|
from placement.objects import resource_provider
|
||||||
from placement import rc_fields as fields
|
|
||||||
|
|
||||||
|
|
||||||
_RESOURCE_CLASS_NAME = 'DISK_GB'
|
_RESOURCE_CLASS_NAME = 'DISK_GB'
|
||||||
_RESOURCE_CLASS_ID = 2
|
_RESOURCE_CLASS_ID = 2
|
||||||
IPV4_ADDRESS_ID = fields.ResourceClass.STANDARD.index(
|
IPV4_ADDRESS_ID = orc.STANDARDS.index(
|
||||||
fields.ResourceClass.IPV4_ADDRESS)
|
orc.IPV4_ADDRESS)
|
||||||
VCPU_ID = fields.ResourceClass.STANDARD.index(
|
VCPU_ID = orc.STANDARDS.index(
|
||||||
fields.ResourceClass.VCPU)
|
orc.VCPU)
|
||||||
|
|
||||||
_RESOURCE_PROVIDER_ID = 1
|
_RESOURCE_PROVIDER_ID = 1
|
||||||
_RESOURCE_PROVIDER_UUID = uuids.resource_provider
|
_RESOURCE_PROVIDER_UUID = uuids.resource_provider
|
||||||
|
@ -155,10 +155,10 @@ class TestProviderSummaryNoDB(_TestCase):
|
||||||
def test_resource_class_names(self):
|
def test_resource_class_names(self):
|
||||||
psum = resource_provider.ProviderSummary(mock.sentinel.ctx)
|
psum = resource_provider.ProviderSummary(mock.sentinel.ctx)
|
||||||
disk_psr = resource_provider.ProviderSummaryResource(
|
disk_psr = resource_provider.ProviderSummaryResource(
|
||||||
mock.sentinel.ctx, resource_class=fields.ResourceClass.DISK_GB,
|
mock.sentinel.ctx, resource_class=orc.DISK_GB,
|
||||||
capacity=100, used=0)
|
capacity=100, used=0)
|
||||||
ram_psr = resource_provider.ProviderSummaryResource(
|
ram_psr = resource_provider.ProviderSummaryResource(
|
||||||
mock.sentinel.ctx, resource_class=fields.ResourceClass.MEMORY_MB,
|
mock.sentinel.ctx, resource_class=orc.MEMORY_MB,
|
||||||
capacity=1024, used=0)
|
capacity=1024, used=0)
|
||||||
psum.resources = [disk_psr, ram_psr]
|
psum.resources = [disk_psr, ram_psr]
|
||||||
expected = set(['DISK_GB', 'MEMORY_MB'])
|
expected = set(['DISK_GB', 'MEMORY_MB'])
|
||||||
|
@ -243,23 +243,23 @@ class TestInventoryList(_TestCase):
|
||||||
inv_list = resource_provider.InventoryList(objects=[
|
inv_list = resource_provider.InventoryList(objects=[
|
||||||
resource_provider.Inventory(
|
resource_provider.Inventory(
|
||||||
resource_provider=rp,
|
resource_provider=rp,
|
||||||
resource_class=fields.ResourceClass.VCPU,
|
resource_class=orc.VCPU,
|
||||||
total=24),
|
total=24),
|
||||||
resource_provider.Inventory(
|
resource_provider.Inventory(
|
||||||
resource_provider=rp,
|
resource_provider=rp,
|
||||||
resource_class=fields.ResourceClass.MEMORY_MB,
|
resource_class=orc.MEMORY_MB,
|
||||||
total=10240),
|
total=10240),
|
||||||
])
|
])
|
||||||
|
|
||||||
found = inv_list.find(fields.ResourceClass.MEMORY_MB)
|
found = inv_list.find(orc.MEMORY_MB)
|
||||||
self.assertIsNotNone(found)
|
self.assertIsNotNone(found)
|
||||||
self.assertEqual(10240, found.total)
|
self.assertEqual(10240, found.total)
|
||||||
|
|
||||||
found = inv_list.find(fields.ResourceClass.VCPU)
|
found = inv_list.find(orc.VCPU)
|
||||||
self.assertIsNotNone(found)
|
self.assertIsNotNone(found)
|
||||||
self.assertEqual(24, found.total)
|
self.assertEqual(24, found.total)
|
||||||
|
|
||||||
found = inv_list.find(fields.ResourceClass.DISK_GB)
|
found = inv_list.find(orc.DISK_GB)
|
||||||
self.assertIsNone(found)
|
self.assertIsNone(found)
|
||||||
|
|
||||||
# Try an integer resource class identifier...
|
# Try an integer resource class identifier...
|
||||||
|
|
|
@ -23,5 +23,6 @@ oslo.i18n>=3.15.3 # Apache-2.0
|
||||||
oslo.middleware>=3.31.0 # Apache-2.0
|
oslo.middleware>=3.31.0 # Apache-2.0
|
||||||
oslo.upgradecheck>=0.1.1 # Apache-2.0
|
oslo.upgradecheck>=0.1.1 # Apache-2.0
|
||||||
oslo.versionedobjects>=1.31.2 # Apache-2.0
|
oslo.versionedobjects>=1.31.2 # Apache-2.0
|
||||||
|
os-resource-classes>=0.1.0 # Apache-2.0
|
||||||
os-traits>=0.4.0 # Apache-2.0
|
os-traits>=0.4.0 # Apache-2.0
|
||||||
microversion-parse>=0.2.1 # Apache-2.0
|
microversion-parse>=0.2.1 # Apache-2.0
|
||||||
|
|
Loading…
Reference in New Issue