From e03f56e7c71f3fe5dfaf6953e383c6b1b2da245b Mon Sep 17 00:00:00 2001 From: Hidekazu Nakamura Date: Wed, 4 Jan 2017 13:58:03 +0900 Subject: [PATCH] Add period input parameter to basic strategy This patch set adds new period strategy input parameter which allows allows to specify the time length of statistic aggregation. Partial-Bug: #1614021 Change-Id: I1a276206e5b2c05d8f94acdeb866c8822fa84f35 --- .../strategies/basic-server-consolidation.rst | 3 ++ .../strategies/basic_consolidation.py | 18 +++++++-- watcher/tests/common/test_clients.py | 12 +++--- .../strategies/test_basic_consolidation.py | 37 +++++++++++++++++++ 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/doc/source/strategies/basic-server-consolidation.rst b/doc/source/strategies/basic-server-consolidation.rst index 87a1457bd..5d476c2b2 100644 --- a/doc/source/strategies/basic-server-consolidation.rst +++ b/doc/source/strategies/basic-server-consolidation.rst @@ -71,6 +71,9 @@ parameter type default Value description be tried by the strategy while searching for potential candidates. To remove the limit, set it to 0 +``period`` Number 7200 The time interval in seconds + for getting statistic aggregation + from metric data source ====================== ====== ============= =================================== Efficacy Indicator diff --git a/watcher/decision_engine/strategy/strategies/basic_consolidation.py b/watcher/decision_engine/strategy/strategies/basic_consolidation.py index 5be1a9bb2..c8586d6d8 100644 --- a/watcher/decision_engine/strategy/strategies/basic_consolidation.py +++ b/watcher/decision_engine/strategy/strategies/basic_consolidation.py @@ -101,6 +101,10 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy): def migration_attempts(self): return self.input_parameters.get('migration_attempts', 0) + @property + def period(self): + return self.input_parameters.get('period', 7200) + @classmethod def get_display_name(cls): return _("Basic offline consolidation") @@ -122,6 +126,12 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy): "type": "number", "default": 0 }, + "period": { + "description": "The time interval in seconds for " + "getting statistic aggregation", + "type": "number", + "default": 7200 + }, }, } @@ -247,14 +257,14 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy): return self.ceilometer.statistic_aggregation( resource_id=resource_id, meter_name=metric_name, - period="7200", + period=self.period, aggregate='avg', ) elif self.config.datasource == "monasca": statistics = self.monasca.statistic_aggregation( meter_name=metric_name, dimensions=dict(hostname=node.uuid), - period=7200, + period=self.period, aggregate='avg' ) cpu_usage = None @@ -276,14 +286,14 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy): return self.ceilometer.statistic_aggregation( resource_id=instance.uuid, meter_name=metric_name, - period="7200", + period=self.period, aggregate='avg' ) elif self.config.datasource == "monasca": statistics = self.monasca.statistic_aggregation( meter_name=metric_name, dimensions=dict(resource_id=instance.uuid), - period=7200, + period=self.period, aggregate='avg' ) cpu_usage = None diff --git a/watcher/tests/common/test_clients.py b/watcher/tests/common/test_clients.py index d54aa669f..87b00ad03 100644 --- a/watcher/tests/common/test_clients.py +++ b/watcher/tests/common/test_clients.py @@ -194,11 +194,11 @@ class TestClients(base.TestCase): session=mock_session) @mock.patch.object(clients.OpenStackClients, 'session') - @mock.patch.object(ceclient_v2.Client, '_get_alarm_client') - def test_clients_ceilometer_diff_vers(self, mock_get_alarm_client, + @mock.patch.object(ceclient_v2.Client, '_get_redirect_client') + def test_clients_ceilometer_diff_vers(self, mock_get_redirect_client, mock_session): '''ceilometerclient currently only has one version (v2)''' - mock_get_alarm_client.return_value = [mock.Mock(), mock.Mock()] + mock_get_redirect_client.return_value = [mock.Mock(), mock.Mock()] CONF.set_override('api_version', '2', group='ceilometer_client') osc = clients.OpenStackClients() @@ -208,10 +208,10 @@ class TestClients(base.TestCase): type(osc.ceilometer())) @mock.patch.object(clients.OpenStackClients, 'session') - @mock.patch.object(ceclient_v2.Client, '_get_alarm_client') - def test_clients_ceilometer_cached(self, mock_get_alarm_client, + @mock.patch.object(ceclient_v2.Client, '_get_redirect_client') + def test_clients_ceilometer_cached(self, mock_get_redirect_client, mock_session): - mock_get_alarm_client.return_value = [mock.Mock(), mock.Mock()] + mock_get_redirect_client.return_value = [mock.Mock(), mock.Mock()] osc = clients.OpenStackClients() osc._ceilometer = None ceilometer = osc.ceilometer() diff --git a/watcher/tests/decision_engine/strategy/strategies/test_basic_consolidation.py b/watcher/tests/decision_engine/strategy/strategies/test_basic_consolidation.py index 870a6f997..e14a73812 100644 --- a/watcher/tests/decision_engine/strategy/strategies/test_basic_consolidation.py +++ b/watcher/tests/decision_engine/strategy/strategies/test_basic_consolidation.py @@ -264,3 +264,40 @@ class TestBasicConsolidation(base.TestCase): loaded_action = loader.load(action['action_type']) loaded_action.input_parameters = action['input_parameters'] loaded_action.validate_parameters() + + def test_periods(self): + model = self.fake_cluster.generate_scenario_1() + self.m_model.return_value = model + node_1 = model.get_node_by_uuid("Node_1") + p_ceilometer = mock.patch.object( + strategies.BasicConsolidation, "ceilometer") + m_ceilometer = p_ceilometer.start() + self.addCleanup(p_ceilometer.stop) + p_monasca = mock.patch.object(strategies.BasicConsolidation, "monasca") + m_monasca = p_monasca.start() + self.addCleanup(p_monasca.stop) + m_monasca.return_value = mock.Mock( + statistic_aggregation=self.fake_metrics.mock_get_statistics) + m_ceilometer.return_value = mock.Mock( + statistic_aggregation=self.fake_metrics.mock_get_statistics) + self.strategy.calculate_score_node(node_1) + resource_id = "%s_%s" % (node_1.uuid, node_1.hostname) + if self.strategy.config.datasource == "ceilometer": + m_ceilometer.statistic_aggregation.assert_called_with( + aggregate='avg', meter_name='compute.node.cpu.percent', + period=7200, resource_id=resource_id) + elif self.strategy.config.datasource == "monasca": + m_monasca.statistic_aggregation.assert_called_with( + aggregate='avg', meter_name='cpu.percent', + period=7200, dimensions={'hostname': 'Node_1'}) + + self.strategy.input_parameters.update({"period": 600}) + self.strategy.calculate_score_node(node_1) + if self.strategy.config.datasource == "ceilometer": + m_ceilometer.statistic_aggregation.assert_called_with( + aggregate='avg', meter_name='compute.node.cpu.percent', + period=600, resource_id=resource_id) + elif self.strategy.config.datasource == "monasca": + m_monasca.statistic_aggregation.assert_called_with( + aggregate='avg', meter_name='cpu.percent', + period=600, dimensions={'hostname': 'Node_1'})