From 6f52de12024939bbfb566b095795c82fa71c08ab Mon Sep 17 00:00:00 2001 From: tengqm Date: Fri, 27 May 2016 03:49:11 -0400 Subject: [PATCH] ovo - switch action calls This patch switch action DB calls to use action object. Change-Id: I0b521e75169c08196a362aa91bc47b89d72116e0 --- senlin/engine/actions/base.py | 80 ++++---- senlin/engine/actions/cluster_action.py | 24 +-- senlin/engine/cluster_policy.py | 9 +- senlin/engine/scheduler.py | 11 +- senlin/engine/senlin_lock.py | 12 +- senlin/engine/service.py | 16 +- senlin/objects/action.py | 29 +-- senlin/objects/cluster.py | 3 +- senlin/objects/cluster_policy.py | 9 +- senlin/objects/credential.py | 2 + .../unit/engine/actions/test_action_base.py | 162 ++++++++--------- .../engine/actions/test_cluster_action.py | 171 +++++++++--------- .../tests/unit/engine/service/test_actions.py | 16 +- senlin/tests/unit/engine/test_senlin_lock.py | 13 +- 14 files changed, 281 insertions(+), 276 deletions(-) diff --git a/senlin/engine/actions/base.py b/senlin/engine/actions/base.py index f6ec0afe..c80827ef 100644 --- a/senlin/engine/actions/base.py +++ b/senlin/engine/actions/base.py @@ -21,9 +21,9 @@ from senlin.common import context as req_context from senlin.common import exception from senlin.common.i18n import _ from senlin.common.i18n import _LE -from senlin.db import api as db_api from senlin.engine import cluster_policy as cp_mod from senlin.engine import event as EVENT +from senlin.objects import action as ao from senlin.objects import dependency as dobj from senlin.policies import base as policy_mod @@ -179,43 +179,43 @@ class Action(object): if self.id: self.updated_at = timestamp values['updated_at'] = timestamp - db_api.action_update(context, self.id, values) + ao.Action.update(context, self.id, values) else: self.created_at = timestamp values['created_at'] = timestamp - action = db_api.action_create(context, values) + action = ao.Action.create(context, values) self.id = action.id return self.id @classmethod - def _from_db_record(cls, record): - """Construct a action object from database record. + def _from_object(cls, obj): + """Construct an action from database object. :param context: the context used for DB operations; - :param record: a DB action object that contains all fields. + :param obj: a DB action object that contains all fields. :return: An `Action` object deserialized from the DB action object. """ - context = req_context.RequestContext.from_dict(record.context) + context = req_context.RequestContext.from_dict(obj.context) kwargs = { - 'id': record.id, - 'name': record.name, - 'cause': record.cause, - 'owner': record.owner, - 'interval': record.interval, - 'start_time': record.start_time, - 'end_time': record.end_time, - 'timeout': record.timeout, - 'status': record.status, - 'status_reason': record.status_reason, - 'inputs': record.inputs or {}, - 'outputs': record.outputs or {}, - 'created_at': record.created_at, - 'updated_at': record.updated_at, - 'data': record.data, + 'id': obj.id, + 'name': obj.name, + 'cause': obj.cause, + 'owner': obj.owner, + 'interval': obj.interval, + 'start_time': obj.start_time, + 'end_time': obj.end_time, + 'timeout': obj.timeout, + 'status': obj.status, + 'status_reason': obj.status_reason, + 'inputs': obj.inputs or {}, + 'outputs': obj.outputs or {}, + 'created_at': obj.created_at, + 'updated_at': obj.updated_at, + 'data': obj.data, } - return cls(record.target, record.action, context, **kwargs) + return cls(obj.target, obj.action, context, **kwargs) @classmethod def load(cls, context, action_id=None, db_action=None): @@ -227,11 +227,11 @@ class Action(object): :return: A `Action` object instance. """ if db_action is None: - db_action = db_api.action_get(context, action_id) + db_action = ao.Action.get(context, action_id) if db_action is None: raise exception.ActionNotFound(action=action_id) - return cls._from_db_record(db_action) + return cls._from_object(db_action) @classmethod def load_all(cls, context, filters=None, limit=None, marker=None, @@ -251,12 +251,12 @@ class Action(object): :return: A list of `Action` objects. """ - records = db_api.action_get_all(context, filters=filters, sort=sort, - limit=limit, marker=marker, - project_safe=project_safe) + records = ao.Action.get_all(context, filters=filters, sort=sort, + limit=limit, marker=marker, + project_safe=project_safe) for record in records: - yield cls._from_db_record(record) + yield cls._from_object(record) @classmethod def create(cls, context, target, action, **kwargs): @@ -288,7 +288,7 @@ class Action(object): :param action_id: The UUID of the target action to be deleted. :return: Nothing. """ - db_api.action_delete(context, action_id) + ao.Action.delete(context, action_id) def signal(self, cmd): '''Send a signal to the action.''' @@ -313,7 +313,7 @@ class Action(object): return # TODO(Yanyan Hu): use DB session here - db_api.action_signal(self.context, self.id, cmd) + ao.Action.signal(self.context, self.id, cmd) def execute(self, **kwargs): '''Execute the action. @@ -332,27 +332,27 @@ class Action(object): if result == self.RES_OK: status = self.SUCCEEDED - db_api.action_mark_succeeded(self.context, self.id, timestamp) + ao.Action.mark_succeeded(self.context, self.id, timestamp) elif result == self.RES_ERROR: status = self.FAILED - db_api.action_mark_failed(self.context, self.id, timestamp, - reason=reason or 'ERROR') + ao.Action.mark_failed(self.context, self.id, timestamp, + reason or 'ERROR') elif result == self.RES_TIMEOUT: status = self.FAILED - db_api.action_mark_failed(self.context, self.id, timestamp, - reason=reason or 'TIMEOUT') + ao.Action.mark_failed(self.context, self.id, timestamp, + reason or 'TIMEOUT') elif result == self.RES_CANCEL: status = self.CANCELLED - db_api.action_mark_cancelled(self.context, self.id, timestamp) + ao.Action.mark_cancelled(self.context, self.id, timestamp) else: # result == self.RES_RETRY: status = self.READY # Action failed at the moment, but can be retried # We abandon it and then notify other dispatchers to execute it - db_api.action_abandon(self.context, self.id) + ao.Action.abandon(self.context, self.id) if status == self.SUCCEEDED: EVENT.info(self.context, self, self.action, status, reason) @@ -366,7 +366,7 @@ class Action(object): def get_status(self): timestamp = wallclock() - status = db_api.action_check_status(self.context, self.id, timestamp) + status = ao.Action.check_status(self.context, self.id, timestamp) self.status = status return status @@ -380,7 +380,7 @@ class Action(object): EVENT.debug(self.context, self, self.action, 'TIMEOUT') return self.RES_TIMEOUT - result = db_api.action_signal_query(self.context, self.id) + result = ao.Action.signal_query(self.context, self.id) return result def is_cancelled(self): diff --git a/senlin/engine/actions/cluster_action.py b/senlin/engine/actions/cluster_action.py index 1d18d5aa..da530a40 100644 --- a/senlin/engine/actions/cluster_action.py +++ b/senlin/engine/actions/cluster_action.py @@ -21,7 +21,6 @@ from senlin.common.i18n import _ from senlin.common.i18n import _LI from senlin.common import scaleutils from senlin.common import utils -from senlin.db import api as db_api from senlin.engine.actions import base from senlin.engine import cluster as cluster_mod from senlin.engine import dispatcher @@ -29,6 +28,7 @@ from senlin.engine import event as EVENT from senlin.engine import node as node_mod from senlin.engine import scheduler from senlin.engine import senlin_lock +from senlin.objects import action as ao from senlin.objects import cluster as co from senlin.objects import dependency as dobj from senlin.objects import node as no @@ -153,8 +153,8 @@ class ClusterAction(base.Action): # Build dependency and make the new action ready dobj.Dependency.create(self.context, [a for a in child], self.id) for cid in child: - db_api.action_update(self.context, cid, - {'status': base.Action.READY}) + ao.Action.update(self.context, cid, + {'status': base.Action.READY}) dispatcher.start_action() # Wait for cluster creation to complete @@ -246,8 +246,8 @@ class ClusterAction(base.Action): if child: dobj.Dependency.create(self.context, [c for c in child], self.id) for cid in child: - db_api.action_update(self.context, cid, - {'status': base.Action.READY}) + ao.Action.update(self.context, cid, + {'status': base.Action.READY}) dispatcher.start_action() result, new_reason = self._wait_for_dependents() @@ -284,8 +284,8 @@ class ClusterAction(base.Action): dobj.Dependency.create(self.context, [c for c in child], self.id) for cid in child: # Build dependency and make the new action ready - db_api.action_update(self.context, cid, - {'status': base.Action.READY}) + ao.Action.update(self.context, cid, + {'status': base.Action.READY}) dispatcher.start_action() res, reason = self._wait_for_dependents() @@ -381,8 +381,8 @@ class ClusterAction(base.Action): if child: dobj.Dependency.create(self.context, [c for c in child], self.id) for cid in child: - db_api.action_update(self.context, cid, - {'status': base.Action.READY}) + ao.Action.update(self.context, cid, + {'status': base.Action.READY}) dispatcher.start_action() # Wait for dependent action if any @@ -494,8 +494,8 @@ class ClusterAction(base.Action): if child: dobj.Dependency.create(self.context, [c for c in child], self.id) for cid in child: - db_api.action_update(self.context, cid, - {'status': base.Action.READY}) + ao.Action.update(self.context, cid, + {'status': base.Action.READY}) dispatcher.start_action() # Wait for dependent action if any @@ -548,7 +548,7 @@ class ClusterAction(base.Action): dobj.Dependency.create(self.context, [c for c in children], self.id) for cid in children: - db_api.action_update(self.context, cid, {'status': 'READY'}) + ao.Action.update(self.context, cid, {'status': 'READY'}) dispatcher.start_action() # Wait for dependent action if any diff --git a/senlin/engine/cluster_policy.py b/senlin/engine/cluster_policy.py index 8bc98026..58de8464 100644 --- a/senlin/engine/cluster_policy.py +++ b/senlin/engine/cluster_policy.py @@ -13,7 +13,6 @@ from oslo_utils import timeutils from senlin.common import exception -from senlin.db import api as db_api from senlin.objects import cluster_policy as cpo @@ -47,11 +46,11 @@ class ClusterPolicy(object): } if self.id: - db_api.cluster_policy_update(context, self.cluster_id, - self.policy_id, values) + cpo.ClusterPolicy.update(context, self.cluster_id, self.policy_id, + values) else: - binding = db_api.cluster_policy_attach(context, self.cluster_id, - self.policy_id, values) + binding = cpo.ClusterPolicy.create(context, self.cluster_id, + self.policy_id, values) self.cluster_name = binding.cluster.name self.policy_name = binding.policy.name self.policy_type = binding.policy.type diff --git a/senlin/engine/scheduler.py b/senlin/engine/scheduler.py index e6a3777f..0a1779cb 100644 --- a/senlin/engine/scheduler.py +++ b/senlin/engine/scheduler.py @@ -19,8 +19,8 @@ from oslo_service import threadgroup from senlin.common import context from senlin.common.i18n import _ -from senlin.db import api as db_api from senlin.engine.actions import base as action_mod +from senlin.objects import action as ao LOG = logging.getLogger(__name__) @@ -84,8 +84,8 @@ class ThreadGroupManager(object): actions_launched = 0 if action_id is not None: timestamp = wallclock() - action = db_api.action_acquire(self.db_session, action_id, - worker_id, timestamp) + action = ao.Action.acquire(self.db_session, action_id, worker_id, + timestamp) if action: launch(action.id) actions_launched += 1 @@ -94,9 +94,8 @@ class ThreadGroupManager(object): batch_interval = cfg.CONF.batch_interval while True: timestamp = wallclock() - action = db_api.action_acquire_1st_ready(self.db_session, - worker_id, - timestamp) + action = ao.Action.acquire_1st_ready(self.db_session, worker_id, + timestamp) if action: if batch_size > 0 and 'NODE' in action.action: if actions_launched < batch_size: diff --git a/senlin/engine/senlin_lock.py b/senlin/engine/senlin_lock.py index 6c8d8368..2e9e311f 100644 --- a/senlin/engine/senlin_lock.py +++ b/senlin/engine/senlin_lock.py @@ -18,8 +18,8 @@ import time from senlin.common.i18n import _ from senlin.common.i18n import _LE from senlin.common.i18n import _LI -from senlin.db import api as db_api from senlin.engine import scheduler +from senlin.objects import action as ao from senlin.objects import cluster_lock as cl_obj from senlin.objects import node_lock as nl_obj from senlin.objects import service as service_obj @@ -89,7 +89,7 @@ def cluster_lock_acquire(context, cluster_id, action_id, engine=None, return action_id in owners # Will reach here only because scope == CLUSTER_SCOPE - action = db_api.action_get(context, owners[0]) + action = ao.Action.get(context, owners[0]) if (action and action.owner and action.owner != engine and is_engine_dead(context, action.owner)): LOG.info(_LI('The cluster %(c)s is locked by dead action %(a)s, ' @@ -98,8 +98,7 @@ def cluster_lock_acquire(context, cluster_id, action_id, engine=None, 'a': owners[0] }) reason = _('Engine died when executing this action.') - db_api.action_mark_failed(context, action.id, time.time(), - reason=reason) + ao.Action.mark_failed(context, action.id, time.time(), reason) owners = cl_obj.ClusterLock.steal(cluster_id, action_id) return action_id in owners @@ -156,7 +155,7 @@ def node_lock_acquire(context, node_id, action_id, engine=None, return action_id == owner # if this node lock by dead engine - action = db_api.action_get(context, owner) + action = ao.Action.get(context, owner) if (action and action.owner and action.owner != engine and is_engine_dead(context, action.owner)): LOG.info(_LI('The node %(n)s is locked by dead action %(a)s, ' @@ -165,8 +164,7 @@ def node_lock_acquire(context, node_id, action_id, engine=None, 'a': owner }) reason = _('Engine died when executing this action.') - db_api.action_mark_failed(context, action.id, time.time(), - reason=reason) + ao.Action.mark_failed(context, action.id, time.time(), reason) nl_obj.NodeLock.steal(node_id, action_id) return True diff --git a/senlin/engine/service.py b/senlin/engine/service.py index da0b990c..ac66208e 100644 --- a/senlin/engine/service.py +++ b/senlin/engine/service.py @@ -33,7 +33,6 @@ from senlin.common import messaging as rpc_messaging from senlin.common import scaleutils as su from senlin.common import schema from senlin.common import utils -from senlin.db import api as db_api from senlin.engine.actions import base as action_mod from senlin.engine import cluster as cluster_mod from senlin.engine import cluster_policy as cpm @@ -43,6 +42,7 @@ from senlin.engine import health_manager from senlin.engine import node as node_mod from senlin.engine import receiver as receiver_mod from senlin.engine import scheduler +from senlin.objects import action as action_obj from senlin.objects import cluster as cluster_obj from senlin.objects import cluster_policy as cp_obj from senlin.objects import credential as cred_obj @@ -1805,16 +1805,16 @@ class EngineService(service.Service): matching action is found. """ if uuidutils.is_uuid_like(identity): - action = db_api.action_get(context, identity, - project_safe=project_safe) + action = action_obj.Action.get(context, identity, + project_safe=project_safe) if not action: - action = db_api.action_get_by_name(context, identity, - project_safe=project_safe) + action = action_obj.Action.get_by_name( + context, identity, project_safe=project_safe) else: - action = db_api.action_get_by_name(context, identity, - project_safe=project_safe) + action = action_obj.Action.get_by_name( + context, identity, project_safe=project_safe) if not action: - action = db_api.action_get_by_short_id( + action = action_obj.Action.get_by_short_id( context, identity, project_safe=project_safe) if not action: diff --git a/senlin/objects/action.py b/senlin/objects/action.py index 92dfcf33..1de2c632 100644 --- a/senlin/objects/action.py +++ b/senlin/objects/action.py @@ -27,7 +27,7 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): 'created_at': fields.DateTimeField(), 'updated_at': fields.DateTimeField(nullable=True), 'name': fields.StringField(), - 'context': fields.DictOfStringField(), + 'context': fields.DictOfStringsField(), 'target': fields.UUIDField(), 'action': fields.StringField(), 'cause': fields.StringField(), @@ -39,9 +39,9 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): 'status': fields.StringField(), 'status_reason': fields.StringField(), 'control': fields.StringField(nullable=True), - 'inputs': fields.DictOfStringField(nullable=True), - 'outputs': fields.DictOfStringField(nullable=True), - 'data': fields.DictOfStringField(nullable=True), + 'inputs': fields.DictOfStringsField(nullable=True), + 'outputs': fields.DictOfStringsField(nullable=True), + 'data': fields.DictOfStringsField(nullable=True), 'user': fields.StringField(), 'project': fields.StringField(), 'domain': fields.StringField(), @@ -49,6 +49,8 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): @staticmethod def _from_db_object(context, action, db_obj): + if db_obj is None: + return None for field in action.fields: action[field] = db_obj[field] @@ -79,11 +81,13 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): @classmethod def get_all(cls, context, **kwargs): - return db_api.action_get_all(context, **kwargs) + objs = db_api.action_get_all(context, **kwargs) + return [cls._from_db_object(context, cls(), obj) for obj in objs] @classmethod def get_all_by_owner(cls, context, owner): - return db_api.action_get_all_by_owner(context, owner) + objs = db_api.action_get_all_by_owner(context, owner) + return [cls._from_db_object(context, cls(), obj) for obj in objs] @classmethod def check_status(cls, context, action_id, timestamp): @@ -94,8 +98,8 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): return db_api.action_mark_succeeded(context, action_id, timestamp) @classmethod - def mark_failed(cls, context, action_id, timestamp): - return db_api.action_mark_failed(context, action_id, timestamp) + def mark_failed(cls, context, action_id, timestamp, reason=None): + return db_api.action_mark_failed(context, action_id, timestamp, reason) @classmethod def mark_cancelled(cls, context, action_id, timestamp): @@ -106,9 +110,8 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): return db_api.action_acquire(context, action_id, owner, timestamp) @classmethod - def acquire_1st_ready(cls, context, action_id, owner, timestamp): - return db_api.action_acquire_1st_ready(context, action_id, owner, - timestamp) + def acquire_1st_ready(cls, context, owner, timestamp): + return db_api.action_acquire_1st_ready(context, owner, timestamp) @classmethod def abandon(cls, context, action_id): @@ -126,6 +129,10 @@ class Action(senlin_base.SenlinObject, base.VersionedObjectDictCompat): def lock_check(cls, context, action_id, owner=None): return db_api.action_lock_check(context, action_id, owner) + @classmethod + def update(cls, context, action_id, values): + return db_api.action_update(context, action_id, values) + @classmethod def delete(cls, context, action_id): db_api.action_delete(context, action_id) diff --git a/senlin/objects/cluster.py b/senlin/objects/cluster.py index 392feca8..7187df40 100644 --- a/senlin/objects/cluster.py +++ b/senlin/objects/cluster.py @@ -82,7 +82,8 @@ class Cluster(senlin_base.SenlinObject, base.VersionedObjectDictCompat): @classmethod def get_all(cls, context, **kwargs): - return db_api.cluster_get_all(context, **kwargs) + objs = db_api.cluster_get_all(context, **kwargs) + return [cls._from_db_object(context, cls(), obj) for obj in objs] @classmethod def next_index(cls, context, cluster_id): diff --git a/senlin/objects/cluster_policy.py b/senlin/objects/cluster_policy.py index 496052b5..cc15c5a6 100644 --- a/senlin/objects/cluster_policy.py +++ b/senlin/objects/cluster_policy.py @@ -59,13 +59,14 @@ class ClusterPolicy(senlin_base.SenlinObject, base.VersionedObjectDictCompat): @classmethod def get_by_type(cls, context, cluster_id, policy_type, filters=None): - obj = db_api.cluster_policy_get_by_type(context, cluster_id, - policy_type, filters=filters) - return cls._from_db_object(context, cls(), obj) + objs = db_api.cluster_policy_get_by_type(context, cluster_id, + policy_type, filters=filters) + return [cls._from_db_object(context, cls(), obj) for obj in objs] @classmethod def get_all(cls, context, cluster_id, **kwargs): - return db_api.cluster_policy_get_all(context, cluster_id, **kwargs) + objs = db_api.cluster_policy_get_all(context, cluster_id, **kwargs) + return [cls._from_db_object(context, cls(), obj) for obj in objs] @classmethod def update(cls, context, cluster_id, policy_id, values): diff --git a/senlin/objects/credential.py b/senlin/objects/credential.py index a120caeb..306b1e61 100644 --- a/senlin/objects/credential.py +++ b/senlin/objects/credential.py @@ -31,6 +31,8 @@ class Credential(senlin_base.SenlinObject, base.VersionedObjectDictCompat): @staticmethod def _from_db_object(context, credential, db_obj): + if db_obj is None: + return None for field in credential.fields: credential[field] = db_obj[field] diff --git a/senlin/tests/unit/engine/actions/test_action_base.py b/senlin/tests/unit/engine/actions/test_action_base.py index 5d247f41..fbc92d5e 100644 --- a/senlin/tests/unit/engine/actions/test_action_base.py +++ b/senlin/tests/unit/engine/actions/test_action_base.py @@ -17,13 +17,13 @@ from oslo_config import cfg import six from senlin.common import exception -from senlin.db.sqlalchemy import api as db_api -from senlin.engine.actions import base as action_base +from senlin.engine.actions import base as ab from senlin.engine import cluster as cluster_mod from senlin.engine import cluster_policy as cp_mod from senlin.engine import environment from senlin.engine import event as EVENT from senlin.engine import node as node_mod +from senlin.objects import action as ao from senlin.objects import dependency as dobj from senlin.policies import base as policy_mod from senlin.tests.unit.common import base @@ -31,7 +31,7 @@ from senlin.tests.unit.common import utils from senlin.tests.unit import fakes -class DummyAction(action_base.Action): +class DummyAction(ab.Action): def __init__(self, target, action, context, **kwargs): super(DummyAction, self).__init__(target, action, context, **kwargs) @@ -84,7 +84,7 @@ class ActionBaseTest(base.SenlinTestCase): @mock.patch.object(cluster_mod.Cluster, 'load') def test_action_new(self, mock_n_load, mock_c_load): for action in ['CLUSTER_CREATE', 'NODE_CREATE', 'WHAT_EVER']: - obj = action_base.Action('OBJID', action, self.ctx) + obj = ab.Action('OBJID', action, self.ctx) self._verify_new_action(obj, 'OBJID', action) def test_action_init_with_values(self): @@ -94,7 +94,7 @@ class ActionBaseTest(base.SenlinTestCase): values['created_at'] = 'FAKE_CREATED_TIME' values['updated_at'] = 'FAKE_UPDATED_TIME' - obj = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + obj = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) self.assertEqual('FAKE_ID', obj.id) @@ -117,7 +117,7 @@ class ActionBaseTest(base.SenlinTestCase): def test_action_store_for_create(self): values = copy.deepcopy(self.action_values) - obj = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + obj = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) self.assertIsNone(obj.created_at) @@ -133,7 +133,7 @@ class ActionBaseTest(base.SenlinTestCase): def test_action_store_for_update(self): values = copy.deepcopy(self.action_values) - obj = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + obj = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) obj_id = obj.store(self.ctx) self.assertIsNotNone(obj_id) @@ -150,14 +150,14 @@ class ActionBaseTest(base.SenlinTestCase): def test_from_db_record(self): values = copy.deepcopy(self.action_values) - obj = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + obj = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) obj.store(self.ctx) - record = db_api.action_get(self.ctx, obj.id) + record = ao.Action.get(self.ctx, obj.id) - action_obj = action_base.Action._from_db_record(record) - self.assertIsInstance(action_obj, action_base.Action) + action_obj = ab.Action._from_object(record) + self.assertIsInstance(action_obj, ab.Action) self.assertEqual(obj.id, action_obj.id) self.assertEqual(obj.action, action_obj.action) self.assertEqual(obj.name, action_obj.name) @@ -183,26 +183,26 @@ class ActionBaseTest(base.SenlinTestCase): values = copy.deepcopy(self.action_values) del values['inputs'] del values['outputs'] - obj = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + obj = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) obj.store(self.ctx) - record = db_api.action_get(self.ctx, obj.id) - action_obj = action_base.Action._from_db_record(record) + record = ao.Action.get(self.ctx, obj.id) + action_obj = ab.Action._from_object(record) self.assertEqual({}, action_obj.inputs) self.assertEqual({}, action_obj.outputs) def test_load(self): values = copy.deepcopy(self.action_values) - obj = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) + obj = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) obj.store(self.ctx) - result = action_base.Action.load(self.ctx, obj.id, None) + result = ab.Action.load(self.ctx, obj.id, None) # no need to do a thorough test here self.assertEqual(obj.id, result.id) self.assertEqual(obj.action, result.action) - db_action = db_api.action_get(self.ctx, obj.id) - result = action_base.Action.load(self.ctx, None, db_action) + db_action = ao.Action.get(self.ctx, obj.id) + result = ab.Action.load(self.ctx, None, db_action) # no need to do a thorough test here self.assertEqual(obj.id, result.id) self.assertEqual(obj.action, result.action) @@ -210,44 +210,44 @@ class ActionBaseTest(base.SenlinTestCase): def test_load_not_found(self): # not found due to bad identity ex = self.assertRaises(exception.ActionNotFound, - action_base.Action.load, + ab.Action.load, self.ctx, 'non-existent', None) self.assertEqual('The action (non-existent) could not be found.', six.text_type(ex)) # not found due to no object - self.patchobject(db_api, 'action_get', return_value=None) + self.patchobject(ao.Action, 'get', return_value=None) ex = self.assertRaises(exception.ActionNotFound, - action_base.Action.load, + ab.Action.load, self.ctx, 'whatever', None) self.assertEqual('The action (whatever) could not be found.', six.text_type(ex)) def test_load_all(self): - result = action_base.Action.load_all(self.ctx) + result = ab.Action.load_all(self.ctx) self.assertEqual([], [c for c in result]) values = copy.deepcopy(self.action_values) - action1 = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + action1 = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) action1.store(self.ctx) - action2 = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + action2 = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) action2.store(self.ctx) # NOTE: we don't test all other parameters because the db api tests # already covered that - results = list(action_base.Action.load_all(self.ctx)) + results = list(ab.Action.load_all(self.ctx)) actions = [a.id for a in results] self.assertEqual(2, len(actions)) self.assertIn(action1.id, actions) self.assertIn(action2.id, actions) - @mock.patch.object(db_api, 'action_get_all') + @mock.patch.object(ao.Action, 'get_all') def test_load_all_with_params(self, mock_call): mock_call.return_value = [] - results = action_base.Action.load_all( + results = ab.Action.load_all( self.ctx, filters='FAKE_FILTER', limit='FAKE_LIMIT', marker='FAKE_MARKER', sort='FAKE_SORT') @@ -259,38 +259,38 @@ class ActionBaseTest(base.SenlinTestCase): marker='FAKE_MARKER', sort='FAKE_SORT', project_safe=True) - @mock.patch.object(action_base.Action, 'store') + @mock.patch.object(ab.Action, 'store') def test_action_create(self, mock_store): mock_store.return_value = 'FAKE_ID' - result = action_base.Action.create(self.ctx, 'OBJ_ID', 'CLUSTER_DANCE', - name='test') + result = ab.Action.create(self.ctx, 'OBJ_ID', 'CLUSTER_DANCE', + name='test') self.assertEqual('FAKE_ID', result) mock_store.assert_called_once_with(self.ctx) def test_action_delete(self): - result = action_base.Action.delete(self.ctx, 'non-existent') + result = ab.Action.delete(self.ctx, 'non-existent') self.assertIsNone(result) values = copy.deepcopy(self.action_values) - action1 = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + action1 = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) action1.store(self.ctx) - result = action_base.Action.delete(self.ctx, action1.id) + result = ab.Action.delete(self.ctx, action1.id) self.assertIsNone(result) - @mock.patch.object(db_api, 'action_delete') + @mock.patch.object(ao.Action, 'delete') def test_action_delete_db_call(self, mock_call): # test db api call - action_base.Action.delete(self.ctx, 'FAKE_ID') - mock_call.assert_called_once_with(self.ctx, 'FAKE_ID', False) + ab.Action.delete(self.ctx, 'FAKE_ID') + mock_call.assert_called_once_with(self.ctx, 'FAKE_ID') - @mock.patch.object(db_api, 'action_signal') + @mock.patch.object(ao.Action, 'signal') def test_action_signal_bad_command(self, mock_call): values = copy.deepcopy(self.action_values) - action1 = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + action1 = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) action1.store(self.ctx) @@ -298,11 +298,11 @@ class ActionBaseTest(base.SenlinTestCase): self.assertIsNone(result) self.assertEqual(0, mock_call.call_count) - @mock.patch.object(db_api, 'action_signal') + @mock.patch.object(ao.Action, 'signal') @mock.patch.object(EVENT, 'error') def test_action_signal_cancel(self, mock_error, mock_call): values = copy.deepcopy(self.action_values) - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **values) action.store(self.ctx) @@ -325,10 +325,10 @@ class ActionBaseTest(base.SenlinTestCase): self.assertEqual(1, mock_error.call_count) mock_error.reset_mock() - @mock.patch.object(db_api, 'action_signal') + @mock.patch.object(ao.Action, 'signal') @mock.patch.object(EVENT, 'error') def test_action_signal_suspend(self, mock_error, mock_call): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) expected = [action.RUNNING] for status in expected: @@ -349,10 +349,10 @@ class ActionBaseTest(base.SenlinTestCase): self.assertEqual(1, mock_error.call_count) mock_error.reset_mock() - @mock.patch.object(db_api, 'action_signal') + @mock.patch.object(ao.Action, 'signal') @mock.patch.object(EVENT, 'error') def test_action_signal_resume(self, mock_error, mock_call): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) expected = [action.SUSPENDED] for status in expected: @@ -374,18 +374,17 @@ class ActionBaseTest(base.SenlinTestCase): mock_error.reset_mock() def test_execute_default(self): - action = action_base.Action.__new__(DummyAction, 'OBJID', 'BOOM', - self.ctx) + action = ab.Action.__new__(DummyAction, 'OBJID', 'BOOM', self.ctx) res = action.execute() self.assertEqual(NotImplemented, res) - @mock.patch.object(db_api, 'action_mark_succeeded') - @mock.patch.object(db_api, 'action_mark_failed') - @mock.patch.object(db_api, 'action_mark_cancelled') - @mock.patch.object(db_api, 'action_abandon') + @mock.patch.object(ao.Action, 'mark_succeeded') + @mock.patch.object(ao.Action, 'mark_failed') + @mock.patch.object(ao.Action, 'mark_cancelled') + @mock.patch.object(ao.Action, 'abandon') def test_set_status(self, mock_abandon, mark_cancel, mark_fail, mark_succeed): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' action.set_status(action.RES_OK, 'FAKE_REASON') @@ -420,11 +419,11 @@ class ActionBaseTest(base.SenlinTestCase): self.assertEqual('BUSY', action.status_reason) mock_abandon.assert_called_once_with(action.context, 'FAKE_ID') - @mock.patch.object(db_api, 'action_check_status') + @mock.patch.object(ao.Action, 'check_status') def test_get_status(self, mock_get): mock_get.return_value = 'FAKE_STATUS' - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' res = action.get_status() @@ -433,10 +432,9 @@ class ActionBaseTest(base.SenlinTestCase): self.assertEqual('FAKE_STATUS', action.status) mock_get.assert_called_once_with(action.context, 'FAKE_ID', mock.ANY) - @mock.patch.object(action_base, 'wallclock') + @mock.patch.object(ab, 'wallclock') def test_is_timeout(self, mock_time): - action = action_base.Action.__new__(DummyAction, 'OBJ', 'BOOM', - self.ctx) + action = ab.Action.__new__(DummyAction, 'OBJ', 'BOOM', self.ctx) action.start_time = 1 action.timeout = 10 @@ -453,7 +451,7 @@ class ActionBaseTest(base.SenlinTestCase): self.assertTrue(action.is_timeout()) def test_check_signal_timeout(self): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' action.timeout = 10 self.patchobject(action, 'is_timeout', return_value=True) @@ -461,9 +459,9 @@ class ActionBaseTest(base.SenlinTestCase): res = action._check_signal() self.assertEqual(action.RES_TIMEOUT, res) - @mock.patch.object(db_api, 'action_signal_query') + @mock.patch.object(ao.Action, 'signal_query') def test_check_signal_signals_caught(self, mock_query): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' action.timeout = 100 self.patchobject(action, 'is_timeout', return_value=False) @@ -474,9 +472,9 @@ class ActionBaseTest(base.SenlinTestCase): self.assertEqual(sig_cmd, res) mock_query.assert_called_once_with(action.context, 'FAKE_ID') - @mock.patch.object(db_api, 'action_signal_query') + @mock.patch.object(ao.Action, 'signal_query') def test_is_cancelled(self, mock_query): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' action.timeout = 100 self.patchobject(action, 'is_timeout', return_value=False) @@ -492,9 +490,9 @@ class ActionBaseTest(base.SenlinTestCase): self.assertFalse(res) mock_query.assert_called_once_with(action.context, 'FAKE_ID') - @mock.patch.object(db_api, 'action_signal_query') + @mock.patch.object(ao.Action, 'signal_query') def test_is_suspended(self, mock_query): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' action.timeout = 100 self.patchobject(action, 'is_timeout', return_value=False) @@ -510,9 +508,9 @@ class ActionBaseTest(base.SenlinTestCase): self.assertFalse(res) mock_query.assert_called_once_with(action.context, 'FAKE_ID') - @mock.patch.object(db_api, 'action_signal_query') + @mock.patch.object(ao.Action, 'signal_query') def test_is_resumed(self, mock_query): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.id = 'FAKE_ID' action.timeout = 100 self.patchobject(action, 'is_timeout', return_value=False) @@ -530,14 +528,14 @@ class ActionBaseTest(base.SenlinTestCase): @mock.patch.object(cp_mod.ClusterPolicy, 'load_all') def test_policy_check_target_invalid(self, mock_load): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) res = action.policy_check('FAKE_CLUSTER', 'WHEN') self.assertIsNone(res) self.assertEqual(0, mock_load.call_count) @mock.patch.object(cp_mod.ClusterPolicy, 'load_all') def test_policy_check_no_bindings(self, mock_load): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) mock_load.return_value = [] res = action.policy_check('FAKE_CLUSTER', 'BEFORE') self.assertIsNone(res) @@ -551,7 +549,7 @@ class ActionBaseTest(base.SenlinTestCase): def test_action_to_dict(self, mock_dep_by, mock_dep_on): mock_dep_on.return_value = ['ACTION_1'] mock_dep_by.return_value = ['ACTION_2'] - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx, + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx, **self.action_values) action.id = 'FAKE_ID' expected = { @@ -630,7 +628,7 @@ class ActionPolicyCheckTest(base.SenlinTestCase): mock_load.return_value = policy mock_pre_op.return_value = None mock_post_op.return_value = None - action = action_base.Action(cluster_id, 'OBJECT_ACTION_1', self.ctx) + action = ab.Action(cluster_id, 'OBJECT_ACTION_1', self.ctx) res = action.policy_check(cluster_id, 'AFTER') @@ -664,7 +662,7 @@ class ActionPolicyCheckTest(base.SenlinTestCase): self.assertIsNone(pb.last_op) mock_load_all.return_value = [pb] mock_load.return_value = policy - action = action_base.Action(cluster_id, 'OBJECT_ACTION', self.ctx) + action = ab.Action(cluster_id, 'OBJECT_ACTION', self.ctx) res = action.policy_check(cluster_id, 'BEFORE') @@ -691,7 +689,7 @@ class ActionPolicyCheckTest(base.SenlinTestCase): self.assertIsNone(pb.last_op) mock_load_all.return_value = [pb] mock_load.return_value = policy - action = action_base.Action(cluster_id, 'OBJECT_ACTION', self.ctx) + action = ab.Action(cluster_id, 'OBJECT_ACTION', self.ctx) res = action.policy_check('FAKE_CLUSTER_ID', 'AFTER') @@ -721,7 +719,7 @@ class ActionPolicyCheckTest(base.SenlinTestCase): self.assertIsNone(pb.last_op) mock_load_all.return_value = [pb] mock_load.return_value = policy - action = action_base.Action(cluster_id, 'OBJECT_ACTION', self.ctx) + action = ab.Action(cluster_id, 'OBJECT_ACTION', self.ctx) res = action.policy_check('FAKE_CLUSTER_ID', 'AFTER') @@ -741,7 +739,7 @@ class ActionPolicyCheckTest(base.SenlinTestCase): @mock.patch.object(cp_mod.ClusterPolicy, 'load_all') @mock.patch.object(policy_mod.Policy, 'load') - @mock.patch.object(action_base.Action, '_check_result') + @mock.patch.object(ab.Action, '_check_result') def test_policy_check_abort_in_middle(self, mock_check, mock_load, mock_load_all): cluster_id = 'FAKE_CLUSTER_ID' @@ -757,7 +755,7 @@ class ActionPolicyCheckTest(base.SenlinTestCase): policy2.cooldown = 0 policy2.TARGET = [('AFTER', 'OBJECT_ACTION')] - action = action_base.Action(cluster_id, 'OBJECT_ACTION', self.ctx) + action = ab.Action(cluster_id, 'OBJECT_ACTION', self.ctx) # Note: policy binding is created but not stored pb1 = self._create_cp_binding(cluster_id, policy1.id) @@ -790,18 +788,18 @@ class ActionProcTest(base.SenlinTestCase): self.ctx = utils.dummy_context() @mock.patch.object(EVENT, 'info') - @mock.patch.object(action_base.Action, 'load') - @mock.patch.object(db_api, 'action_mark_succeeded') + @mock.patch.object(ab.Action, 'load') + @mock.patch.object(ao.Action, 'mark_succeeded') def test_action_proc_successful(self, mock_mark, mock_load, mock_event_info): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.owner = 'WORKER' action.start_time = 123456 self.patchobject(action, 'execute', return_value=(action.RES_OK, 'BIG SUCCESS')) mock_load.return_value = action - res = action_base.ActionProc(self.ctx, 'ACTION') + res = ab.ActionProc(self.ctx, 'ACTION') self.assertTrue(res) mock_load.assert_called_once_with(self.ctx, action_id='ACTION') @@ -811,17 +809,17 @@ class ActionProcTest(base.SenlinTestCase): self.assertEqual('BIG SUCCESS', action.status_reason) @mock.patch.object(EVENT, 'info') - @mock.patch.object(action_base.Action, 'load') - @mock.patch.object(db_api, 'action_mark_failed') + @mock.patch.object(ab.Action, 'load') + @mock.patch.object(ao.Action, 'mark_failed') def test_action_proc_failed_error(self, mock_mark, mock_load, mock_event_info): - action = action_base.Action('OBJID', 'OBJECT_ACTION', self.ctx) + action = ab.Action('OBJID', 'OBJECT_ACTION', self.ctx) action.owner = 'WORKER' action.start_time = 123456 self.patchobject(action, 'execute', side_effect=Exception('Boom!')) mock_load.return_value = action - res = action_base.ActionProc(self.ctx, 'ACTION') + res = ab.ActionProc(self.ctx, 'ACTION') self.assertFalse(res) mock_load.assert_called_once_with(self.ctx, action_id='ACTION') diff --git a/senlin/tests/unit/engine/actions/test_cluster_action.py b/senlin/tests/unit/engine/actions/test_cluster_action.py index 918d1c3b..9924805d 100644 --- a/senlin/tests/unit/engine/actions/test_cluster_action.py +++ b/senlin/tests/unit/engine/actions/test_cluster_action.py @@ -15,18 +15,19 @@ import mock from senlin.common import exception from senlin.common.i18n import _ from senlin.common import scaleutils -from senlin.db.sqlalchemy import api as db_api -from senlin.engine.actions import base as base_action +from senlin.engine.actions import base as ab from senlin.engine.actions import cluster_action as ca -from senlin.engine import cluster as cluster_mod +from senlin.engine import cluster as cm from senlin.engine import dispatcher from senlin.engine import event as EVENT -from senlin.engine import node as node_mod +from senlin.engine import node as nm from senlin.engine import scheduler from senlin.engine import senlin_lock +from senlin.objects import action as ao +from senlin.objects import cluster as co from senlin.objects import dependency as dobj from senlin.objects import node as no -from senlin.policies import base as policy_base +from senlin.policies import base as pb from senlin.tests.unit.common import base from senlin.tests.unit.common import utils @@ -35,48 +36,48 @@ class ClusterActionWaitTest(base.SenlinTestCase): scenarios = [ ('wait_ready', dict( statuses=[ - base_action.Action.WAITING, - base_action.Action.READY + ab.Action.WAITING, + ab.Action.READY ], cancelled=[False, False], timeout=[False, False], failed=[False, False], - code=base_action.Action.RES_OK, + code=ab.Action.RES_OK, rescheduled_times=1, message='All dependents ended with success') ), ('wait_fail', dict( statuses=[ - base_action.Action.WAITING, - base_action.Action.FAILED + ab.Action.WAITING, + ab.Action.FAILED ], cancelled=[False, False], timeout=[False, False], - code=base_action.Action.RES_ERROR, + code=ab.Action.RES_ERROR, rescheduled_times=1, message='ACTION [FAKE_ID] failed') ), ('wait_wait_cancel', dict( statuses=[ - base_action.Action.WAITING, - base_action.Action.WAITING, - base_action.Action.WAITING, + ab.Action.WAITING, + ab.Action.WAITING, + ab.Action.WAITING, ], cancelled=[False, False, True], timeout=[False, False, False], - code=base_action.Action.RES_CANCEL, + code=ab.Action.RES_CANCEL, rescheduled_times=2, message='ACTION [FAKE_ID] cancelled') ), ('wait_wait_timeout', dict( statuses=[ - base_action.Action.WAITING, - base_action.Action.WAITING, - base_action.Action.WAITING, + ab.Action.WAITING, + ab.Action.WAITING, + ab.Action.WAITING, ], cancelled=[False, False, False], timeout=[False, False, True], - code=base_action.Action.RES_TIMEOUT, + code=ab.Action.RES_TIMEOUT, rescheduled_times=2, message='ACTION [FAKE_ID] timeout') ), @@ -87,7 +88,7 @@ class ClusterActionWaitTest(base.SenlinTestCase): super(ClusterActionWaitTest, self).setUp() self.ctx = utils.dummy_context() - @mock.patch.object(cluster_mod.Cluster, 'load') + @mock.patch.object(cm.Cluster, 'load') @mock.patch.object(scheduler, 'reschedule') def test_wait_dependents(self, mock_reschedule, mock_load): action = ca.ClusterAction('ID', 'ACTION', self.ctx) @@ -102,17 +103,17 @@ class ClusterActionWaitTest(base.SenlinTestCase): self.assertEqual(self.rescheduled_times, mock_reschedule.call_count) -@mock.patch.object(cluster_mod.Cluster, 'load') +@mock.patch.object(cm.Cluster, 'load') class ClusterActionTest(base.SenlinTestCase): def setUp(self): super(ClusterActionTest, self).setUp() self.ctx = utils.dummy_context() - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') - @mock.patch.object(db_api, 'cluster_next_index') - @mock.patch.object(node_mod, 'Node') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') + @mock.patch.object(co.Cluster, 'next_index') + @mock.patch.object(nm, 'Node') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -164,12 +165,12 @@ class ClusterActionTest(base.SenlinTestCase): 'CLUSTER_ACTION_ID') mock_update.assert_called_once_with( action.context, 'NODE_ACTION_ID', - {'status': base_action.Action.READY}) + {'status': ab.Action.READY}) mock_start.assert_called_once_with() mock_wait.assert_called_once_with() self.assertEqual({'nodes_added': ['NODE_ID']}, action.outputs) - @mock.patch.object(db_api, 'cluster_get') + @mock.patch.object(co.Cluster, 'get') def test_create_nodes_zero(self, mock_get, mock_load): cluster = mock.Mock() cluster.id = 'FAKE_CLUSTER' @@ -182,10 +183,10 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_OK, res_code) self.assertEqual('', res_msg) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') - @mock.patch.object(db_api, 'cluster_next_index') - @mock.patch.object(node_mod, 'Node') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') + @mock.patch.object(co.Cluster, 'next_index') + @mock.patch.object(nm, 'Node') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -259,9 +260,9 @@ class ClusterActionTest(base.SenlinTestCase): cluster.add_node.assert_has_calls([ mock.call(node1), mock.call(node2)]) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(db_api, 'cluster_get') - @mock.patch.object(node_mod, 'Node') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(co.Cluster, 'get') + @mock.patch.object(nm, 'Node') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -299,7 +300,7 @@ class ClusterActionTest(base.SenlinTestCase): # node_action is faked n_action_1 = mock.Mock() n_action_2 = mock.Mock() - self.patchobject(base_action, 'Action', + self.patchobject(ab, 'Action', side_effect=[n_action_1, n_action_2]) # do it @@ -385,8 +386,8 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual('retry', res_msg) cluster.set_status.assert_called_once_with(action.context, 'INIT') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -456,8 +457,8 @@ class ClusterActionTest(base.SenlinTestCase): action.context, 'ACTIVE', 'Cluster update completed.', profile_id='FAKE_PROFILE') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -489,8 +490,8 @@ class ClusterActionTest(base.SenlinTestCase): mock_start.assert_called_once_with() mock_wait.assert_called_once_with() - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -526,8 +527,8 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(['NODE_ID'], action.outputs['nodes_removed']) cluster.remove_node.assert_called_once_with('NODE_ID') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -579,8 +580,8 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_OK, res_code) self.assertEqual('', res_msg) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -611,8 +612,8 @@ class ClusterActionTest(base.SenlinTestCase): action.context, 'NODE_ID', 'NODE_LEAVE', name='node_delete_NODE_ID', cause='Derived Action') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -747,9 +748,9 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_ERROR, res_code) self.assertEqual('Cannot delete cluster object.', res_msg) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') + @mock.patch.object(nm.Node, 'load') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -798,9 +799,9 @@ class ClusterActionTest(base.SenlinTestCase): cluster.store.assert_called_once_with(action.context) cluster.add_node.assert_called_once_with(node) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') + @mock.patch.object(nm.Node, 'load') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -864,7 +865,7 @@ class ClusterActionTest(base.SenlinTestCase): cluster.add_node.assert_has_calls([ mock.call(node1), mock.call(node2)]) - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(nm.Node, 'load') def test_do_add_nodes_node_not_found(self, mock_load_node, mock_load): action = ca.ClusterAction('ID', 'CLUSTER_ACTION', self.ctx) action.inputs = {'nodes': ['NODE_1']} @@ -877,7 +878,7 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_ERROR, res_code) self.assertEqual("Node [NODE_1] is not found.", res_msg) - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(nm.Node, 'load') def test_do_add_nodes_node_already_member(self, mock_load_node, mock_load): cluster = mock.Mock() cluster.id = 'FAKE_CLUSTER' @@ -900,7 +901,7 @@ class ClusterActionTest(base.SenlinTestCase): "[FAKE_CLUSTER].", res_msg) self.assertEqual({}, action.data) - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(nm.Node, 'load') def test_do_add_nodes_node_in_other_cluster(self, mock_load_node, mock_load): cluster = mock.Mock() @@ -923,7 +924,7 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual("Node [NODE_1] is already owned by cluster " "[ANOTHER_CLUSTER].", res_msg) - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(nm.Node, 'load') def test_do_add_nodes_node_not_active(self, mock_load_node, mock_load): action = ca.ClusterAction('ID', 'CLUSTER_ACTION', self.ctx) action.inputs = {'nodes': ['NODE_1']} @@ -943,9 +944,9 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_ERROR, res_code) self.assertEqual("Node [NODE_1] is not in ACTIVE status.", res_msg) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') - @mock.patch.object(node_mod.Node, 'load') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') + @mock.patch.object(nm.Node, 'load') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -969,7 +970,7 @@ class ClusterActionTest(base.SenlinTestCase): # assertions mock_update.assert_called_once_with( action.context, 'NODE_ACTION_ID', - {'status': base_action.Action.READY}) + {'status': ab.Action.READY}) self.assertEqual(action.RES_TIMEOUT, res_code) self.assertEqual('Timeout!', res_msg) self.assertEqual({}, action.data) @@ -1092,8 +1093,8 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_ERROR, res_code) self.assertEqual("Things went bad.", res_msg) - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -1125,10 +1126,10 @@ class ClusterActionTest(base.SenlinTestCase): mock_action.assert_has_calls([ mock.call(action.context, 'NODE_1', 'NODE_CHECK', name='node_check_NODE_1', - cause=base_action.CAUSE_DERIVED), + cause=ab.CAUSE_DERIVED), mock.call(action.context, 'NODE_2', 'NODE_CHECK', name='node_check_NODE_2', - cause=base_action.CAUSE_DERIVED) + cause=ab.CAUSE_DERIVED) ]) mock_dep.assert_called_once_with(action.context, ['NODE_ACTION_1', 'NODE_ACTION_2'], @@ -1176,8 +1177,8 @@ class ClusterActionTest(base.SenlinTestCase): cluster.set_status.assert_called_once_with( action.context, 'old status', 'old reason') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -1206,7 +1207,7 @@ class ClusterActionTest(base.SenlinTestCase): mock_action.assert_called_once_with( action.context, 'NODE_1', 'NODE_CHECK', name='node_check_NODE_1', - cause=base_action.CAUSE_DERIVED, + cause=ab.CAUSE_DERIVED, ) mock_dep.assert_called_once_with(action.context, ['NODE_ACTION_ID'], 'CLUSTER_ACTION_ID') @@ -1217,8 +1218,8 @@ class ClusterActionTest(base.SenlinTestCase): cluster.set_status.assert_called_once_with( action.context, 'old status', 'old reason') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -1250,7 +1251,7 @@ class ClusterActionTest(base.SenlinTestCase): mock_action.assert_called_once_with( action.context, 'NODE_2', 'NODE_RECOVER', name='node_recover_NODE_2', - cause=base_action.CAUSE_DERIVED, + cause=ab.CAUSE_DERIVED, inputs={'operation': 'RECREATE'} ) mock_dep.assert_called_once_with(action.context, ['NODE_RECOVER_ID'], @@ -1277,8 +1278,8 @@ class ClusterActionTest(base.SenlinTestCase): mock_load.assert_called_once_with(self.ctx, 'FAKE_CLUSTER') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -1312,7 +1313,7 @@ class ClusterActionTest(base.SenlinTestCase): mock_action.assert_called_once_with( action.context, 'NODE_1', 'NODE_RECOVER', name='node_recover_NODE_1', - cause=base_action.CAUSE_DERIVED, + cause=ab.CAUSE_DERIVED, inputs={'operation': 'REBOOT'} ) mock_dep.assert_called_once_with(action.context, ['NODE_RECOVER_ID'], @@ -1344,8 +1345,8 @@ class ClusterActionTest(base.SenlinTestCase): cluster.set_status.assert_called_once_with( action.context, cluster.ACTIVE, 'Cluster recovery succeeded.') - @mock.patch.object(db_api, 'action_update') - @mock.patch.object(base_action.Action, 'create') + @mock.patch.object(ao.Action, 'update') + @mock.patch.object(ab.Action, 'create') @mock.patch.object(dobj.Dependency, 'create') @mock.patch.object(dispatcher, 'start_action') @mock.patch.object(ca.ClusterAction, '_wait_for_dependents') @@ -1373,7 +1374,7 @@ class ClusterActionTest(base.SenlinTestCase): mock_action.assert_called_once_with( action.context, 'NODE_1', 'NODE_RECOVER', name='node_recover_NODE_1', - cause=base_action.CAUSE_DERIVED, + cause=ab.CAUSE_DERIVED, inputs={'operation': 'RECREATE'} ) mock_dep.assert_called_once_with(action.context, ['NODE_ACTION_ID'], @@ -2270,7 +2271,7 @@ class ClusterActionTest(base.SenlinTestCase): self.assertEqual(action.RES_ERROR, res_code) self.assertEqual('Policy not specified.', res_msg) - @mock.patch.object(base_action.Action, 'policy_check') + @mock.patch.object(ab.Action, 'policy_check') def test__execute(self, mock_check, mock_load): cluster = mock.Mock() cluster.id = 'FAKE_CLUSTER' @@ -2278,7 +2279,7 @@ class ClusterActionTest(base.SenlinTestCase): action = ca.ClusterAction(cluster.id, 'CLUSTER_FLY', self.ctx) action.do_fly = mock.Mock(return_value=(action.RES_OK, 'Good!')) action.data = { - 'status': policy_base.CHECK_OK, + 'status': pb.CHECK_OK, 'reason': 'Policy checking passed' } @@ -2291,7 +2292,7 @@ class ClusterActionTest(base.SenlinTestCase): mock.call('FAKE_CLUSTER', 'AFTER')]) @mock.patch.object(EVENT, 'error') - @mock.patch.object(base_action.Action, 'policy_check') + @mock.patch.object(ab.Action, 'policy_check') def test_execute_failed_policy_check(self, mock_check, mock_error, mock_load): cluster = mock.Mock() @@ -2300,7 +2301,7 @@ class ClusterActionTest(base.SenlinTestCase): action = ca.ClusterAction(cluster.id, 'CLUSTER_FLY', self.ctx) action.do_fly = mock.Mock(return_value=(action.RES_OK, 'Good!')) action.data = { - 'status': policy_base.CHECK_ERROR, + 'status': pb.CHECK_ERROR, 'reason': 'Something is wrong.' } @@ -2314,7 +2315,7 @@ class ClusterActionTest(base.SenlinTestCase): 'Policy check failure: Something is wrong.') @mock.patch.object(EVENT, 'error') - @mock.patch.object(base_action.Action, 'policy_check') + @mock.patch.object(ab.Action, 'policy_check') def test_execute_unsupported_action(self, mock_check, mock_error, mock_load): cluster = mock.Mock() @@ -2322,7 +2323,7 @@ class ClusterActionTest(base.SenlinTestCase): mock_load.return_value = cluster action = ca.ClusterAction(cluster.id, 'CLUSTER_DANCE', self.ctx) action.data = { - 'status': policy_base.CHECK_OK, + 'status': pb.CHECK_OK, 'reason': 'All is going well.' } @@ -2340,12 +2341,12 @@ class ClusterActionTest(base.SenlinTestCase): def fake_check(cluster_id, target): if target == 'BEFORE': action.data = { - 'status': policy_base.CHECK_OK, + 'status': pb.CHECK_OK, 'reason': 'Policy checking passed.' } else: action.data = { - 'status': policy_base.CHECK_ERROR, + 'status': pb.CHECK_ERROR, 'reason': 'Policy checking failed.' } diff --git a/senlin/tests/unit/engine/service/test_actions.py b/senlin/tests/unit/engine/service/test_actions.py index 035463d3..efdc4aad 100644 --- a/senlin/tests/unit/engine/service/test_actions.py +++ b/senlin/tests/unit/engine/service/test_actions.py @@ -16,9 +16,9 @@ from oslo_utils import uuidutils import six from senlin.common import exception as exc -from senlin.db import api as db_api from senlin.engine.actions import base as action_base from senlin.engine import service +from senlin.objects import action as ao from senlin.tests.unit.common import base from senlin.tests.unit.common import utils @@ -31,7 +31,7 @@ class ActionTest(base.SenlinTestCase): self.eng = service.EngineService('host-a', 'topic-a') self.eng.init_tgm() - @mock.patch.object(db_api, 'action_get') + @mock.patch.object(ao.Action, 'get') def test_action_find_by_uuid(self, mock_get): x_action = mock.Mock() mock_get.return_value = x_action @@ -42,8 +42,8 @@ class ActionTest(base.SenlinTestCase): self.assertEqual(x_action, result) mock_get.assert_called_once_with(self.ctx, aid, project_safe=True) - @mock.patch.object(db_api, 'action_get_by_name') - @mock.patch.object(db_api, 'action_get') + @mock.patch.object(ao.Action, 'get_by_name') + @mock.patch.object(ao.Action, 'get') def test_action_find_by_uuid_as_name(self, mock_get, mock_get_name): x_action = mock.Mock() mock_get_name.return_value = x_action @@ -57,7 +57,7 @@ class ActionTest(base.SenlinTestCase): mock_get_name.assert_called_once_with(self.ctx, aid, project_safe=False) - @mock.patch.object(db_api, 'action_get_by_name') + @mock.patch.object(ao.Action, 'get_by_name') def test_action_find_by_name(self, mock_get_name): x_action = mock.Mock() mock_get_name.return_value = x_action @@ -68,8 +68,8 @@ class ActionTest(base.SenlinTestCase): self.assertEqual(x_action, result) mock_get_name.assert_called_once_with(self.ctx, aid, project_safe=True) - @mock.patch.object(db_api, 'action_get_by_short_id') - @mock.patch.object(db_api, 'action_get_by_name') + @mock.patch.object(ao.Action, 'get_by_short_id') + @mock.patch.object(ao.Action, 'get_by_name') def test_action_find_by_shortid(self, mock_get_name, mock_get_shortid): x_action = mock.Mock() mock_get_shortid.return_value = x_action @@ -84,7 +84,7 @@ class ActionTest(base.SenlinTestCase): mock_get_shortid.assert_called_once_with(self.ctx, aid, project_safe=False) - @mock.patch.object(db_api, 'action_get_by_name') + @mock.patch.object(ao.Action, 'get_by_name') def test_action_find_not_found(self, mock_get_name): mock_get_name.return_value = None diff --git a/senlin/tests/unit/engine/test_senlin_lock.py b/senlin/tests/unit/engine/test_senlin_lock.py index 08e49eb8..d5e927a5 100644 --- a/senlin/tests/unit/engine/test_senlin_lock.py +++ b/senlin/tests/unit/engine/test_senlin_lock.py @@ -14,9 +14,9 @@ import datetime import mock from oslo_config import cfg -from senlin.db.sqlalchemy import api as db_api from senlin.engine import scheduler from senlin.engine import senlin_lock as lockm +from senlin.objects import action as ao from senlin.objects import cluster_lock as clo from senlin.objects import node_lock as nlo from senlin.objects import service as service_obj @@ -31,9 +31,8 @@ class SenlinLockTest(base.SenlinTestCase): self.ctx = utils.dummy_context() - self.stub_get = self.patchobject( - db_api, 'action_get', - return_value=mock.Mock(owner='ENGINE', id='ACTION_ABC')) + ret = mock.Mock(owner='ENGINE', id='ACTION_ABC') + self.stub_get = self.patchobject(ao.Action, 'get', return_value=ret) @mock.patch.object(clo.ClusterLock, "acquire") def test_cluster_lock_acquire_already_owner(self, mock_acquire): @@ -47,7 +46,7 @@ class SenlinLockTest(base.SenlinTestCase): @mock.patch.object(lockm, 'is_engine_dead') @mock.patch.object(scheduler, 'sleep') - @mock.patch.object(db_api, 'action_mark_failed') + @mock.patch.object(ao.Action, 'mark_failed') @mock.patch.object(clo.ClusterLock, "acquire") @mock.patch.object(clo.ClusterLock, "steal") def test_cluster_lock_acquire_dead_owner(self, mock_steal, mock_acquire, @@ -170,7 +169,7 @@ class SenlinLockTest(base.SenlinTestCase): mock_acquire.assert_called_once_with('NODE_A', 'ACTION_XYZ') @mock.patch.object(lockm, 'is_engine_dead') - @mock.patch.object(db_api, 'action_mark_failed') + @mock.patch.object(ao.Action, 'mark_failed') @mock.patch.object(nlo.NodeLock, "acquire") @mock.patch.object(nlo.NodeLock, "steal") def test_node_lock_acquire_dead_owner(self, mock_steal, mock_acquire, @@ -243,7 +242,7 @@ class SenlinLockTest(base.SenlinTestCase): mock_acquire.assert_has_calls(acquire_calls * 3) mock_steal.assert_called_once_with('NODE_A', 'ACTION_XY') - @mock.patch.object(db_api, 'action_get') + @mock.patch.object(ao.Action, 'get') @mock.patch.object(scheduler, 'sleep') @mock.patch.object(nlo.NodeLock, "acquire") @mock.patch.object(nlo.NodeLock, "steal")