Added action_plan.execution.* actions
Partially Implements: blueprint action-plan-versioned-notifications-api Change-Id: I9bd346c19f1cafcaa720de554fd9c056c76de050
This commit is contained in:
parent
e51e7e4317
commit
d49c6c16a6
55
doc/notification_samples/action_plan-execution-end.json
Normal file
55
doc/notification_samples/action_plan-execution-end.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"event_type": "action_plan.execution.end",
|
||||||
|
"payload": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "ActionPlanActionPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"audit": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "TerseAuditPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
|
||||||
|
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
|
||||||
|
"scope": [],
|
||||||
|
"audit_type": "ONESHOT",
|
||||||
|
"state": "SUCCEEDED",
|
||||||
|
"parameters": {},
|
||||||
|
"interval": null,
|
||||||
|
"updated_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
|
||||||
|
"fault": null,
|
||||||
|
"state": "ONGOING",
|
||||||
|
"global_efficacy": {},
|
||||||
|
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||||
|
"strategy": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "StrategyPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"name": "TEST",
|
||||||
|
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||||
|
"parameters_spec": {},
|
||||||
|
"display_name": "test strategy",
|
||||||
|
"updated_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priority": "INFO",
|
||||||
|
"message_id": "3984dc2b-8aef-462b-a220-8ae04237a56e",
|
||||||
|
"timestamp": "2016-10-18 09:52:05.219414",
|
||||||
|
"publisher_id": "infra-optim:node0"
|
||||||
|
}
|
65
doc/notification_samples/action_plan-execution-error.json
Normal file
65
doc/notification_samples/action_plan-execution-error.json
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"event_type": "action_plan.execution.error",
|
||||||
|
"publisher_id": "infra-optim:node0",
|
||||||
|
"priority": "ERROR",
|
||||||
|
"message_id": "9a45c5ae-0e21-4300-8fa0-5555d52a66d9",
|
||||||
|
"payload": {
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "ActionPlanActionPayload",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"fault": {
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "ExceptionPayload",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"exception_message": "TEST",
|
||||||
|
"module_name": "watcher.tests.notifications.test_action_plan_notification",
|
||||||
|
"function_name": "test_send_action_plan_action_with_error",
|
||||||
|
"exception": "WatcherException"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||||
|
"strategy": {
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "StrategyPayload",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"name": "TEST",
|
||||||
|
"updated_at": null,
|
||||||
|
"display_name": "test strategy",
|
||||||
|
"parameters_spec": {},
|
||||||
|
"deleted_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": null,
|
||||||
|
"deleted_at": null,
|
||||||
|
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"audit": {
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "TerseAuditPayload",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"parameters": {},
|
||||||
|
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
|
||||||
|
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"scope": [],
|
||||||
|
"updated_at": null,
|
||||||
|
"audit_type": "ONESHOT",
|
||||||
|
"interval": null,
|
||||||
|
"deleted_at": null,
|
||||||
|
"state": "PENDING"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"global_efficacy": {},
|
||||||
|
"state": "ONGOING"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"timestamp": "2016-10-18 09:52:05.219414"
|
||||||
|
}
|
55
doc/notification_samples/action_plan-execution-start.json
Normal file
55
doc/notification_samples/action_plan-execution-start.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"event_type": "action_plan.execution.start",
|
||||||
|
"payload": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "ActionPlanActionPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"audit": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "TerseAuditPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
|
||||||
|
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
|
||||||
|
"scope": [],
|
||||||
|
"audit_type": "ONESHOT",
|
||||||
|
"state": "PENDING",
|
||||||
|
"parameters": {},
|
||||||
|
"interval": null,
|
||||||
|
"updated_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
|
||||||
|
"fault": null,
|
||||||
|
"state": "ONGOING",
|
||||||
|
"global_efficacy": {},
|
||||||
|
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||||
|
"strategy": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "StrategyPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"name": "TEST",
|
||||||
|
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||||
|
"parameters_spec": {},
|
||||||
|
"display_name": "test strategy",
|
||||||
|
"updated_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updated_at": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priority": "INFO",
|
||||||
|
"message_id": "3984dc2b-8aef-462b-a220-8ae04237a56e",
|
||||||
|
"timestamp": "2016-10-18 09:52:05.219414",
|
||||||
|
"publisher_id": "infra-optim:node0"
|
||||||
|
}
|
@ -20,33 +20,47 @@ from oslo_log import log
|
|||||||
|
|
||||||
from watcher.applier.action_plan import base
|
from watcher.applier.action_plan import base
|
||||||
from watcher.applier import default
|
from watcher.applier import default
|
||||||
|
from watcher import notifications
|
||||||
from watcher import objects
|
from watcher import objects
|
||||||
|
from watcher.objects import fields
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DefaultActionPlanHandler(base.BaseActionPlanHandler):
|
class DefaultActionPlanHandler(base.BaseActionPlanHandler):
|
||||||
|
|
||||||
def __init__(self, context, service, action_plan_uuid):
|
def __init__(self, context, service, action_plan_uuid):
|
||||||
super(DefaultActionPlanHandler, self).__init__()
|
super(DefaultActionPlanHandler, self).__init__()
|
||||||
self.ctx = context
|
self.ctx = context
|
||||||
self.service = service
|
self.service = service
|
||||||
self.action_plan_uuid = action_plan_uuid
|
self.action_plan_uuid = action_plan_uuid
|
||||||
|
|
||||||
def update_action_plan(self, uuid, state):
|
|
||||||
action_plan = objects.ActionPlan.get_by_uuid(
|
|
||||||
self.ctx, uuid, eager=True)
|
|
||||||
action_plan.state = state
|
|
||||||
action_plan.save()
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
try:
|
try:
|
||||||
self.update_action_plan(self.action_plan_uuid,
|
action_plan = objects.ActionPlan.get_by_uuid(
|
||||||
objects.action_plan.State.ONGOING)
|
self.ctx, self.action_plan_uuid, eager=True)
|
||||||
|
action_plan.state = objects.action_plan.State.ONGOING
|
||||||
|
action_plan.save()
|
||||||
|
notifications.action_plan.send_action_notification(
|
||||||
|
self.ctx, action_plan,
|
||||||
|
action=fields.NotificationAction.EXECUTION,
|
||||||
|
phase=fields.NotificationPhase.START)
|
||||||
|
|
||||||
applier = default.DefaultApplier(self.ctx, self.service)
|
applier = default.DefaultApplier(self.ctx, self.service)
|
||||||
applier.execute(self.action_plan_uuid)
|
applier.execute(self.action_plan_uuid)
|
||||||
state = objects.action_plan.State.SUCCEEDED
|
|
||||||
|
action_plan.state = objects.action_plan.State.SUCCEEDED
|
||||||
|
notifications.action_plan.send_action_notification(
|
||||||
|
self.ctx, action_plan,
|
||||||
|
action=fields.NotificationAction.EXECUTION,
|
||||||
|
phase=fields.NotificationPhase.END)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
state = objects.action_plan.State.FAILED
|
action_plan.state = objects.action_plan.State.FAILED
|
||||||
|
notifications.action_plan.send_action_notification(
|
||||||
|
self.ctx, action_plan,
|
||||||
|
action=fields.NotificationAction.EXECUTION,
|
||||||
|
priority=fields.NotificationPriority.ERROR,
|
||||||
|
phase=fields.NotificationPhase.ERROR)
|
||||||
finally:
|
finally:
|
||||||
self.update_action_plan(self.action_plan_uuid, state)
|
action_plan.save()
|
||||||
|
@ -56,7 +56,7 @@ class DefaultApplier(base.BaseApplier):
|
|||||||
|
|
||||||
def execute(self, action_plan_uuid):
|
def execute(self, action_plan_uuid):
|
||||||
LOG.debug("Executing action plan %s ", action_plan_uuid)
|
LOG.debug("Executing action plan %s ", action_plan_uuid)
|
||||||
|
|
||||||
filters = {'action_plan_uuid': action_plan_uuid}
|
filters = {'action_plan_uuid': action_plan_uuid}
|
||||||
actions = objects.Action.list(self.context,
|
actions = objects.Action.list(self.context, filters=filters)
|
||||||
filters=filters)
|
|
||||||
return self.engine.execute(actions)
|
return self.engine.execute(actions)
|
||||||
|
@ -22,6 +22,7 @@ from watcher.common import context as wcontext
|
|||||||
from watcher.common import exception
|
from watcher.common import exception
|
||||||
from watcher.notifications import audit as audit_notifications
|
from watcher.notifications import audit as audit_notifications
|
||||||
from watcher.notifications import base as notificationbase
|
from watcher.notifications import base as notificationbase
|
||||||
|
from watcher.notifications import exception as exception_notifications
|
||||||
from watcher.notifications import strategy as strategy_notifications
|
from watcher.notifications import strategy as strategy_notifications
|
||||||
from watcher import objects
|
from watcher import objects
|
||||||
from watcher.objects import base
|
from watcher.objects import base
|
||||||
@ -138,6 +139,19 @@ class ActionPlanDeletePayload(ActionPlanPayload):
|
|||||||
strategy=strategy)
|
strategy=strategy)
|
||||||
|
|
||||||
|
|
||||||
|
@notificationbase.notification_sample('action_plan-execution-error.json')
|
||||||
|
@notificationbase.notification_sample('action_plan-execution-end.json')
|
||||||
|
@notificationbase.notification_sample('action_plan-execution-start.json')
|
||||||
|
@base.WatcherObjectRegistry.register_notification
|
||||||
|
class ActionPlanActionNotification(notificationbase.NotificationBase):
|
||||||
|
# Version 1.0: Initial version
|
||||||
|
VERSION = '1.0'
|
||||||
|
|
||||||
|
fields = {
|
||||||
|
'payload': wfields.ObjectField('ActionPlanActionPayload')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@notificationbase.notification_sample('action_plan-create.json')
|
@notificationbase.notification_sample('action_plan-create.json')
|
||||||
@base.WatcherObjectRegistry.register_notification
|
@base.WatcherObjectRegistry.register_notification
|
||||||
class ActionPlanCreateNotification(notificationbase.NotificationBase):
|
class ActionPlanCreateNotification(notificationbase.NotificationBase):
|
||||||
@ -265,3 +279,34 @@ def send_delete(context, action_plan, service='infra-optim', host=None):
|
|||||||
payload=versioned_payload)
|
payload=versioned_payload)
|
||||||
|
|
||||||
notification.emit(context)
|
notification.emit(context)
|
||||||
|
|
||||||
|
|
||||||
|
def send_action_notification(context, action_plan, action, phase=None,
|
||||||
|
priority=wfields.NotificationPriority.INFO,
|
||||||
|
service='infra-optim', host=None):
|
||||||
|
"""Emit an action_plan action notification."""
|
||||||
|
audit_payload, strategy_payload = _get_common_payload(action_plan)
|
||||||
|
|
||||||
|
fault = None
|
||||||
|
if phase == wfields.NotificationPhase.ERROR:
|
||||||
|
fault = exception_notifications.ExceptionPayload.from_exception()
|
||||||
|
|
||||||
|
versioned_payload = ActionPlanActionPayload(
|
||||||
|
action_plan=action_plan,
|
||||||
|
audit=audit_payload,
|
||||||
|
strategy=strategy_payload,
|
||||||
|
fault=fault,
|
||||||
|
)
|
||||||
|
|
||||||
|
notification = ActionPlanActionNotification(
|
||||||
|
priority=priority,
|
||||||
|
event_type=notificationbase.EventType(
|
||||||
|
object='action_plan',
|
||||||
|
action=action,
|
||||||
|
phase=phase),
|
||||||
|
publisher=notificationbase.NotificationPublisher(
|
||||||
|
host=host or CONF.host,
|
||||||
|
binary=service),
|
||||||
|
payload=versioned_payload)
|
||||||
|
|
||||||
|
notification.emit(context)
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
import mock
|
import mock
|
||||||
|
|
||||||
from watcher.applier.action_plan import default
|
from watcher.applier.action_plan import default
|
||||||
|
from watcher.applier import default as ap_applier
|
||||||
|
from watcher import notifications
|
||||||
|
from watcher import objects
|
||||||
from watcher.objects import action_plan as ap_objects
|
from watcher.objects import action_plan as ap_objects
|
||||||
from watcher.tests.db import base
|
from watcher.tests.db import base
|
||||||
from watcher.tests.objects import utils as obj_utils
|
from watcher.tests.objects import utils as obj_utils
|
||||||
@ -25,17 +28,67 @@ from watcher.tests.objects import utils as obj_utils
|
|||||||
|
|
||||||
class TestDefaultActionPlanHandler(base.DbTestCase):
|
class TestDefaultActionPlanHandler(base.DbTestCase):
|
||||||
|
|
||||||
|
class FakeApplierException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestDefaultActionPlanHandler, self).setUp()
|
super(TestDefaultActionPlanHandler, self).setUp()
|
||||||
|
|
||||||
|
p_action_plan_notifications = mock.patch.object(
|
||||||
|
notifications, 'action_plan', autospec=True)
|
||||||
|
self.m_action_plan_notifications = p_action_plan_notifications.start()
|
||||||
|
self.addCleanup(p_action_plan_notifications.stop)
|
||||||
|
|
||||||
obj_utils.create_test_goal(self.context)
|
obj_utils.create_test_goal(self.context)
|
||||||
obj_utils.create_test_strategy(self.context)
|
obj_utils.create_test_strategy(self.context)
|
||||||
obj_utils.create_test_audit(self.context)
|
obj_utils.create_test_audit(self.context)
|
||||||
self.action_plan = obj_utils.create_test_action_plan(self.context)
|
self.action_plan = obj_utils.create_test_action_plan(self.context)
|
||||||
|
|
||||||
def test_launch_action_plan(self):
|
@mock.patch.object(objects.ActionPlan, "get_by_uuid")
|
||||||
|
def test_launch_action_plan(self, m_get_action_plan):
|
||||||
|
m_get_action_plan.return_value = self.action_plan
|
||||||
command = default.DefaultActionPlanHandler(
|
command = default.DefaultActionPlanHandler(
|
||||||
self.context, mock.MagicMock(), self.action_plan.uuid)
|
self.context, mock.MagicMock(), self.action_plan.uuid)
|
||||||
command.execute()
|
command.execute()
|
||||||
action_plan = ap_objects.ActionPlan.get_by_uuid(
|
|
||||||
self.context, self.action_plan.uuid)
|
expected_calls = [
|
||||||
self.assertEqual(ap_objects.State.SUCCEEDED, action_plan.state)
|
mock.call(self.context, self.action_plan,
|
||||||
|
action=objects.fields.NotificationAction.EXECUTION,
|
||||||
|
phase=objects.fields.NotificationPhase.START),
|
||||||
|
mock.call(self.context, self.action_plan,
|
||||||
|
action=objects.fields.NotificationAction.EXECUTION,
|
||||||
|
phase=objects.fields.NotificationPhase.END)]
|
||||||
|
|
||||||
|
self.assertEqual(ap_objects.State.SUCCEEDED, self.action_plan.state)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
expected_calls,
|
||||||
|
self.m_action_plan_notifications
|
||||||
|
.send_action_notification
|
||||||
|
.call_args_list)
|
||||||
|
|
||||||
|
@mock.patch.object(ap_applier.DefaultApplier, "execute")
|
||||||
|
@mock.patch.object(objects.ActionPlan, "get_by_uuid")
|
||||||
|
def test_launch_action_plan_with_error(self, m_get_action_plan, m_execute):
|
||||||
|
m_get_action_plan.return_value = self.action_plan
|
||||||
|
m_execute.side_effect = self.FakeApplierException
|
||||||
|
command = default.DefaultActionPlanHandler(
|
||||||
|
self.context, mock.MagicMock(), self.action_plan.uuid)
|
||||||
|
command.execute()
|
||||||
|
|
||||||
|
expected_calls = [
|
||||||
|
mock.call(self.context, self.action_plan,
|
||||||
|
action=objects.fields.NotificationAction.EXECUTION,
|
||||||
|
phase=objects.fields.NotificationPhase.START),
|
||||||
|
mock.call(self.context, self.action_plan,
|
||||||
|
action=objects.fields.NotificationAction.EXECUTION,
|
||||||
|
priority=objects.fields.NotificationPriority.ERROR,
|
||||||
|
phase=objects.fields.NotificationPhase.ERROR)]
|
||||||
|
|
||||||
|
self.assertEqual(ap_objects.State.FAILED, self.action_plan.state)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
expected_calls,
|
||||||
|
self.m_action_plan_notifications
|
||||||
|
.send_action_notification
|
||||||
|
.call_args_list)
|
||||||
|
@ -259,3 +259,161 @@ class TestActionPlanNotification(base.DbTestCase):
|
|||||||
},
|
},
|
||||||
payload
|
payload
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_send_action_plan_action(self):
|
||||||
|
action_plan = utils.create_test_action_plan(
|
||||||
|
mock.Mock(), state=objects.action_plan.State.ONGOING,
|
||||||
|
audit_id=self.audit.id, strategy_id=self.strategy.id,
|
||||||
|
audit=self.audit, strategy=self.strategy)
|
||||||
|
notifications.action_plan.send_action_notification(
|
||||||
|
mock.MagicMock(), action_plan, host='node0',
|
||||||
|
action='execution', phase='start')
|
||||||
|
|
||||||
|
# The 1st notification is because we created the audit object.
|
||||||
|
# The 2nd notification is because we created the action plan object.
|
||||||
|
self.assertEqual(3, self.m_notifier.info.call_count)
|
||||||
|
notification = self.m_notifier.info.call_args[1]
|
||||||
|
|
||||||
|
self.assertEqual("infra-optim:node0", self.m_notifier.publisher_id)
|
||||||
|
self.assertDictEqual(
|
||||||
|
{
|
||||||
|
"event_type": "action_plan.execution.start",
|
||||||
|
"payload": {
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": None,
|
||||||
|
"fault": None,
|
||||||
|
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"audit": {
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.name": "TerseAuditPayload",
|
||||||
|
"watcher_object.version": "1.0",
|
||||||
|
"watcher_object.data": {
|
||||||
|
"interval": None,
|
||||||
|
"parameters": {},
|
||||||
|
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"strategy_uuid": None,
|
||||||
|
"goal_uuid": (
|
||||||
|
"f7ad87ae-4298-91cf-93a0-f35a852e3652"),
|
||||||
|
"deleted_at": None,
|
||||||
|
"scope": [],
|
||||||
|
"state": "PENDING",
|
||||||
|
"updated_at": None,
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"audit_type": "ONESHOT"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"global_efficacy": {},
|
||||||
|
"state": "ONGOING",
|
||||||
|
"strategy_uuid": (
|
||||||
|
"cb3d0b58-4415-4d90-b75b-1e96878730e3"),
|
||||||
|
"strategy": {
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": None,
|
||||||
|
"display_name": "test strategy",
|
||||||
|
"name": "TEST",
|
||||||
|
"parameters_spec": {},
|
||||||
|
"updated_at": None,
|
||||||
|
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3"
|
||||||
|
},
|
||||||
|
"watcher_object.name": "StrategyPayload",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.version": "1.0"
|
||||||
|
},
|
||||||
|
"updated_at": None,
|
||||||
|
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061"
|
||||||
|
},
|
||||||
|
"watcher_object.name": "ActionPlanActionPayload",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.version": "1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notification
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_send_action_plan_action_with_error(self):
|
||||||
|
action_plan = utils.create_test_action_plan(
|
||||||
|
mock.Mock(), state=objects.action_plan.State.ONGOING,
|
||||||
|
audit_id=self.audit.id, strategy_id=self.strategy.id,
|
||||||
|
audit=self.audit, strategy=self.strategy)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# This is to load the exception in sys.exc_info()
|
||||||
|
raise exception.WatcherException("TEST")
|
||||||
|
except exception.WatcherException:
|
||||||
|
notifications.action_plan.send_action_notification(
|
||||||
|
mock.MagicMock(), action_plan, host='node0',
|
||||||
|
action='execution', priority='error', phase='error')
|
||||||
|
|
||||||
|
self.assertEqual(1, self.m_notifier.error.call_count)
|
||||||
|
notification = self.m_notifier.error.call_args[1]
|
||||||
|
self.assertEqual("infra-optim:node0", self.m_notifier.publisher_id)
|
||||||
|
self.assertDictEqual(
|
||||||
|
{
|
||||||
|
"event_type": "action_plan.execution.error",
|
||||||
|
"payload": {
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": None,
|
||||||
|
"fault": {
|
||||||
|
"watcher_object.data": {
|
||||||
|
"exception": "WatcherException",
|
||||||
|
"exception_message": "TEST",
|
||||||
|
"function_name": (
|
||||||
|
"test_send_action_plan_action_with_error"),
|
||||||
|
"module_name": "watcher.tests.notifications."
|
||||||
|
"test_action_plan_notification"
|
||||||
|
},
|
||||||
|
"watcher_object.name": "ExceptionPayload",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.version": "1.0"
|
||||||
|
},
|
||||||
|
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"audit": {
|
||||||
|
"watcher_object.data": {
|
||||||
|
"interval": None,
|
||||||
|
"parameters": {},
|
||||||
|
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||||
|
"strategy_uuid": None,
|
||||||
|
"goal_uuid": (
|
||||||
|
"f7ad87ae-4298-91cf-93a0-f35a852e3652"),
|
||||||
|
"deleted_at": None,
|
||||||
|
"scope": [],
|
||||||
|
"state": "PENDING",
|
||||||
|
"updated_at": None,
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"audit_type": "ONESHOT"
|
||||||
|
},
|
||||||
|
"watcher_object.name": "TerseAuditPayload",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.version": "1.0"
|
||||||
|
},
|
||||||
|
"global_efficacy": {},
|
||||||
|
"state": "ONGOING",
|
||||||
|
"strategy_uuid": (
|
||||||
|
"cb3d0b58-4415-4d90-b75b-1e96878730e3"),
|
||||||
|
"strategy": {
|
||||||
|
"watcher_object.data": {
|
||||||
|
"created_at": "2016-10-18T09:52:05Z",
|
||||||
|
"deleted_at": None,
|
||||||
|
"display_name": "test strategy",
|
||||||
|
"name": "TEST",
|
||||||
|
"parameters_spec": {},
|
||||||
|
"updated_at": None,
|
||||||
|
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3"
|
||||||
|
},
|
||||||
|
"watcher_object.name": "StrategyPayload",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.version": "1.0"
|
||||||
|
},
|
||||||
|
"updated_at": None,
|
||||||
|
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061"
|
||||||
|
},
|
||||||
|
"watcher_object.name": "ActionPlanActionPayload",
|
||||||
|
"watcher_object.namespace": "watcher",
|
||||||
|
"watcher_object.version": "1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notification
|
||||||
|
)
|
||||||
|
@ -276,6 +276,7 @@ expected_notification_fingerprints = {
|
|||||||
'ActionPlanStateUpdatePayload': '1.0-1a1b606bf14a2c468800c2b010801ce5',
|
'ActionPlanStateUpdatePayload': '1.0-1a1b606bf14a2c468800c2b010801ce5',
|
||||||
'ActionPlanUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
'ActionPlanUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||||
'ActionPlanUpdatePayload': '1.0-7912a45fe53775c721f42aa87f06a023',
|
'ActionPlanUpdatePayload': '1.0-7912a45fe53775c721f42aa87f06a023',
|
||||||
|
'ActionPlanActionNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user