Merge "Make InstanceGroup object favor the API database"
This commit is contained in:
commit
419ae224a9
@ -12,11 +12,18 @@
|
|||||||
# 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 copy
|
||||||
|
|
||||||
|
from oslo_db import exception as db_exc
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
from oslo_utils import versionutils
|
from oslo_utils import versionutils
|
||||||
|
from sqlalchemy.orm import contains_eager
|
||||||
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from nova.compute import utils as compute_utils
|
from nova.compute import utils as compute_utils
|
||||||
from nova import db
|
from nova import db
|
||||||
|
from nova.db.sqlalchemy import api as db_api
|
||||||
|
from nova.db.sqlalchemy import api_models
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import objects
|
from nova import objects
|
||||||
from nova.objects import base
|
from nova.objects import base
|
||||||
@ -26,6 +33,79 @@ from nova.objects import fields
|
|||||||
LAZY_LOAD_FIELDS = ['hosts']
|
LAZY_LOAD_FIELDS = ['hosts']
|
||||||
|
|
||||||
|
|
||||||
|
def _instance_group_get_query(context, id_field=None, id=None):
|
||||||
|
query = context.session.query(api_models.InstanceGroup).\
|
||||||
|
options(joinedload('_policies')).\
|
||||||
|
options(joinedload('_members'))
|
||||||
|
if not context.is_admin:
|
||||||
|
query = query.filter_by(project_id=context.project_id)
|
||||||
|
if id and id_field:
|
||||||
|
query = query.filter(id_field == id)
|
||||||
|
return query
|
||||||
|
|
||||||
|
|
||||||
|
def _instance_group_model_get_query(context, model_class, group_id):
|
||||||
|
return context.session.query(model_class).filter_by(group_id=group_id)
|
||||||
|
|
||||||
|
|
||||||
|
def _instance_group_model_add(context, model_class, items, item_models, field,
|
||||||
|
group_id, append_to_models=None):
|
||||||
|
models = []
|
||||||
|
already_existing = set()
|
||||||
|
for db_item in item_models:
|
||||||
|
already_existing.add(getattr(db_item, field))
|
||||||
|
models.append(db_item)
|
||||||
|
for item in items:
|
||||||
|
if item in already_existing:
|
||||||
|
continue
|
||||||
|
model = model_class()
|
||||||
|
values = {'group_id': group_id}
|
||||||
|
values[field] = item
|
||||||
|
model.update(values)
|
||||||
|
context.session.add(model)
|
||||||
|
if append_to_models:
|
||||||
|
append_to_models.append(model)
|
||||||
|
models.append(model)
|
||||||
|
return models
|
||||||
|
|
||||||
|
|
||||||
|
def _instance_group_policies_add(context, group, policies):
|
||||||
|
query = _instance_group_model_get_query(context,
|
||||||
|
api_models.InstanceGroupPolicy,
|
||||||
|
group.id)
|
||||||
|
query = query.filter(
|
||||||
|
api_models.InstanceGroupPolicy.policy.in_(set(policies)))
|
||||||
|
return _instance_group_model_add(context, api_models.InstanceGroupPolicy,
|
||||||
|
policies, query.all(), 'policy', group.id,
|
||||||
|
append_to_models=group._policies)
|
||||||
|
|
||||||
|
|
||||||
|
def _instance_group_members_add(context, group, members):
|
||||||
|
query = _instance_group_model_get_query(context,
|
||||||
|
api_models.InstanceGroupMember,
|
||||||
|
group.id)
|
||||||
|
query = query.filter(
|
||||||
|
api_models.InstanceGroupMember.instance_uuid.in_(set(members)))
|
||||||
|
return _instance_group_model_add(context, api_models.InstanceGroupMember,
|
||||||
|
members, query.all(), 'instance_uuid',
|
||||||
|
group.id, append_to_models=group._members)
|
||||||
|
|
||||||
|
|
||||||
|
def _instance_group_members_add_by_uuid(context, group_uuid, members):
|
||||||
|
# NOTE(melwitt): The condition on the join limits the number of members
|
||||||
|
# returned to only those we wish to check as already existing.
|
||||||
|
group = context.session.query(api_models.InstanceGroup).\
|
||||||
|
outerjoin(api_models.InstanceGroupMember,
|
||||||
|
api_models.InstanceGroupMember.instance_uuid.in_(set(members))).\
|
||||||
|
filter(api_models.InstanceGroup.uuid == group_uuid).\
|
||||||
|
options(contains_eager('_members')).first()
|
||||||
|
if not group:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid=group_uuid)
|
||||||
|
return _instance_group_model_add(context, api_models.InstanceGroupMember,
|
||||||
|
members, group._members, 'instance_uuid',
|
||||||
|
group.id)
|
||||||
|
|
||||||
|
|
||||||
# TODO(berrange): Remove NovaObjectDictCompat
|
# TODO(berrange): Remove NovaObjectDictCompat
|
||||||
@base.NovaObjectRegistry.register
|
@base.NovaObjectRegistry.register
|
||||||
class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
||||||
@ -74,8 +154,15 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
for field in instance_group.fields:
|
for field in instance_group.fields:
|
||||||
if field in LAZY_LOAD_FIELDS:
|
if field in LAZY_LOAD_FIELDS:
|
||||||
continue
|
continue
|
||||||
if field == 'deleted':
|
# This is needed to handle db models from both the api
|
||||||
instance_group.deleted = db_inst['deleted'] == db_inst['id']
|
# database and the main database. In the migration to
|
||||||
|
# the api database, we have removed soft-delete, so
|
||||||
|
# the object fields for delete must be filled in with
|
||||||
|
# default values for db models from the api database.
|
||||||
|
ignore = {'deleted': False,
|
||||||
|
'deleted_at': None}
|
||||||
|
if field in ignore and not hasattr(db_inst, field):
|
||||||
|
instance_group[field] = ignore[field]
|
||||||
else:
|
else:
|
||||||
instance_group[field] = db_inst[field]
|
instance_group[field] = db_inst[field]
|
||||||
|
|
||||||
@ -83,6 +170,114 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
instance_group.obj_reset_changes()
|
instance_group.obj_reset_changes()
|
||||||
return instance_group
|
return instance_group
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.reader
|
||||||
|
def _get_from_db_by_uuid(context, uuid):
|
||||||
|
grp = _instance_group_get_query(context,
|
||||||
|
id_field=api_models.InstanceGroup.uuid,
|
||||||
|
id=uuid).first()
|
||||||
|
if not grp:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid=uuid)
|
||||||
|
return grp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.reader
|
||||||
|
def _get_from_db_by_id(context, id):
|
||||||
|
grp = _instance_group_get_query(context,
|
||||||
|
id_field=api_models.InstanceGroup.id,
|
||||||
|
id=id).first()
|
||||||
|
if not grp:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid=id)
|
||||||
|
return grp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.reader
|
||||||
|
def _get_from_db_by_name(context, name):
|
||||||
|
grp = _instance_group_get_query(context).filter_by(name=name).first()
|
||||||
|
if not grp:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid=name)
|
||||||
|
return grp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.reader
|
||||||
|
def _get_from_db_by_instance(context, instance_uuid):
|
||||||
|
grp_member = context.session.query(api_models.InstanceGroupMember).\
|
||||||
|
filter_by(instance_uuid=instance_uuid).first()
|
||||||
|
if not grp_member:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid='')
|
||||||
|
grp = InstanceGroup._get_from_db_by_id(context, grp_member.group_id)
|
||||||
|
return grp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.writer
|
||||||
|
def _save_in_db(context, group_uuid, values):
|
||||||
|
grp = _instance_group_get_query(context,
|
||||||
|
id_field=api_models.InstanceGroup.uuid,
|
||||||
|
id=group_uuid).first()
|
||||||
|
if not grp:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid=group_uuid)
|
||||||
|
|
||||||
|
values_copy = copy.copy(values)
|
||||||
|
policies = values_copy.pop('policies', None)
|
||||||
|
members = values_copy.pop('members', None)
|
||||||
|
|
||||||
|
grp.update(values_copy)
|
||||||
|
|
||||||
|
if policies is not None:
|
||||||
|
_instance_group_policies_add(context, grp, policies)
|
||||||
|
if members is not None:
|
||||||
|
_instance_group_members_add(context, grp, members)
|
||||||
|
|
||||||
|
return grp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.writer
|
||||||
|
def _create_in_db(context, values, policies=None, members=None):
|
||||||
|
try:
|
||||||
|
group = api_models.InstanceGroup()
|
||||||
|
group.update(values)
|
||||||
|
group.save(context.session)
|
||||||
|
except db_exc.DBDuplicateEntry:
|
||||||
|
raise exception.InstanceGroupIdExists(group_uuid=values['uuid'])
|
||||||
|
|
||||||
|
if policies:
|
||||||
|
group._policies = _instance_group_policies_add(context, group,
|
||||||
|
policies)
|
||||||
|
else:
|
||||||
|
group._policies = []
|
||||||
|
|
||||||
|
if members:
|
||||||
|
group._members = _instance_group_members_add(context, group,
|
||||||
|
members)
|
||||||
|
else:
|
||||||
|
group._members = []
|
||||||
|
|
||||||
|
return group
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.writer
|
||||||
|
def _destroy_in_db(context, group_uuid):
|
||||||
|
qry = _instance_group_get_query(context,
|
||||||
|
id_field=api_models.InstanceGroup.uuid,
|
||||||
|
id=group_uuid)
|
||||||
|
if qry.count() == 0:
|
||||||
|
raise exception.InstanceGroupNotFound(group_uuid=group_uuid)
|
||||||
|
|
||||||
|
# Delete policies and members
|
||||||
|
group_id = qry.first().id
|
||||||
|
instance_models = [api_models.InstanceGroupPolicy,
|
||||||
|
api_models.InstanceGroupMember]
|
||||||
|
for model in instance_models:
|
||||||
|
context.session.query(model).filter_by(group_id=group_id).delete()
|
||||||
|
|
||||||
|
qry.delete()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.writer
|
||||||
|
def _add_members_in_db(context, group_uuid, members):
|
||||||
|
return _instance_group_members_add_by_uuid(context, group_uuid,
|
||||||
|
members)
|
||||||
|
|
||||||
def obj_load_attr(self, attrname):
|
def obj_load_attr(self, attrname):
|
||||||
# NOTE(sbauza): Only hosts could be lazy-loaded right now
|
# NOTE(sbauza): Only hosts could be lazy-loaded right now
|
||||||
if attrname != 'hosts':
|
if attrname != 'hosts':
|
||||||
@ -94,27 +289,39 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_by_uuid(cls, context, uuid):
|
def get_by_uuid(cls, context, uuid):
|
||||||
db_inst = db.instance_group_get(context, uuid)
|
db_group = None
|
||||||
return cls._from_db_object(context, cls(), db_inst)
|
try:
|
||||||
|
db_group = cls._get_from_db_by_uuid(context, uuid)
|
||||||
|
except exception.InstanceGroupNotFound:
|
||||||
|
pass
|
||||||
|
if db_group is None:
|
||||||
|
db_group = db.instance_group_get(context, uuid)
|
||||||
|
return cls._from_db_object(context, cls(), db_group)
|
||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_by_name(cls, context, name):
|
def get_by_name(cls, context, name):
|
||||||
# TODO(russellb) We need to get the group by name here. There's no
|
try:
|
||||||
# db.api method for this yet. Come back and optimize this by
|
db_group = cls._get_from_db_by_name(context, name)
|
||||||
# adding a new query by name. This is unnecessarily expensive if a
|
except exception.InstanceGroupNotFound:
|
||||||
# tenant has lots of groups.
|
igs = InstanceGroupList._get_main_by_project_id(context,
|
||||||
igs = objects.InstanceGroupList.get_by_project_id(context,
|
|
||||||
context.project_id)
|
context.project_id)
|
||||||
for ig in igs:
|
for ig in igs:
|
||||||
if ig.name == name:
|
if ig.name == name:
|
||||||
return ig
|
return ig
|
||||||
|
|
||||||
raise exception.InstanceGroupNotFound(group_uuid=name)
|
raise exception.InstanceGroupNotFound(group_uuid=name)
|
||||||
|
return cls._from_db_object(context, cls(), db_group)
|
||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_by_instance_uuid(cls, context, instance_uuid):
|
def get_by_instance_uuid(cls, context, instance_uuid):
|
||||||
db_inst = db.instance_group_get_by_instance(context, instance_uuid)
|
db_group = None
|
||||||
return cls._from_db_object(context, cls(), db_inst)
|
try:
|
||||||
|
db_group = cls._get_from_db_by_instance(context, instance_uuid)
|
||||||
|
except exception.InstanceGroupNotFound:
|
||||||
|
pass
|
||||||
|
if db_group is None:
|
||||||
|
db_group = db.instance_group_get_by_instance(context,
|
||||||
|
instance_uuid)
|
||||||
|
return cls._from_db_object(context, cls(), db_group)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_hint(cls, context, hint):
|
def get_by_hint(cls, context, hint):
|
||||||
@ -147,9 +354,12 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
payload = dict(updates)
|
payload = dict(updates)
|
||||||
payload['server_group_id'] = self.uuid
|
payload['server_group_id'] = self.uuid
|
||||||
|
|
||||||
|
try:
|
||||||
|
db_group = self._save_in_db(self._context, self.uuid, updates)
|
||||||
|
except exception.InstanceGroupNotFound:
|
||||||
db.instance_group_update(self._context, self.uuid, updates)
|
db.instance_group_update(self._context, self.uuid, updates)
|
||||||
db_inst = db.instance_group_get(self._context, self.uuid)
|
db_group = db.instance_group_get(self._context, self.uuid)
|
||||||
self._from_db_object(self._context, self, db_inst)
|
self._from_db_object(self._context, self, db_group)
|
||||||
compute_utils.notify_about_server_group_update(self._context,
|
compute_utils.notify_about_server_group_update(self._context,
|
||||||
"update", payload)
|
"update", payload)
|
||||||
|
|
||||||
@ -173,10 +383,21 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
policies = updates.pop('policies', None)
|
policies = updates.pop('policies', None)
|
||||||
members = updates.pop('members', None)
|
members = updates.pop('members', None)
|
||||||
|
|
||||||
db_inst = db.instance_group_create(self._context, updates,
|
if 'uuid' not in updates:
|
||||||
|
self.uuid = uuidutils.generate_uuid()
|
||||||
|
updates['uuid'] = self.uuid
|
||||||
|
|
||||||
|
try:
|
||||||
|
db.instance_group_get(self._context, self.uuid)
|
||||||
|
raise exception.ObjectActionError(
|
||||||
|
action='create',
|
||||||
|
reason='already created in main')
|
||||||
|
except exception.InstanceGroupNotFound:
|
||||||
|
pass
|
||||||
|
db_group = self._create_in_db(self._context, updates,
|
||||||
policies=policies,
|
policies=policies,
|
||||||
members=members)
|
members=members)
|
||||||
self._from_db_object(self._context, self, db_inst)
|
self._from_db_object(self._context, self, db_group)
|
||||||
payload['server_group_id'] = self.uuid
|
payload['server_group_id'] = self.uuid
|
||||||
compute_utils.notify_about_server_group_update(self._context,
|
compute_utils.notify_about_server_group_update(self._context,
|
||||||
"create", payload)
|
"create", payload)
|
||||||
@ -184,6 +405,9 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
@base.remotable
|
@base.remotable
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
payload = {'server_group_id': self.uuid}
|
payload = {'server_group_id': self.uuid}
|
||||||
|
try:
|
||||||
|
self._destroy_in_db(self._context, self.uuid)
|
||||||
|
except exception.InstanceGroupNotFound:
|
||||||
db.instance_group_delete(self._context, self.uuid)
|
db.instance_group_delete(self._context, self.uuid)
|
||||||
self.obj_reset_changes()
|
self.obj_reset_changes()
|
||||||
compute_utils.notify_about_server_group_update(self._context,
|
compute_utils.notify_about_server_group_update(self._context,
|
||||||
@ -193,6 +417,11 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||||||
def add_members(cls, context, group_uuid, instance_uuids):
|
def add_members(cls, context, group_uuid, instance_uuids):
|
||||||
payload = {'server_group_id': group_uuid,
|
payload = {'server_group_id': group_uuid,
|
||||||
'instance_uuids': instance_uuids}
|
'instance_uuids': instance_uuids}
|
||||||
|
try:
|
||||||
|
members = cls._add_members_in_db(context, group_uuid,
|
||||||
|
instance_uuids)
|
||||||
|
members = [member['instance_uuid'] for member in members]
|
||||||
|
except exception.InstanceGroupNotFound:
|
||||||
members = db.instance_group_members_add(context, group_uuid,
|
members = db.instance_group_members_add(context, group_uuid,
|
||||||
instance_uuids)
|
instance_uuids)
|
||||||
compute_utils.notify_about_server_group_update(context,
|
compute_utils.notify_about_server_group_update(context,
|
||||||
@ -244,14 +473,32 @@ class InstanceGroupList(base.ObjectListBase, base.NovaObject):
|
|||||||
'objects': fields.ListOfObjectsField('InstanceGroup'),
|
'objects': fields.ListOfObjectsField('InstanceGroup'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@db_api.api_context_manager.reader
|
||||||
|
def _get_from_db(context, project_id=None):
|
||||||
|
query = _instance_group_get_query(context)
|
||||||
|
if project_id is not None:
|
||||||
|
query = query.filter_by(project_id=project_id)
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_main_by_project_id(cls, context, project_id):
|
||||||
|
main_db_groups = db.instance_group_get_all_by_project_id(context,
|
||||||
|
project_id)
|
||||||
|
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
|
||||||
|
main_db_groups)
|
||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_by_project_id(cls, context, project_id):
|
def get_by_project_id(cls, context, project_id):
|
||||||
groups = db.instance_group_get_all_by_project_id(context, project_id)
|
api_db_groups = cls._get_from_db(context, project_id=project_id)
|
||||||
|
main_db_groups = db.instance_group_get_all_by_project_id(context,
|
||||||
|
project_id)
|
||||||
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
|
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
|
||||||
groups)
|
api_db_groups + main_db_groups)
|
||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_all(cls, context):
|
def get_all(cls, context):
|
||||||
groups = db.instance_group_get_all(context)
|
api_db_groups = cls._get_from_db(context)
|
||||||
|
main_db_groups = db.instance_group_get_all(context)
|
||||||
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
|
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
|
||||||
groups)
|
api_db_groups + main_db_groups)
|
||||||
|
185
nova/tests/functional/db/test_instance_group.py
Normal file
185
nova/tests/functional/db/test_instance_group.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# 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_versionedobjects import fixture as ovo_fixture
|
||||||
|
|
||||||
|
from nova import context
|
||||||
|
from nova.db.sqlalchemy import api as db_api
|
||||||
|
from nova import exception
|
||||||
|
from nova import objects
|
||||||
|
from nova.objects import base
|
||||||
|
from nova import test
|
||||||
|
from nova.tests import uuidsentinel as uuids
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceGroupObjectTestCase(test.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(InstanceGroupObjectTestCase, self).setUp()
|
||||||
|
self.context = context.RequestContext('fake-user', 'fake-project')
|
||||||
|
|
||||||
|
def _api_group(self, **values):
|
||||||
|
group = objects.InstanceGroup(context=self.context,
|
||||||
|
user_id=self.context.user_id,
|
||||||
|
project_id=self.context.project_id,
|
||||||
|
name='foogroup',
|
||||||
|
policies=['foo1', 'foo2'],
|
||||||
|
members=['memberfoo'])
|
||||||
|
group.update(values)
|
||||||
|
group.create()
|
||||||
|
return group
|
||||||
|
|
||||||
|
def _main_group(self, policies=None, members=None, **values):
|
||||||
|
vals = {
|
||||||
|
'user_id': self.context.user_id,
|
||||||
|
'project_id': self.context.project_id,
|
||||||
|
'name': 'foogroup',
|
||||||
|
}
|
||||||
|
vals.update(values)
|
||||||
|
policies = policies or ['foo1', 'foo2']
|
||||||
|
members = members or ['memberfoo']
|
||||||
|
return db_api.instance_group_create(self.context, vals,
|
||||||
|
policies=policies,
|
||||||
|
members=members)
|
||||||
|
|
||||||
|
def test_create(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
db_group = create_group._get_from_db_by_uuid(self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
ovo_fixture.compare_obj(self, create_group, db_group,
|
||||||
|
allow_missing=('deleted', 'deleted_at'))
|
||||||
|
|
||||||
|
def test_create_duplicate_in_main(self):
|
||||||
|
self._main_group(uuid=uuids.main)
|
||||||
|
self.assertRaises(exception.ObjectActionError,
|
||||||
|
self._api_group, uuid=uuids.main)
|
||||||
|
|
||||||
|
def test_destroy(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
create_group.destroy()
|
||||||
|
self.assertRaises(exception.InstanceGroupNotFound,
|
||||||
|
create_group._get_from_db_by_uuid, self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
|
||||||
|
def test_destroy_main(self):
|
||||||
|
db_group = self._main_group()
|
||||||
|
create_group = objects.InstanceGroup._from_db_object(
|
||||||
|
self.context, objects.InstanceGroup(), db_group)
|
||||||
|
create_group.destroy()
|
||||||
|
self.assertRaises(exception.InstanceGroupNotFound,
|
||||||
|
db_api.instance_group_get, self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
|
||||||
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
|
def test_save(self, _mock_notify):
|
||||||
|
create_group = self._api_group()
|
||||||
|
create_group.policies = ['bar1', 'bar2']
|
||||||
|
create_group.members = ['memberbar1', 'memberbar2']
|
||||||
|
create_group.name = 'anewname'
|
||||||
|
create_group.save()
|
||||||
|
db_group = create_group._get_from_db_by_uuid(self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
ovo_fixture.compare_obj(self, create_group, db_group,
|
||||||
|
allow_missing=('deleted', 'deleted_at'))
|
||||||
|
|
||||||
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
|
def test_save_main(self, _mock_notify):
|
||||||
|
db_group = self._main_group()
|
||||||
|
create_group = objects.InstanceGroup._from_db_object(
|
||||||
|
self.context, objects.InstanceGroup(), db_group)
|
||||||
|
create_group.policies = ['bar1', 'bar2']
|
||||||
|
create_group.members = ['memberbar1', 'memberbar2']
|
||||||
|
create_group.name = 'anewname'
|
||||||
|
create_group.save()
|
||||||
|
db_group = db_api.instance_group_get(self.context, create_group.uuid)
|
||||||
|
ovo_fixture.compare_obj(self, create_group, db_group)
|
||||||
|
|
||||||
|
def test_add_members(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
new_member = ['memberbar']
|
||||||
|
objects.InstanceGroup.add_members(self.context, create_group.uuid,
|
||||||
|
new_member)
|
||||||
|
db_group = create_group._get_from_db_by_uuid(self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
self.assertEqual(create_group.members + new_member, db_group.members)
|
||||||
|
|
||||||
|
def test_add_members_main(self):
|
||||||
|
db_group = self._main_group()
|
||||||
|
create_group = objects.InstanceGroup._from_db_object(
|
||||||
|
self.context, objects.InstanceGroup(), db_group)
|
||||||
|
new_member = ['memberbar']
|
||||||
|
objects.InstanceGroup.add_members(self.context, create_group.uuid,
|
||||||
|
new_member)
|
||||||
|
db_group = db_api.instance_group_get(self.context, create_group.uuid)
|
||||||
|
self.assertEqual(create_group.members + new_member, db_group.members)
|
||||||
|
|
||||||
|
def test_add_members_to_group_with_no_members(self):
|
||||||
|
create_group = self._api_group(members=[])
|
||||||
|
new_member = ['memberbar']
|
||||||
|
objects.InstanceGroup.add_members(self.context, create_group.uuid,
|
||||||
|
new_member)
|
||||||
|
db_group = create_group._get_from_db_by_uuid(self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
self.assertEqual(new_member, db_group.members)
|
||||||
|
|
||||||
|
def test_get_by_uuid(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
get_group = objects.InstanceGroup.get_by_uuid(self.context,
|
||||||
|
create_group.uuid)
|
||||||
|
self.assertTrue(base.obj_equal_prims(create_group, get_group))
|
||||||
|
|
||||||
|
def test_get_by_uuid_main(self):
|
||||||
|
db_group = self._main_group()
|
||||||
|
get_group = objects.InstanceGroup.get_by_uuid(self.context,
|
||||||
|
db_group.uuid)
|
||||||
|
ovo_fixture.compare_obj(self, get_group, db_group)
|
||||||
|
|
||||||
|
def test_get_by_name(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
get_group = objects.InstanceGroup.get_by_name(self.context,
|
||||||
|
create_group.name)
|
||||||
|
self.assertTrue(base.obj_equal_prims(create_group, get_group))
|
||||||
|
|
||||||
|
def test_get_by_name_main(self):
|
||||||
|
db_group = self._main_group()
|
||||||
|
get_group = objects.InstanceGroup.get_by_name(self.context,
|
||||||
|
db_group.name)
|
||||||
|
ovo_fixture.compare_obj(self, get_group, db_group)
|
||||||
|
|
||||||
|
def test_get_by_instance_uuid(self):
|
||||||
|
create_group = self._api_group(members=[uuids.instance])
|
||||||
|
get_group = objects.InstanceGroup.get_by_instance_uuid(self.context,
|
||||||
|
uuids.instance)
|
||||||
|
self.assertTrue(base.obj_equal_prims(create_group, get_group))
|
||||||
|
|
||||||
|
def test_get_by_instance_uuid_main(self):
|
||||||
|
db_group = self._main_group(members=[uuids.instance])
|
||||||
|
get_group = objects.InstanceGroup.get_by_instance_uuid(self.context,
|
||||||
|
uuids.instance)
|
||||||
|
ovo_fixture.compare_obj(self, get_group, db_group)
|
||||||
|
|
||||||
|
def test_get_by_project_id(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
db_group = self._main_group()
|
||||||
|
get_groups = objects.InstanceGroupList.get_by_project_id(
|
||||||
|
self.context, self.context.project_id)
|
||||||
|
self.assertEqual(2, len(get_groups))
|
||||||
|
self.assertTrue(base.obj_equal_prims(create_group, get_groups[0]))
|
||||||
|
ovo_fixture.compare_obj(self, get_groups[1], db_group)
|
||||||
|
|
||||||
|
def test_get_all(self):
|
||||||
|
create_group = self._api_group()
|
||||||
|
db_group = self._main_group()
|
||||||
|
get_groups = objects.InstanceGroupList.get_all(self.context)
|
||||||
|
self.assertEqual(2, len(get_groups))
|
||||||
|
self.assertTrue(base.obj_equal_prims(create_group, get_groups[0]))
|
||||||
|
ovo_fixture.compare_obj(self, get_groups[1], db_group)
|
@ -45,10 +45,12 @@ _INST_GROUP_DB = {
|
|||||||
class _TestInstanceGroupObject(object):
|
class _TestInstanceGroupObject(object):
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get', return_value=_INST_GROUP_DB)
|
@mock.patch('nova.db.instance_group_get', return_value=_INST_GROUP_DB)
|
||||||
def test_get_by_uuid(self, mock_db_get):
|
@mock.patch('nova.objects.InstanceGroup._get_from_db_by_uuid',
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx,
|
side_effect=exception.InstanceGroupNotFound(group_uuid=_DB_UUID))
|
||||||
|
def test_get_by_uuid_main(self, mock_api_get, mock_db_get):
|
||||||
|
obj = objects.InstanceGroup.get_by_uuid(self.context,
|
||||||
_DB_UUID)
|
_DB_UUID)
|
||||||
mock_db_get.assert_called_once_with(mock.sentinel.ctx, _DB_UUID)
|
mock_db_get.assert_called_once_with(self.context, _DB_UUID)
|
||||||
self.assertEqual(_INST_GROUP_DB['members'], obj.members)
|
self.assertEqual(_INST_GROUP_DB['members'], obj.members)
|
||||||
self.assertEqual(_INST_GROUP_DB['policies'], obj.policies)
|
self.assertEqual(_INST_GROUP_DB['policies'], obj.policies)
|
||||||
self.assertEqual(_DB_UUID, obj.uuid)
|
self.assertEqual(_DB_UUID, obj.uuid)
|
||||||
@ -58,18 +60,21 @@ class _TestInstanceGroupObject(object):
|
|||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get_by_instance',
|
@mock.patch('nova.db.instance_group_get_by_instance',
|
||||||
return_value=_INST_GROUP_DB)
|
return_value=_INST_GROUP_DB)
|
||||||
def test_get_by_instance_uuid(self, mock_db_get):
|
@mock.patch('nova.objects.InstanceGroup._get_from_db_by_instance')
|
||||||
|
def test_get_by_instance_uuid_main(self, mock_api_get, mock_db_get):
|
||||||
|
error = exception.InstanceGroupNotFound(group_uuid='')
|
||||||
|
mock_api_get.side_effect = error
|
||||||
objects.InstanceGroup.get_by_instance_uuid(
|
objects.InstanceGroup.get_by_instance_uuid(
|
||||||
mock.sentinel.ctx, mock.sentinel.instance_uuid)
|
self.context, mock.sentinel.instance_uuid)
|
||||||
mock_db_get.assert_called_once_with(
|
mock_db_get.assert_called_once_with(
|
||||||
mock.sentinel.ctx, mock.sentinel.instance_uuid)
|
self.context, mock.sentinel.instance_uuid)
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get')
|
@mock.patch('nova.db.instance_group_get')
|
||||||
def test_refresh(self, mock_db_get):
|
def test_refresh(self, mock_db_get):
|
||||||
changed_group = copy.deepcopy(_INST_GROUP_DB)
|
changed_group = copy.deepcopy(_INST_GROUP_DB)
|
||||||
changed_group['name'] = 'new_name'
|
changed_group['name'] = 'new_name'
|
||||||
mock_db_get.side_effect = [_INST_GROUP_DB, changed_group]
|
mock_db_get.side_effect = [_INST_GROUP_DB, changed_group]
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx,
|
obj = objects.InstanceGroup.get_by_uuid(self.context,
|
||||||
_DB_UUID)
|
_DB_UUID)
|
||||||
self.assertEqual(_INST_GROUP_DB['name'], obj.name)
|
self.assertEqual(_INST_GROUP_DB['name'], obj.name)
|
||||||
obj.refresh()
|
obj.refresh()
|
||||||
@ -79,22 +84,22 @@ class _TestInstanceGroupObject(object):
|
|||||||
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
@mock.patch('nova.db.instance_group_update')
|
@mock.patch('nova.db.instance_group_update')
|
||||||
@mock.patch('nova.db.instance_group_get')
|
@mock.patch('nova.db.instance_group_get')
|
||||||
def test_save(self, mock_db_get, mock_db_update, mock_notify):
|
def test_save_main(self, mock_db_get, mock_db_update, mock_notify):
|
||||||
changed_group = copy.deepcopy(_INST_GROUP_DB)
|
changed_group = copy.deepcopy(_INST_GROUP_DB)
|
||||||
changed_group['name'] = 'new_name'
|
changed_group['name'] = 'new_name'
|
||||||
mock_db_get.side_effect = [_INST_GROUP_DB, changed_group]
|
mock_db_get.side_effect = [_INST_GROUP_DB, changed_group]
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx,
|
obj = objects.InstanceGroup.get_by_uuid(self.context,
|
||||||
_DB_UUID)
|
_DB_UUID)
|
||||||
self.assertEqual(obj.name, 'fake_name')
|
self.assertEqual(obj.name, 'fake_name')
|
||||||
obj.name = 'new_name'
|
obj.name = 'new_name'
|
||||||
obj.policies = ['policy1'] # Remove policy 2
|
obj.policies = ['policy1'] # Remove policy 2
|
||||||
obj.members = ['instance_id1'] # Remove member 2
|
obj.members = ['instance_id1'] # Remove member 2
|
||||||
obj.save()
|
obj.save()
|
||||||
mock_db_update.assert_called_once_with(mock.sentinel.ctx, _DB_UUID,
|
mock_db_update.assert_called_once_with(self.context, _DB_UUID,
|
||||||
{'name': 'new_name',
|
{'name': 'new_name',
|
||||||
'members': ['instance_id1'],
|
'members': ['instance_id1'],
|
||||||
'policies': ['policy1']})
|
'policies': ['policy1']})
|
||||||
mock_notify.assert_called_once_with(mock.sentinel.ctx, "update",
|
mock_notify.assert_called_once_with(self.context, "update",
|
||||||
{'name': 'new_name',
|
{'name': 'new_name',
|
||||||
'members': ['instance_id1'],
|
'members': ['instance_id1'],
|
||||||
'policies': ['policy1'],
|
'policies': ['policy1'],
|
||||||
@ -103,10 +108,10 @@ class _TestInstanceGroupObject(object):
|
|||||||
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
@mock.patch('nova.db.instance_group_update')
|
@mock.patch('nova.db.instance_group_update')
|
||||||
@mock.patch('nova.db.instance_group_get')
|
@mock.patch('nova.db.instance_group_get')
|
||||||
def test_save_without_hosts(self, mock_db_get, mock_db_update,
|
def test_save_without_hosts_main(self, mock_db_get, mock_db_update,
|
||||||
mock_notify):
|
mock_notify):
|
||||||
mock_db_get.side_effect = [_INST_GROUP_DB, _INST_GROUP_DB]
|
mock_db_get.side_effect = [_INST_GROUP_DB, _INST_GROUP_DB]
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx, _DB_UUID)
|
obj = objects.InstanceGroup.get_by_uuid(self.context, _DB_UUID)
|
||||||
obj.hosts = ['fake-host1']
|
obj.hosts = ['fake-host1']
|
||||||
self.assertRaises(exception.InstanceGroupSaveException,
|
self.assertRaises(exception.InstanceGroupSaveException,
|
||||||
obj.save)
|
obj.save)
|
||||||
@ -118,9 +123,10 @@ class _TestInstanceGroupObject(object):
|
|||||||
self.assertFalse(mock_notify.called)
|
self.assertFalse(mock_notify.called)
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
@mock.patch('nova.db.instance_group_create', return_value=_INST_GROUP_DB)
|
@mock.patch('nova.objects.InstanceGroup._create_in_db',
|
||||||
|
return_value=_INST_GROUP_DB)
|
||||||
def test_create(self, mock_db_create, mock_notify):
|
def test_create(self, mock_db_create, mock_notify):
|
||||||
obj = objects.InstanceGroup(context=mock.sentinel.ctx)
|
obj = objects.InstanceGroup(context=self.context)
|
||||||
obj.uuid = _DB_UUID
|
obj.uuid = _DB_UUID
|
||||||
obj.name = _INST_GROUP_DB['name']
|
obj.name = _INST_GROUP_DB['name']
|
||||||
obj.user_id = _INST_GROUP_DB['user_id']
|
obj.user_id = _INST_GROUP_DB['user_id']
|
||||||
@ -133,7 +139,7 @@ class _TestInstanceGroupObject(object):
|
|||||||
obj.deleted = False
|
obj.deleted = False
|
||||||
obj.create()
|
obj.create()
|
||||||
mock_db_create.assert_called_once_with(
|
mock_db_create.assert_called_once_with(
|
||||||
mock.sentinel.ctx,
|
self.context,
|
||||||
{'uuid': _DB_UUID,
|
{'uuid': _DB_UUID,
|
||||||
'name': _INST_GROUP_DB['name'],
|
'name': _INST_GROUP_DB['name'],
|
||||||
'user_id': _INST_GROUP_DB['user_id'],
|
'user_id': _INST_GROUP_DB['user_id'],
|
||||||
@ -146,7 +152,7 @@ class _TestInstanceGroupObject(object):
|
|||||||
members=_INST_GROUP_DB['members'],
|
members=_INST_GROUP_DB['members'],
|
||||||
policies=_INST_GROUP_DB['policies'])
|
policies=_INST_GROUP_DB['policies'])
|
||||||
mock_notify.assert_called_once_with(
|
mock_notify.assert_called_once_with(
|
||||||
mock.sentinel.ctx, "create",
|
self.context, "create",
|
||||||
{'uuid': _DB_UUID,
|
{'uuid': _DB_UUID,
|
||||||
'name': _INST_GROUP_DB['name'],
|
'name': _INST_GROUP_DB['name'],
|
||||||
'user_id': _INST_GROUP_DB['user_id'],
|
'user_id': _INST_GROUP_DB['user_id'],
|
||||||
@ -162,60 +168,64 @@ class _TestInstanceGroupObject(object):
|
|||||||
self.assertRaises(exception.ObjectActionError, obj.create)
|
self.assertRaises(exception.ObjectActionError, obj.create)
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
@mock.patch('nova.db.instance_group_delete')
|
@mock.patch('nova.objects.InstanceGroup._destroy_in_db')
|
||||||
def test_destroy(self, mock_db_delete, mock_notify):
|
def test_destroy(self, mock_db_delete, mock_notify):
|
||||||
obj = objects.InstanceGroup(context=mock.sentinel.ctx)
|
obj = objects.InstanceGroup(context=self.context)
|
||||||
obj.uuid = _DB_UUID
|
obj.uuid = _DB_UUID
|
||||||
obj.destroy()
|
obj.destroy()
|
||||||
mock_db_delete.assert_called_once_with(mock.sentinel.ctx, _DB_UUID)
|
mock_db_delete.assert_called_once_with(self.context, _DB_UUID)
|
||||||
mock_notify.assert_called_once_with(mock.sentinel.ctx, "delete",
|
mock_notify.assert_called_once_with(self.context, "delete",
|
||||||
{'server_group_id': _DB_UUID})
|
{'server_group_id': _DB_UUID})
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
@mock.patch('nova.compute.utils.notify_about_server_group_update')
|
||||||
@mock.patch('nova.db.instance_group_members_add')
|
@mock.patch('nova.objects.InstanceGroup._add_members_in_db')
|
||||||
def test_add_members(self, mock_members_add_db, mock_notify):
|
def test_add_members(self, mock_members_add_db, mock_notify):
|
||||||
mock_members_add_db.return_value = [mock.sentinel.members]
|
fake_member_models = [{'instance_uuid': mock.sentinel.uuid}]
|
||||||
members = objects.InstanceGroup.add_members(mock.sentinel.ctx,
|
fake_member_uuids = [mock.sentinel.uuid]
|
||||||
|
mock_members_add_db.return_value = fake_member_models
|
||||||
|
members = objects.InstanceGroup.add_members(self.context,
|
||||||
_DB_UUID,
|
_DB_UUID,
|
||||||
mock.sentinel.members)
|
fake_member_uuids)
|
||||||
self.assertEqual([mock.sentinel.members], members)
|
self.assertEqual(fake_member_uuids, members)
|
||||||
mock_members_add_db.assert_called_once_with(
|
mock_members_add_db.assert_called_once_with(
|
||||||
mock.sentinel.ctx,
|
self.context,
|
||||||
_DB_UUID,
|
_DB_UUID,
|
||||||
mock.sentinel.members)
|
fake_member_uuids)
|
||||||
mock_notify.assert_called_once_with(
|
mock_notify.assert_called_once_with(
|
||||||
mock.sentinel.ctx, "addmember",
|
self.context, "addmember",
|
||||||
{'instance_uuids': mock.sentinel.members,
|
{'instance_uuids': fake_member_uuids,
|
||||||
'server_group_id': _DB_UUID})
|
'server_group_id': _DB_UUID})
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstanceList.get_by_filters')
|
@mock.patch('nova.objects.InstanceList.get_by_filters')
|
||||||
@mock.patch('nova.db.instance_group_get', return_value=_INST_GROUP_DB)
|
@mock.patch('nova.objects.InstanceGroup._get_from_db_by_uuid',
|
||||||
|
return_value=_INST_GROUP_DB)
|
||||||
def test_count_members_by_user(self, mock_get_db, mock_il_get):
|
def test_count_members_by_user(self, mock_get_db, mock_il_get):
|
||||||
mock_il_get.return_value = [mock.ANY]
|
mock_il_get.return_value = [mock.ANY]
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx, _DB_UUID)
|
obj = objects.InstanceGroup.get_by_uuid(self.context, _DB_UUID)
|
||||||
expected_filters = {
|
expected_filters = {
|
||||||
'uuid': ['instance_id1', 'instance_id2'],
|
'uuid': ['instance_id1', 'instance_id2'],
|
||||||
'user_id': 'fake_user',
|
'user_id': 'fake_user',
|
||||||
'deleted': False
|
'deleted': False
|
||||||
}
|
}
|
||||||
self.assertEqual(1, obj.count_members_by_user('fake_user'))
|
self.assertEqual(1, obj.count_members_by_user('fake_user'))
|
||||||
mock_il_get.assert_called_once_with(mock.sentinel.ctx,
|
mock_il_get.assert_called_once_with(self.context,
|
||||||
filters=expected_filters)
|
filters=expected_filters)
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstanceList.get_by_filters')
|
@mock.patch('nova.objects.InstanceList.get_by_filters')
|
||||||
@mock.patch('nova.db.instance_group_get', return_value=_INST_GROUP_DB)
|
@mock.patch('nova.objects.InstanceGroup._get_from_db_by_uuid',
|
||||||
|
return_value=_INST_GROUP_DB)
|
||||||
def test_get_hosts(self, mock_get_db, mock_il_get):
|
def test_get_hosts(self, mock_get_db, mock_il_get):
|
||||||
mock_il_get.return_value = [objects.Instance(host='host1'),
|
mock_il_get.return_value = [objects.Instance(host='host1'),
|
||||||
objects.Instance(host='host2'),
|
objects.Instance(host='host2'),
|
||||||
objects.Instance(host=None)]
|
objects.Instance(host=None)]
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx, _DB_UUID)
|
obj = objects.InstanceGroup.get_by_uuid(self.context, _DB_UUID)
|
||||||
hosts = obj.get_hosts()
|
hosts = obj.get_hosts()
|
||||||
self.assertEqual(['instance_id1', 'instance_id2'], obj.members)
|
self.assertEqual(['instance_id1', 'instance_id2'], obj.members)
|
||||||
expected_filters = {
|
expected_filters = {
|
||||||
'uuid': ['instance_id1', 'instance_id2'],
|
'uuid': ['instance_id1', 'instance_id2'],
|
||||||
'deleted': False
|
'deleted': False
|
||||||
}
|
}
|
||||||
mock_il_get.assert_called_once_with(mock.sentinel.ctx,
|
mock_il_get.assert_called_once_with(self.context,
|
||||||
filters=expected_filters)
|
filters=expected_filters)
|
||||||
self.assertEqual(2, len(hosts))
|
self.assertEqual(2, len(hosts))
|
||||||
self.assertIn('host1', hosts)
|
self.assertIn('host1', hosts)
|
||||||
@ -228,12 +238,11 @@ class _TestInstanceGroupObject(object):
|
|||||||
'uuid': set(['instance_id2']),
|
'uuid': set(['instance_id2']),
|
||||||
'deleted': False
|
'deleted': False
|
||||||
}
|
}
|
||||||
mock_il_get.assert_called_once_with(mock.sentinel.ctx,
|
mock_il_get.assert_called_once_with(self.context,
|
||||||
filters=expected_filters)
|
filters=expected_filters)
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get', return_value=_INST_GROUP_DB)
|
def test_obj_make_compatible(self):
|
||||||
def test_obj_make_compatible(self, mock_db_get):
|
obj = objects.InstanceGroup(self.context, **_INST_GROUP_DB)
|
||||||
obj = objects.InstanceGroup.get_by_uuid(mock.sentinel.ctx, _DB_UUID)
|
|
||||||
obj_primitive = obj.obj_to_primitive()
|
obj_primitive = obj.obj_to_primitive()
|
||||||
self.assertNotIn('metadetails', obj_primitive)
|
self.assertNotIn('metadetails', obj_primitive)
|
||||||
obj.obj_make_compatible(obj_primitive, '1.6')
|
obj.obj_make_compatible(obj_primitive, '1.6')
|
||||||
@ -244,14 +253,14 @@ class _TestInstanceGroupObject(object):
|
|||||||
mock_get_by_filt.return_value = [objects.Instance(host='host1'),
|
mock_get_by_filt.return_value = [objects.Instance(host='host1'),
|
||||||
objects.Instance(host='host2')]
|
objects.Instance(host='host2')]
|
||||||
|
|
||||||
obj = objects.InstanceGroup(mock.sentinel.ctx, members=['uuid1'])
|
obj = objects.InstanceGroup(self.context, members=['uuid1'])
|
||||||
self.assertEqual(2, len(obj.hosts))
|
self.assertEqual(2, len(obj.hosts))
|
||||||
self.assertIn('host1', obj.hosts)
|
self.assertIn('host1', obj.hosts)
|
||||||
self.assertIn('host2', obj.hosts)
|
self.assertIn('host2', obj.hosts)
|
||||||
self.assertNotIn('hosts', obj.obj_what_changed())
|
self.assertNotIn('hosts', obj.obj_what_changed())
|
||||||
|
|
||||||
def test_load_anything_else_but_hosts(self):
|
def test_load_anything_else_but_hosts(self):
|
||||||
obj = objects.InstanceGroup(mock.sentinel.ctx)
|
obj = objects.InstanceGroup(self.context)
|
||||||
self.assertRaises(exception.ObjectActionError, getattr, obj, 'members')
|
self.assertRaises(exception.ObjectActionError, getattr, obj, 'members')
|
||||||
|
|
||||||
|
|
||||||
@ -283,22 +292,29 @@ def _mock_db_list_get(*args):
|
|||||||
class _TestInstanceGroupListObject(object):
|
class _TestInstanceGroupListObject(object):
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get_all')
|
@mock.patch('nova.db.instance_group_get_all')
|
||||||
def test_list_all(self, mock_db_get):
|
@mock.patch('nova.objects.InstanceGroupList._get_from_db')
|
||||||
|
def test_list_all_main(self, mock_api_get, mock_db_get):
|
||||||
|
mock_api_get.return_value = []
|
||||||
mock_db_get.side_effect = _mock_db_list_get
|
mock_db_get.side_effect = _mock_db_list_get
|
||||||
inst_list = objects.InstanceGroupList.get_all(mock.sentinel.ctx)
|
inst_list = objects.InstanceGroupList.get_all(self.context)
|
||||||
self.assertEqual(4, len(inst_list.objects))
|
self.assertEqual(4, len(inst_list.objects))
|
||||||
mock_db_get.assert_called_once_with(mock.sentinel.ctx)
|
mock_db_get.assert_called_once_with(self.context)
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get_all_by_project_id')
|
@mock.patch('nova.db.instance_group_get_all_by_project_id')
|
||||||
def test_list_by_project_id(self, mock_db_get):
|
@mock.patch('nova.objects.InstanceGroupList._get_from_db')
|
||||||
|
def test_list_by_project_id_main(self, mock_api_get, mock_db_get):
|
||||||
|
mock_api_get.return_value = []
|
||||||
mock_db_get.side_effect = _mock_db_list_get
|
mock_db_get.side_effect = _mock_db_list_get
|
||||||
objects.InstanceGroupList.get_by_project_id(
|
objects.InstanceGroupList.get_by_project_id(
|
||||||
mock.sentinel.ctx, mock.sentinel.project_id)
|
self.context, mock.sentinel.project_id)
|
||||||
mock_db_get.assert_called_once_with(
|
mock_db_get.assert_called_once_with(
|
||||||
mock.sentinel.ctx, mock.sentinel.project_id)
|
self.context, mock.sentinel.project_id)
|
||||||
|
|
||||||
@mock.patch('nova.db.instance_group_get_all_by_project_id')
|
@mock.patch('nova.db.instance_group_get_all_by_project_id')
|
||||||
def test_get_by_name(self, mock_db_get):
|
@mock.patch('nova.objects.InstanceGroup._get_from_db_by_name')
|
||||||
|
def test_get_by_name_main(self, mock_api_get, mock_db_get):
|
||||||
|
error = exception.InstanceGroupNotFound(group_uuid='f1')
|
||||||
|
mock_api_get.side_effect = error
|
||||||
mock_db_get.side_effect = _mock_db_list_get
|
mock_db_get.side_effect = _mock_db_list_get
|
||||||
# Need the project_id value set, otherwise we'd use mock.sentinel
|
# Need the project_id value set, otherwise we'd use mock.sentinel
|
||||||
mock_ctx = mock.MagicMock()
|
mock_ctx = mock.MagicMock()
|
||||||
@ -313,10 +329,10 @@ class _TestInstanceGroupListObject(object):
|
|||||||
@mock.patch('nova.objects.InstanceGroup.get_by_uuid')
|
@mock.patch('nova.objects.InstanceGroup.get_by_uuid')
|
||||||
@mock.patch('nova.objects.InstanceGroup.get_by_name')
|
@mock.patch('nova.objects.InstanceGroup.get_by_name')
|
||||||
def test_get_by_hint(self, mock_name, mock_uuid):
|
def test_get_by_hint(self, mock_name, mock_uuid):
|
||||||
objects.InstanceGroup.get_by_hint(mock.sentinel.ctx, _DB_UUID)
|
objects.InstanceGroup.get_by_hint(self.context, _DB_UUID)
|
||||||
mock_uuid.assert_called_once_with(mock.sentinel.ctx, _DB_UUID)
|
mock_uuid.assert_called_once_with(self.context, _DB_UUID)
|
||||||
objects.InstanceGroup.get_by_hint(mock.sentinel.ctx, 'name')
|
objects.InstanceGroup.get_by_hint(self.context, 'name')
|
||||||
mock_name.assert_called_once_with(mock.sentinel.ctx, 'name')
|
mock_name.assert_called_once_with(self.context, 'name')
|
||||||
|
|
||||||
|
|
||||||
class TestInstanceGroupListObject(test_objects._LocalTest,
|
class TestInstanceGroupListObject(test_objects._LocalTest,
|
||||||
|
Loading…
Reference in New Issue
Block a user