diff --git a/watcher/decision_engine/audit/default.py b/watcher/decision_engine/audit/default.py index 027fad0c5..80f7a71f1 100644 --- a/watcher/decision_engine/audit/default.py +++ b/watcher/decision_engine/audit/default.py @@ -24,26 +24,21 @@ from watcher.decision_engine.strategy.context.default import \ DefaultStrategyContext from watcher.objects.audit import Audit from watcher.objects.audit import AuditStatus -from watcher.objects.audit_template import AuditTemplate + LOG = log.getLogger(__name__) class DefaultAuditHandler(BaseAuditHandler): - def __init__(self, messaging, cluster_collector): + def __init__(self, messaging): super(DefaultAuditHandler, self).__init__() self._messaging = messaging - self._cluster_collector = cluster_collector self._strategy_context = DefaultStrategyContext() @property def messaging(self): return self._messaging - @property - def cluster_collector(self): - return self._cluster_collector - @property def strategy_context(self): return self._strategy_context @@ -73,15 +68,9 @@ class DefaultAuditHandler(BaseAuditHandler): audit = self.update_audit_state(request_context, audit_uuid, AuditStatus.ONGOING) - # Retrieve cluster-data-model - cluster = self.cluster_collector.get_latest_cluster_data_model() - - # Retrieve the Audit Template - audit_template = AuditTemplate.get_by_id(request_context, - audit.audit_template_id) # execute the strategy - solution = self.strategy_context.execute_strategy(audit_template. - goal, cluster) + solution = self.strategy_context.execute_strategy(audit_uuid, + request_context) # schedule the actions and create in the watcher db the ActionPlan planner = DefaultPlanner() diff --git a/watcher/decision_engine/messaging/audit_endpoint.py b/watcher/decision_engine/messaging/audit_endpoint.py index 322263cb7..09f1950bf 100644 --- a/watcher/decision_engine/messaging/audit_endpoint.py +++ b/watcher/decision_engine/messaging/audit_endpoint.py @@ -21,8 +21,6 @@ from concurrent.futures import ThreadPoolExecutor from oslo_log import log from watcher.decision_engine.audit.default import DefaultAuditHandler -from watcher.metrics_engine.cluster_model_collector.manager import \ - CollectorManager LOG = log.getLogger(__name__) @@ -30,13 +28,8 @@ LOG = log.getLogger(__name__) class AuditEndpoint(object): def __init__(self, messaging, max_workers): self._messaging = messaging - self._collector_manager = CollectorManager() self._executor = ThreadPoolExecutor(max_workers=max_workers) - @property - def collector_manager(self): - return self._collector_manager - @property def executor(self): return self._executor @@ -46,9 +39,7 @@ class AuditEndpoint(object): return self._messaging def do_trigger_audit(self, context, audit_uuid): - model_collector = self.collector_manager.get_cluster_model_collector() - - audit = DefaultAuditHandler(self.messaging, model_collector) + audit = DefaultAuditHandler(self.messaging) audit.execute(audit_uuid, context) def trigger_audit(self, context, audit_uuid): diff --git a/watcher/decision_engine/strategy/context/base.py b/watcher/decision_engine/strategy/context/base.py index 35c6afe13..28f8aec11 100644 --- a/watcher/decision_engine/strategy/context/base.py +++ b/watcher/decision_engine/strategy/context/base.py @@ -23,5 +23,5 @@ import six @six.add_metaclass(abc.ABCMeta) class BaseStrategyContext(object): @abc.abstractmethod - def execute_strategy(self, goal, cluster_data_model): + def execute_strategy(self, audit_uuid, request_context): raise NotImplementedError() diff --git a/watcher/decision_engine/strategy/context/default.py b/watcher/decision_engine/strategy/context/default.py index 4e1103561..2310cbbea 100644 --- a/watcher/decision_engine/strategy/context/default.py +++ b/watcher/decision_engine/strategy/context/default.py @@ -18,6 +18,9 @@ from oslo_log import log from watcher.decision_engine.strategy.context.base import BaseStrategyContext from watcher.decision_engine.strategy.selection.default import \ DefaultStrategySelector +from watcher.metrics_engine.cluster_model_collector.manager import \ + CollectorManager +from watcher import objects LOG = log.getLogger(__name__) @@ -27,11 +30,32 @@ class DefaultStrategyContext(BaseStrategyContext): super(DefaultStrategyContext, self).__init__() LOG.debug("Initializing Strategy Context") self._strategy_selector = DefaultStrategySelector() + self._collector_manager = CollectorManager() + + @property + def collector(self): + return self._collector_manager @property def strategy_selector(self): return self._strategy_selector - def execute_strategy(self, goal, cluster_data_model): - selected_strategy = self.strategy_selector.define_from_goal(goal) + def execute_strategy(self, audit_uuid, request_context): + audit = objects.Audit.get_by_uuid(request_context, audit_uuid) + + # Retrieve the Audit Template + audit_template = objects.\ + AuditTemplate.get_by_id(request_context, audit.audit_template_id) + + # todo(jed) retrieve in audit_template parameters (threshold,...) + # todo(jed) create ActionPlan + collector_manager = self.collector.get_cluster_model_collector() + + # todo(jed) remove call to get_latest_cluster_data_model + cluster_data_model = collector_manager.get_latest_cluster_data_model() + + selected_strategy = self.strategy_selector. \ + define_from_goal(audit_template.goal) + + # todo(jed) add parameters and remove cluster_data_model return selected_strategy.execute(cluster_data_model) diff --git a/watcher/tests/decision_engine/audit/test_default_audit_handler.py b/watcher/tests/decision_engine/audit/test_default_audit_handler.py index 963182a99..312bd6d29 100644 --- a/watcher/tests/decision_engine/audit/test_default_audit_handler.py +++ b/watcher/tests/decision_engine/audit/test_default_audit_handler.py @@ -13,10 +13,12 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. -from mock import call -from mock import MagicMock +import mock + from watcher.decision_engine.audit.default import DefaultAuditHandler from watcher.decision_engine.messaging.events import Events +from watcher.metrics_engine.cluster_model_collector.manager import \ + CollectorManager from watcher.objects.audit import Audit from watcher.objects.audit import AuditStatus from watcher.tests.db.base import DbTestCase @@ -34,28 +36,31 @@ class TestDefaultAuditHandler(DbTestCase): self.context, audit_template_id=self.audit_template.id) - def test_trigger_audit_without_errors(self): - model_collector = FakerModelCollector() - audit_handler = DefaultAuditHandler(MagicMock(), model_collector) + @mock.patch.object(CollectorManager, "get_cluster_model_collector") + def test_trigger_audit_without_errors(self, mock_collector): + mock_collector.return_value = FakerModelCollector() + audit_handler = DefaultAuditHandler(mock.MagicMock()) audit_handler.execute(self.audit.uuid, self.context) - def test_trigger_audit_state_success(self): - model_collector = FakerModelCollector() - audit_handler = DefaultAuditHandler(MagicMock(), model_collector) + @mock.patch.object(CollectorManager, "get_cluster_model_collector") + def test_trigger_audit_state_success(self, mock_collector): + mock_collector.return_value = FakerModelCollector() + audit_handler = DefaultAuditHandler(mock.MagicMock()) audit_handler.execute(self.audit.uuid, self.context) audit = Audit.get_by_uuid(self.context, self.audit.uuid) self.assertEqual(AuditStatus.SUCCEEDED, audit.state) - def test_trigger_audit_send_notification(self): - messaging = MagicMock() - model_collector = FakerModelCollector() - audit_handler = DefaultAuditHandler(messaging, model_collector) + @mock.patch.object(CollectorManager, "get_cluster_model_collector") + def test_trigger_audit_send_notification(self, mock_collector): + messaging = mock.MagicMock() + mock_collector.return_value = FakerModelCollector() + audit_handler = DefaultAuditHandler(messaging) audit_handler.execute(self.audit.uuid, self.context) - call_on_going = call(Events.TRIGGER_AUDIT.name, { + call_on_going = mock.call(Events.TRIGGER_AUDIT.name, { 'audit_status': AuditStatus.ONGOING, 'audit_uuid': self.audit.uuid}) - call_succeeded = call(Events.TRIGGER_AUDIT.name, { + call_succeeded = mock.call(Events.TRIGGER_AUDIT.name, { 'audit_status': AuditStatus.SUCCEEDED, 'audit_uuid': self.audit.uuid}) diff --git a/watcher/tests/decision_engine/messaging/test_audit_endpoint.py b/watcher/tests/decision_engine/messaging/test_audit_endpoint.py index 5e242834a..9288da920 100644 --- a/watcher/tests/decision_engine/messaging/test_audit_endpoint.py +++ b/watcher/tests/decision_engine/messaging/test_audit_endpoint.py @@ -14,55 +14,51 @@ # See the License for the specific language governing permissions and # limitations under the License. import mock -from mock import MagicMock from watcher.common import utils from watcher.decision_engine.audit.default import DefaultAuditHandler from watcher.decision_engine.messaging.audit_endpoint import AuditEndpoint from watcher.metrics_engine.cluster_model_collector.manager import \ CollectorManager -from watcher.tests import base +from watcher.tests.db.base import DbTestCase from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state \ import FakerModelCollector +from watcher.tests.objects import utils as obj_utils -class DefaultAuditHandlerMock(DefaultAuditHandler): - def setUp(self): - super(DefaultAuditHandlerMock, self).setUp() - - def executor(self): - pass - - -class TestAuditEndpoint(base.TestCase): +class TestAuditEndpoint(DbTestCase): def setUp(self): super(TestAuditEndpoint, self).setUp() + self.audit_template = obj_utils.create_test_audit_template( + self.context) + self.audit = obj_utils.create_test_audit( + self.context, + audit_template_id=self.audit_template.id) - def test_do_trigger_audit(self): + @mock.patch.object(CollectorManager, "get_cluster_model_collector") + def test_do_trigger_audit(self, mock_collector): + mock_collector.return_value = FakerModelCollector() audit_uuid = utils.generate_uuid() - model_collector = FakerModelCollector() - audit_handler = DefaultAuditHandler(MagicMock(), model_collector) + + audit_handler = DefaultAuditHandler(mock.MagicMock()) endpoint = AuditEndpoint(audit_handler, max_workers=2) - with mock.patch.object(CollectorManager, 'get_cluster_model_collector') \ - as mock_call2: - mock_call2.return_value = 0 + with mock.patch.object(DefaultAuditHandler, 'execute') as mock_call: + mock_call.return_value = 0 + endpoint.do_trigger_audit(audit_handler, audit_uuid) - with mock.patch.object(DefaultAuditHandler, 'execute') \ - as mock_call: - mock_call.return_value = 0 - endpoint.do_trigger_audit(audit_handler, audit_uuid) - # mock_call.assert_called_once_with() - mock_call2.assert_called_once_with() + mock_call.assert_called_once_with(audit_uuid, audit_handler) - def test_trigger_audit(self): + @mock.patch.object(CollectorManager, "get_cluster_model_collector") + def test_trigger_audit(self, mock_collector): + mock_collector.return_value = FakerModelCollector() audit_uuid = utils.generate_uuid() - model_collector = FakerModelCollector() - audit_handler = DefaultAuditHandlerMock(MagicMock(), - model_collector) + audit_handler = DefaultAuditHandler(mock.MagicMock()) endpoint = AuditEndpoint(audit_handler, max_workers=2) - with mock.patch.object(DefaultAuditHandlerMock, 'executor') \ + with mock.patch.object(DefaultAuditHandler, 'execute') \ as mock_call: mock_call.return_value = 0 endpoint.trigger_audit(audit_handler, audit_uuid) + + mock_call.assert_called_once_with(audit_uuid, audit_handler) diff --git a/watcher/tests/decision_engine/strategy/context/test_strategy_context.py b/watcher/tests/decision_engine/strategy/context/test_strategy_context.py index b7b23bada..1536cda75 100644 --- a/watcher/tests/decision_engine/strategy/context/test_strategy_context.py +++ b/watcher/tests/decision_engine/strategy/context/test_strategy_context.py @@ -13,8 +13,7 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. -from mock import MagicMock -from mock import patch +import mock from watcher.decision_engine.solution.default import DefaultSolution from watcher.decision_engine.strategy.context.default import \ @@ -23,16 +22,28 @@ from watcher.decision_engine.strategy.selection.default import \ DefaultStrategySelector from watcher.decision_engine.strategy.strategies.dummy_strategy import \ DummyStrategy -from watcher.tests import base +from watcher.metrics_engine.cluster_model_collector.manager import \ + CollectorManager +from watcher.tests.db import base +from watcher.tests.objects import utils as obj_utils -class TestStrategyContext(base.BaseTestCase): +class TestStrategyContext(base.DbTestCase): + def setUp(self): + super(TestStrategyContext, self).setUp() + self.audit_template = obj_utils. \ + create_test_audit_template(self.context) + self.audit = obj_utils. \ + create_test_audit(self.context, + audit_template_id=self.audit_template.id) + strategy_context = DefaultStrategyContext() - @patch.object(DefaultStrategySelector, 'define_from_goal') + @mock.patch.object(DefaultStrategySelector, 'define_from_goal') + @mock.patch.object(CollectorManager, "get_cluster_model_collector", + mock.Mock()) def test_execute_strategy(self, mock_call): mock_call.return_value = DummyStrategy() - cluster_data_model = MagicMock() - solution = self.strategy_context.execute_strategy("dummy", - cluster_data_model) + solution = self.strategy_context.execute_strategy(self.audit.uuid, + self.context) self.assertIsInstance(solution, DefaultSolution)