Merge "Added EfficacyIndicator model in DB"

This commit is contained in:
Jenkins
2016-06-15 08:59:41 +00:00
committed by Gerrit Code Review
8 changed files with 669 additions and 21 deletions

View File

@@ -248,6 +248,14 @@ class ActionFilterCombinationProhibited(Invalid):
"prohibited") "prohibited")
class EfficacyIndicatorNotFound(ResourceNotFound):
msg_fmt = _("Efficacy indicator %(efficacy_indicator)s could not be found")
class EfficacyIndicatorAlreadyExists(Conflict):
msg_fmt = _("An action with UUID %(uuid)s already exists")
class HTTPNotFound(ResourceNotFound): class HTTPNotFound(ResourceNotFound):
pass pass

View File

@@ -560,3 +560,93 @@ class BaseConnection(object):
:raises: :py:class:`~.ActionPlanReferenced` :raises: :py:class:`~.ActionPlanReferenced`
:raises: :py:class:`~.Invalid` :raises: :py:class:`~.Invalid`
""" """
@abc.abstractmethod
def get_efficacy_indicator_list(self, context, filters=None, limit=None,
marker=None, sort_key=None, sort_dir=None):
"""Get specific columns for matching efficacy indicators.
Return a list of the specified columns for all efficacy indicators that
match the specified filters.
:param context: The security context
:param columns: List of column names to return.
Defaults to 'id' column when columns == None.
:param filters: Filters to apply. Defaults to None.
:param limit: Maximum number of efficacy indicators to return.
:param marker: The last item of the previous page; we return the next
result set.
:param sort_key: Attribute by which results should be sorted.
:param sort_dir: Direction in which results should be sorted.
(asc, desc)
:returns: A list of tuples of the specified columns.
"""
@abc.abstractmethod
def create_efficacy_indicator(self, values):
"""Create a new efficacy indicator.
:param values: A dict containing items used to identify
and track the efficacy indicator. For example:
::
{
'id': 1,
'uuid': utils.generate_uuid(),
'name': 'my_efficacy_indicator',
'display_name': 'My efficacy indicator',
'goal_uuid': utils.generate_uuid(),
}
:returns: An efficacy_indicator
:raises: :py:class:`~.EfficacyIndicatorAlreadyExists`
"""
@abc.abstractmethod
def get_efficacy_indicator_by_id(self, context, efficacy_indicator_id):
"""Return an efficacy indicator given its ID.
:param context: The security context
:param efficacy_indicator_id: The ID of an efficacy indicator
:returns: An efficacy indicator
:raises: :py:class:`~.EfficacyIndicatorNotFound`
"""
@abc.abstractmethod
def get_efficacy_indicator_by_uuid(self, context, efficacy_indicator_uuid):
"""Return an efficacy indicator given its UUID.
:param context: The security context
:param efficacy_indicator_uuid: The UUID of an efficacy indicator
:returns: An efficacy indicator
:raises: :py:class:`~.EfficacyIndicatorNotFound`
"""
@abc.abstractmethod
def get_efficacy_indicator_by_name(self, context, efficacy_indicator_name):
"""Return an efficacy indicator given its name.
:param context: The security context
:param efficacy_indicator_name: The name of an efficacy indicator
:returns: An efficacy indicator
:raises: :py:class:`~.EfficacyIndicatorNotFound`
"""
@abc.abstractmethod
def destroy_efficacy_indicator(self, efficacy_indicator_uuid):
"""Destroy an efficacy indicator.
:param efficacy_indicator_uuid: The UUID of an efficacy indicator
:raises: :py:class:`~.EfficacyIndicatorNotFound`
"""
@abc.abstractmethod
def update_efficacy_indicator(self, efficacy_indicator_uuid, values):
"""Update properties of an efficacy indicator.
:param efficacy_indicator_uuid: The UUID of an efficacy indicator
:returns: An efficacy indicator
:raises: :py:class:`~.EfficacyIndicatorNotFound`
:raises: :py:class:`~.Invalid`
"""

View File

@@ -17,6 +17,8 @@
"""SQLAlchemy storage backend.""" """SQLAlchemy storage backend."""
import collections
from oslo_config import cfg from oslo_config import cfg
from oslo_db import exception as db_exc from oslo_db import exception as db_exc
from oslo_db.sqlalchemy import session as db_session from oslo_db.sqlalchemy import session as db_session
@@ -102,6 +104,14 @@ def _paginate_query(model, limit=None, marker=None, sort_key=None,
return query.all() return query.all()
class JoinMap(utils.Struct):
"""Mapping for the Join-based queries"""
NaturalJoinFilter = collections.namedtuple(
'NaturalJoinFilter', ['join_fieldname', 'join_model'])
class Connection(api.BaseConnection): class Connection(api.BaseConnection):
"""SqlAlchemy connection.""" """SqlAlchemy connection."""
@@ -185,9 +195,11 @@ class Connection(api.BaseConnection):
def __add_simple_filter(self, query, model, fieldname, value): def __add_simple_filter(self, query, model, fieldname, value):
return query.filter(getattr(model, fieldname) == value) return query.filter(getattr(model, fieldname) == value)
def __add_join_filter(self, query, model, join_model, fieldname, value): def __add_natural_join_filter(self, query, join_model,
join_fieldname, value):
query = query.join(join_model) query = query.join(join_model)
return self.__add_simple_filter(query, join_model, fieldname, value) return self.__add_simple_filter(
query, join_model, join_fieldname, value)
def _add_filters(self, query, model, filters=None, def _add_filters(self, query, model, filters=None,
plain_fields=None, join_fieldmap=None): plain_fields=None, join_fieldmap=None):
@@ -198,20 +210,19 @@ class Connection(api.BaseConnection):
:param filters: dict with the following structure {"fieldname": value} :param filters: dict with the following structure {"fieldname": value}
:param plain_fields: a :py:class:`sqlalchemy.orm.query.Query` instance :param plain_fields: a :py:class:`sqlalchemy.orm.query.Query` instance
:param join_fieldmap: a :py:class:`sqlalchemy.orm.query.Query` instance :param join_fieldmap: a :py:class:`sqlalchemy.orm.query.Query` instance
""" """
filters = filters or {} filters = filters or {}
plain_fields = plain_fields or () plain_fields = plain_fields or ()
join_fieldmap = join_fieldmap or {} join_fieldmap = join_fieldmap or JoinMap()
for fieldname, value in filters.items(): for fieldname, value in filters.items():
if fieldname in plain_fields: if fieldname in plain_fields:
query = self.__add_simple_filter( query = self.__add_simple_filter(
query, model, fieldname, value) query, model, fieldname, value)
elif fieldname in join_fieldmap: elif fieldname in join_fieldmap:
join_field, join_model = join_fieldmap[fieldname] join_fieldname, join_model = join_fieldmap[fieldname]
query = self.__add_join_filter( query = self.__add_natural_join_filter(
query, model, join_model, join_field, value) query, join_model, join_fieldname, value)
query = self.__add_soft_delete_mixin_filters(query, filters, model) query = self.__add_soft_delete_mixin_filters(query, filters, model)
query = self.__add_timestamp_mixin_filters(query, filters, model) query = self.__add_timestamp_mixin_filters(query, filters, model)
@@ -281,11 +292,11 @@ class Connection(api.BaseConnection):
def _add_strategies_filters(self, query, filters): def _add_strategies_filters(self, query, filters):
plain_fields = ['uuid', 'name', 'display_name', 'goal_id'] plain_fields = ['uuid', 'name', 'display_name', 'goal_id']
join_fieldmap = { join_fieldmap = JoinMap(
'goal_uuid': ("uuid", models.Goal), goal_uuid=NaturalJoinFilter(
'goal_name': ("name", models.Goal) join_fieldname="uuid", join_model=models.Goal),
} goal_name=NaturalJoinFilter(
join_fieldname="name", join_model=models.Goal))
return self._add_filters( return self._add_filters(
query=query, model=models.Strategy, filters=filters, query=query, model=models.Strategy, filters=filters,
plain_fields=plain_fields, join_fieldmap=join_fieldmap) plain_fields=plain_fields, join_fieldmap=join_fieldmap)
@@ -296,12 +307,16 @@ class Connection(api.BaseConnection):
plain_fields = ['uuid', 'name', 'host_aggregate', plain_fields = ['uuid', 'name', 'host_aggregate',
'goal_id', 'strategy_id'] 'goal_id', 'strategy_id']
join_fieldmap = { join_fieldmap = JoinMap(
'goal_uuid': ("uuid", models.Goal), goal_uuid=NaturalJoinFilter(
'goal_name': ("name", models.Goal), join_fieldname="uuid", join_model=models.Goal),
'strategy_uuid': ("uuid", models.Strategy), goal_name=NaturalJoinFilter(
'strategy_name': ("name", models.Strategy), join_fieldname="name", join_model=models.Goal),
} strategy_uuid=NaturalJoinFilter(
join_fieldname="uuid", join_model=models.Strategy),
strategy_name=NaturalJoinFilter(
join_fieldname="name", join_model=models.Strategy),
)
return self._add_filters( return self._add_filters(
query=query, model=models.AuditTemplate, filters=filters, query=query, model=models.AuditTemplate, filters=filters,
@@ -394,6 +409,20 @@ class Connection(api.BaseConnection):
return query return query
def _add_efficacy_indicators_filters(self, query, filters):
if filters is None:
filters = {}
plain_fields = ['uuid', 'name', 'unit', 'schema', 'action_plan_id']
join_fieldmap = JoinMap(
action_plan_uuid=NaturalJoinFilter(
join_fieldname="uuid", join_model=models.ActionPlan),
)
return self._add_filters(
query=query, model=models.EfficacyIndicator, filters=filters,
plain_fields=plain_fields, join_fieldmap=join_fieldmap)
# ### GOALS ### # # ### GOALS ### #
def get_goal_list(self, context, filters=None, limit=None, def get_goal_list(self, context, filters=None, limit=None,
@@ -923,3 +952,76 @@ class Connection(api.BaseConnection):
raise exception.ActionPlanNotFound(action_plan=action_plan_id) raise exception.ActionPlanNotFound(action_plan=action_plan_id)
query.soft_delete() query.soft_delete()
# ### EFFICACY INDICATORS ### #
def get_efficacy_indicator_list(self, context, filters=None, limit=None,
marker=None, sort_key=None, sort_dir=None):
query = model_query(models.EfficacyIndicator)
query = self._add_efficacy_indicators_filters(query, filters)
if not context.show_deleted:
query = query.filter_by(deleted_at=None)
return _paginate_query(models.EfficacyIndicator, limit, marker,
sort_key, sort_dir, query)
def create_efficacy_indicator(self, values):
# ensure defaults are present for new efficacy indicators
if not values.get('uuid'):
values['uuid'] = utils.generate_uuid()
efficacy_indicator = models.EfficacyIndicator()
efficacy_indicator.update(values)
try:
efficacy_indicator.save()
except db_exc.DBDuplicateEntry:
raise exception.EfficacyIndicatorAlreadyExists(uuid=values['uuid'])
return efficacy_indicator
def _get_efficacy_indicator(self, context, fieldname, value):
try:
return self._get(context, model=models.EfficacyIndicator,
fieldname=fieldname, value=value)
except exception.ResourceNotFound:
raise exception.EfficacyIndicatorNotFound(efficacy_indicator=value)
def get_efficacy_indicator_by_id(self, context, efficacy_indicator_id):
return self._get_efficacy_indicator(
context, fieldname="id", value=efficacy_indicator_id)
def get_efficacy_indicator_by_uuid(self, context, efficacy_indicator_uuid):
return self._get_efficacy_indicator(
context, fieldname="uuid", value=efficacy_indicator_uuid)
def get_efficacy_indicator_by_name(self, context, efficacy_indicator_name):
return self._get_efficacy_indicator(
context, fieldname="name", value=efficacy_indicator_name)
def update_efficacy_indicator(self, efficacy_indicator_id, values):
if 'uuid' in values:
raise exception.Invalid(
message=_("Cannot overwrite UUID for an existing "
"efficacy indicator."))
try:
return self._update(
models.EfficacyIndicator, efficacy_indicator_id, values)
except exception.ResourceNotFound:
raise exception.EfficacyIndicatorNotFound(
efficacy_indicator=efficacy_indicator_id)
def soft_delete_efficacy_indicator(self, efficacy_indicator_id):
try:
self._soft_delete(models.EfficacyIndicator, efficacy_indicator_id)
except exception.ResourceNotFound:
raise exception.EfficacyIndicatorNotFound(
efficacy_indicator=efficacy_indicator_id)
def destroy_efficacy_indicator(self, efficacy_indicator_id):
try:
return self._destroy(
models.EfficacyIndicator, efficacy_indicator_id)
except exception.ResourceNotFound:
raise exception.EfficacyIndicatorNotFound(
efficacy_indicator=efficacy_indicator_id)

View File

@@ -27,6 +27,7 @@ from sqlalchemy import DateTime
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy import Integer from sqlalchemy import Integer
from sqlalchemy import Numeric
from sqlalchemy import schema from sqlalchemy import schema
from sqlalchemy import String from sqlalchemy import String
from sqlalchemy.types import TypeDecorator, TEXT from sqlalchemy.types import TypeDecorator, TEXT
@@ -205,6 +206,24 @@ class ActionPlan(Base):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
uuid = Column(String(36)) uuid = Column(String(36))
first_action_id = Column(Integer) first_action_id = Column(Integer)
audit_id = Column(Integer, ForeignKey('audits.id'), audit_id = Column(Integer, ForeignKey('audits.id'), nullable=True)
nullable=True)
state = Column(String(20), nullable=True) state = Column(String(20), nullable=True)
global_efficacy = Column(JSONEncodedDict, nullable=True)
class EfficacyIndicator(Base):
"""Represents an efficacy indicator."""
__tablename__ = 'efficacy_indicators'
__table_args__ = (
schema.UniqueConstraint('uuid', name='uniq_efficacy_indicators0uuid'),
table_args()
)
id = Column(Integer, primary_key=True)
uuid = Column(String(36))
name = Column(String(63))
description = Column(String(255), nullable=True)
unit = Column(String(63), nullable=True)
value = Column(Numeric())
action_plan_id = Column(Integer, ForeignKey('action_plans.id'),
nullable=False)

View File

@@ -46,6 +46,15 @@ def datetime_or_str_or_none(val):
return datetime_or_none(val) return datetime_or_none(val)
def numeric_or_none(val):
"""Attempt to parse an integer value, or None."""
if val is None:
return val
else:
f_val = float(val)
return f_val if not f_val.is_integer() else val
def int_or_none(val): def int_or_none(val):
"""Attempt to parse an integer value, or None.""" """Attempt to parse an integer value, or None."""
if val is None: if val is None:

View File

@@ -0,0 +1,385 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Tests for manipulating EfficacyIndicator via the DB API"""
import freezegun
import six
from watcher.common import exception
from watcher.common import utils as w_utils
from watcher.tests.db import base
from watcher.tests.db import utils
class TestDbEfficacyIndicatorFilters(base.DbTestCase):
FAKE_OLDER_DATE = '2014-01-01T09:52:05.219414'
FAKE_OLD_DATE = '2015-01-01T09:52:05.219414'
FAKE_TODAY = '2016-02-24T09:52:05.219414'
def setUp(self):
super(TestDbEfficacyIndicatorFilters, self).setUp()
self.context.show_deleted = True
self._data_setup()
def _data_setup(self):
self.audit_template_name = "Audit Template"
self.audit_template = utils.create_test_audit_template(
name=self.audit_template_name, id=1, uuid=None)
self.audit = utils.create_test_audit(
audit_template_id=self.audit_template.id, id=1, uuid=None)
self.action_plan = utils.create_test_action_plan(
audit_id=self.audit.id, id=1, uuid=None)
with freezegun.freeze_time(self.FAKE_TODAY):
self.efficacy_indicator1 = utils.create_test_efficacy_indicator(
action_plan_id=self.action_plan.id, id=1, uuid=None,
name="efficacy_indicator1", description="Test Indicator 1")
with freezegun.freeze_time(self.FAKE_OLD_DATE):
self.efficacy_indicator2 = utils.create_test_efficacy_indicator(
action_plan_id=self.action_plan.id, id=2, uuid=None,
name="efficacy_indicator2", description="Test Indicator 2")
with freezegun.freeze_time(self.FAKE_OLDER_DATE):
self.efficacy_indicator3 = utils.create_test_efficacy_indicator(
action_plan_id=self.action_plan.id, id=3, uuid=None,
name="efficacy_indicator3", description="Test Indicator 3")
def _soft_delete_efficacy_indicators(self):
with freezegun.freeze_time(self.FAKE_TODAY):
self.dbapi.soft_delete_efficacy_indicator(
self.efficacy_indicator1.uuid)
with freezegun.freeze_time(self.FAKE_OLD_DATE):
self.dbapi.soft_delete_efficacy_indicator(
self.efficacy_indicator2.uuid)
with freezegun.freeze_time(self.FAKE_OLDER_DATE):
self.dbapi.soft_delete_efficacy_indicator(
self.efficacy_indicator3.uuid)
def _update_efficacy_indicators(self):
with freezegun.freeze_time(self.FAKE_TODAY):
self.dbapi.update_efficacy_indicator(
self.efficacy_indicator1.uuid,
values={"description": "New decription 1"})
with freezegun.freeze_time(self.FAKE_OLD_DATE):
self.dbapi.update_efficacy_indicator(
self.efficacy_indicator2.uuid,
values={"description": "New decription 2"})
with freezegun.freeze_time(self.FAKE_OLDER_DATE):
self.dbapi.update_efficacy_indicator(
self.efficacy_indicator3.uuid,
values={"description": "New decription 3"})
def test_get_efficacy_indicator_filter_deleted_true(self):
with freezegun.freeze_time(self.FAKE_TODAY):
self.dbapi.soft_delete_efficacy_indicator(
self.efficacy_indicator1.uuid)
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted': True})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_deleted_false(self):
with freezegun.freeze_time(self.FAKE_TODAY):
self.dbapi.soft_delete_efficacy_indicator(
self.efficacy_indicator1.uuid)
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted': False})
self.assertEqual([self.efficacy_indicator2['id'],
self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_deleted_at_eq(self):
self._soft_delete_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted_at__eq': self.FAKE_TODAY})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_deleted_at_lt(self):
self._soft_delete_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted_at__lt': self.FAKE_TODAY})
self.assertEqual(
[self.efficacy_indicator2['id'], self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_deleted_at_lte(self):
self._soft_delete_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted_at__lte': self.FAKE_OLD_DATE})
self.assertEqual(
[self.efficacy_indicator2['id'], self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_deleted_at_gt(self):
self._soft_delete_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted_at__gt': self.FAKE_OLD_DATE})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_deleted_at_gte(self):
self._soft_delete_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'deleted_at__gte': self.FAKE_OLD_DATE})
self.assertEqual(
[self.efficacy_indicator1['id'], self.efficacy_indicator2['id']],
[r.id for r in res])
# created_at #
def test_get_efficacy_indicator_filter_created_at_eq(self):
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'created_at__eq': self.FAKE_TODAY})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_created_at_lt(self):
with freezegun.freeze_time(self.FAKE_TODAY):
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'created_at__lt': self.FAKE_TODAY})
self.assertEqual(
[self.efficacy_indicator2['id'], self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_created_at_lte(self):
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'created_at__lte': self.FAKE_OLD_DATE})
self.assertEqual(
[self.efficacy_indicator2['id'], self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_created_at_gt(self):
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'created_at__gt': self.FAKE_OLD_DATE})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_created_at_gte(self):
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'created_at__gte': self.FAKE_OLD_DATE})
self.assertEqual(
[self.efficacy_indicator1['id'], self.efficacy_indicator2['id']],
[r.id for r in res])
# updated_at #
def test_get_efficacy_indicator_filter_updated_at_eq(self):
self._update_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'updated_at__eq': self.FAKE_TODAY})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_updated_at_lt(self):
self._update_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'updated_at__lt': self.FAKE_TODAY})
self.assertEqual(
[self.efficacy_indicator2['id'], self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_updated_at_lte(self):
self._update_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'updated_at__lte': self.FAKE_OLD_DATE})
self.assertEqual(
[self.efficacy_indicator2['id'], self.efficacy_indicator3['id']],
[r.id for r in res])
def test_get_efficacy_indicator_filter_updated_at_gt(self):
self._update_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'updated_at__gt': self.FAKE_OLD_DATE})
self.assertEqual([self.efficacy_indicator1['id']], [r.id for r in res])
def test_get_efficacy_indicator_filter_updated_at_gte(self):
self._update_efficacy_indicators()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'updated_at__gte': self.FAKE_OLD_DATE})
self.assertEqual(
[self.efficacy_indicator1['id'], self.efficacy_indicator2['id']],
[r.id for r in res])
class DbEfficacyIndicatorTestCase(base.DbTestCase):
def _create_test_efficacy_indicator(self, **kwargs):
efficacy_indicator_dict = utils.get_test_efficacy_indicator(**kwargs)
efficacy_indicator = self.dbapi.create_efficacy_indicator(
efficacy_indicator_dict)
return efficacy_indicator
def _create_test_action_plan(self, **kwargs):
action_plan_dict = utils.get_test_action_plan(**kwargs)
action_plan = self.dbapi.create_action_plan(action_plan_dict)
return action_plan
def test_get_efficacy_indicator_list(self):
uuids = []
action_plan = self._create_test_action_plan()
for id_ in range(1, 6):
efficacy_indicator = utils.create_test_efficacy_indicator(
action_plan_id=action_plan.id, id=id_, uuid=None,
name="efficacy_indicator", description="Test Indicator ")
uuids.append(six.text_type(efficacy_indicator['uuid']))
res = self.dbapi.get_efficacy_indicator_list(self.context)
res_uuids = [r.uuid for r in res]
self.assertEqual(uuids.sort(), res_uuids.sort())
def test_get_efficacy_indicator_list_with_filters(self):
audit = utils.create_test_audit(uuid=w_utils.generate_uuid())
action_plan = self._create_test_action_plan(
id=1,
uuid=w_utils.generate_uuid(),
audit_id=audit.id,
first_efficacy_indicator_id=None,
state='RECOMMENDED')
efficacy_indicator1 = self._create_test_efficacy_indicator(
id=1,
name='indicator_1',
uuid=w_utils.generate_uuid(),
action_plan_id=1,
description='Description efficacy indicator 1',
unit='%')
efficacy_indicator2 = self._create_test_efficacy_indicator(
id=2,
name='indicator_2',
uuid=w_utils.generate_uuid(),
action_plan_id=2,
description='Description efficacy indicator 2',
unit='%')
efficacy_indicator3 = self._create_test_efficacy_indicator(
id=3,
name='indicator_3',
uuid=w_utils.generate_uuid(),
action_plan_id=1,
description='Description efficacy indicator 3',
unit='%')
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'name': 'indicator_3'})
self.assertEqual([efficacy_indicator3['id']], [r.id for r in res])
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'unit': 'kWh'})
self.assertEqual([], [r.id for r in res])
res = self.dbapi.get_efficacy_indicator_list(
self.context,
filters={'action_plan_id': 2})
self.assertEqual([efficacy_indicator2['id']], [r.id for r in res])
res = self.dbapi.get_efficacy_indicator_list(
self.context,
filters={'action_plan_uuid': action_plan['uuid']})
self.assertEqual(
[efficacy_indicator1['id'], efficacy_indicator3['id']].sort(),
[r.id for r in res].sort())
def test_get_efficacy_indicator_list_with_filter_by_uuid(self):
efficacy_indicator = self._create_test_efficacy_indicator()
res = self.dbapi.get_efficacy_indicator_list(
self.context, filters={'uuid': efficacy_indicator.uuid})
self.assertEqual(len(res), 1)
self.assertEqual(efficacy_indicator.uuid, res[0].uuid)
def test_get_efficacy_indicator_by_id(self):
efficacy_indicator = self._create_test_efficacy_indicator()
efficacy_indicator = self.dbapi.get_efficacy_indicator_by_id(
self.context, efficacy_indicator.id)
self.assertEqual(efficacy_indicator.uuid, efficacy_indicator.uuid)
def test_get_efficacy_indicator_by_uuid(self):
efficacy_indicator = self._create_test_efficacy_indicator()
efficacy_indicator = self.dbapi.get_efficacy_indicator_by_uuid(
self.context, efficacy_indicator.uuid)
self.assertEqual(efficacy_indicator['id'], efficacy_indicator.id)
def test_get_efficacy_indicator_that_does_not_exist(self):
self.assertRaises(
exception.EfficacyIndicatorNotFound,
self.dbapi.get_efficacy_indicator_by_id, self.context, 1234)
def test_update_efficacy_indicator(self):
efficacy_indicator = self._create_test_efficacy_indicator()
res = self.dbapi.update_efficacy_indicator(
efficacy_indicator.id, {'state': 'CANCELLED'})
self.assertEqual('CANCELLED', res.state)
def test_update_efficacy_indicator_that_does_not_exist(self):
self.assertRaises(
exception.EfficacyIndicatorNotFound,
self.dbapi.update_efficacy_indicator, 1234, {'state': ''})
def test_update_efficacy_indicator_uuid(self):
efficacy_indicator = self._create_test_efficacy_indicator()
self.assertRaises(
exception.Invalid,
self.dbapi.update_efficacy_indicator, efficacy_indicator.id,
{'uuid': 'hello'})
def test_destroy_efficacy_indicator(self):
efficacy_indicator = self._create_test_efficacy_indicator()
self.dbapi.destroy_efficacy_indicator(efficacy_indicator['id'])
self.assertRaises(exception.EfficacyIndicatorNotFound,
self.dbapi.get_efficacy_indicator_by_id,
self.context, efficacy_indicator['id'])
def test_destroy_efficacy_indicator_by_uuid(self):
uuid = w_utils.generate_uuid()
self._create_test_efficacy_indicator(uuid=uuid)
self.assertIsNotNone(self.dbapi.get_efficacy_indicator_by_uuid(
self.context, uuid))
self.dbapi.destroy_efficacy_indicator(uuid)
self.assertRaises(
exception.EfficacyIndicatorNotFound,
self.dbapi.get_efficacy_indicator_by_uuid, self.context, uuid)
def test_destroy_efficacy_indicator_that_does_not_exist(self):
self.assertRaises(exception.EfficacyIndicatorNotFound,
self.dbapi.destroy_efficacy_indicator, 1234)
def test_create_efficacy_indicator_already_exists(self):
uuid = w_utils.generate_uuid()
self._create_test_efficacy_indicator(id=1, uuid=uuid)
self.assertRaises(exception.EfficacyIndicatorAlreadyExists,
self._create_test_efficacy_indicator,
id=2, uuid=uuid)

View File

@@ -273,7 +273,12 @@ class DbGoalTestCase(base.DbTestCase):
self.assertEqual([goal2['uuid']], [r.uuid for r in res]) self.assertEqual([goal2['uuid']], [r.uuid for r in res])
def test_get_goal_by_uuid(self): def test_get_goal_by_uuid(self):
created_goal = self._create_test_goal() efficacy_spec = [{"unit": "%", "name": "dummy",
"schema": "Range(min=0, max=100, min_included=True, "
"max_included=True, msg=None)",
"description": "Dummy indicator"}]
created_goal = self._create_test_goal(
efficacy_specification=efficacy_spec)
goal = self.dbapi.get_goal_by_uuid(self.context, created_goal['uuid']) goal = self.dbapi.get_goal_by_uuid(self.context, created_goal['uuid'])
self.assertEqual(goal.uuid, created_goal['uuid']) self.assertEqual(goal.uuid, created_goal['uuid'])

View File

@@ -189,3 +189,33 @@ def create_test_strategy(**kwargs):
strategy = get_test_strategy(**kwargs) strategy = get_test_strategy(**kwargs)
dbapi = db_api.get_instance() dbapi = db_api.get_instance()
return dbapi.create_strategy(strategy) return dbapi.create_strategy(strategy)
def get_test_efficacy_indicator(**kwargs):
return {
'id': kwargs.get('id', 1),
'uuid': kwargs.get('uuid', '202cfcf9-811c-411a-8a35-d8351f64eb24'),
'name': kwargs.get('name', 'test_indicator'),
'description': kwargs.get('description', 'Test indicator'),
'unit': kwargs.get('unit', '%'),
'value': kwargs.get('value', 0),
'action_plan_id': kwargs.get('action_plan_id', 1),
'created_at': kwargs.get('created_at'),
'updated_at': kwargs.get('updated_at'),
'deleted_at': kwargs.get('deleted_at'),
}
def create_test_efficacy_indicator(**kwargs):
"""Create and return a test efficacy indicator entry in DB.
Function to be used to create test EfficacyIndicator objects in the DB.
:param kwargs: kwargs for overriding the values of the attributes
:returns: Test EfficacyIndicator DB object.
"""
efficacy_indicator = get_test_efficacy_indicator(**kwargs)
# Let DB generate ID if it isn't specified explicitly
if 'id' not in kwargs:
del efficacy_indicator['id']
dbapi = db_api.get_instance()
return dbapi.create_efficacy_indicator(efficacy_indicator)