Merge "Added action_plan.execution.* actions"
This commit is contained in:
@@ -18,6 +18,9 @@
|
||||
import mock
|
||||
|
||||
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.tests.db import base
|
||||
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 FakeApplierException(Exception):
|
||||
pass
|
||||
|
||||
def setUp(self):
|
||||
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_strategy(self.context)
|
||||
obj_utils.create_test_audit(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(
|
||||
self.context, mock.MagicMock(), self.action_plan.uuid)
|
||||
command.execute()
|
||||
action_plan = ap_objects.ActionPlan.get_by_uuid(
|
||||
self.context, self.action_plan.uuid)
|
||||
self.assertEqual(ap_objects.State.SUCCEEDED, action_plan.state)
|
||||
|
||||
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,
|
||||
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
|
||||
)
|
||||
|
||||
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',
|
||||
'ActionPlanUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ActionPlanUpdatePayload': '1.0-7912a45fe53775c721f42aa87f06a023',
|
||||
'ActionPlanActionNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user