Refactor sqlalchemy service methods
This patch refactors the sqlalchemy DB methods related to the service to consolidate the methods into the minimum number that is actually needed, to reduce the number of DB calls per operation, and to reduce the data retrieved from the DB server. For method consolidation the patch removes `service_get_by_host_and_topic`, `service_get_by_args`, `service_get_all_by_topic`, and `service_get_all_by_binary`, and includes the functionality provided by those methods in `service_get` and `service_get_all` methods. To reduce the number of DB calls we won't retrieve the service from the DB when deleting or updating a service. And to reduce the data retrieved from the DB we filter UP nodes in the DB instead of locally. This patch is related to the efforts to support HA A/A in c-vol nodes. Job distribution patches are dependent on this one. Specs: https://review.openstack.org/327283 Implements: blueprint cinder-volume-active-active-support Change-Id: I5c453dcb5c38301721c3017ba8e782c0fdf850e6
This commit is contained in:
parent
58e554f381
commit
6cfecade9e
@ -99,34 +99,27 @@ def service_destroy(context, service_id):
|
|||||||
return IMPL.service_destroy(context, service_id)
|
return IMPL.service_destroy(context, service_id)
|
||||||
|
|
||||||
|
|
||||||
def service_get(context, service_id):
|
def service_get(context, service_id=None, **filters):
|
||||||
"""Get a service or raise if it does not exist."""
|
"""Get a service that matches the criteria.
|
||||||
return IMPL.service_get(context, service_id)
|
|
||||||
|
A possible filter is is_up=True and it will filter nodes that are down.
|
||||||
|
|
||||||
|
:param service_id: Id of the service.
|
||||||
|
:param filters: Filters for the query in the form of key/value.
|
||||||
|
|
||||||
|
:raise ServiceNotFound: If service doesn't exist.
|
||||||
|
"""
|
||||||
|
return IMPL.service_get(context, service_id, **filters)
|
||||||
|
|
||||||
|
|
||||||
def service_get_by_host_and_topic(context, host, topic):
|
def service_get_all(context, **filters):
|
||||||
"""Get a service by host it's on and topic it listens to."""
|
"""Get all services that match the criteria.
|
||||||
return IMPL.service_get_by_host_and_topic(context, host, topic)
|
|
||||||
|
|
||||||
|
A possible filter is is_up=True and it will filter nodes that are down.
|
||||||
|
|
||||||
def service_get_all(context, filters=None):
|
:param filters: Filters for the query in the form of key/value arguments.
|
||||||
"""Get all services."""
|
"""
|
||||||
return IMPL.service_get_all(context, filters)
|
return IMPL.service_get_all(context, **filters)
|
||||||
|
|
||||||
|
|
||||||
def service_get_all_by_topic(context, topic, disabled=None):
|
|
||||||
"""Get all services for a given topic."""
|
|
||||||
return IMPL.service_get_all_by_topic(context, topic, disabled=disabled)
|
|
||||||
|
|
||||||
|
|
||||||
def service_get_all_by_binary(context, binary, disabled=None):
|
|
||||||
"""Get all services for a given binary."""
|
|
||||||
return IMPL.service_get_all_by_binary(context, binary, disabled)
|
|
||||||
|
|
||||||
|
|
||||||
def service_get_by_args(context, host, binary):
|
|
||||||
"""Get the state of a service by node name and binary."""
|
|
||||||
return IMPL.service_get_by_args(context, host, binary)
|
|
||||||
|
|
||||||
|
|
||||||
def service_create(context, values):
|
def service_create(context, values):
|
||||||
@ -138,7 +131,6 @@ def service_update(context, service_id, values):
|
|||||||
"""Set the given properties on an service and update it.
|
"""Set the given properties on an service and update it.
|
||||||
|
|
||||||
Raises NotFound if service does not exist.
|
Raises NotFound if service does not exist.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return IMPL.service_update(context, service_id, values)
|
return IMPL.service_update(context, service_id, values)
|
||||||
|
|
||||||
|
@ -362,105 +362,84 @@ QUOTA_SYNC_FUNCTIONS = {
|
|||||||
###################
|
###################
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
def _clean_filters(filters):
|
||||||
def service_destroy(context, service_id):
|
return {k: v for k, v in filters.items() if v is not None}
|
||||||
session = get_session()
|
|
||||||
with session.begin():
|
|
||||||
service_ref = _service_get(context, service_id, session=session)
|
|
||||||
service_ref.delete(session=session)
|
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
def _service_query(context, session=None, read_deleted='no', host=None,
|
||||||
def _service_get(context, service_id, session=None):
|
is_up=None, **filters):
|
||||||
result = model_query(
|
filters = _clean_filters(filters)
|
||||||
context,
|
|
||||||
models.Service,
|
|
||||||
session=session).\
|
|
||||||
filter_by(id=service_id).\
|
|
||||||
first()
|
|
||||||
if not result:
|
|
||||||
raise exception.ServiceNotFound(service_id=service_id)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
|
||||||
def service_get(context, service_id):
|
|
||||||
return _service_get(context, service_id)
|
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
|
||||||
def service_get_all(context, filters=None):
|
|
||||||
if filters and not is_valid_model_filters(models.Service, filters):
|
if filters and not is_valid_model_filters(models.Service, filters):
|
||||||
return []
|
return None
|
||||||
|
|
||||||
query = model_query(context, models.Service)
|
query = model_query(context, models.Service, session=session,
|
||||||
|
read_deleted=read_deleted)
|
||||||
|
|
||||||
|
# Host is a particular case of filter, because we must retrieve not only
|
||||||
|
# exact matches (single backend configuration), but also match hosts that
|
||||||
|
# have the backend defined (multi backend configuration).
|
||||||
|
if host:
|
||||||
|
host_attr = models.Service.host
|
||||||
|
# Mysql is not doing case sensitive filtering, so we force it
|
||||||
|
if CONF.database.connection.startswith('mysql:'):
|
||||||
|
conditions = or_(host_attr == func.binary(host),
|
||||||
|
host_attr.op('LIKE BINARY')(host + '@%'))
|
||||||
|
else:
|
||||||
|
conditions = or_(host_attr == host,
|
||||||
|
host_attr.op('LIKE')(host + '@%'))
|
||||||
|
query = query.filter(conditions)
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
try:
|
|
||||||
host = filters.pop('host')
|
|
||||||
host_attr = models.Service.host
|
|
||||||
conditions = or_(host_attr ==
|
|
||||||
host, host_attr.op('LIKE')(host + '@%'))
|
|
||||||
query = query.filter(conditions)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
query = query.filter_by(**filters)
|
query = query.filter_by(**filters)
|
||||||
|
|
||||||
return query.all()
|
if is_up is not None:
|
||||||
|
date_limit = (timeutils.utcnow() -
|
||||||
|
dt.timedelta(seconds=CONF.service_down_time))
|
||||||
|
svc = models.Service
|
||||||
|
filter_ = or_(
|
||||||
|
and_(svc.created_at.isnot(None), svc.created_at >= date_limit),
|
||||||
|
and_(svc.updated_at.isnot(None), svc.updated_at >= date_limit))
|
||||||
|
query = query.filter(filter_ == is_up)
|
||||||
|
|
||||||
|
return query
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
def service_get_all_by_topic(context, topic, disabled=None):
|
def service_destroy(context, service_id):
|
||||||
query = model_query(
|
query = _service_query(context, id=service_id)
|
||||||
context, models.Service, read_deleted="no").\
|
if not query.update(models.Service.delete_values()):
|
||||||
filter_by(topic=topic)
|
raise exception.ServiceNotFound(service_id=service_id)
|
||||||
|
|
||||||
if disabled is not None:
|
|
||||||
query = query.filter_by(disabled=disabled)
|
|
||||||
|
|
||||||
return query.all()
|
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
def service_get_all_by_binary(context, binary, disabled=None):
|
def service_get(context, service_id=None, **filters):
|
||||||
query = model_query(
|
"""Get a service that matches the criteria.
|
||||||
context, models.Service, read_deleted="no").filter_by(binary=binary)
|
|
||||||
|
|
||||||
if disabled is not None:
|
A possible filter is is_up=True and it will filter nodes that are down.
|
||||||
query = query.filter_by(disabled=disabled)
|
|
||||||
|
|
||||||
return query.all()
|
:param service_id: Id of the service.
|
||||||
|
:param filters: Filters for the query in the form of key/value.
|
||||||
|
:raise ServiceNotFound: If service doesn't exist.
|
||||||
|
"""
|
||||||
|
query = _service_query(context, id=service_id, **filters)
|
||||||
|
service = None if not query else query.first()
|
||||||
|
if not service:
|
||||||
|
serv_id = service_id or filters.get('topic') or filters.get('binary')
|
||||||
|
raise exception.ServiceNotFound(service_id=serv_id,
|
||||||
|
host=filters.get('host'))
|
||||||
|
return service
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
def service_get_by_host_and_topic(context, host, topic):
|
def service_get_all(context, **filters):
|
||||||
result = model_query(
|
"""Get all services that match the criteria.
|
||||||
context, models.Service, read_deleted="no").\
|
|
||||||
filter_by(disabled=False).\
|
|
||||||
filter_by(host=host).\
|
|
||||||
filter_by(topic=topic).\
|
|
||||||
first()
|
|
||||||
if not result:
|
|
||||||
raise exception.ServiceNotFound(service_id=topic,
|
|
||||||
host=host)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
A possible filter is is_up=True and it will filter nodes that are down.
|
||||||
|
|
||||||
@require_admin_context
|
:param filters: Filters for the query in the form of key/value.
|
||||||
def service_get_by_args(context, host, binary):
|
"""
|
||||||
results = model_query(context, models.Service).\
|
query = _service_query(context, **filters)
|
||||||
filter_by(host=host).\
|
return [] if not query else query.all()
|
||||||
filter_by(binary=binary).\
|
|
||||||
all()
|
|
||||||
|
|
||||||
for result in results:
|
|
||||||
if host == result['host']:
|
|
||||||
return result
|
|
||||||
|
|
||||||
raise exception.ServiceNotFound(service_id=binary,
|
|
||||||
host=host)
|
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
@ -479,14 +458,15 @@ def service_create(context, values):
|
|||||||
@require_admin_context
|
@require_admin_context
|
||||||
@_retry_on_deadlock
|
@_retry_on_deadlock
|
||||||
def service_update(context, service_id, values):
|
def service_update(context, service_id, values):
|
||||||
session = get_session()
|
if 'disabled' in values:
|
||||||
with session.begin():
|
values = values.copy()
|
||||||
service_ref = _service_get(context, service_id, session=session)
|
values['modified_at'] = values.get('modified_at', timeutils.utcnow())
|
||||||
if ('disabled' in values):
|
values['updated_at'] = values.get('updated_at',
|
||||||
service_ref['modified_at'] = timeutils.utcnow()
|
literal_column('updated_at'))
|
||||||
service_ref['updated_at'] = literal_column('updated_at')
|
query = _service_query(context, id=service_id)
|
||||||
service_ref.update(values)
|
result = query.update(values)
|
||||||
return service_ref
|
if not result:
|
||||||
|
raise exception.ServiceNotFound(service_id=service_id)
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
|
@ -45,10 +45,14 @@ class CinderBase(models.TimestampMixin,
|
|||||||
deleted = Column(Boolean, default=False)
|
deleted = Column(Boolean, default=False)
|
||||||
metadata = None
|
metadata = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def delete_values():
|
||||||
|
return {'deleted': True,
|
||||||
|
'deleted_at': timeutils.utcnow()}
|
||||||
|
|
||||||
def delete(self, session):
|
def delete(self, session):
|
||||||
"""Delete this object."""
|
"""Delete this object."""
|
||||||
self.deleted = True
|
self.update(self.delete_values())
|
||||||
self.deleted_at = timeutils.utcnow()
|
|
||||||
self.save(session=session)
|
self.save(session=session)
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,12 +70,13 @@ class Service(base.CinderPersistentObject, base.CinderObject,
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_host_and_topic(cls, context, host, topic):
|
def get_by_host_and_topic(cls, context, host, topic):
|
||||||
db_service = db.service_get_by_host_and_topic(context, host, topic)
|
db_service = db.service_get(context, disabled=False, host=host,
|
||||||
|
topic=topic)
|
||||||
return cls._from_db_object(context, cls(context), db_service)
|
return cls._from_db_object(context, cls(context), db_service)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_args(cls, context, host, binary_key):
|
def get_by_args(cls, context, host, binary_key):
|
||||||
db_service = db.service_get_by_args(context, host, binary_key)
|
db_service = db.service_get(context, host=host, binary=binary_key)
|
||||||
return cls._from_db_object(context, cls(context), db_service)
|
return cls._from_db_object(context, cls(context), db_service)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
@ -139,20 +140,19 @@ class ServiceList(base.ObjectListBase, base.CinderObject):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all(cls, context, filters=None):
|
def get_all(cls, context, filters=None):
|
||||||
services = db.service_get_all(context, filters)
|
services = db.service_get_all(context, **(filters or {}))
|
||||||
return base.obj_make_list(context, cls(context), objects.Service,
|
return base.obj_make_list(context, cls(context), objects.Service,
|
||||||
services)
|
services)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all_by_topic(cls, context, topic, disabled=None):
|
def get_all_by_topic(cls, context, topic, disabled=None):
|
||||||
services = db.service_get_all_by_topic(context, topic,
|
services = db.service_get_all(context, topic=topic, disabled=disabled)
|
||||||
disabled=disabled)
|
|
||||||
return base.obj_make_list(context, cls(context), objects.Service,
|
return base.obj_make_list(context, cls(context), objects.Service,
|
||||||
services)
|
services)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all_by_binary(cls, context, binary, disabled=None):
|
def get_all_by_binary(cls, context, binary, disabled=None):
|
||||||
services = db.service_get_all_by_binary(context, binary,
|
services = db.service_get_all(context, binary=binary,
|
||||||
disabled=disabled)
|
disabled=disabled)
|
||||||
return base.obj_make_list(context, cls(context), objects.Service,
|
return base.obj_make_list(context, cls(context), objects.Service,
|
||||||
services)
|
services)
|
||||||
|
@ -321,6 +321,13 @@ class TestCase(testtools.TestCase):
|
|||||||
self.addCleanup(patcher.stop)
|
self.addCleanup(patcher.stop)
|
||||||
return new_attr
|
return new_attr
|
||||||
|
|
||||||
|
def patch(self, path, *args, **kwargs):
|
||||||
|
"""Use python mock to mock a path with automatic cleanup."""
|
||||||
|
patcher = mock.patch(path, *args, **kwargs)
|
||||||
|
result = patcher.start()
|
||||||
|
self.addCleanup(patcher.stop)
|
||||||
|
return result
|
||||||
|
|
||||||
# Useful assertions
|
# Useful assertions
|
||||||
def assertDictMatch(self, d1, d2, approx_equal=False, tolerance=0.001):
|
def assertDictMatch(self, d1, d2, approx_equal=False, tolerance=0.001):
|
||||||
"""Assert two dicts are equivalent.
|
"""Assert two dicts are equivalent.
|
||||||
|
@ -659,11 +659,12 @@ class AdminActionsTest(BaseAdminTest):
|
|||||||
vac.validate_update,
|
vac.validate_update,
|
||||||
{'status': 'creating'})
|
{'status': 'creating'})
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.backup.rpcapi.BackupAPI.delete_backup', mock.Mock())
|
||||||
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch('cinder.backup.api.API._check_support_to_force_delete')
|
@mock.patch('cinder.backup.api.API._check_support_to_force_delete')
|
||||||
def _force_delete_backup_util(self, test_status, mock_check_support,
|
def _force_delete_backup_util(self, test_status, mock_check_support,
|
||||||
_mock_service_get_all_by_topic):
|
mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
mock_service_get_all.return_value = [
|
||||||
{'availability_zone': "az1", 'host': 'testhost',
|
{'availability_zone': "az1", 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
# admin context
|
# admin context
|
||||||
|
@ -57,6 +57,8 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
self.user_context = context.RequestContext(
|
self.user_context = context.RequestContext(
|
||||||
fake.USER_ID, fake.PROJECT_ID, auth_token=True)
|
fake.USER_ID, fake.PROJECT_ID, auth_token=True)
|
||||||
self.controller = backups.BackupsController()
|
self.controller = backups.BackupsController()
|
||||||
|
self.patch('cinder.objects.service.Service._get_minimum_version',
|
||||||
|
return_value=None)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_backup(volume_id=fake.VOLUME_ID,
|
def _create_backup(volume_id=fake.VOLUME_ID,
|
||||||
@ -462,12 +464,12 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
fake_auth_context=self.user_context))
|
fake_auth_context=self.user_context))
|
||||||
self.assertEqual(400, res.status_int)
|
self.assertEqual(400, res.status_int)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
||||||
def test_create_backup_json(self, mock_validate,
|
def test_create_backup_json(self, mock_validate,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -491,15 +493,17 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(202, res.status_int)
|
self.assertEqual(202, res.status_int)
|
||||||
self.assertIn('id', res_dict['backup'])
|
self.assertIn('id', res_dict['backup'])
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
_mock_service_get_all.assert_called_once_with(mock.ANY,
|
||||||
|
disabled=False,
|
||||||
|
topic='cinder-backup')
|
||||||
self.assertTrue(mock_validate.called)
|
self.assertTrue(mock_validate.called)
|
||||||
|
|
||||||
db.volume_destroy(context.get_admin_context(), volume_id)
|
db.volume_destroy(context.get_admin_context(), volume_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_backup_inuse_no_force(self,
|
def test_create_backup_inuse_no_force(self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -528,9 +532,9 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
db.volume_destroy(context.get_admin_context(), volume_id)
|
db.volume_destroy(context.get_admin_context(), volume_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_backup_inuse_force(self, _mock_service_get_all_by_topic):
|
def test_create_backup_inuse_force(self, _mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -557,17 +561,19 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(202, res.status_int)
|
self.assertEqual(202, res.status_int)
|
||||||
self.assertIn('id', res_dict['backup'])
|
self.assertIn('id', res_dict['backup'])
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
_mock_service_get_all.assert_called_once_with(mock.ANY,
|
||||||
|
disabled=False,
|
||||||
|
topic='cinder-backup')
|
||||||
|
|
||||||
db.backup_destroy(context.get_admin_context(), backup_id)
|
db.backup_destroy(context.get_admin_context(), backup_id)
|
||||||
db.volume_destroy(context.get_admin_context(), volume_id)
|
db.volume_destroy(context.get_admin_context(), volume_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
||||||
def test_create_backup_snapshot_json(self, mock_validate,
|
def test_create_backup_snapshot_json(self, mock_validate,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -591,7 +597,9 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
res_dict = jsonutils.loads(res.body)
|
res_dict = jsonutils.loads(res.body)
|
||||||
self.assertEqual(202, res.status_int)
|
self.assertEqual(202, res.status_int)
|
||||||
self.assertIn('id', res_dict['backup'])
|
self.assertIn('id', res_dict['backup'])
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
_mock_service_get_all.assert_called_once_with(mock.ANY,
|
||||||
|
disabled=False,
|
||||||
|
topic='cinder-backup')
|
||||||
self.assertTrue(mock_validate.called)
|
self.assertTrue(mock_validate.called)
|
||||||
|
|
||||||
db.volume_destroy(context.get_admin_context(), volume_id)
|
db.volume_destroy(context.get_admin_context(), volume_id)
|
||||||
@ -705,14 +713,14 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
req,
|
req,
|
||||||
body)
|
body)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
||||||
@ddt.data(False, True)
|
@ddt.data(False, True)
|
||||||
def test_create_backup_delta(self, backup_from_snapshot,
|
def test_create_backup_delta(self, backup_from_snapshot,
|
||||||
mock_validate,
|
mock_validate,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -746,7 +754,9 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(202, res.status_int)
|
self.assertEqual(202, res.status_int)
|
||||||
self.assertIn('id', res_dict['backup'])
|
self.assertIn('id', res_dict['backup'])
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
_mock_service_get_all.assert_called_once_with(mock.ANY,
|
||||||
|
disabled=False,
|
||||||
|
topic='cinder-backup')
|
||||||
self.assertTrue(mock_validate.called)
|
self.assertTrue(mock_validate.called)
|
||||||
|
|
||||||
db.backup_destroy(context.get_admin_context(), backup_id)
|
db.backup_destroy(context.get_admin_context(), backup_id)
|
||||||
@ -754,10 +764,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
snapshot.destroy()
|
snapshot.destroy()
|
||||||
db.volume_destroy(context.get_admin_context(), volume_id)
|
db.volume_destroy(context.get_admin_context(), volume_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_incremental_backup_invalid_status(
|
def test_create_incremental_backup_invalid_status(
|
||||||
self, _mock_service_get_all_by_topic):
|
self, _mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -869,12 +879,12 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
self.assertEqual(400, res.status_int)
|
self.assertEqual(400, res.status_int)
|
||||||
self.assertEqual(400, res_dict['badRequest']['code'])
|
self.assertEqual(400, res_dict['badRequest']['code'])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_backup_WithOUT_enabled_backup_service(
|
def test_create_backup_WithOUT_enabled_backup_service(
|
||||||
self,
|
self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
# need an enabled backup service available
|
# need an enabled backup service available
|
||||||
_mock_service_get_all_by_topic.return_value = []
|
_mock_service_get_all.return_value = []
|
||||||
|
|
||||||
volume_id = utils.create_volume(self.context, size=2).id
|
volume_id = utils.create_volume(self.context, size=2).id
|
||||||
req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID)
|
req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID)
|
||||||
@ -901,10 +911,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
volume = self.volume_api.get(context.get_admin_context(), volume_id)
|
volume = self.volume_api.get(context.get_admin_context(), volume_id)
|
||||||
self.assertEqual('available', volume['status'])
|
self.assertEqual('available', volume['status'])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_incremental_backup_invalid_no_full(
|
def test_create_incremental_backup_invalid_no_full(
|
||||||
self, _mock_service_get_all_by_topic):
|
self, _mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'fake_az', 'host': 'testhost',
|
{'availability_zone': 'fake_az', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
@ -934,8 +944,8 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
db.volume_destroy(context.get_admin_context(), volume_id)
|
db.volume_destroy(context.get_admin_context(), volume_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_is_backup_service_enabled(self, _mock_service_get_all_by_topic):
|
def test_is_backup_service_enabled(self, _mock_service_get_all):
|
||||||
|
|
||||||
testhost = 'test_host'
|
testhost = 'test_host'
|
||||||
alt_host = 'strange_host'
|
alt_host = 'strange_host'
|
||||||
@ -960,12 +970,12 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
# Setup mock to run through the following service cases
|
# Setup mock to run through the following service cases
|
||||||
_mock_service_get_all_by_topic.side_effect = [empty_service,
|
_mock_service_get_all.side_effect = [empty_service,
|
||||||
host_not_match,
|
host_not_match,
|
||||||
az_not_match,
|
az_not_match,
|
||||||
disabled_service,
|
disabled_service,
|
||||||
dead_service,
|
dead_service,
|
||||||
multi_services]
|
multi_services]
|
||||||
|
|
||||||
volume_id = utils.create_volume(self.context, size=2,
|
volume_id = utils.create_volume(self.context, size=2,
|
||||||
host=testhost).id
|
host=testhost).id
|
||||||
@ -1006,10 +1016,9 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
volume['availability_zone'],
|
volume['availability_zone'],
|
||||||
testhost))
|
testhost))
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_get_available_backup_service(self,
|
def test_get_available_backup_service(self, _mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all.return_value = [
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
|
||||||
{'availability_zone': 'az1', 'host': 'testhost1',
|
{'availability_zone': 'az1', 'host': 'testhost1',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()},
|
'disabled': 0, 'updated_at': timeutils.utcnow()},
|
||||||
{'availability_zone': 'az2', 'host': 'testhost2',
|
{'availability_zone': 'az2', 'host': 'testhost2',
|
||||||
@ -1026,10 +1035,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
'testhost4', 'az1')
|
'testhost4', 'az1')
|
||||||
self.assertEqual('testhost1', actual_host)
|
self.assertEqual('testhost1', actual_host)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_get_available_backup_service_with_same_host(
|
def test_get_available_backup_service_with_same_host(
|
||||||
self, _mock_service_get_all_by_topic):
|
self, _mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost1',
|
{'availability_zone': 'az1', 'host': 'testhost1',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()},
|
'disabled': 0, 'updated_at': timeutils.utcnow()},
|
||||||
{'availability_zone': 'az2', 'host': 'testhost2',
|
{'availability_zone': 'az2', 'host': 'testhost2',
|
||||||
@ -1045,10 +1054,9 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
self.backup_api._get_available_backup_service_host,
|
self.backup_api._get_available_backup_service_host,
|
||||||
'testhost4', 'az1')
|
'testhost4', 'az1')
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_delete_backup_available(
|
def test_delete_backup_available(self, _mock_service_get_all):
|
||||||
self, _mock_service_get_all_by_topic):
|
_mock_service_get_all.return_value = [
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE)
|
backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE)
|
||||||
@ -1065,10 +1073,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
db.backup_destroy(context.get_admin_context(), backup_id)
|
db.backup_destroy(context.get_admin_context(), backup_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_delete_delta_backup(self,
|
def test_delete_delta_backup(self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE)
|
backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE)
|
||||||
@ -1088,10 +1096,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
db.backup_destroy(context.get_admin_context(), delta_id)
|
db.backup_destroy(context.get_admin_context(), delta_id)
|
||||||
db.backup_destroy(context.get_admin_context(), backup_id)
|
db.backup_destroy(context.get_admin_context(), backup_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_delete_backup_error(self,
|
def test_delete_backup_error(self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
backup_id = self._create_backup(status=fields.BackupStatus.ERROR)
|
backup_id = self._create_backup(status=fields.BackupStatus.ERROR)
|
||||||
@ -1141,10 +1149,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
|
|
||||||
db.backup_destroy(context.get_admin_context(), backup_id)
|
db.backup_destroy(context.get_admin_context(), backup_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_delete_backup_with_InvalidBackup2(self,
|
def test_delete_backup_with_InvalidBackup2(self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
volume_id = utils.create_volume(self.context, size=5).id
|
volume_id = utils.create_volume(self.context, size=5).id
|
||||||
@ -1170,10 +1178,10 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
db.backup_destroy(context.get_admin_context(), delta_backup_id)
|
db.backup_destroy(context.get_admin_context(), delta_backup_id)
|
||||||
db.backup_destroy(context.get_admin_context(), backup_id)
|
db.backup_destroy(context.get_admin_context(), backup_id)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_delete_backup_service_down(self,
|
def test_delete_backup_service_down(self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': '1775-04-19 05:00:00'}]
|
'disabled': 0, 'updated_at': '1775-04-19 05:00:00'}]
|
||||||
backup_id = self._create_backup(status='available')
|
backup_id = self._create_backup(status='available')
|
||||||
@ -1256,18 +1264,17 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
self.assertEqual("Missing required element 'restore' in request body.",
|
self.assertEqual("Missing required element 'restore' in request body.",
|
||||||
res_dict['badRequest']['message'])
|
res_dict['badRequest']['message'])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch('cinder.volume.api.API.create')
|
@mock.patch('cinder.volume.api.API.create')
|
||||||
def test_restore_backup_volume_id_unspecified(
|
def test_restore_backup_volume_id_unspecified(
|
||||||
self, _mock_volume_api_create,
|
self, _mock_volume_api_create, _mock_service_get_all):
|
||||||
_mock_service_get_all_by_topic):
|
|
||||||
# intercept volume creation to ensure created volume
|
# intercept volume creation to ensure created volume
|
||||||
# has status of available
|
# has status of available
|
||||||
def fake_volume_api_create(context, size, name, description):
|
def fake_volume_api_create(context, size, name, description):
|
||||||
volume_id = utils.create_volume(self.context, size=size).id
|
volume_id = utils.create_volume(self.context, size=size).id
|
||||||
return db.volume_get(context, volume_id)
|
return db.volume_get(context, volume_id)
|
||||||
|
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
_mock_volume_api_create.side_effect = fake_volume_api_create
|
_mock_volume_api_create.side_effect = fake_volume_api_create
|
||||||
@ -1288,11 +1295,11 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
self.assertEqual(202, res.status_int)
|
self.assertEqual(202, res.status_int)
|
||||||
self.assertEqual(backup_id, res_dict['restore']['backup_id'])
|
self.assertEqual(backup_id, res_dict['restore']['backup_id'])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch('cinder.volume.api.API.create')
|
@mock.patch('cinder.volume.api.API.create')
|
||||||
def test_restore_backup_name_specified(self,
|
def test_restore_backup_name_specified(self,
|
||||||
_mock_volume_api_create,
|
_mock_volume_api_create,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
# Intercept volume creation to ensure created volume
|
# Intercept volume creation to ensure created volume
|
||||||
# has status of available
|
# has status of available
|
||||||
def fake_volume_api_create(context, size, name, description):
|
def fake_volume_api_create(context, size, name, description):
|
||||||
@ -1301,7 +1308,7 @@ class BackupsAPITestCase(test.TestCase):
|
|||||||
return db.volume_get(context, volume_id)
|
return db.volume_get(context, volume_id)
|
||||||
|
|
||||||
_mock_volume_api_create.side_effect = fake_volume_api_create
|
_mock_volume_api_create.side_effect = fake_volume_api_create
|
||||||
_mock_service_get_all_by_topic.return_value = [
|
_mock_service_get_all.return_value = [
|
||||||
{'availability_zone': 'az1', 'host': 'testhost',
|
{'availability_zone': 'az1', 'host': 'testhost',
|
||||||
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
'disabled': 0, 'updated_at': timeutils.utcnow()}]
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ import webob.exc
|
|||||||
|
|
||||||
from cinder.api.contrib import hosts as os_hosts
|
from cinder.api.contrib import hosts as os_hosts
|
||||||
from cinder import context
|
from cinder import context
|
||||||
from cinder import db
|
|
||||||
from cinder import test
|
from cinder import test
|
||||||
|
|
||||||
|
|
||||||
@ -69,10 +68,6 @@ def stub_utcnow(with_timezone=False):
|
|||||||
return datetime.datetime(2013, 7, 3, 0, 0, 2, tzinfo=tzinfo)
|
return datetime.datetime(2013, 7, 3, 0, 0, 2, tzinfo=tzinfo)
|
||||||
|
|
||||||
|
|
||||||
def stub_service_get_all(context, filters=None):
|
|
||||||
return SERVICE_LIST
|
|
||||||
|
|
||||||
|
|
||||||
class FakeRequest(object):
|
class FakeRequest(object):
|
||||||
environ = {'cinder.context': context.get_admin_context()}
|
environ = {'cinder.context': context.get_admin_context()}
|
||||||
GET = {}
|
GET = {}
|
||||||
@ -90,9 +85,9 @@ class HostTestCase(test.TestCase):
|
|||||||
super(HostTestCase, self).setUp()
|
super(HostTestCase, self).setUp()
|
||||||
self.controller = os_hosts.HostController()
|
self.controller = os_hosts.HostController()
|
||||||
self.req = FakeRequest()
|
self.req = FakeRequest()
|
||||||
self.stubs.Set(db, 'service_get_all',
|
self.patch('cinder.db.service_get_all', autospec=True,
|
||||||
stub_service_get_all)
|
return_value=SERVICE_LIST)
|
||||||
self.stubs.Set(timeutils, 'utcnow', stub_utcnow)
|
self.mock_object(timeutils, 'utcnow', stub_utcnow)
|
||||||
|
|
||||||
def _test_host_update(self, host, key, val, expected_value):
|
def _test_host_update(self, host, key, val, expected_value):
|
||||||
body = {key: val}
|
body = {key: val}
|
||||||
|
@ -17,15 +17,13 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from iso8601 import iso8601
|
from iso8601 import iso8601
|
||||||
from oslo_utils import timeutils
|
import mock
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
from cinder.api.contrib import services
|
from cinder.api.contrib import services
|
||||||
from cinder.api import extensions
|
from cinder.api import extensions
|
||||||
from cinder import context
|
from cinder import context
|
||||||
from cinder import db
|
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
from cinder import policy
|
|
||||||
from cinder import test
|
from cinder import test
|
||||||
from cinder.tests.unit.api import fakes
|
from cinder.tests.unit.api import fakes
|
||||||
from cinder.tests.unit import fake_constants as fake
|
from cinder.tests.unit import fake_constants as fake
|
||||||
@ -132,21 +130,24 @@ class FakeRequestWithHostBinary(object):
|
|||||||
GET = {"host": "host1", "binary": "cinder-volume"}
|
GET = {"host": "host1", "binary": "cinder-volume"}
|
||||||
|
|
||||||
|
|
||||||
def fake_service_get_all(context, filters=None):
|
def fake_service_get_all(context, **filters):
|
||||||
filters = filters or {}
|
result = []
|
||||||
host = filters.get('host')
|
host = filters.pop('host', None)
|
||||||
binary = filters.get('binary')
|
|
||||||
return [s for s in fake_services_list
|
|
||||||
if (not host or s['host'] == host or
|
|
||||||
s['host'].startswith(host + '@'))
|
|
||||||
and (not binary or s['binary'] == binary)]
|
|
||||||
|
|
||||||
|
|
||||||
def fake_service_get_by_host_binary(context, host, binary):
|
|
||||||
for service in fake_services_list:
|
for service in fake_services_list:
|
||||||
if service['host'] == host and service['binary'] == binary:
|
if (host and service['host'] != host and
|
||||||
return service
|
not service['host'].startswith(host + '@')):
|
||||||
return None
|
continue
|
||||||
|
|
||||||
|
if all(v is None or service.get(k) == v for k, v in filters.items()):
|
||||||
|
result.append(service)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def fake_service_get(context, service_id=None, **filters):
|
||||||
|
result = fake_service_get_all(context, id=service_id, **filters)
|
||||||
|
if not result:
|
||||||
|
raise exception.ServiceNotFound(service_id=service_id)
|
||||||
|
return result[0]
|
||||||
|
|
||||||
|
|
||||||
def fake_service_get_by_id(value):
|
def fake_service_get_by_id(value):
|
||||||
@ -174,18 +175,16 @@ def fake_utcnow(with_timezone=False):
|
|||||||
return datetime.datetime(2012, 10, 29, 13, 42, 11, tzinfo=tzinfo)
|
return datetime.datetime(2012, 10, 29, 13, 42, 11, tzinfo=tzinfo)
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('cinder.db.service_get_all', fake_service_get_all)
|
||||||
|
@mock.patch('cinder.db.service_get', fake_service_get)
|
||||||
|
@mock.patch('oslo_utils.timeutils.utcnow', fake_utcnow)
|
||||||
|
@mock.patch('cinder.db.sqlalchemy.api.service_update', fake_service_update)
|
||||||
|
@mock.patch('cinder.policy.enforce', fake_policy_enforce)
|
||||||
class ServicesTest(test.TestCase):
|
class ServicesTest(test.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(ServicesTest, self).setUp()
|
super(ServicesTest, self).setUp()
|
||||||
|
|
||||||
self.stubs.Set(db, "service_get_all", fake_service_get_all)
|
|
||||||
self.stubs.Set(timeutils, "utcnow", fake_utcnow)
|
|
||||||
self.stubs.Set(db, "service_get_by_args",
|
|
||||||
fake_service_get_by_host_binary)
|
|
||||||
self.stubs.Set(db, "service_update", fake_service_update)
|
|
||||||
self.stubs.Set(policy, "enforce", fake_policy_enforce)
|
|
||||||
|
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
self.ext_mgr = extensions.ExtensionManager()
|
self.ext_mgr = extensions.ExtensionManager()
|
||||||
self.ext_mgr.extensions = {}
|
self.ext_mgr.extensions = {}
|
||||||
|
@ -109,7 +109,7 @@ class SnapshotManageTest(test.TestCase):
|
|||||||
|
|
||||||
@mock.patch('cinder.volume.rpcapi.VolumeAPI.manage_existing_snapshot')
|
@mock.patch('cinder.volume.rpcapi.VolumeAPI.manage_existing_snapshot')
|
||||||
@mock.patch('cinder.volume.api.API.create_snapshot_in_db')
|
@mock.patch('cinder.volume.api.API.create_snapshot_in_db')
|
||||||
@mock.patch('cinder.db.service_get_by_args')
|
@mock.patch('cinder.db.service_get')
|
||||||
def test_manage_snapshot_ok(self, mock_db,
|
def test_manage_snapshot_ok(self, mock_db,
|
||||||
mock_create_snapshot, mock_rpcapi):
|
mock_create_snapshot, mock_rpcapi):
|
||||||
"""Test successful manage volume execution.
|
"""Test successful manage volume execution.
|
||||||
@ -126,11 +126,9 @@ class SnapshotManageTest(test.TestCase):
|
|||||||
res = self._get_resp_post(body)
|
res = self._get_resp_post(body)
|
||||||
self.assertEqual(202, res.status_int, res)
|
self.assertEqual(202, res.status_int, res)
|
||||||
|
|
||||||
# Check the db.service_get_by_host_and_topic was called with correct
|
# Check the db.service_get was called with correct arguments.
|
||||||
# arguments.
|
mock_db.assert_called_once_with(
|
||||||
self.assertEqual(1, mock_db.call_count)
|
mock.ANY, host='fake_host', binary='cinder-volume')
|
||||||
args = mock_db.call_args[0]
|
|
||||||
self.assertEqual('fake_host', args[1])
|
|
||||||
|
|
||||||
# Check the create_snapshot_in_db was called with correct arguments.
|
# Check the create_snapshot_in_db was called with correct arguments.
|
||||||
self.assertEqual(1, mock_create_snapshot.call_count)
|
self.assertEqual(1, mock_create_snapshot.call_count)
|
||||||
|
@ -40,13 +40,13 @@ def app():
|
|||||||
return mapper
|
return mapper
|
||||||
|
|
||||||
|
|
||||||
def db_service_get_by_host_and_topic(context, host, topic):
|
def service_get_by_host_and_topic(context, host, topic):
|
||||||
"""Replacement for db.service_get_by_host_and_topic.
|
"""Replacement for Service.service_get_by_host_and_topic.
|
||||||
|
|
||||||
We stub the db.service_get_by_host_and_topic method to return something
|
We mock the Service.service_get_by_host_and_topic method to return
|
||||||
for a specific host, and raise an exception for anything else. We don't
|
something for a specific host, and raise an exception for anything else.
|
||||||
use the returned data (the code under test just use the call to check for
|
We don't use the returned data (the code under test just use the call to
|
||||||
existence of a host, so the content returned doesn't matter.
|
check for existence of a host, so the content returned doesn't matter.
|
||||||
"""
|
"""
|
||||||
if host == 'host_ok':
|
if host == 'host_ok':
|
||||||
return {}
|
return {}
|
||||||
@ -126,8 +126,8 @@ def api_get_manageable_volumes(*args, **kwargs):
|
|||||||
return vols
|
return vols
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_by_host_and_topic',
|
@mock.patch('cinder.objects.service.Service.get_by_host_and_topic',
|
||||||
db_service_get_by_host_and_topic)
|
service_get_by_host_and_topic)
|
||||||
@mock.patch('cinder.volume.volume_types.get_volume_type_by_name',
|
@mock.patch('cinder.volume.volume_types.get_volume_type_by_name',
|
||||||
vt_get_volume_type_by_name)
|
vt_get_volume_type_by_name)
|
||||||
@mock.patch('cinder.volume.volume_types.get_volume_type',
|
@mock.patch('cinder.volume.volume_types.get_volume_type',
|
||||||
|
@ -190,7 +190,7 @@ def stub_snapshot_update(self, context, *args, **param):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def stub_service_get_all_by_topic(context, topic, disabled=None):
|
def stub_service_get_all(context, **filters):
|
||||||
return [{'availability_zone': "zone1:host1", "disabled": 0}]
|
return [{'availability_zone': "zone1:host1", "disabled": 0}]
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,8 +145,10 @@ class volumeMetaDataTest(test.TestCase):
|
|||||||
self.stubs.Set(volume.api.API, 'get', stubs.stub_volume_get)
|
self.stubs.Set(volume.api.API, 'get', stubs.stub_volume_get)
|
||||||
self.stubs.Set(cinder.db, 'volume_metadata_get',
|
self.stubs.Set(cinder.db, 'volume_metadata_get',
|
||||||
return_volume_metadata)
|
return_volume_metadata)
|
||||||
self.stubs.Set(cinder.db, 'service_get_all_by_topic',
|
self.patch(
|
||||||
stubs.stub_service_get_all_by_topic)
|
'cinder.db.service_get_all', autospec=True,
|
||||||
|
return_value=stubs.stub_service_get_all(None))
|
||||||
|
|
||||||
self.ext_mgr = extensions.ExtensionManager()
|
self.ext_mgr = extensions.ExtensionManager()
|
||||||
self.ext_mgr.extensions = {}
|
self.ext_mgr.extensions = {}
|
||||||
self.volume_controller = volumes.VolumeController(self.ext_mgr)
|
self.volume_controller = volumes.VolumeController(self.ext_mgr)
|
||||||
|
@ -48,8 +48,9 @@ class VolumeApiTest(test.TestCase):
|
|||||||
self.controller = volumes.VolumeController(self.ext_mgr)
|
self.controller = volumes.VolumeController(self.ext_mgr)
|
||||||
|
|
||||||
self.stubs.Set(db, 'volume_get_all', stubs.stub_volume_get_all)
|
self.stubs.Set(db, 'volume_get_all', stubs.stub_volume_get_all)
|
||||||
self.stubs.Set(db, 'service_get_all_by_topic',
|
self.patch(
|
||||||
stubs.stub_service_get_all_by_topic)
|
'cinder.db.service_get_all', autospec=True,
|
||||||
|
return_value=stubs.stub_service_get_all(None))
|
||||||
self.stubs.Set(volume_api.API, 'delete', stubs.stub_volume_delete)
|
self.stubs.Set(volume_api.API, 'delete', stubs.stub_volume_delete)
|
||||||
|
|
||||||
def test_volume_create(self):
|
def test_volume_create(self):
|
||||||
|
@ -220,6 +220,10 @@ def stub_snapshot_update(self, context, *args, **param):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def stub_service_get_all(*args, **kwargs):
|
||||||
|
return [{'availability_zone': "zone1:host1", "disabled": 0}]
|
||||||
|
|
||||||
|
|
||||||
def stub_service_get_all_by_topic(context, topic, disabled=None):
|
def stub_service_get_all_by_topic(context, topic, disabled=None):
|
||||||
return [{'availability_zone': "zone1:host1", "disabled": 0}]
|
return [{'availability_zone': "zone1:host1", "disabled": 0}]
|
||||||
|
|
||||||
|
@ -132,8 +132,9 @@ class volumeMetaDataTest(test.TestCase):
|
|||||||
self.stubs.Set(volume.api.API, 'get', get_volume)
|
self.stubs.Set(volume.api.API, 'get', get_volume)
|
||||||
self.stubs.Set(db, 'volume_metadata_get',
|
self.stubs.Set(db, 'volume_metadata_get',
|
||||||
return_volume_metadata)
|
return_volume_metadata)
|
||||||
self.stubs.Set(db, 'service_get_all_by_topic',
|
self.patch(
|
||||||
stubs.stub_service_get_all_by_topic)
|
'cinder.db.service_get_all', autospec=True,
|
||||||
|
return_value=stubs.stub_service_get_all_by_topic(None, None))
|
||||||
|
|
||||||
self.stubs.Set(self.volume_api, 'update_volume_metadata',
|
self.stubs.Set(self.volume_api, 'update_volume_metadata',
|
||||||
fake_update_volume_metadata)
|
fake_update_volume_metadata)
|
||||||
|
@ -59,8 +59,9 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
self.stubs.Set(db, 'volume_get_all', stubs.stub_volume_get_all)
|
self.stubs.Set(db, 'volume_get_all', stubs.stub_volume_get_all)
|
||||||
self.stubs.Set(volume_api.API, 'delete', stubs.stub_volume_delete)
|
self.stubs.Set(volume_api.API, 'delete', stubs.stub_volume_delete)
|
||||||
self.stubs.Set(db, 'service_get_all_by_topic',
|
self.patch(
|
||||||
stubs.stub_service_get_all_by_topic)
|
'cinder.db.service_get_all', autospec=True,
|
||||||
|
return_value=stubs.stub_service_get_all_by_topic(None, None))
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True)
|
self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True)
|
||||||
|
|
||||||
|
@ -30,25 +30,25 @@ class TestService(test_objects.BaseObjectsTestCase):
|
|||||||
self._compare(self, db_service, service)
|
self._compare(self, db_service, service)
|
||||||
service_get.assert_called_once_with(self.context, 1)
|
service_get.assert_called_once_with(self.context, 1)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_by_host_and_topic')
|
@mock.patch('cinder.db.service_get')
|
||||||
def test_get_by_host_and_topic(self, service_get_by_host_and_topic):
|
def test_get_by_host_and_topic(self, service_get):
|
||||||
db_service = fake_service.fake_db_service()
|
db_service = fake_service.fake_db_service()
|
||||||
service_get_by_host_and_topic.return_value = db_service
|
service_get.return_value = db_service
|
||||||
service = objects.Service.get_by_host_and_topic(
|
service = objects.Service.get_by_host_and_topic(
|
||||||
self.context, 'fake-host', 'fake-topic')
|
self.context, 'fake-host', 'fake-topic')
|
||||||
self._compare(self, db_service, service)
|
self._compare(self, db_service, service)
|
||||||
service_get_by_host_and_topic.assert_called_once_with(
|
service_get.assert_called_once_with(
|
||||||
self.context, 'fake-host', 'fake-topic')
|
self.context, disabled=False, host='fake-host', topic='fake-topic')
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_by_args')
|
@mock.patch('cinder.db.service_get')
|
||||||
def test_get_by_args(self, service_get_by_args):
|
def test_get_by_args(self, service_get):
|
||||||
db_service = fake_service.fake_db_service()
|
db_service = fake_service.fake_db_service()
|
||||||
service_get_by_args.return_value = db_service
|
service_get.return_value = db_service
|
||||||
service = objects.Service.get_by_args(
|
service = objects.Service.get_by_args(
|
||||||
self.context, 'fake-host', 'fake-key')
|
self.context, 'fake-host', 'fake-key')
|
||||||
self._compare(self, db_service, service)
|
self._compare(self, db_service, service)
|
||||||
service_get_by_args.assert_called_once_with(
|
service_get.assert_called_once_with(
|
||||||
self.context, 'fake-host', 'fake-key')
|
self.context, host='fake-host', binary='fake-key')
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_create')
|
@mock.patch('cinder.db.service_create')
|
||||||
def test_create(self, service_create):
|
def test_create(self, service_create):
|
||||||
@ -102,21 +102,21 @@ class TestService(test_objects.BaseObjectsTestCase):
|
|||||||
call_bool,
|
call_bool,
|
||||||
mock.call(self.context, 123)])
|
mock.call(self.context, 123)])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_binary')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def _test_get_minimum_version(self, services_update, expected,
|
def _test_get_minimum_version(self, services_update, expected,
|
||||||
service_get_all_by_binary):
|
service_get_all):
|
||||||
services = [fake_service.fake_db_service(**s) for s in services_update]
|
services = [fake_service.fake_db_service(**s) for s in services_update]
|
||||||
service_get_all_by_binary.return_value = services
|
service_get_all.return_value = services
|
||||||
|
|
||||||
min_rpc = objects.Service.get_minimum_rpc_version(self.context, 'foo')
|
min_rpc = objects.Service.get_minimum_rpc_version(self.context, 'foo')
|
||||||
self.assertEqual(expected[0], min_rpc)
|
self.assertEqual(expected[0], min_rpc)
|
||||||
min_obj = objects.Service.get_minimum_obj_version(self.context, 'foo')
|
min_obj = objects.Service.get_minimum_obj_version(self.context, 'foo')
|
||||||
self.assertEqual(expected[1], min_obj)
|
self.assertEqual(expected[1], min_obj)
|
||||||
service_get_all_by_binary.assert_has_calls(
|
service_get_all.assert_has_calls(
|
||||||
[mock.call(self.context, 'foo', disabled=None)] * 2)
|
[mock.call(self.context, binary='foo', disabled=None)] * 2)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_binary')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_get_minimum_version(self, service_get_all_by_binary):
|
def test_get_minimum_version(self, service_get_all):
|
||||||
services_update = [
|
services_update = [
|
||||||
{'rpc_current_version': '1.0', 'object_current_version': '1.3'},
|
{'rpc_current_version': '1.0', 'object_current_version': '1.3'},
|
||||||
{'rpc_current_version': '1.1', 'object_current_version': '1.2'},
|
{'rpc_current_version': '1.1', 'object_current_version': '1.2'},
|
||||||
@ -125,8 +125,8 @@ class TestService(test_objects.BaseObjectsTestCase):
|
|||||||
expected = ('1.0', '1.2')
|
expected = ('1.0', '1.2')
|
||||||
self._test_get_minimum_version(services_update, expected)
|
self._test_get_minimum_version(services_update, expected)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_binary')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_get_minimum_version_liberty(self, service_get_all_by_binary):
|
def test_get_minimum_version_liberty(self, service_get_all):
|
||||||
services_update = [
|
services_update = [
|
||||||
{'rpc_current_version': '1.0', 'object_current_version': '1.3'},
|
{'rpc_current_version': '1.0', 'object_current_version': '1.3'},
|
||||||
{'rpc_current_version': '1.1', 'object_current_version': None},
|
{'rpc_current_version': '1.1', 'object_current_version': None},
|
||||||
@ -144,30 +144,30 @@ class TestServiceList(test_objects.BaseObjectsTestCase):
|
|||||||
|
|
||||||
filters = {'host': 'host', 'binary': 'foo', 'disabled': False}
|
filters = {'host': 'host', 'binary': 'foo', 'disabled': False}
|
||||||
services = objects.ServiceList.get_all(self.context, filters)
|
services = objects.ServiceList.get_all(self.context, filters)
|
||||||
service_get_all.assert_called_once_with(self.context, filters)
|
service_get_all.assert_called_once_with(self.context, **filters)
|
||||||
self.assertEqual(1, len(services))
|
self.assertEqual(1, len(services))
|
||||||
TestService._compare(self, db_service, services[0])
|
TestService._compare(self, db_service, services[0])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_get_all_by_topic(self, service_get_all_by_topic):
|
def test_get_all_by_topic(self, service_get_all):
|
||||||
db_service = fake_service.fake_db_service()
|
db_service = fake_service.fake_db_service()
|
||||||
service_get_all_by_topic.return_value = [db_service]
|
service_get_all.return_value = [db_service]
|
||||||
|
|
||||||
services = objects.ServiceList.get_all_by_topic(
|
services = objects.ServiceList.get_all_by_topic(
|
||||||
self.context, 'foo', 'bar')
|
self.context, 'foo', 'bar')
|
||||||
service_get_all_by_topic.assert_called_once_with(
|
service_get_all.assert_called_once_with(
|
||||||
self.context, 'foo', disabled='bar')
|
self.context, topic='foo', disabled='bar')
|
||||||
self.assertEqual(1, len(services))
|
self.assertEqual(1, len(services))
|
||||||
TestService._compare(self, db_service, services[0])
|
TestService._compare(self, db_service, services[0])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_binary')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_get_all_by_binary(self, service_get_all_by_binary):
|
def test_get_all_by_binary(self, service_get_all):
|
||||||
db_service = fake_service.fake_db_service()
|
db_service = fake_service.fake_db_service()
|
||||||
service_get_all_by_binary.return_value = [db_service]
|
service_get_all.return_value = [db_service]
|
||||||
|
|
||||||
services = objects.ServiceList.get_all_by_binary(
|
services = objects.ServiceList.get_all_by_binary(
|
||||||
self.context, 'foo', 'bar')
|
self.context, 'foo', 'bar')
|
||||||
service_get_all_by_binary.assert_called_once_with(
|
service_get_all.assert_called_once_with(
|
||||||
self.context, 'foo', disabled='bar')
|
self.context, binary='foo', disabled='bar')
|
||||||
self.assertEqual(1, len(services))
|
self.assertEqual(1, len(services))
|
||||||
TestService._compare(self, db_service, services[0])
|
TestService._compare(self, db_service, services[0])
|
||||||
|
@ -43,14 +43,14 @@ class AllocatedCapacityWeigherTestCase(test.TestCase):
|
|||||||
[weights.capacity.AllocatedCapacityWeigher], hosts,
|
[weights.capacity.AllocatedCapacityWeigher], hosts,
|
||||||
weight_properties)[0]
|
weight_properties)[0]
|
||||||
|
|
||||||
@mock.patch('cinder.db.sqlalchemy.api.service_get_all_by_topic')
|
@mock.patch('cinder.db.sqlalchemy.api.service_get_all')
|
||||||
def _get_all_hosts(self, _mock_service_get_all_by_topic, disabled=False):
|
def _get_all_hosts(self, _mock_service_get_all, disabled=False):
|
||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
fakes.mock_host_manager_db_calls(_mock_service_get_all_by_topic,
|
fakes.mock_host_manager_db_calls(_mock_service_get_all,
|
||||||
disabled=disabled)
|
disabled=disabled)
|
||||||
host_states = self.host_manager.get_all_host_states(ctxt)
|
host_states = self.host_manager.get_all_host_states(ctxt)
|
||||||
_mock_service_get_all_by_topic.assert_called_once_with(
|
_mock_service_get_all.assert_called_once_with(
|
||||||
ctxt, CONF.volume_topic, disabled=disabled)
|
ctxt, topic=CONF.volume_topic, disabled=disabled)
|
||||||
return host_states
|
return host_states
|
||||||
|
|
||||||
def test_default_of_spreading_first(self):
|
def test_default_of_spreading_first(self):
|
||||||
|
@ -43,14 +43,14 @@ class CapacityWeigherTestCase(test.TestCase):
|
|||||||
hosts,
|
hosts,
|
||||||
weight_properties)
|
weight_properties)
|
||||||
|
|
||||||
@mock.patch('cinder.db.sqlalchemy.api.service_get_all_by_topic')
|
@mock.patch('cinder.db.sqlalchemy.api.service_get_all')
|
||||||
def _get_all_hosts(self, _mock_service_get_all_by_topic, disabled=False):
|
def _get_all_hosts(self, _mock_service_get_all, disabled=False):
|
||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
fakes.mock_host_manager_db_calls(_mock_service_get_all_by_topic,
|
fakes.mock_host_manager_db_calls(_mock_service_get_all,
|
||||||
disabled=disabled)
|
disabled=disabled)
|
||||||
host_states = self.host_manager.get_all_host_states(ctxt)
|
host_states = self.host_manager.get_all_host_states(ctxt)
|
||||||
_mock_service_get_all_by_topic.assert_called_once_with(
|
_mock_service_get_all.assert_called_once_with(
|
||||||
ctxt, CONF.volume_topic, disabled=disabled)
|
ctxt, topic=CONF.volume_topic, disabled=disabled)
|
||||||
return host_states
|
return host_states
|
||||||
|
|
||||||
# If thin_provisioning_support = False, use the following formula:
|
# If thin_provisioning_support = False, use the following formula:
|
||||||
|
@ -50,16 +50,16 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
sched.schedule_create_consistencygroup,
|
sched.schedule_create_consistencygroup,
|
||||||
fake_context, 'faki-id1', request_spec_list, {})
|
fake_context, 'faki-id1', request_spec_list, {})
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_schedule_consistencygroup(self,
|
def test_schedule_consistencygroup(self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
# Make sure _schedule_group() can find host successfully.
|
# Make sure _schedule_group() can find host successfully.
|
||||||
sched = fakes.FakeFilterScheduler()
|
sched = fakes.FakeFilterScheduler()
|
||||||
sched.host_manager = fakes.FakeHostManager()
|
sched.host_manager = fakes.FakeHostManager()
|
||||||
fake_context = context.RequestContext('user', 'project',
|
fake_context = context.RequestContext('user', 'project',
|
||||||
is_admin=True)
|
is_admin=True)
|
||||||
|
|
||||||
fakes.mock_host_manager_db_calls(_mock_service_get_all_by_topic)
|
fakes.mock_host_manager_db_calls(_mock_service_get_all)
|
||||||
|
|
||||||
specs = {'capabilities:consistencygroup_support': '<is> True'}
|
specs = {'capabilities:consistencygroup_support': '<is> True'}
|
||||||
request_spec = {'volume_properties': {'project_id': 1,
|
request_spec = {'volume_properties': {'project_id': 1,
|
||||||
@ -75,12 +75,12 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
request_spec_list,
|
request_spec_list,
|
||||||
{})
|
{})
|
||||||
self.assertIsNotNone(weighed_host.obj)
|
self.assertIsNotNone(weighed_host.obj)
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
self.assertTrue(_mock_service_get_all.called)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_schedule_consistencygroup_no_cg_support_in_extra_specs(
|
def test_schedule_consistencygroup_no_cg_support_in_extra_specs(
|
||||||
self,
|
self,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
# Make sure _schedule_group() can find host successfully even
|
# Make sure _schedule_group() can find host successfully even
|
||||||
# when consistencygroup_support is not specified in volume type's
|
# when consistencygroup_support is not specified in volume type's
|
||||||
# extra specs
|
# extra specs
|
||||||
@ -89,7 +89,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
fake_context = context.RequestContext('user', 'project',
|
fake_context = context.RequestContext('user', 'project',
|
||||||
is_admin=True)
|
is_admin=True)
|
||||||
|
|
||||||
fakes.mock_host_manager_db_calls(_mock_service_get_all_by_topic)
|
fakes.mock_host_manager_db_calls(_mock_service_get_all)
|
||||||
|
|
||||||
request_spec = {'volume_properties': {'project_id': 1,
|
request_spec = {'volume_properties': {'project_id': 1,
|
||||||
'size': 0},
|
'size': 0},
|
||||||
@ -104,7 +104,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
request_spec_list,
|
request_spec_list,
|
||||||
{})
|
{})
|
||||||
self.assertIsNotNone(weighed_host.obj)
|
self.assertIsNotNone(weighed_host.obj)
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
self.assertTrue(_mock_service_get_all.called)
|
||||||
|
|
||||||
def test_create_volume_no_hosts(self):
|
def test_create_volume_no_hosts(self):
|
||||||
# Ensure empty hosts/child_zones result in NoValidHosts exception.
|
# Ensure empty hosts/child_zones result in NoValidHosts exception.
|
||||||
@ -174,8 +174,8 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
fake_context, request_spec, {})
|
fake_context, request_spec, {})
|
||||||
self.assertTrue(self.was_admin)
|
self.assertTrue(self.was_admin)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_schedule_happy_day(self, _mock_service_get_all_by_topic):
|
def test_schedule_happy_day(self, _mock_service_get_all):
|
||||||
# Make sure there's nothing glaringly wrong with _schedule()
|
# Make sure there's nothing glaringly wrong with _schedule()
|
||||||
# by doing a happy day pass through.
|
# by doing a happy day pass through.
|
||||||
sched = fakes.FakeFilterScheduler()
|
sched = fakes.FakeFilterScheduler()
|
||||||
@ -183,16 +183,16 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
fake_context = context.RequestContext('user', 'project',
|
fake_context = context.RequestContext('user', 'project',
|
||||||
is_admin=True)
|
is_admin=True)
|
||||||
|
|
||||||
fakes.mock_host_manager_db_calls(_mock_service_get_all_by_topic)
|
fakes.mock_host_manager_db_calls(_mock_service_get_all)
|
||||||
|
|
||||||
request_spec = {'volume_type': {'name': 'LVM_iSCSI'},
|
request_spec = {'volume_type': {'name': 'LVM_iSCSI'},
|
||||||
'volume_properties': {'project_id': 1,
|
'volume_properties': {'project_id': 1,
|
||||||
'size': 1}}
|
'size': 1}}
|
||||||
weighed_host = sched._schedule(fake_context, request_spec, {})
|
weighed_host = sched._schedule(fake_context, request_spec, {})
|
||||||
self.assertIsNotNone(weighed_host.obj)
|
self.assertIsNotNone(weighed_host.obj)
|
||||||
self.assertTrue(_mock_service_get_all_by_topic.called)
|
self.assertTrue(_mock_service_get_all.called)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_volume_clear_host_different_with_cg(self,
|
def test_create_volume_clear_host_different_with_cg(self,
|
||||||
_mock_service_get_all):
|
_mock_service_get_all):
|
||||||
# Ensure we clear those hosts whose backend is not same as
|
# Ensure we clear those hosts whose backend is not same as
|
||||||
@ -208,7 +208,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
weighed_host = sched._schedule(fake_context, request_spec, {})
|
weighed_host = sched._schedule(fake_context, request_spec, {})
|
||||||
self.assertIsNone(weighed_host)
|
self.assertIsNone(weighed_host)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_create_volume_host_same_as_cg(self, _mock_service_get_all):
|
def test_create_volume_host_same_as_cg(self, _mock_service_get_all):
|
||||||
# Ensure we don't clear the host whose backend is same as
|
# Ensure we don't clear the host whose backend is same as
|
||||||
# consistencygroup's backend.
|
# consistencygroup's backend.
|
||||||
@ -338,7 +338,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
|
|
||||||
return (sched, fake_context)
|
return (sched, fake_context)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_host_passes_filters_happy_day(self, _mock_service_get_topic):
|
def test_host_passes_filters_happy_day(self, _mock_service_get_topic):
|
||||||
"""Do a successful pass through of with host_passes_filters()."""
|
"""Do a successful pass through of with host_passes_filters()."""
|
||||||
sched, ctx = self._host_passes_filters_setup(
|
sched, ctx = self._host_passes_filters_setup(
|
||||||
@ -352,7 +352,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
self.assertEqual('host1', utils.extract_host(ret_host.host))
|
self.assertEqual('host1', utils.extract_host(ret_host.host))
|
||||||
self.assertTrue(_mock_service_get_topic.called)
|
self.assertTrue(_mock_service_get_topic.called)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_host_passes_filters_default_pool_happy_day(
|
def test_host_passes_filters_default_pool_happy_day(
|
||||||
self, _mock_service_get_topic):
|
self, _mock_service_get_topic):
|
||||||
"""Do a successful pass through of with host_passes_filters()."""
|
"""Do a successful pass through of with host_passes_filters()."""
|
||||||
@ -367,7 +367,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
self.assertEqual('host5', utils.extract_host(ret_host.host))
|
self.assertEqual('host5', utils.extract_host(ret_host.host))
|
||||||
self.assertTrue(_mock_service_get_topic.called)
|
self.assertTrue(_mock_service_get_topic.called)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_host_passes_filters_no_capacity(self, _mock_service_get_topic):
|
def test_host_passes_filters_no_capacity(self, _mock_service_get_topic):
|
||||||
"""Fail the host due to insufficient capacity."""
|
"""Fail the host due to insufficient capacity."""
|
||||||
sched, ctx = self._host_passes_filters_setup(
|
sched, ctx = self._host_passes_filters_setup(
|
||||||
@ -381,7 +381,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
ctx, 'host1#lvm1', request_spec, {})
|
ctx, 'host1#lvm1', request_spec, {})
|
||||||
self.assertTrue(_mock_service_get_topic.called)
|
self.assertTrue(_mock_service_get_topic.called)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_retype_policy_never_migrate_pass(self, _mock_service_get_topic):
|
def test_retype_policy_never_migrate_pass(self, _mock_service_get_topic):
|
||||||
# Retype should pass if current host passes filters and
|
# Retype should pass if current host passes filters and
|
||||||
# policy=never. host4 doesn't have enough space to hold an additional
|
# policy=never. host4 doesn't have enough space to hold an additional
|
||||||
@ -401,7 +401,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
migration_policy='never')
|
migration_policy='never')
|
||||||
self.assertEqual('host4', utils.extract_host(host_state.host))
|
self.assertEqual('host4', utils.extract_host(host_state.host))
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_retype_with_pool_policy_never_migrate_pass(
|
def test_retype_with_pool_policy_never_migrate_pass(
|
||||||
self, _mock_service_get_topic):
|
self, _mock_service_get_topic):
|
||||||
# Retype should pass if current host passes filters and
|
# Retype should pass if current host passes filters and
|
||||||
@ -422,7 +422,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
migration_policy='never')
|
migration_policy='never')
|
||||||
self.assertEqual('host3#lvm3', host_state.host)
|
self.assertEqual('host3#lvm3', host_state.host)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_retype_policy_never_migrate_fail(self, _mock_service_get_topic):
|
def test_retype_policy_never_migrate_fail(self, _mock_service_get_topic):
|
||||||
# Retype should fail if current host doesn't pass filters and
|
# Retype should fail if current host doesn't pass filters and
|
||||||
# policy=never.
|
# policy=never.
|
||||||
@ -439,7 +439,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
request_spec, filter_properties={},
|
request_spec, filter_properties={},
|
||||||
migration_policy='never')
|
migration_policy='never')
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_retype_policy_demand_migrate_pass(self, _mock_service_get_topic):
|
def test_retype_policy_demand_migrate_pass(self, _mock_service_get_topic):
|
||||||
# Retype should pass if current host fails filters but another host
|
# Retype should pass if current host fails filters but another host
|
||||||
# is suitable when policy=on-demand.
|
# is suitable when policy=on-demand.
|
||||||
@ -457,7 +457,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
|
|||||||
migration_policy='on-demand')
|
migration_policy='on-demand')
|
||||||
self.assertEqual('host1', utils.extract_host(host_state.host))
|
self.assertEqual('host1', utils.extract_host(host_state.host))
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_retype_policy_demand_migrate_fail(self, _mock_service_get_topic):
|
def test_retype_policy_demand_migrate_fail(self, _mock_service_get_topic):
|
||||||
# Retype should fail if current host doesn't pass filters and
|
# Retype should fail if current host doesn't pass filters and
|
||||||
# no other suitable candidates exist even if policy=on-demand.
|
# no other suitable candidates exist even if policy=on-demand.
|
||||||
|
@ -121,8 +121,8 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
self.assertDictMatch(expected, service_states)
|
self.assertDictMatch(expected, service_states)
|
||||||
|
|
||||||
@mock.patch('cinder.utils.service_is_up')
|
@mock.patch('cinder.utils.service_is_up')
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
def test_has_all_capabilities(self, _mock_service_get_all_by_topic,
|
def test_has_all_capabilities(self, _mock_service_get_all,
|
||||||
_mock_service_is_up):
|
_mock_service_is_up):
|
||||||
_mock_service_is_up.return_value = True
|
_mock_service_is_up.return_value = True
|
||||||
services = [
|
services = [
|
||||||
@ -133,8 +133,8 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
dict(id=3, host='host3', topic='volume', disabled=False,
|
dict(id=3, host='host3', topic='volume', disabled=False,
|
||||||
availability_zone='zone1', updated_at=timeutils.utcnow()),
|
availability_zone='zone1', updated_at=timeutils.utcnow()),
|
||||||
]
|
]
|
||||||
_mock_service_get_all_by_topic.return_value = services
|
_mock_service_get_all.return_value = services
|
||||||
# Create host_manager again to let db.service_get_all_by_topic mock run
|
# Create host_manager again to let db.service_get_all mock run
|
||||||
self.host_manager = host_manager.HostManager()
|
self.host_manager = host_manager.HostManager()
|
||||||
self.assertFalse(self.host_manager.has_all_capabilities())
|
self.assertFalse(self.host_manager.has_all_capabilities())
|
||||||
|
|
||||||
@ -153,12 +153,12 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
host3_volume_capabs)
|
host3_volume_capabs)
|
||||||
self.assertTrue(self.host_manager.has_all_capabilities())
|
self.assertTrue(self.host_manager.has_all_capabilities())
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch('cinder.utils.service_is_up')
|
@mock.patch('cinder.utils.service_is_up')
|
||||||
@mock.patch('oslo_utils.timeutils.utcnow')
|
@mock.patch('oslo_utils.timeutils.utcnow')
|
||||||
def test_update_and_get_pools(self, _mock_utcnow,
|
def test_update_and_get_pools(self, _mock_utcnow,
|
||||||
_mock_service_is_up,
|
_mock_service_is_up,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
"""Test interaction between update and get_pools
|
"""Test interaction between update and get_pools
|
||||||
|
|
||||||
This test verifies that each time that get_pools is called it gets the
|
This test verifies that each time that get_pools is called it gets the
|
||||||
@ -182,7 +182,7 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
timestamp=None, reserved_percentage=0),
|
timestamp=None, reserved_percentage=0),
|
||||||
}
|
}
|
||||||
|
|
||||||
_mock_service_get_all_by_topic.return_value = services
|
_mock_service_get_all.return_value = services
|
||||||
_mock_service_is_up.return_value = True
|
_mock_service_is_up.return_value = True
|
||||||
_mock_warning = mock.Mock()
|
_mock_warning = mock.Mock()
|
||||||
host_manager.LOG.warn = _mock_warning
|
host_manager.LOG.warn = _mock_warning
|
||||||
@ -206,10 +206,10 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
self.assertEqual(1, len(res))
|
self.assertEqual(1, len(res))
|
||||||
self.assertEqual(dates[2], res[0]['capabilities']['timestamp'])
|
self.assertEqual(dates[2], res[0]['capabilities']['timestamp'])
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch('cinder.utils.service_is_up')
|
@mock.patch('cinder.utils.service_is_up')
|
||||||
def test_get_all_host_states(self, _mock_service_is_up,
|
def test_get_all_host_states(self, _mock_service_is_up,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
context = 'fake_context'
|
context = 'fake_context'
|
||||||
topic = CONF.volume_topic
|
topic = CONF.volume_topic
|
||||||
|
|
||||||
@ -257,16 +257,16 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
# First test: service_is_up is always True, host5 is disabled,
|
# First test: service_is_up is always True, host5 is disabled,
|
||||||
# host4 has no capabilities
|
# host4 has no capabilities
|
||||||
self.host_manager.service_states = service_states
|
self.host_manager.service_states = service_states
|
||||||
_mock_service_get_all_by_topic.return_value = services
|
_mock_service_get_all.return_value = services
|
||||||
_mock_service_is_up.return_value = True
|
_mock_service_is_up.return_value = True
|
||||||
_mock_warning = mock.Mock()
|
_mock_warning = mock.Mock()
|
||||||
host_manager.LOG.warning = _mock_warning
|
host_manager.LOG.warning = _mock_warning
|
||||||
|
|
||||||
# Get all states
|
# Get all states
|
||||||
self.host_manager.get_all_host_states(context)
|
self.host_manager.get_all_host_states(context)
|
||||||
_mock_service_get_all_by_topic.assert_called_with(context,
|
_mock_service_get_all.assert_called_with(context,
|
||||||
topic,
|
disabled=False,
|
||||||
disabled=False)
|
topic=topic)
|
||||||
expected = []
|
expected = []
|
||||||
for service in service_objs:
|
for service in service_objs:
|
||||||
expected.append(mock.call(service))
|
expected.append(mock.call(service))
|
||||||
@ -284,14 +284,14 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
# Second test: Now service_is_up returns False for host3
|
# Second test: Now service_is_up returns False for host3
|
||||||
_mock_service_is_up.reset_mock()
|
_mock_service_is_up.reset_mock()
|
||||||
_mock_service_is_up.side_effect = [True, True, False, True]
|
_mock_service_is_up.side_effect = [True, True, False, True]
|
||||||
_mock_service_get_all_by_topic.reset_mock()
|
_mock_service_get_all.reset_mock()
|
||||||
_mock_warning.reset_mock()
|
_mock_warning.reset_mock()
|
||||||
|
|
||||||
# Get all states, make sure host 3 is reported as down
|
# Get all states, make sure host 3 is reported as down
|
||||||
self.host_manager.get_all_host_states(context)
|
self.host_manager.get_all_host_states(context)
|
||||||
_mock_service_get_all_by_topic.assert_called_with(context,
|
_mock_service_get_all.assert_called_with(context,
|
||||||
topic,
|
disabled=False,
|
||||||
disabled=False)
|
topic=topic)
|
||||||
|
|
||||||
self.assertEqual(expected, _mock_service_is_up.call_args_list)
|
self.assertEqual(expected, _mock_service_is_up.call_args_list)
|
||||||
self.assertGreater(_mock_warning.call_count, 0)
|
self.assertGreater(_mock_warning.call_count, 0)
|
||||||
@ -306,10 +306,10 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
test_service.TestService._compare(self, volume_node,
|
test_service.TestService._compare(self, volume_node,
|
||||||
host_state_map[host].service)
|
host_state_map[host].service)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all_by_topic')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@mock.patch('cinder.utils.service_is_up')
|
@mock.patch('cinder.utils.service_is_up')
|
||||||
def test_get_pools(self, _mock_service_is_up,
|
def test_get_pools(self, _mock_service_is_up,
|
||||||
_mock_service_get_all_by_topic):
|
_mock_service_get_all):
|
||||||
context = 'fake_context'
|
context = 'fake_context'
|
||||||
|
|
||||||
services = [
|
services = [
|
||||||
@ -336,7 +336,7 @@ class HostManagerTestCase(test.TestCase):
|
|||||||
provisioned_capacity_gb=9300),
|
provisioned_capacity_gb=9300),
|
||||||
}
|
}
|
||||||
|
|
||||||
_mock_service_get_all_by_topic.return_value = services
|
_mock_service_get_all.return_value = services
|
||||||
_mock_service_is_up.return_value = True
|
_mock_service_is_up.return_value = True
|
||||||
_mock_warning = mock.Mock()
|
_mock_warning = mock.Mock()
|
||||||
host_manager.LOG.warn = _mock_warning
|
host_manager.LOG.warn = _mock_warning
|
||||||
|
@ -69,14 +69,14 @@ class VolumeNumberWeigherTestCase(test.TestCase):
|
|||||||
hosts,
|
hosts,
|
||||||
weight_properties)[0]
|
weight_properties)[0]
|
||||||
|
|
||||||
@mock.patch('cinder.db.sqlalchemy.api.service_get_all_by_topic')
|
@mock.patch('cinder.db.sqlalchemy.api.service_get_all')
|
||||||
def _get_all_hosts(self, _mock_service_get_all_by_topic, disabled=False):
|
def _get_all_hosts(self, _mock_service_get_all, disabled=False):
|
||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
fakes.mock_host_manager_db_calls(_mock_service_get_all_by_topic,
|
fakes.mock_host_manager_db_calls(_mock_service_get_all,
|
||||||
disabled=disabled)
|
disabled=disabled)
|
||||||
host_states = self.host_manager.get_all_host_states(ctxt)
|
host_states = self.host_manager.get_all_host_states(ctxt)
|
||||||
_mock_service_get_all_by_topic.assert_called_once_with(
|
_mock_service_get_all.assert_called_once_with(
|
||||||
ctxt, CONF.volume_topic, disabled=disabled)
|
ctxt, topic=CONF.volume_topic, disabled=disabled)
|
||||||
return host_states
|
return host_states
|
||||||
|
|
||||||
def test_volume_number_weight_multiplier1(self):
|
def test_volume_number_weight_multiplier1(self):
|
||||||
|
@ -439,7 +439,7 @@ class TestCinderManageCmd(test.TestCase):
|
|||||||
host_cmds.list()
|
host_cmds.list()
|
||||||
|
|
||||||
get_admin_context.assert_called_once_with()
|
get_admin_context.assert_called_once_with()
|
||||||
service_get_all.assert_called_once_with(mock.sentinel.ctxt, None)
|
service_get_all.assert_called_once_with(mock.sentinel.ctxt)
|
||||||
self.assertEqual(expected_out, fake_out.getvalue())
|
self.assertEqual(expected_out, fake_out.getvalue())
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_get_all')
|
@mock.patch('cinder.db.service_get_all')
|
||||||
@ -462,7 +462,7 @@ class TestCinderManageCmd(test.TestCase):
|
|||||||
host_cmds.list(zone='fake-az1')
|
host_cmds.list(zone='fake-az1')
|
||||||
|
|
||||||
get_admin_context.assert_called_once_with()
|
get_admin_context.assert_called_once_with()
|
||||||
service_get_all.assert_called_once_with(mock.sentinel.ctxt, None)
|
service_get_all.assert_called_once_with(mock.sentinel.ctxt)
|
||||||
self.assertEqual(expected_out, fake_out.getvalue())
|
self.assertEqual(expected_out, fake_out.getvalue())
|
||||||
|
|
||||||
@mock.patch('cinder.objects.base.CinderObjectSerializer')
|
@mock.patch('cinder.objects.base.CinderObjectSerializer')
|
||||||
@ -747,7 +747,7 @@ class TestCinderManageCmd(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(expected_out, fake_out.getvalue())
|
self.assertEqual(expected_out, fake_out.getvalue())
|
||||||
get_admin_context.assert_called_with()
|
get_admin_context.assert_called_with()
|
||||||
service_get_all.assert_called_with(ctxt, None)
|
service_get_all.assert_called_with(ctxt)
|
||||||
|
|
||||||
def test_service_commands_list(self):
|
def test_service_commands_list(self):
|
||||||
service = {'binary': 'cinder-binary',
|
service = {'binary': 'cinder-binary',
|
||||||
@ -858,8 +858,7 @@ class TestCinderManageCmd(test.TestCase):
|
|||||||
self.assertEqual(2, exit)
|
self.assertEqual(2, exit)
|
||||||
|
|
||||||
@mock.patch('cinder.db.service_destroy')
|
@mock.patch('cinder.db.service_destroy')
|
||||||
@mock.patch('cinder.db.service_get_by_args',
|
@mock.patch('cinder.db.service_get', return_value = {'id': '12'})
|
||||||
return_value = {'id': '12'})
|
|
||||||
def test_remove_service_success(self, mock_get_by_args,
|
def test_remove_service_success(self, mock_get_by_args,
|
||||||
mock_service_destroy):
|
mock_service_destroy):
|
||||||
service_commands = cinder_manage.ServiceCommands()
|
service_commands = cinder_manage.ServiceCommands()
|
||||||
|
@ -18,6 +18,7 @@ import datetime
|
|||||||
|
|
||||||
import enum
|
import enum
|
||||||
import mock
|
import mock
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ from cinder import test
|
|||||||
from cinder.tests.unit import fake_constants as fake
|
from cinder.tests.unit import fake_constants as fake
|
||||||
from cinder.tests.unit import utils
|
from cinder.tests.unit import utils
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
THREE = 3
|
THREE = 3
|
||||||
THREE_HUNDREDS = 300
|
THREE_HUNDREDS = 300
|
||||||
ONE_HUNDREDS = 100
|
ONE_HUNDREDS = 100
|
||||||
@ -127,7 +129,12 @@ class DBAPIServiceTestCase(BaseTest):
|
|||||||
def _create_service(self, values):
|
def _create_service(self, values):
|
||||||
v = self._get_base_values()
|
v = self._get_base_values()
|
||||||
v.update(values)
|
v.update(values)
|
||||||
return db.service_create(self.ctxt, v)
|
service = db.service_create(self.ctxt, v)
|
||||||
|
# We need to read the contents from the DB if we have set updated_at
|
||||||
|
# or created_at fields
|
||||||
|
if 'updated_at' in values or 'created_at' in values:
|
||||||
|
service = db.service_get(self.ctxt, service.id)
|
||||||
|
return service
|
||||||
|
|
||||||
def test_service_create(self):
|
def test_service_create(self):
|
||||||
service = self._create_service({})
|
service = self._create_service({})
|
||||||
@ -142,8 +149,9 @@ class DBAPIServiceTestCase(BaseTest):
|
|||||||
db.service_destroy(self.ctxt, service1['id'])
|
db.service_destroy(self.ctxt, service1['id'])
|
||||||
self.assertRaises(exception.ServiceNotFound,
|
self.assertRaises(exception.ServiceNotFound,
|
||||||
db.service_get, self.ctxt, service1['id'])
|
db.service_get, self.ctxt, service1['id'])
|
||||||
self._assertEqualObjects(db.service_get(self.ctxt, service2['id']),
|
self._assertEqualObjects(
|
||||||
service2)
|
service2,
|
||||||
|
db.service_get(self.ctxt, service2['id']))
|
||||||
|
|
||||||
def test_service_update(self):
|
def test_service_update(self):
|
||||||
service = self._create_service({})
|
service = self._create_service({})
|
||||||
@ -175,33 +183,35 @@ class DBAPIServiceTestCase(BaseTest):
|
|||||||
def test_service_get_by_host_and_topic(self):
|
def test_service_get_by_host_and_topic(self):
|
||||||
service1 = self._create_service({'host': 'host1', 'topic': 'topic1'})
|
service1 = self._create_service({'host': 'host1', 'topic': 'topic1'})
|
||||||
|
|
||||||
real_service1 = db.service_get_by_host_and_topic(self.ctxt,
|
real_service1 = db.service_get(self.ctxt, host='host1', topic='topic1')
|
||||||
host='host1',
|
|
||||||
topic='topic1')
|
|
||||||
self._assertEqualObjects(service1, real_service1)
|
self._assertEqualObjects(service1, real_service1)
|
||||||
|
|
||||||
def test_service_get_all(self):
|
def test_service_get_all(self):
|
||||||
|
expired = (datetime.datetime.utcnow()
|
||||||
|
- datetime.timedelta(seconds=CONF.service_down_time + 1))
|
||||||
values = [
|
values = [
|
||||||
{'host': 'host1', 'binary': 'b1'},
|
{'host': 'host1', 'binary': 'b1', 'created_at': expired},
|
||||||
{'host': 'host1@ceph', 'binary': 'b2'},
|
{'host': 'host1@ceph', 'binary': 'b2'},
|
||||||
{'host': 'host2', 'binary': 'b2'},
|
{'host': 'host2', 'binary': 'b2'},
|
||||||
{'disabled': True}
|
{'disabled': True, 'created_at': expired, 'updated_at': expired}
|
||||||
]
|
]
|
||||||
services = [self._create_service(vals) for vals in values]
|
services = [self._create_service(vals) for vals in values]
|
||||||
|
|
||||||
disabled_services = [services[-1]]
|
disabled_services = services[-1:]
|
||||||
non_disabled_services = services[:-1]
|
non_disabled_services = services[:-1]
|
||||||
|
up_services = services[1:3]
|
||||||
|
down_services = [services[0], services[3]]
|
||||||
expected = services[:2]
|
expected = services[:2]
|
||||||
expected_bin = services[1:3]
|
expected_bin = services[1:3]
|
||||||
compares = [
|
compares = [
|
||||||
(services, db.service_get_all(self.ctxt, {})),
|
|
||||||
(services, db.service_get_all(self.ctxt)),
|
(services, db.service_get_all(self.ctxt)),
|
||||||
(expected, db.service_get_all(self.ctxt, {'host': 'host1'})),
|
(expected, db.service_get_all(self.ctxt, host='host1')),
|
||||||
(expected_bin, db.service_get_all(self.ctxt, {'binary': 'b2'})),
|
(expected_bin, db.service_get_all(self.ctxt, binary='b2')),
|
||||||
(disabled_services, db.service_get_all(self.ctxt,
|
(disabled_services, db.service_get_all(self.ctxt, disabled=True)),
|
||||||
{'disabled': True})),
|
|
||||||
(non_disabled_services, db.service_get_all(self.ctxt,
|
(non_disabled_services, db.service_get_all(self.ctxt,
|
||||||
{'disabled': False})),
|
disabled=False)),
|
||||||
|
(up_services, db.service_get_all(self.ctxt, is_up=True)),
|
||||||
|
(down_services, db.service_get_all(self.ctxt, is_up=False)),
|
||||||
]
|
]
|
||||||
for comp in compares:
|
for comp in compares:
|
||||||
self._assertEqualListsOfObjects(*comp)
|
self._assertEqualListsOfObjects(*comp)
|
||||||
@ -215,7 +225,7 @@ class DBAPIServiceTestCase(BaseTest):
|
|||||||
]
|
]
|
||||||
services = [self._create_service(vals) for vals in values]
|
services = [self._create_service(vals) for vals in values]
|
||||||
expected = services[:3]
|
expected = services[:3]
|
||||||
real = db.service_get_all_by_topic(self.ctxt, 't1')
|
real = db.service_get_all(self.ctxt, topic='t1')
|
||||||
self._assertEqualListsOfObjects(expected, real)
|
self._assertEqualListsOfObjects(expected, real)
|
||||||
|
|
||||||
def test_service_get_all_by_binary(self):
|
def test_service_get_all_by_binary(self):
|
||||||
@ -227,7 +237,7 @@ class DBAPIServiceTestCase(BaseTest):
|
|||||||
]
|
]
|
||||||
services = [self._create_service(vals) for vals in values]
|
services = [self._create_service(vals) for vals in values]
|
||||||
expected = services[:3]
|
expected = services[:3]
|
||||||
real = db.service_get_all_by_binary(self.ctxt, 'b1')
|
real = db.service_get_all(self.ctxt, binary='b1')
|
||||||
self._assertEqualListsOfObjects(expected, real)
|
self._assertEqualListsOfObjects(expected, real)
|
||||||
|
|
||||||
def test_service_get_by_args(self):
|
def test_service_get_by_args(self):
|
||||||
@ -237,58 +247,30 @@ class DBAPIServiceTestCase(BaseTest):
|
|||||||
]
|
]
|
||||||
services = [self._create_service(vals) for vals in values]
|
services = [self._create_service(vals) for vals in values]
|
||||||
|
|
||||||
service1 = db.service_get_by_args(self.ctxt, 'host1', 'a')
|
service1 = db.service_get(self.ctxt, host='host1', binary='a')
|
||||||
self._assertEqualObjects(services[0], service1)
|
self._assertEqualObjects(services[0], service1)
|
||||||
|
|
||||||
service2 = db.service_get_by_args(self.ctxt, 'host2', 'b')
|
service2 = db.service_get(self.ctxt, host='host2', binary='b')
|
||||||
self._assertEqualObjects(services[1], service2)
|
self._assertEqualObjects(services[1], service2)
|
||||||
|
|
||||||
def test_service_get_by_args_not_found_exception(self):
|
def test_service_get_by_args_not_found_exception(self):
|
||||||
self.assertRaises(exception.ServiceNotFound,
|
self.assertRaises(exception.ServiceNotFound,
|
||||||
db.service_get_by_args,
|
db.service_get,
|
||||||
self.ctxt, 'non-exists-host', 'a')
|
self.ctxt, host='non-exists-host', binary='a')
|
||||||
|
|
||||||
@mock.patch('cinder.db.sqlalchemy.api.model_query')
|
@mock.patch('sqlalchemy.orm.query.Query.filter_by')
|
||||||
def test_service_get_by_args_with_case_insensitive(self, model_query):
|
def test_service_get_by_args_with_case_insensitive(self, filter_by):
|
||||||
class case_insensitive_filter(object):
|
CONF.set_default('connection', 'mysql://', 'database')
|
||||||
def __init__(self, records):
|
db.service_get(self.ctxt, host='host', binary='a')
|
||||||
self.records = records
|
|
||||||
|
|
||||||
def filter_by(self, **kwargs):
|
self.assertNotEqual(0, filter_by.call_count)
|
||||||
ret = mock.Mock()
|
self.assertEqual(1, filter_by.return_value.filter.call_count)
|
||||||
ret.all = mock.Mock()
|
or_op = filter_by.return_value.filter.call_args[0][0].clauses[0]
|
||||||
|
self.assertIsInstance(or_op,
|
||||||
results = []
|
sqlalchemy_api.sql.elements.BinaryExpression)
|
||||||
for record in self.records:
|
binary_op = or_op.right
|
||||||
for key, value in kwargs.items():
|
self.assertIsInstance(binary_op, sqlalchemy_api.sql.functions.Function)
|
||||||
if record[key].lower() != value.lower():
|
self.assertEqual('binary', binary_op.name)
|
||||||
break
|
|
||||||
else:
|
|
||||||
results.append(record)
|
|
||||||
|
|
||||||
ret.filter_by = case_insensitive_filter(results).filter_by
|
|
||||||
ret.all.return_value = results
|
|
||||||
return ret
|
|
||||||
|
|
||||||
values = [
|
|
||||||
{'host': 'host', 'binary': 'a'},
|
|
||||||
{'host': 'HOST', 'binary': 'a'}
|
|
||||||
]
|
|
||||||
services = [self._create_service(vals) for vals in values]
|
|
||||||
|
|
||||||
query = mock.Mock()
|
|
||||||
query.filter_by = case_insensitive_filter(services).filter_by
|
|
||||||
model_query.return_value = query
|
|
||||||
|
|
||||||
service1 = db.service_get_by_args(self.ctxt, 'host', 'a')
|
|
||||||
self._assertEqualObjects(services[0], service1)
|
|
||||||
|
|
||||||
service2 = db.service_get_by_args(self.ctxt, 'HOST', 'a')
|
|
||||||
self._assertEqualObjects(services[1], service2)
|
|
||||||
|
|
||||||
self.assertRaises(exception.ServiceNotFound,
|
|
||||||
db.service_get_by_args,
|
|
||||||
self.ctxt, 'Host', 'a')
|
|
||||||
|
|
||||||
|
|
||||||
class DBAPIVolumeTestCase(BaseTest):
|
class DBAPIVolumeTestCase(BaseTest):
|
||||||
|
@ -128,6 +128,12 @@ class ServiceTestCase(test.TestCase):
|
|||||||
self.host = 'foo'
|
self.host = 'foo'
|
||||||
self.binary = 'cinder-fake'
|
self.binary = 'cinder-fake'
|
||||||
self.topic = 'fake'
|
self.topic = 'fake'
|
||||||
|
self.service_ref = {'host': self.host,
|
||||||
|
'binary': self.binary,
|
||||||
|
'topic': self.topic,
|
||||||
|
'report_count': 0,
|
||||||
|
'availability_zone': 'nova',
|
||||||
|
'id': 1}
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
# NOTE(vish): Create was moved out of mock replay to make sure that
|
# NOTE(vish): Create was moved out of mock replay to make sure that
|
||||||
@ -143,17 +149,13 @@ class ServiceTestCase(test.TestCase):
|
|||||||
# Check that the entry has been really created in the DB
|
# Check that the entry has been really created in the DB
|
||||||
objects.Service.get_by_id(context.get_admin_context(), app.service_id)
|
objects.Service.get_by_id(context.get_admin_context(), app.service_id)
|
||||||
|
|
||||||
def test_report_state_newly_disconnected(self):
|
@mock.patch.object(objects.service.Service, 'get_by_args')
|
||||||
service_ref = {'host': self.host,
|
@mock.patch.object(objects.service.Service, 'get_by_id')
|
||||||
'binary': self.binary,
|
def test_report_state_newly_disconnected(self, get_by_id, get_by_args):
|
||||||
'topic': self.topic,
|
get_by_args.side_effect = exception.NotFound()
|
||||||
'report_count': 0,
|
get_by_id.side_effect = db_exc.DBConnectionError()
|
||||||
'availability_zone': 'nova',
|
|
||||||
'id': 1}
|
|
||||||
with mock.patch.object(objects.service, 'db') as mock_db:
|
with mock.patch.object(objects.service, 'db') as mock_db:
|
||||||
mock_db.service_get_by_args.side_effect = exception.NotFound()
|
mock_db.service_create.return_value = self.service_ref
|
||||||
mock_db.service_create.return_value = service_ref
|
|
||||||
mock_db.service_get.side_effect = db_exc.DBConnectionError()
|
|
||||||
|
|
||||||
serv = service.Service(
|
serv = service.Service(
|
||||||
self.host,
|
self.host,
|
||||||
@ -166,17 +168,13 @@ class ServiceTestCase(test.TestCase):
|
|||||||
self.assertTrue(serv.model_disconnected)
|
self.assertTrue(serv.model_disconnected)
|
||||||
self.assertFalse(mock_db.service_update.called)
|
self.assertFalse(mock_db.service_update.called)
|
||||||
|
|
||||||
def test_report_state_disconnected_DBError(self):
|
@mock.patch.object(objects.service.Service, 'get_by_args')
|
||||||
service_ref = {'host': self.host,
|
@mock.patch.object(objects.service.Service, 'get_by_id')
|
||||||
'binary': self.binary,
|
def test_report_state_disconnected_DBError(self, get_by_id, get_by_args):
|
||||||
'topic': self.topic,
|
get_by_args.side_effect = exception.NotFound()
|
||||||
'report_count': 0,
|
get_by_id.side_effect = db_exc.DBError()
|
||||||
'availability_zone': 'nova',
|
|
||||||
'id': 1}
|
|
||||||
with mock.patch.object(objects.service, 'db') as mock_db:
|
with mock.patch.object(objects.service, 'db') as mock_db:
|
||||||
mock_db.service_get_by_args.side_effect = exception.NotFound()
|
mock_db.service_create.return_value = self.service_ref
|
||||||
mock_db.service_create.return_value = service_ref
|
|
||||||
mock_db.service_get.side_effect = db_exc.DBError()
|
|
||||||
|
|
||||||
serv = service.Service(
|
serv = service.Service(
|
||||||
self.host,
|
self.host,
|
||||||
@ -189,41 +187,27 @@ class ServiceTestCase(test.TestCase):
|
|||||||
self.assertTrue(serv.model_disconnected)
|
self.assertTrue(serv.model_disconnected)
|
||||||
self.assertFalse(mock_db.service_update.called)
|
self.assertFalse(mock_db.service_update.called)
|
||||||
|
|
||||||
def test_report_state_newly_connected(self):
|
@mock.patch('cinder.db.sqlalchemy.api.service_update')
|
||||||
service_ref = {'host': self.host,
|
@mock.patch('cinder.db.sqlalchemy.api.service_get')
|
||||||
'binary': self.binary,
|
def test_report_state_newly_connected(self, get_by_id, service_update):
|
||||||
'topic': self.topic,
|
get_by_id.return_value = self.service_ref
|
||||||
'report_count': 0,
|
|
||||||
'availability_zone': 'nova',
|
|
||||||
'id': 1}
|
|
||||||
with mock.patch.object(objects.service, 'db') as mock_db,\
|
|
||||||
mock.patch('cinder.db.sqlalchemy.api.get_by_id') as get_by_id:
|
|
||||||
mock_db.service_get_by_args.side_effect = exception.NotFound()
|
|
||||||
mock_db.service_create.return_value = service_ref
|
|
||||||
get_by_id.return_value = service_ref
|
|
||||||
|
|
||||||
serv = service.Service(
|
serv = service.Service(
|
||||||
self.host,
|
self.host,
|
||||||
self.binary,
|
self.binary,
|
||||||
self.topic,
|
self.topic,
|
||||||
'cinder.tests.unit.test_service.FakeManager'
|
'cinder.tests.unit.test_service.FakeManager'
|
||||||
)
|
)
|
||||||
serv.start()
|
serv.start()
|
||||||
serv.model_disconnected = True
|
serv.model_disconnected = True
|
||||||
serv.report_state()
|
serv.report_state()
|
||||||
|
|
||||||
self.assertFalse(serv.model_disconnected)
|
self.assertFalse(serv.model_disconnected)
|
||||||
self.assertTrue(mock_db.service_update.called)
|
self.assertTrue(service_update.called)
|
||||||
|
|
||||||
def test_report_state_manager_not_working(self):
|
def test_report_state_manager_not_working(self):
|
||||||
service_ref = {'host': self.host,
|
|
||||||
'binary': self.binary,
|
|
||||||
'topic': self.topic,
|
|
||||||
'report_count': 0,
|
|
||||||
'availability_zone': 'nova',
|
|
||||||
'id': 1}
|
|
||||||
with mock.patch('cinder.db') as mock_db:
|
with mock.patch('cinder.db') as mock_db:
|
||||||
mock_db.service_get.return_value = service_ref
|
mock_db.service_get.return_value = self.service_ref
|
||||||
|
|
||||||
serv = service.Service(
|
serv = service.Service(
|
||||||
self.host,
|
self.host,
|
||||||
|
@ -240,105 +240,71 @@ class BaseVolumeTestCase(test.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class AvailabilityZoneTestCase(BaseVolumeTestCase):
|
class AvailabilityZoneTestCase(BaseVolumeTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(AvailabilityZoneTestCase, self).setUp()
|
||||||
|
self.get_all = self.patch(
|
||||||
|
'cinder.db.service_get_all', autospec=True,
|
||||||
|
return_value = [{'availability_zone': 'a', 'disabled': False}])
|
||||||
|
|
||||||
def test_list_availability_zones_cached(self):
|
def test_list_availability_zones_cached(self):
|
||||||
volume_api = cinder.volume.api.API()
|
azs = self.volume_api.list_availability_zones(enable_cache=True)
|
||||||
with mock.patch.object(volume_api.db,
|
self.assertEqual([{"name": 'a', 'available': True}], list(azs))
|
||||||
'service_get_all_by_topic') as get_all:
|
self.assertIsNotNone(self.volume_api.availability_zones_last_fetched)
|
||||||
get_all.return_value = [
|
self.assertTrue(self.get_all.called)
|
||||||
{
|
self.volume_api.list_availability_zones(enable_cache=True)
|
||||||
'availability_zone': 'a',
|
self.assertEqual(1, self.get_all.call_count)
|
||||||
'disabled': False,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
azs = volume_api.list_availability_zones(enable_cache=True)
|
|
||||||
self.assertEqual([{"name": 'a', 'available': True}], list(azs))
|
|
||||||
self.assertIsNotNone(volume_api.availability_zones_last_fetched)
|
|
||||||
self.assertTrue(get_all.called)
|
|
||||||
volume_api.list_availability_zones(enable_cache=True)
|
|
||||||
self.assertEqual(1, get_all.call_count)
|
|
||||||
|
|
||||||
def test_list_availability_zones_no_cached(self):
|
def test_list_availability_zones_no_cached(self):
|
||||||
volume_api = cinder.volume.api.API()
|
azs = self.volume_api.list_availability_zones(enable_cache=False)
|
||||||
with mock.patch.object(volume_api.db,
|
self.assertEqual([{"name": 'a', 'available': True}], list(azs))
|
||||||
'service_get_all_by_topic') as get_all:
|
self.assertIsNone(self.volume_api.availability_zones_last_fetched)
|
||||||
get_all.return_value = [
|
|
||||||
{
|
|
||||||
'availability_zone': 'a',
|
|
||||||
'disabled': False,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
azs = volume_api.list_availability_zones(enable_cache=False)
|
|
||||||
self.assertEqual([{"name": 'a', 'available': True}], list(azs))
|
|
||||||
self.assertIsNone(volume_api.availability_zones_last_fetched)
|
|
||||||
|
|
||||||
with mock.patch.object(volume_api.db,
|
self.get_all.return_value[0]['disabled'] = True
|
||||||
'service_get_all_by_topic') as get_all:
|
azs = self.volume_api.list_availability_zones(enable_cache=False)
|
||||||
get_all.return_value = [
|
self.assertEqual([{"name": 'a', 'available': False}], list(azs))
|
||||||
{
|
self.assertIsNone(self.volume_api.availability_zones_last_fetched)
|
||||||
'availability_zone': 'a',
|
|
||||||
'disabled': True,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
azs = volume_api.list_availability_zones(enable_cache=False)
|
|
||||||
self.assertEqual([{"name": 'a', 'available': False}], list(azs))
|
|
||||||
self.assertIsNone(volume_api.availability_zones_last_fetched)
|
|
||||||
|
|
||||||
def test_list_availability_zones_refetched(self):
|
def test_list_availability_zones_refetched(self):
|
||||||
timeutils.set_time_override()
|
timeutils.set_time_override()
|
||||||
self.addCleanup(timeutils.clear_time_override)
|
self.addCleanup(timeutils.clear_time_override)
|
||||||
volume_api = cinder.volume.api.API()
|
azs = self.volume_api.list_availability_zones(enable_cache=True)
|
||||||
with mock.patch.object(volume_api.db,
|
self.assertEqual([{"name": 'a', 'available': True}], list(azs))
|
||||||
'service_get_all_by_topic') as get_all:
|
self.assertIsNotNone(self.volume_api.availability_zones_last_fetched)
|
||||||
get_all.return_value = [
|
last_fetched = self.volume_api.availability_zones_last_fetched
|
||||||
{
|
self.assertTrue(self.get_all.called)
|
||||||
'availability_zone': 'a',
|
self.volume_api.list_availability_zones(enable_cache=True)
|
||||||
'disabled': False,
|
self.assertEqual(1, self.get_all.call_count)
|
||||||
},
|
|
||||||
]
|
|
||||||
azs = volume_api.list_availability_zones(enable_cache=True)
|
|
||||||
self.assertEqual([{"name": 'a', 'available': True}], list(azs))
|
|
||||||
self.assertIsNotNone(volume_api.availability_zones_last_fetched)
|
|
||||||
last_fetched = volume_api.availability_zones_last_fetched
|
|
||||||
self.assertTrue(get_all.called)
|
|
||||||
volume_api.list_availability_zones(enable_cache=True)
|
|
||||||
self.assertEqual(1, get_all.call_count)
|
|
||||||
|
|
||||||
# The default cache time is 3600, push past that...
|
# The default cache time is 3600, push past that...
|
||||||
timeutils.advance_time_seconds(3800)
|
timeutils.advance_time_seconds(3800)
|
||||||
get_all.return_value = [
|
self.get_all.return_value = [
|
||||||
{
|
{
|
||||||
'availability_zone': 'a',
|
'availability_zone': 'a',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'availability_zone': 'b',
|
'availability_zone': 'b',
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
azs = volume_api.list_availability_zones(enable_cache=True)
|
azs = self.volume_api.list_availability_zones(enable_cache=True)
|
||||||
azs = sorted([n['name'] for n in azs])
|
azs = sorted([n['name'] for n in azs])
|
||||||
self.assertEqual(['a', 'b'], azs)
|
self.assertEqual(['a', 'b'], azs)
|
||||||
self.assertEqual(2, get_all.call_count)
|
self.assertEqual(2, self.get_all.call_count)
|
||||||
self.assertGreater(volume_api.availability_zones_last_fetched,
|
self.assertGreater(self.volume_api.availability_zones_last_fetched,
|
||||||
last_fetched)
|
last_fetched)
|
||||||
|
|
||||||
def test_list_availability_zones_enabled_service(self):
|
def test_list_availability_zones_enabled_service(self):
|
||||||
services = [
|
def sort_func(obj):
|
||||||
|
return obj['name']
|
||||||
|
|
||||||
|
self.get_all.return_value = [
|
||||||
{'availability_zone': 'ping', 'disabled': 0},
|
{'availability_zone': 'ping', 'disabled': 0},
|
||||||
{'availability_zone': 'ping', 'disabled': 1},
|
{'availability_zone': 'ping', 'disabled': 1},
|
||||||
{'availability_zone': 'pong', 'disabled': 0},
|
{'availability_zone': 'pong', 'disabled': 0},
|
||||||
{'availability_zone': 'pung', 'disabled': 1},
|
{'availability_zone': 'pung', 'disabled': 1},
|
||||||
]
|
]
|
||||||
|
|
||||||
def stub_service_get_all_by_topic(*args, **kwargs):
|
|
||||||
return services
|
|
||||||
|
|
||||||
self.stubs.Set(db, 'service_get_all_by_topic',
|
|
||||||
stub_service_get_all_by_topic)
|
|
||||||
|
|
||||||
def sort_func(obj):
|
|
||||||
return obj['name']
|
|
||||||
|
|
||||||
volume_api = cinder.volume.api.API()
|
volume_api = cinder.volume.api.API()
|
||||||
azs = volume_api.list_availability_zones()
|
azs = volume_api.list_availability_zones()
|
||||||
azs = sorted(azs, key=sort_func)
|
azs = sorted(azs, key=sort_func)
|
||||||
@ -1493,8 +1459,7 @@ class VolumeTestCase(BaseVolumeTestCase):
|
|||||||
snapshot_obj = fake_snapshot.fake_snapshot_obj(self.context,
|
snapshot_obj = fake_snapshot.fake_snapshot_obj(self.context,
|
||||||
**snapshot)
|
**snapshot)
|
||||||
|
|
||||||
with mock.patch.object(db,
|
with mock.patch('cinder.db.service_get_all') as mock_get_service, \
|
||||||
'service_get_all_by_topic') as mock_get_service, \
|
|
||||||
mock.patch.object(volume_api,
|
mock.patch.object(volume_api,
|
||||||
'list_availability_zones') as mock_get_azs:
|
'list_availability_zones') as mock_get_azs:
|
||||||
mock_get_service.return_value = [{'host': 'foo'}]
|
mock_get_service.return_value = [{'host': 'foo'}]
|
||||||
@ -5356,7 +5321,7 @@ class ReplicationTestCase(BaseVolumeTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volume_rpcapi.VolumeAPI, 'failover_host')
|
@mock.patch.object(volume_rpcapi.VolumeAPI, 'failover_host')
|
||||||
@mock.patch.object(cinder.db, 'conditional_update')
|
@mock.patch.object(cinder.db, 'conditional_update')
|
||||||
@mock.patch.object(cinder.db, 'service_get_by_args')
|
@mock.patch.object(cinder.db, 'service_get')
|
||||||
def test_failover_host(self, mock_db_args, mock_db_update,
|
def test_failover_host(self, mock_db_args, mock_db_update,
|
||||||
mock_failover):
|
mock_failover):
|
||||||
"""Test replication failover_host."""
|
"""Test replication failover_host."""
|
||||||
@ -5371,7 +5336,7 @@ class ReplicationTestCase(BaseVolumeTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volume_rpcapi.VolumeAPI, 'failover_host')
|
@mock.patch.object(volume_rpcapi.VolumeAPI, 'failover_host')
|
||||||
@mock.patch.object(cinder.db, 'conditional_update')
|
@mock.patch.object(cinder.db, 'conditional_update')
|
||||||
@mock.patch.object(cinder.db, 'service_get_by_args')
|
@mock.patch.object(cinder.db, 'service_get')
|
||||||
def test_failover_host_unexpected_status(self, mock_db_args,
|
def test_failover_host_unexpected_status(self, mock_db_args,
|
||||||
mock_db_update,
|
mock_db_update,
|
||||||
mock_failover):
|
mock_failover):
|
||||||
@ -5389,7 +5354,7 @@ class ReplicationTestCase(BaseVolumeTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volume_rpcapi.VolumeAPI, 'freeze_host')
|
@mock.patch.object(volume_rpcapi.VolumeAPI, 'freeze_host')
|
||||||
@mock.patch.object(cinder.db, 'conditional_update')
|
@mock.patch.object(cinder.db, 'conditional_update')
|
||||||
@mock.patch.object(cinder.db, 'service_get_by_args')
|
@mock.patch.object(cinder.db, 'service_get')
|
||||||
def test_freeze_host(self, mock_db_args, mock_db_update,
|
def test_freeze_host(self, mock_db_args, mock_db_update,
|
||||||
mock_freeze):
|
mock_freeze):
|
||||||
"""Test replication freeze_host."""
|
"""Test replication freeze_host."""
|
||||||
@ -5404,7 +5369,7 @@ class ReplicationTestCase(BaseVolumeTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volume_rpcapi.VolumeAPI, 'freeze_host')
|
@mock.patch.object(volume_rpcapi.VolumeAPI, 'freeze_host')
|
||||||
@mock.patch.object(cinder.db, 'conditional_update')
|
@mock.patch.object(cinder.db, 'conditional_update')
|
||||||
@mock.patch.object(cinder.db, 'service_get_by_args')
|
@mock.patch.object(cinder.db, 'service_get')
|
||||||
def test_freeze_host_unexpected_status(self, mock_db_args,
|
def test_freeze_host_unexpected_status(self, mock_db_args,
|
||||||
mock_db_update,
|
mock_db_update,
|
||||||
mock_freeze):
|
mock_freeze):
|
||||||
@ -5422,7 +5387,7 @@ class ReplicationTestCase(BaseVolumeTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volume_rpcapi.VolumeAPI, 'thaw_host')
|
@mock.patch.object(volume_rpcapi.VolumeAPI, 'thaw_host')
|
||||||
@mock.patch.object(cinder.db, 'conditional_update')
|
@mock.patch.object(cinder.db, 'conditional_update')
|
||||||
@mock.patch.object(cinder.db, 'service_get_by_args')
|
@mock.patch.object(cinder.db, 'service_get')
|
||||||
def test_thaw_host(self, mock_db_args, mock_db_update,
|
def test_thaw_host(self, mock_db_args, mock_db_update,
|
||||||
mock_thaw):
|
mock_thaw):
|
||||||
"""Test replication thaw_host."""
|
"""Test replication thaw_host."""
|
||||||
@ -5438,7 +5403,7 @@ class ReplicationTestCase(BaseVolumeTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volume_rpcapi.VolumeAPI, 'thaw_host')
|
@mock.patch.object(volume_rpcapi.VolumeAPI, 'thaw_host')
|
||||||
@mock.patch.object(cinder.db, 'conditional_update')
|
@mock.patch.object(cinder.db, 'conditional_update')
|
||||||
@mock.patch.object(cinder.db, 'service_get_by_args')
|
@mock.patch.object(cinder.db, 'service_get')
|
||||||
def test_thaw_host_unexpected_status(self, mock_db_args,
|
def test_thaw_host_unexpected_status(self, mock_db_args,
|
||||||
mock_db_update,
|
mock_db_update,
|
||||||
mock_thaw):
|
mock_thaw):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user