From 7e44b1d3f23fa4f3b828ca302e10e3372d86b912 Mon Sep 17 00:00:00 2001 From: Niv Oppenhaim Date: Tue, 12 Jun 2018 14:19:11 +0000 Subject: [PATCH] add gnocchi to tempest clients and new aodh alarm type tests Task: #22521 Story: #2002693 Depends-On: I65dd102635b1f6c6500a9c34da130aaea33708b2 Change-Id: Id816a292ef9801917543647dc5bafbc0f39f4a92 --- .../tests/common/aodh_utils.py | 104 +++++++++++++++--- .../tests/common/constants.py | 33 ++++++ .../tests/common/tempest_clients.py | 11 ++ .../tests/datasources/test_aodh.py | 75 ++++++++++++- 4 files changed, 206 insertions(+), 17 deletions(-) diff --git a/vitrage_tempest_plugin/tests/common/aodh_utils.py b/vitrage_tempest_plugin/tests/common/aodh_utils.py index 2844ecd..6d62e90 100644 --- a/vitrage_tempest_plugin/tests/common/aodh_utils.py +++ b/vitrage_tempest_plugin/tests/common/aodh_utils.py @@ -11,9 +11,11 @@ # 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 json import random import time -from vitrage.datasources.aodh.properties import AodhProperties as AodhProps +from vitrage_tempest_plugin.tests.common.constants import AodhProperties as \ + AodhProps from vitrage_tempest_plugin.tests.common.tempest_clients import TempestClients @@ -23,33 +25,107 @@ def create_aodh_alarm(resource_id=None, name=None, unic=True): elif unic: name = '%s-%s' % (name, random.randrange(0, 100000, 1)) - aodh_request = _aodh_request(resource_id=resource_id, name=name) + aodh_request = _aodh_request('event', + resource_id=resource_id, + name=name) TempestClients.aodh().alarm.create(aodh_request) - time.sleep(45) + time.sleep(20) + + +def create_aodh_metrics_threshold_alarm(resource_id=None, name=None): + if not name: + name = '%s-%s' % ('test_', random.randrange(0, 100000, 1)) + met = TempestClients.gnocchi().metric.create(resource_id=resource_id, + name='test', + archive_policy_name='high') + metric = met[AodhProps.ID] + rule_opts = dict( + threshold='100', + aggregation_method='mean', + comparison_operator='lt', + metrics=[metric] + ) + rule = { + AodhProps.METRICS_THRESHOLD_RULE: rule_opts + } + aodh_request = _aodh_request(AodhProps.METRICS_THRESHOLD, + resource_id=resource_id, + name=name, + rule=rule) + TempestClients.aodh().alarm.create(aodh_request) + time.sleep(10) + + +def create_aodh_resources_threshold_alarm(resource_id, name=None): + if not name: + name = '%s-%s' % ('test_', random.randrange(0, 100000, 1)) + + gnocchi_resource = _get_gnocchi_resource_id() + met = TempestClients.gnocchi().metric.create(resource_id=gnocchi_resource, + name='test', + archive_policy_name='high') + metric = met[AodhProps.ID] + rule_opts = dict( + threshold='100', + aggregation_method='mean', + comparison_operator='lt', + metric=metric, + resource_type='nova.instance' + ) + rule = { + AodhProps.RESOURCES_THRESHOLD_RULE: rule_opts + } + aodh_request = _aodh_request(AodhProps.RESOURCES_THRESHOLD, + resource_id=resource_id, + name=name, + rule=rule) + TempestClients.aodh().alarm.create(aodh_request) + time.sleep(10) def delete_all_aodh_alarms(): alarms = TempestClients.aodh().alarm.list() for alarm in alarms: TempestClients.aodh().alarm.delete(alarm[AodhProps.ALARM_ID]) - time.sleep(120) + time.sleep(10) -def _aodh_request(resource_id=None, name=None): +def delete_all_gnocchi_metrics(): + metrics = TempestClients.gnocchi().metric.list() + for metric in metrics: + TempestClients.gnocchi().metric.delete(metric[AodhProps.ID]) + time.sleep(10) + + +def _get_gnocchi_resource_id(): + return TempestClients.gnocchi().resource.list()[0][AodhProps.ID] + + +def _aodh_request(type, resource_id=None, name=None, rule=None): query = [] if resource_id: query = [ dict( - field=u'traits.resource_id', + field='traits.resource_id', type='', - op=u'eq', + op='eq', value=resource_id) ] - - return dict( + request = dict( name=name, - description=u'test alarm', - event_rule=dict(query=query), - severity=u'low', - state=u'alarm', - type=u'event') + description='test alarm', + severity='low', + state='alarm', + type=type) + + if not rule: + rule = dict(event_rule=(dict(query=query))) + elif rule.get(AodhProps.RESOURCES_THRESHOLD_RULE): + # aggregation_by_resources_threshold requests are different from other + # alarms, update accordingly + query[0].update(dict(field='resource_id')) + rule[AodhProps.RESOURCES_THRESHOLD_RULE].update(dict( + query=json.dumps(query))) + + request.update(rule) + return request diff --git a/vitrage_tempest_plugin/tests/common/constants.py b/vitrage_tempest_plugin/tests/common/constants.py index 229b827..d9f1a47 100644 --- a/vitrage_tempest_plugin/tests/common/constants.py +++ b/vitrage_tempest_plugin/tests/common/constants.py @@ -180,3 +180,36 @@ class TenantProps(object): ALL_TENANTS = 'all_tenants' TENANT = 'tenant' IS_ADMIN = 'is_admin' + + +class AodhProperties(object): + ALARM_ID = 'alarm_id' + DESCRIPTION = 'description' + ENABLED = 'enabled' + EVENT = 'event' + EVENT_RULE = 'event_rule' + EVENT_TYPE = 'event_type' + EVENT_RESOURCE_ID = 'traits.resource_id' + NAME = 'name' + STATE = 'state' + PROJECT_ID = 'project_id' + QUERY = 'query' + REPEAT_ACTIONS = 'repeat_actions' + RESOURCE_ID = 'resource_id' + SEVERITY = 'severity' + STATE_TIMESTAMP = 'state_timestamp' + THRESHOLD = 'threshold' + THRESHOLD_RULE = 'threshold_rule' + RESOURCES_THRESHOLD = 'gnocchi_aggregation_by_resources_threshold' + METRICS_THRESHOLD = 'gnocchi_aggregation_by_metrics_threshold' + METRICS_THRESHOLD_RULE = 'gnocchi_aggregation_by_metrics_threshold_rule' + TIMESTAMP = 'timestamp' + TYPE = 'type' + VITRAGE_ID = 'vitrage_id' + DETAIL = 'detail' + RULE = 'rule' + RESOURCES_THRESHOLD_RULE = \ + 'gnocchi_aggregation_by_resources_threshold_rule' + USER_ID = 'user_id' + STATE_REASON = 'state_reason' + ID = 'id' diff --git a/vitrage_tempest_plugin/tests/common/tempest_clients.py b/vitrage_tempest_plugin/tests/common/tempest_clients.py index b943de8..0aa7e29 100644 --- a/vitrage_tempest_plugin/tests/common/tempest_clients.py +++ b/vitrage_tempest_plugin/tests/common/tempest_clients.py @@ -35,6 +35,7 @@ class TempestClients(object): cls._mistral = None cls._aodh = None cls._keystone = None + cls._gnocchi = None @classmethod def vitrage(cls): @@ -155,6 +156,16 @@ class TempestClients(object): cls._keystone = keystone_client.get_client(cls._conf) return cls._keystone + @classmethod + def gnocchi(cls): + """gnocchi client + + :rtype: gnocchiclient.v1.client.Client + """ + if not cls._gnocchi: + cls._gnocchi = os_clients.gnocchi_client(cls._conf) + return cls._gnocchi + @classmethod def _get_session_for_user(cls, username, user_domain_id, project_name, project_domain_id): diff --git a/vitrage_tempest_plugin/tests/datasources/test_aodh.py b/vitrage_tempest_plugin/tests/datasources/test_aodh.py index 5e63dd9..d84564f 100644 --- a/vitrage_tempest_plugin/tests/datasources/test_aodh.py +++ b/vitrage_tempest_plugin/tests/datasources/test_aodh.py @@ -42,9 +42,7 @@ class TestAodhAlarm(BaseAlarmsTest): try: # Action nova_utils.create_instances(num_instances=self.NUM_INSTANCE) - aodh_utils.create_aodh_alarm( - self._find_instance_resource_id()) - + aodh_utils.create_aodh_alarm(self._find_instance_resource_id()) # Calculate expected results api_graph = self.vitrage_client.topology.get(all_tenants=True) graph = self._create_graph_from_graph_dictionary(api_graph) @@ -73,6 +71,77 @@ class TestAodhAlarm(BaseAlarmsTest): aodh_utils.delete_all_aodh_alarms() nova_utils.delete_all_instances() + @utils.tempest_logger + def test_gnocchi_aggregation_by_metrics_threshold_alarm(self): + try: + # Action + nova_utils.create_instances(num_instances=self.NUM_INSTANCE) + aodh_utils.create_aodh_metrics_threshold_alarm() + + api_graph = self.vitrage_client.topology.get(all_tenants=True) + graph = self._create_graph_from_graph_dictionary(api_graph) + entities = self._entities_validation_data( + host_entities=1, + host_edges=1 + self.NUM_INSTANCE, + instance_entities=self.NUM_INSTANCE, + instance_edges=2 * self.NUM_INSTANCE, + aodh_entities=self.NUM_ALARM, + aodh_edges=0) + num_entities = self.num_default_entities + \ + 2 * self.NUM_INSTANCE + self.NUM_ALARM + \ + self.num_default_networks + self.num_default_ports + num_edges = self.num_default_edges + 3 * self.NUM_INSTANCE + \ + self.num_default_ports + + self._validate_graph_correctness(graph, + num_entities, + num_edges, + entities) + + except Exception as e: + self._handle_exception(e) + raise + finally: + aodh_utils.delete_all_aodh_alarms() + aodh_utils.delete_all_gnocchi_metrics() + nova_utils.delete_all_instances() + + @utils.tempest_logger + def test_gnocchi_aggregation_by_resources_threshold(self): + try: + # Action + nova_utils.create_instances(num_instances=self.NUM_INSTANCE) + aodh_utils.create_aodh_resources_threshold_alarm( + resource_id=self._find_instance_resource_id()) + + api_graph = self.vitrage_client.topology.get(all_tenants=True) + graph = self._create_graph_from_graph_dictionary(api_graph) + entities = self._entities_validation_data( + host_entities=1, + host_edges=1 + self.NUM_INSTANCE, + instance_entities=self.NUM_INSTANCE, + instance_edges=2 * self.NUM_INSTANCE + self.NUM_ALARM, + aodh_entities=self.NUM_ALARM, + aodh_edges=self.NUM_ALARM) + num_entities = self.num_default_entities + \ + 2 * self.NUM_INSTANCE + self.NUM_ALARM + \ + self.num_default_networks + self.num_default_ports + num_edges = self.num_default_edges + 3 * self.NUM_INSTANCE + \ + + self.NUM_ALARM + self.num_default_ports + + self._validate_graph_correctness(graph, + num_entities, + num_edges, + entities) + + except Exception as e: + self._handle_exception(e) + raise + finally: + aodh_utils.delete_all_aodh_alarms() + aodh_utils.delete_all_gnocchi_metrics() + nova_utils.delete_all_instances() + @utils.tempest_logger def test_alarm_without_resource_id(self): try: