From e4959cc1ffa33856393b1e20309146cf839aa27f Mon Sep 17 00:00:00 2001 From: Juha Kosonen Date: Wed, 10 Jan 2018 16:57:40 +0200 Subject: [PATCH] Introduce Gnocchi metric service This patch is based on [1] and introduces the metric service which will be used by Gnocchi scenarios in further patches. [1] https://review.openstack.org/#/c/453861/ Co-Authored-By: akrzos Change-Id: Id03ab5692401298ec77313db1ab65bb16498aa6b Signed-off-by: Juha Kosonen --- .../openstack/services/gnocchi/__init__.py | 0 .../openstack/services/gnocchi/metric.py | 185 +++++++++++++++ .../openstack/services/gnocchi/__init__.py | 0 .../openstack/services/gnocchi/test_metric.py | 217 ++++++++++++++++++ 4 files changed, 402 insertions(+) create mode 100644 rally/plugins/openstack/services/gnocchi/__init__.py create mode 100644 rally/plugins/openstack/services/gnocchi/metric.py create mode 100644 tests/unit/plugins/openstack/services/gnocchi/__init__.py create mode 100644 tests/unit/plugins/openstack/services/gnocchi/test_metric.py diff --git a/rally/plugins/openstack/services/gnocchi/__init__.py b/rally/plugins/openstack/services/gnocchi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rally/plugins/openstack/services/gnocchi/metric.py b/rally/plugins/openstack/services/gnocchi/metric.py new file mode 100644 index 00000000..4621e803 --- /dev/null +++ b/rally/plugins/openstack/services/gnocchi/metric.py @@ -0,0 +1,185 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from rally.task import atomic +from rally.task import service + + +class GnocchiService(service.Service): + + @atomic.action_timer("gnocchi.create_archive_policy") + def create_archive_policy(self, name, definition=None, + aggregation_methods=None): + """Create an archive policy. + + :param name: Archive policy name + :param definition: Archive policy definition + :param aggregation_methods: Aggregation method of the archive policy + """ + archive_policy = {"name": name} + archive_policy["definition"] = definition + archive_policy["aggregation_methods"] = aggregation_methods + return self._clients.gnocchi().archive_policy.create( + archive_policy) + + @atomic.action_timer("gnocchi.delete_archive_policy") + def delete_archive_policy(self, name): + """Delete an archive policy. + + :param name: Archive policy name + """ + return self._clients.gnocchi().archive_policy.delete(name) + + @atomic.action_timer("gnocchi.list_archive_policy") + def list_archive_policy(self): + """List archive policies.""" + return self._clients.gnocchi().archive_policy.list() + + @atomic.action_timer("gnocchi.create_archive_policy_rule") + def create_archive_policy_rule(self, name, metric_pattern=None, + archive_policy_name=None): + """Create an archive policy rule. + + :param name: Archive policy rule name + :param metric_pattern: Wildcard of metric name to match + :param archive_policy_name: Archive policy name + """ + archive_policy_rule = {"name": name} + archive_policy_rule["metric_pattern"] = metric_pattern + archive_policy_rule["archive_policy_name"] = archive_policy_name + return self._clients.gnocchi().archive_policy_rule.create( + archive_policy_rule) + + @atomic.action_timer("gnocchi.delete_archive_policy_rule") + def delete_archive_policy_rule(self, name): + """Delete an archive policy rule. + + :param name: Archive policy rule name + """ + return self._clients.gnocchi().archive_policy_rule.delete(name) + + @atomic.action_timer("gnocchi.list_archive_policy_rule") + def list_archive_policy_rule(self): + """List archive policy rules.""" + return self._clients.gnocchi().archive_policy_rule.list() + + @atomic.action_timer("gnocchi.list_capabilities") + def list_capabilities(self): + """List capabilities.""" + return self._clients.gnocchi().capabilities.list() + + @atomic.action_timer("gnocchi.get_measures_aggregation") + def get_measures_aggregation(self, metrics, aggregation=None, + refresh=None): + """Get measurements of aggregated metrics. + + :param metrics: Metric IDs or name + :param aggregation: Granularity aggregation function to retrieve + :param refresh: Force aggregation of all known measures + """ + return self._clients.gnocchi().metric.aggregation( + metrics=metrics, aggregation=aggregation, refresh=refresh) + + @atomic.action_timer("gnocchi.get_measures") + def get_measures(self, metric, aggregation=None, refresh=None): + """Get measurements of a metric. + + :param metric: Metric ID or name + :param aggregation: Aggregation to retrieve + :param refresh: Force aggregation of all known measures + """ + return self._clients.gnocchi().metric.get_measures( + metric=metric, aggregation=aggregation, refresh=refresh) + + @atomic.action_timer("gnocchi.create_metric") + def create_metric(self, name, archive_policy_name=None, resource_id=None, + unit=None): + """Create a metric. + + :param name: Metric name + :param archive_policy_name: Archive policy name + :param resource_id: The resource ID to attach the metric to + :param unit: The unit of the metric + """ + return self._clients.gnocchi().metric.create( + name=name, archive_policy_name=archive_policy_name, + resource_id=resource_id, unit=unit) + + @atomic.action_timer("gnocchi.delete_metric") + def delete_metric(self, metric_id): + """Delete a metric. + + :param metric_id: metric ID + """ + return self._clients.gnocchi().metric.delete(metric_id) + + @atomic.action_timer("gnocchi.list_metric") + def list_metric(self): + """List metrics.""" + return self._clients.gnocchi().metric.list() + + @atomic.action_timer("gnocchi.create_resource") + def create_resource(self, resource_type="generic"): + """Create a resource. + + :param resource_type: Type of the resource + """ + resource = {"id": self.generate_random_name()} + return self._clients.gnocchi().resource.create( + resource_type, resource) + + @atomic.action_timer("gnocchi.delete_resource") + def delete_resource(self, resource_id): + """Delete a resource. + + :param resource_id: ID of the resource + """ + return self._clients.gnocchi().resource.delete(resource_id) + + @atomic.action_timer("gnocchi.list_resource") + def list_resource(self, resource_type="generic"): + """List resources.""" + return self._clients.gnocchi().resource.list( + resource_type=resource_type) + + @atomic.action_timer("gnocchi.create_resource_type") + def create_resource_type(self, name): + """Create a resource type. + + :param name: Name of the resource type + """ + resource_type = {"name": name or self.generate_random_name()} + return self._clients.gnocchi().resource_type.create( + resource_type) + + @atomic.action_timer("gnocchi.delete_resource_type") + def delete_resource_type(self, resource_type): + """Delete a resource type. + + :param resource_type: Resource type dict + """ + return self._clients.gnocchi().resource_type.delete(resource_type) + + @atomic.action_timer("gnocchi.list_resource_type") + def list_resource_type(self): + """List resource types.""" + return self._clients.gnocchi().resource_type.list() + + @atomic.action_timer("gnocchi.get_status") + def get_status(self, detailed=False): + """Get the status of measurements processing. + + :param detailed: Get detailed status. + """ + return self._clients.gnocchi().status.get(detailed) diff --git a/tests/unit/plugins/openstack/services/gnocchi/__init__.py b/tests/unit/plugins/openstack/services/gnocchi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/plugins/openstack/services/gnocchi/test_metric.py b/tests/unit/plugins/openstack/services/gnocchi/test_metric.py new file mode 100644 index 00000000..297e888b --- /dev/null +++ b/tests/unit/plugins/openstack/services/gnocchi/test_metric.py @@ -0,0 +1,217 @@ +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from rally.plugins.openstack.services.gnocchi import metric +from tests.unit import test + + +class GnocchiServiceTestCase(test.TestCase): + def setUp(self): + super(GnocchiServiceTestCase, self).setUp() + self.clients = mock.MagicMock() + self.name_generator = mock.MagicMock() + self.service = metric.GnocchiService( + self.clients, + name_generator=self.name_generator) + + def atomic_actions(self): + return self.service._atomic_actions + + def test__create_archive_policy(self): + definition = [{"granularity": "0:00:01", "timespan": "1:00:00"}] + aggregation_methods = [ + "std", "count", "95pct", "min", "max", "sum", "median", "mean"] + archive_policy = {"name": "fake_name"} + archive_policy["definition"] = definition + archive_policy["aggregation_methods"] = aggregation_methods + + self.assertEqual( + self.service.create_archive_policy( + name="fake_name", + definition=definition, + aggregation_methods=aggregation_methods), + self.service._clients.gnocchi().archive_policy.create( + archive_policy) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.create_archive_policy") + + def test__delete_archive_policy(self): + self.service.delete_archive_policy("fake_name") + self.service._clients.gnocchi().archive_policy.delete \ + .assert_called_once_with("fake_name") + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.delete_archive_policy") + + def test__list_archive_policy(self): + self.assertEqual( + self.service.list_archive_policy(), + self.service._clients.gnocchi().archive_policy.list.return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.list_archive_policy") + + def test__create_archive_policy_rule(self): + archive_policy_rule = {"name": "fake_name"} + archive_policy_rule["metric_pattern"] = "cpu_*" + archive_policy_rule["archive_policy_name"] = "low" + + self.assertEqual( + self.service.create_archive_policy_rule( + name="fake_name", + metric_pattern="cpu_*", + archive_policy_name="low"), + self.service._clients.gnocchi().archive_policy_rule.create( + archive_policy_rule) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.create_archive_policy_rule") + + def test__delete_archive_policy_rule(self): + self.service.delete_archive_policy_rule("fake_name") + self.service._clients.gnocchi().archive_policy_rule \ + .delete.assert_called_once_with("fake_name") + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.delete_archive_policy_rule") + + def test__list_archive_policy_rule(self): + self.assertEqual( + self.service.list_archive_policy_rule(), + self.service._clients.gnocchi().archive_policy_rule.list + .return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.list_archive_policy_rule") + + def test__list_capabilities(self): + self.assertEqual( + self.service.list_capabilities(), + self.service._clients.gnocchi().capabilities.list.return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.list_capabilities") + + def test__get_measures_aggregation(self): + self.assertEqual( + self.service.get_measures_aggregation( + metrics=[1], + aggregation="mean", + refresh=False), + self.service._clients.gnocchi().metric.aggregation( + [1], "mean", False) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.get_measures_aggregation") + + def test__get_measures(self): + self.assertEqual( + self.service.get_measures( + metric=1, + aggregation="mean", + refresh=False), + self.service._clients.gnocchi().metric.get_measures( + 1, "mean", False) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.get_measures") + + def test__create_metric(self): + metric = {"name": "fake_name"} + metric["archive_policy_name"] = "fake_archive_policy" + metric["unit"] = "fake_unit" + metric["resource_id"] = "fake_resource_id" + self.assertEqual( + self.service.create_metric( + name="fake_name", + archive_policy_name="fake_archive_policy", + unit="fake_unit", + resource_id="fake_resource_id"), + self.service._clients.gnocchi().metric.create(metric) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.create_metric") + + def test__delete_metric(self): + self.service.delete_metric("fake_metric_id") + self.service._clients.gnocchi().metric.delete.assert_called_once_with( + "fake_metric_id") + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.delete_metric") + + def test__list_metric(self): + self.assertEqual( + self.service.list_metric(), + self.service._clients.gnocchi().metric.list.return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.list_metric") + + def test__create_resource(self): + resource = {"id": "11111"} + self.assertEqual( + self.service.create_resource("fake_type"), + self.service._clients.gnocchi().resource.create( + "fake_type", resource) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.create_resource") + + def test__delete_resource(self): + self.service.delete_resource("fake_resource_id") + self.service._clients.gnocchi().resource.delete \ + .assert_called_once_with("fake_resource_id") + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.delete_resource") + + def test__list_resource(self): + self.assertEqual( + self.service.list_resource(), + self.service._clients.gnocchi().resource.list.return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.list_resource") + + def test__create_resource_type(self): + resource_type = {"name": "fake_name"} + self.assertEqual( + self.service.create_resource_type("fake_name"), + self.service._clients.gnocchi().resource_type.create(resource_type) + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.create_resource_type") + + def test__delete_resource_type(self): + self.service.delete_resource_type("fake_resource_name") + self.service._clients.gnocchi().resource_type.delete \ + .assert_called_once_with("fake_resource_name") + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.delete_resource_type") + + def test__list_resource_type(self): + self.assertEqual( + self.service.list_resource_type(), + self.service._clients.gnocchi().resource_type.list.return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.list_resource_type") + + def test__get_status(self,): + self.assertEqual( + self.service.get_status(), + self.service._clients.gnocchi().status.get.return_value + ) + self._test_atomic_action_timer(self.atomic_actions(), + "gnocchi.get_status")