Merge "placement: add ResourceClass and ResourceClassList"
This commit is contained in:
commit
4986c2a65a
@ -65,6 +65,13 @@ class ResourceClassCache(object):
|
||||
self.id_cache = {}
|
||||
self.str_cache = {}
|
||||
|
||||
def get_standards(self):
|
||||
"""Return a list of {'id': <ID>, 'name': <NAME> for all standard
|
||||
resource classes.
|
||||
"""
|
||||
return [{'id': fields.ResourceClass.STANDARD.index(s), 'name': s}
|
||||
for s in fields.ResourceClass.STANDARD]
|
||||
|
||||
def id_from_string(self, rc_str):
|
||||
"""Given a string representation of a resource class -- e.g. "DISK_GB"
|
||||
or "IRON_SILVER" -- return the integer code for the resource class. For
|
||||
|
@ -30,6 +30,7 @@ from nova.objects import fields
|
||||
_ALLOC_TBL = models.Allocation.__table__
|
||||
_INV_TBL = models.Inventory.__table__
|
||||
_RP_TBL = models.ResourceProvider.__table__
|
||||
_RC_TBL = models.ResourceClass.__table__
|
||||
_RC_CACHE = None
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -1007,3 +1008,51 @@ class UsageList(base.ObjectListBase, base.NovaObject):
|
||||
def __repr__(self):
|
||||
strings = [repr(x) for x in self.objects]
|
||||
return "UsageList[" + ", ".join(strings) + "]"
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class ResourceClass(base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(read_only=True),
|
||||
'name': fields.ResourceClassField(read_only=True),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, target, source):
|
||||
for field in target.fields:
|
||||
setattr(target, field, source[field])
|
||||
|
||||
target._context = context
|
||||
target.obj_reset_changes()
|
||||
return target
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class ResourceClassList(base.ObjectListBase, base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('ResourceClass'),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@db_api.api_context_manager.reader
|
||||
def _get_all(context):
|
||||
_ensure_rc_cache(context)
|
||||
standards = _RC_CACHE.get_standards()
|
||||
customs = list(context.session.query(models.ResourceClass).all())
|
||||
return standards + customs
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_all(cls, context):
|
||||
resource_classes = cls._get_all(context)
|
||||
return base.obj_make_list(context, cls(context),
|
||||
objects.ResourceClass, resource_classes)
|
||||
|
||||
def __repr__(self):
|
||||
strings = [repr(x) for x in self.objects]
|
||||
return "ResourceClassList[" + ", ".join(strings) + "]"
|
||||
|
@ -14,6 +14,7 @@ import mock
|
||||
|
||||
from nova.db.sqlalchemy import resource_class_cache as rc_cache
|
||||
from nova import exception
|
||||
from nova.objects import fields
|
||||
from nova import test
|
||||
from nova.tests import fixtures
|
||||
|
||||
@ -43,6 +44,14 @@ class TestResourceClassCache(test.TestCase):
|
||||
|
||||
self.assertFalse(sel_mock.called)
|
||||
|
||||
def test_get_standards(self):
|
||||
cache = rc_cache.ResourceClassCache(self.context)
|
||||
standards = cache.get_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)
|
||||
|
||||
def test_rc_cache_custom(self):
|
||||
"""Test that non-standard, custom resource classes hit the database and
|
||||
return appropriate results, caching the results after a single
|
||||
|
@ -18,6 +18,7 @@ from nova import context
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova.objects import fields
|
||||
from nova.objects import resource_provider as rp_obj
|
||||
from nova import test
|
||||
from nova.tests import fixtures
|
||||
from nova.tests import uuidsentinel
|
||||
@ -39,10 +40,14 @@ DISK_ALLOCATION = dict(
|
||||
)
|
||||
|
||||
|
||||
class ResourceProviderBaseCase(test.TestCase):
|
||||
class ResourceProviderBaseCase(test.NoDBTestCase):
|
||||
|
||||
USES_DB_SELF = True
|
||||
|
||||
def setUp(self):
|
||||
super(ResourceProviderBaseCase, self).setUp()
|
||||
self.useFixture(fixtures.Database())
|
||||
self.api_db = self.useFixture(fixtures.Database(database='api'))
|
||||
self.context = context.RequestContext('fake-user', 'fake-project')
|
||||
|
||||
def _make_allocation(self, rp_uuid=None):
|
||||
@ -894,3 +899,33 @@ class UsageListTestCase(ResourceProviderBaseCase):
|
||||
usage_list = objects.UsageList.get_all_by_resource_provider_uuid(
|
||||
self.context, db_rp.uuid)
|
||||
self.assertEqual(2, len(usage_list))
|
||||
|
||||
|
||||
class ResourceClassListTestCase(ResourceProviderBaseCase):
|
||||
|
||||
def test_get_all_no_custom(self):
|
||||
"""Test that if we haven't yet added any custom resource classes, that
|
||||
we only get a list of ResourceClass objects representing the standard
|
||||
classes.
|
||||
"""
|
||||
rcs = objects.ResourceClassList.get_all(self.context)
|
||||
self.assertEqual(len(fields.ResourceClass.STANDARD), len(rcs))
|
||||
|
||||
def test_get_all_with_custom(self):
|
||||
"""Test that if we add some custom resource classes, that we get a list
|
||||
of ResourceClass objects representing the standard classes as well as
|
||||
the custom classes.
|
||||
"""
|
||||
customs = [
|
||||
('IRON_NFV', 10001),
|
||||
('IRON_ENTERPRISE', 10002),
|
||||
]
|
||||
with self.api_db.get_engine().connect() as conn:
|
||||
for custom in customs:
|
||||
c_name, c_id = custom
|
||||
ins = rp_obj._RC_TBL.insert().values(id=c_id, name=c_name)
|
||||
conn.execute(ins)
|
||||
|
||||
rcs = objects.ResourceClassList.get_all(self.context)
|
||||
expected_count = len(fields.ResourceClass.STANDARD) + len(customs)
|
||||
self.assertEqual(expected_count, len(rcs))
|
||||
|
@ -1180,6 +1180,8 @@ object_data = {
|
||||
'Quotas': '1.2-1fe4cd50593aaf5d36a6dc5ab3f98fb3',
|
||||
'QuotasNoOp': '1.2-e041ddeb7dc8188ca71706f78aad41c1',
|
||||
'RequestSpec': '1.7-5ff3e9df208bf25f8215f1b87624970d',
|
||||
'ResourceClass': '1.0-e6b367e2cf1733c5f3526f20a3286fe9',
|
||||
'ResourceClassList': '1.0-4ee0d9efdfd681fed822da88376e04d2',
|
||||
'ResourceProvider': '1.1-7bbcd5ea1c51782692f55489ab08dea6',
|
||||
'ResourceProviderList': '1.0-82bd48d8d0f7913bbe7266f3835c81bf',
|
||||
'S3ImageMapping': '1.0-7dd7366a890d82660ed121de9092276e',
|
||||
|
Loading…
x
Reference in New Issue
Block a user