Merge "Add CellMapping object"
This commit is contained in:
commit
b9beb69b27
|
@ -1857,3 +1857,7 @@ class ImageCPUPinningForbidden(Forbidden):
|
|||
|
||||
class UnsupportedPolicyException(Invalid):
|
||||
msg_fmt = _("ServerGroup policy is not supported: %(reason)s")
|
||||
|
||||
|
||||
class CellMappingNotFound(NotFound):
|
||||
msg_fmt = _("Cell %(uuid)s has no mapping.")
|
||||
|
|
|
@ -28,6 +28,7 @@ def register_all():
|
|||
__import__('nova.objects.aggregate')
|
||||
__import__('nova.objects.bandwidth_usage')
|
||||
__import__('nova.objects.block_device')
|
||||
__import__('nova.objects.cell_mapping')
|
||||
__import__('nova.objects.compute_node')
|
||||
__import__('nova.objects.dns_domain')
|
||||
__import__('nova.objects.ec2')
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
# 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.
|
||||
|
||||
from nova.db.sqlalchemy import api as db_api
|
||||
from nova.db.sqlalchemy import api_models
|
||||
from nova import exception
|
||||
from nova.objects import base
|
||||
from nova.objects import fields
|
||||
|
||||
|
||||
class CellMapping(base.NovaTimestampObject, base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(read_only=True),
|
||||
'uuid': fields.UUIDField(),
|
||||
'name': fields.StringField(nullable=True),
|
||||
'transport_url': fields.StringField(),
|
||||
'database_connection': fields.StringField(),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, cell_mapping, db_cell_mapping):
|
||||
for key in cell_mapping.fields:
|
||||
setattr(cell_mapping, key, db_cell_mapping[key])
|
||||
cell_mapping.obj_reset_changes()
|
||||
cell_mapping._context = context
|
||||
return cell_mapping
|
||||
|
||||
@staticmethod
|
||||
def _get_by_uuid_from_db(context, uuid):
|
||||
session = db_api.get_api_session()
|
||||
|
||||
with session.begin():
|
||||
db_mapping = session.query(api_models.CellMapping).filter_by(
|
||||
uuid=uuid).first()
|
||||
if not db_mapping:
|
||||
raise exception.CellMappingNotFound(uuid=uuid)
|
||||
|
||||
return db_mapping
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
db_mapping = cls._get_by_uuid_from_db(context, uuid)
|
||||
|
||||
return cls._from_db_object(context, cls(), db_mapping)
|
||||
|
||||
@staticmethod
|
||||
def _create_in_db(context, updates):
|
||||
session = db_api.get_api_session()
|
||||
|
||||
db_mapping = api_models.CellMapping()
|
||||
db_mapping.update(updates)
|
||||
db_mapping.save(session)
|
||||
return db_mapping
|
||||
|
||||
@base.remotable
|
||||
def create(self):
|
||||
db_mapping = self._create_in_db(self._context, self.obj_get_changes())
|
||||
self._from_db_object(self._context, self, db_mapping)
|
||||
|
||||
@staticmethod
|
||||
def _save_in_db(context, uuid, updates):
|
||||
session = db_api.get_api_session()
|
||||
|
||||
with session.begin():
|
||||
db_mapping = session.query(
|
||||
api_models.CellMapping).filter_by(uuid=uuid).first()
|
||||
if not db_mapping:
|
||||
raise exception.CellMappingNotFound(uuid=uuid)
|
||||
|
||||
db_mapping.update(updates)
|
||||
session.add(db_mapping)
|
||||
return db_mapping
|
||||
|
||||
@base.remotable
|
||||
def save(self):
|
||||
changes = self.obj_get_changes()
|
||||
db_mapping = self._save_in_db(self._context, self.uuid, changes)
|
||||
self._from_db_object(self._context, self, db_mapping)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@staticmethod
|
||||
def _destroy_in_db(context, uuid):
|
||||
session = db_api.get_api_session()
|
||||
|
||||
with session.begin():
|
||||
result = session.query(api_models.CellMapping).filter_by(
|
||||
uuid=uuid).delete()
|
||||
if not result:
|
||||
raise exception.CellMappingNotFound(uuid=uuid)
|
||||
|
||||
@base.remotable
|
||||
def destroy(self):
|
||||
self._destroy_in_db(self._context, self.uuid)
|
|
@ -0,0 +1,74 @@
|
|||
# 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.
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.objects import cell_mapping
|
||||
from nova import test
|
||||
from nova.tests import fixtures
|
||||
|
||||
|
||||
class CellMappingTestCase(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(CellMappingTestCase, self).setUp()
|
||||
self.useFixture(fixtures.Database(database='api'))
|
||||
self.context = context.RequestContext('fake-user', 'fake-project')
|
||||
self.mapping_obj = cell_mapping.CellMapping()
|
||||
self.uuid = uuidutils.generate_uuid()
|
||||
|
||||
sample_mapping = {'uuid': '',
|
||||
'name': 'fake-cell',
|
||||
'transport_url': 'rabbit:///',
|
||||
'database_connection': 'mysql:///'}
|
||||
|
||||
def _create_mapping(self, **kwargs):
|
||||
args = self.sample_mapping.copy()
|
||||
if 'uuid' not in kwargs:
|
||||
args['uuid'] = self.uuid
|
||||
args.update(kwargs)
|
||||
return self.mapping_obj._create_in_db(self.context, args)
|
||||
|
||||
def test_get_by_uuid(self):
|
||||
mapping = self._create_mapping()
|
||||
db_mapping = self.mapping_obj._get_by_uuid_from_db(self.context,
|
||||
mapping['uuid'])
|
||||
for key in self.mapping_obj.fields.keys():
|
||||
self.assertEqual(db_mapping[key], mapping[key])
|
||||
|
||||
def test_get_by_uuid_not_found(self):
|
||||
self.assertRaises(exception.CellMappingNotFound,
|
||||
self.mapping_obj._get_by_uuid_from_db, self.context, self.uuid)
|
||||
|
||||
def test_save_in_db(self):
|
||||
mapping = self._create_mapping()
|
||||
self.mapping_obj._save_in_db(self.context, mapping['uuid'],
|
||||
{'name': 'meow'})
|
||||
db_mapping = self.mapping_obj._get_by_uuid_from_db(self.context,
|
||||
mapping['uuid'])
|
||||
self.assertNotEqual(db_mapping['name'], mapping['name'])
|
||||
for key in [key for key in self.mapping_obj.fields.keys()
|
||||
if key not in ['name', 'updated_at']]:
|
||||
self.assertEqual(db_mapping[key], mapping[key])
|
||||
|
||||
def test_destroy_in_db(self):
|
||||
mapping = self._create_mapping()
|
||||
self.mapping_obj._get_by_uuid_from_db(self.context, mapping['uuid'])
|
||||
self.mapping_obj._destroy_in_db(self.context, mapping['uuid'])
|
||||
self.assertRaises(exception.CellMappingNotFound,
|
||||
self.mapping_obj._get_by_uuid_from_db, self.context,
|
||||
mapping['uuid'])
|
||||
|
||||
def test_destroy_in_db_not_found(self):
|
||||
self.assertRaises(exception.CellMappingNotFound,
|
||||
self.mapping_obj._destroy_in_db, self.context, self.uuid)
|
|
@ -0,0 +1,97 @@
|
|||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from nova import objects
|
||||
from nova.objects import cell_mapping
|
||||
from nova.tests.unit.objects import test_objects
|
||||
|
||||
|
||||
def get_db_mapping(**updates):
|
||||
db_mapping = {
|
||||
'id': 1,
|
||||
'uuid': uuidutils.generate_uuid(),
|
||||
'name': 'cell1',
|
||||
'transport_url': 'rabbit://',
|
||||
'database_connection': 'sqlite:///',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
}
|
||||
db_mapping.update(updates)
|
||||
return db_mapping
|
||||
|
||||
|
||||
class _TestCellMappingObject(object):
|
||||
@mock.patch.object(cell_mapping.CellMapping, '_get_by_uuid_from_db')
|
||||
def test_get_by_uuid(self, uuid_from_db):
|
||||
db_mapping = get_db_mapping()
|
||||
uuid_from_db.return_value = db_mapping
|
||||
|
||||
mapping_obj = objects.CellMapping().get_by_uuid(self.context,
|
||||
db_mapping['uuid'])
|
||||
uuid_from_db.assert_called_once_with(self.context, db_mapping['uuid'])
|
||||
self.compare_obj(mapping_obj, db_mapping)
|
||||
|
||||
@mock.patch.object(cell_mapping.CellMapping, '_create_in_db')
|
||||
def test_create(self, create_in_db):
|
||||
uuid = uuidutils.generate_uuid()
|
||||
db_mapping = get_db_mapping(uuid=uuid, name='test',
|
||||
database_connection='mysql:///')
|
||||
create_in_db.return_value = db_mapping
|
||||
mapping_obj = objects.CellMapping(self.context)
|
||||
mapping_obj.uuid = uuid
|
||||
mapping_obj.name = 'test'
|
||||
mapping_obj.database_connection = 'mysql:///'
|
||||
|
||||
mapping_obj.create()
|
||||
create_in_db.assert_called_once_with(self.context,
|
||||
{'uuid': uuid,
|
||||
'name': 'test',
|
||||
'database_connection': 'mysql:///'})
|
||||
self.compare_obj(mapping_obj, db_mapping)
|
||||
|
||||
@mock.patch.object(cell_mapping.CellMapping, '_save_in_db')
|
||||
def test_save(self, save_in_db):
|
||||
uuid = uuidutils.generate_uuid()
|
||||
db_mapping = get_db_mapping(database_connection='mysql:///')
|
||||
save_in_db.return_value = db_mapping
|
||||
mapping_obj = objects.CellMapping(self.context)
|
||||
mapping_obj.uuid = uuid
|
||||
mapping_obj.database_connection = 'mysql:///'
|
||||
|
||||
mapping_obj.save()
|
||||
save_in_db.assert_called_once_with(self.context, uuid,
|
||||
{'uuid': uuid,
|
||||
'database_connection': 'mysql:///'})
|
||||
self.compare_obj(mapping_obj, db_mapping)
|
||||
|
||||
@mock.patch.object(cell_mapping.CellMapping, '_destroy_in_db')
|
||||
def test_destroy(self, destroy_in_db):
|
||||
uuid = uuidutils.generate_uuid()
|
||||
mapping_obj = objects.CellMapping(self.context)
|
||||
mapping_obj.uuid = uuid
|
||||
|
||||
mapping_obj.destroy()
|
||||
destroy_in_db.assert_called_once_with(self.context, uuid)
|
||||
|
||||
|
||||
class TestCellMappingObject(test_objects._LocalTest,
|
||||
_TestCellMappingObject):
|
||||
pass
|
||||
|
||||
|
||||
class TestRemoteCellMappingObject(test_objects._RemoteTest,
|
||||
_TestCellMappingObject):
|
||||
pass
|
|
@ -1183,6 +1183,7 @@ object_data = {
|
|||
'BandwidthUsageList': '1.2-5b564cbfd5ae6e106443c086938e7602',
|
||||
'BlockDeviceMapping': '1.8-c87e9c7e5cfd6a402f32727aa74aca95',
|
||||
'BlockDeviceMappingList': '1.9-0faaeebdca213010c791bc37a22546e3',
|
||||
'CellMapping': '1.0-4b1616970814c3c819e10c7ef6b9c3d5',
|
||||
'ComputeNode': '1.10-5f8cd6948ad98fcc0c39b79d49acc4b6',
|
||||
'ComputeNodeList': '1.10-4ae1f844c247029fbcdb5fdccbe9e619',
|
||||
'DNSDomain': '1.0-5bdc288d7c3b723ce86ede998fd5c9ba',
|
||||
|
|
Loading…
Reference in New Issue