# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP # # 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 time from monasca_tempest_tests.tests.api import base from monasca_tempest_tests.tests.api import constants from monasca_tempest_tests.tests.api import helpers from oslo_utils import timeutils from tempest.lib.common.utils import data_utils from tempest.lib import decorators NUM_ALARM_DEFINITIONS = 3 MIN_HISTORY = 3 class TestAlarmsStateHistoryOneTransition(base.BaseMonascaTest): # Alarms state histories with one transition but different alarm # definitions are needed for this test class. @classmethod def resource_setup(cls): super(TestAlarmsStateHistoryOneTransition, cls).resource_setup() for i in range(MIN_HISTORY): alarm_definition = helpers.create_alarm_definition( name=data_utils.rand_name('alarm_state_history' + str(i + 1)), expression="min(name-" + str(i + 1) + ") < " + str(i + 1)) cls.monasca_client.create_alarm_definitions(alarm_definition) # Ensure the new Alarm Definitions get to the Threshold Engine time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) num_transitions = 0 for timer in range(constants.MAX_RETRIES): for i in range(MIN_HISTORY): # Create some metrics to prime the system and waiting for the # alarms to be created and then for them to change state. # MIN_HISTORY number of Alarms State History are needed. metric = helpers.create_metric(name="name-" + str(i + 1)) cls.monasca_client.create_metrics(metric) # Ensure alarms transition at different times time.sleep(0.1) resp, response_body = cls.monasca_client.\ list_alarms_state_history() elements = response_body['elements'] if len(elements) >= MIN_HISTORY: return else: num_transitions = len(elements) time.sleep(constants.RETRY_WAIT_SECS) assert False, "Required {} alarm state transitions, but found {}".\ format(MIN_HISTORY, num_transitions) @classmethod def resource_cleanup(cls): super(TestAlarmsStateHistoryOneTransition, cls).resource_cleanup() @decorators.attr(type="gate") def test_list_alarms_state_history(self): resp, response_body = self.monasca_client.list_alarms_state_history() self.assertEqual(200, resp.status) # Test response body self.assertTrue(set(['links', 'elements']) == set(response_body)) elements = response_body['elements'] number_of_alarms = len(elements) if number_of_alarms < 1: error_msg = "Failed test_list_alarms_state_history: need " \ "at least one alarms state history to test." self.fail(error_msg) else: element = elements[0] self.assertTrue(set(['id', 'alarm_id', 'metrics', 'old_state', 'new_state', 'reason', 'reason_data', 'timestamp', 'sub_alarms']) == set(element)) @decorators.attr(type="gate") def test_list_alarms_state_history_with_dimensions(self): resp, response_body = self.monasca_client.list_alarms_state_history() elements = response_body['elements'] if elements: element = elements[0] dimension = element['metrics'][0]['dimensions'] dimension_items = list(dimension.items()) dimension_item = dimension_items[0] dimension_item_0 = dimension_item[0] dimension_item_1 = dimension_item[1] name = element['metrics'][0]['name'] query_parms = '?dimensions=' + str(dimension_item_0) + ':' + str( dimension_item_1) resp, response_body = self.monasca_client.\ list_alarms_state_history(query_parms) name_new = response_body['elements'][0]['metrics'][0]['name'] self.assertEqual(200, resp.status) self.assertEqual(name, name_new) else: error_msg = "Failed test_list_alarms_state_history_with_" \ "dimensions: need at least one alarms state history " \ "to test." self.fail(error_msg) @decorators.attr(type="gate") def test_list_alarms_state_history_with_start_time(self): # 1, get all histories resp, all_response_body = self.monasca_client.\ list_alarms_state_history() all_elements = all_response_body['elements'] if len(all_elements) < 3: error_msg = "Failed test_list_alarms_state_history_with_" \ "start_time: need 3 or more alarms state history " \ "to test." self.fail(error_msg) # 2, query second(timestamp) <= x min_element, second_element, max_element = \ self._get_elements_with_min_max_timestamp(all_elements) start_time = second_element['timestamp'] query_params = '?start_time=' + str(start_time) resp, selected_response_body = self.monasca_client.\ list_alarms_state_history(query_params) selected_elements = selected_response_body['elements'] # 3. compare #1 and #2 expected_elements = all_elements expected_elements.remove(min_element) self.assertEqual(expected_elements, selected_elements) @decorators.attr(type="gate") def test_list_alarms_state_history_with_end_time(self): # 1, get all histories resp, all_response_body = self.monasca_client.\ list_alarms_state_history() all_elements = all_response_body['elements'] if len(all_elements) < 3: error_msg = "Failed test_list_alarms_state_history_with_" \ "end_time: need 3 or more alarms state history " \ "to test." self.fail(error_msg) # 2, query x <= second(timestamp) min_element, second_element, max_element = \ self._get_elements_with_min_max_timestamp(all_elements) end_time = second_element['timestamp'] query_params = '?end_time=' + str(end_time) resp, selected_response_body = self.monasca_client.\ list_alarms_state_history(query_params) selected_elements = selected_response_body['elements'] # 3. compare #1 and #2 expected_elements = all_elements expected_elements.remove(max_element) self.assertEqual(expected_elements, selected_elements) @decorators.attr(type="gate") def test_list_alarms_state_history_with_start_end_time(self): # 1, get all histories resp, all_response_body = self.monasca_client.\ list_alarms_state_history() all_elements = all_response_body['elements'] if len(all_elements) < 3: error_msg = "Failed test_list_alarms_state_history_with_" \ "start_end_time: need 3 or more alarms state history" \ "to test." self.fail(error_msg) # 2, query min(timestamp) <= x <= max(timestamp) min_element, second_element, max_element = \ self._get_elements_with_min_max_timestamp(all_elements) start_time = min_element['timestamp'] end_time = max_element['timestamp'] query_params = '?start_time=' + str(start_time) + '&end_time=' + \ str(end_time) resp, selected_response_body = self.monasca_client.\ list_alarms_state_history(query_params) selected_elements = selected_response_body['elements'] # 3. compare #1 and #2 self.assertEqual(all_elements, selected_elements) @decorators.attr(type="gate") def test_list_alarms_state_history_with_offset_limit(self): resp, response_body = self.monasca_client.list_alarms_state_history() elements_set1 = response_body['elements'] number_of_alarms = len(elements_set1) if number_of_alarms >= MIN_HISTORY: query_parms = '?limit=' + str(number_of_alarms) resp, response_body = self.monasca_client.\ list_alarms_state_history(query_parms) self.assertEqual(200, resp.status) elements_set2 = response_body['elements'] self.assertEqual(number_of_alarms, len(elements_set2)) for index in range(MIN_HISTORY - 1): self.assertEqual(elements_set1[index], elements_set2[index]) for index in range(MIN_HISTORY - 1): alarm_history = elements_set2[index] max_limit = len(elements_set2) - index for limit in range(1, max_limit): first_index = index + 1 last_index = first_index + limit expected_elements = elements_set2[first_index:last_index] query_parms = '?offset=' + str(alarm_history['timestamp'])\ + '&limit=' + str(limit) resp, response_body = self.\ monasca_client.list_alarms_state_history(query_parms) self.assertEqual(200, resp.status) new_elements = response_body['elements'] self.assertEqual(limit, len(new_elements)) for i in range(len(expected_elements)): self.assertEqual(expected_elements[i], new_elements[i]) else: error_msg = ("Failed test_list_alarms_state_history_with_offset " "limit: need three alarms state history to test. " "Current number of alarms = {}").format( number_of_alarms) self.fail(error_msg) def _get_elements_with_min_max_timestamp(self, elements): sorted_elements = sorted(elements, key=lambda element: timeutils. parse_isotime(element['timestamp'])) min_element = sorted_elements[0] second_element = sorted_elements[1] max_element = sorted_elements[-1] return min_element, second_element, max_element