# Copyright (c) 2018 NEC, Inc. All rights reserved. # # 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 import sys import time sys.modules['monascaclient.client'] = mock.Mock() sys.modules['monascaclient'] = mock.Mock() from congress.datasources import monasca_driver from congress.tests import base from congress.tests import helper class TestMonascaDriver(base.TestCase): def setUp(self): super(TestMonascaDriver, self).setUp() self.keystone_client_p = mock.patch( "keystoneclient.v3.client.Client") self.keystone_client_p.start() self.monasca_client_p = mock.patch("monascaclient.client.Client") self.monasca_client_p.start() args = helper.datasource_openstack_args() args['poll_time'] = 0 args['endpoint'] = 'http://localhost:8070/v2.0' self.driver = monasca_driver.MonascaDriver(args=args) self.mock_metrics = {"links": [{ "rel": "self", "href": "http://192.168.10.4:8070/v2.0/metrics"}], "elements": [{ "id": "0", "name": "mem.used_buffers", "dimensions": { "component": "monasca-persister", "service": "monitoring", "hostname": "ceilosca", "url": "http://localhost:8091/metrics"} }]} self.mock_statistics = {"links": [{ "rel": "self", "href": "http://192.168.10.4:8070/v2.0/metrics/statistics"}], "elements": [{ "id": "2015-11-30T18:00:00Z", "name": "mem.used_buffers", "dimensions": {}, "columns": ["timestamp", "avg"], "statistics": [ ["2015-11-24T00:00:00Z", 56], ["2015-11-24T06:00:00Z", 46], ["2015-11-24T12:00:00Z", 70], ["2015-11-24T18:00:00Z", 60]] }]} def test_statistics_update_from_datasource(self): self.driver._translate_statistics(self.mock_statistics['elements']) stats_list = list(self.driver.state[monasca_driver.STATISTICS]) stats_data_list = list(self.driver.state[monasca_driver.DATA]) self.assertIsNotNone(stats_list) self.assertIsNotNone(stats_data_list) expected_stats = [ ('mem.used_buffers', 'd1fea02438d17fb7446255573bf54d45')] self.assertEqual(expected_stats, stats_list) expected_stats_data = [ ('d1fea02438d17fb7446255573bf54d45', "['2015-11-24T00:00:00Z', 56]"), ('d1fea02438d17fb7446255573bf54d45', "['2015-11-24T12:00:00Z', 70]"), ('d1fea02438d17fb7446255573bf54d45', "['2015-11-24T18:00:00Z', 60]"), ('d1fea02438d17fb7446255573bf54d45', "['2015-11-24T06:00:00Z', 46]")] self.assertEqual(sorted(expected_stats_data), sorted(stats_data_list)) def test_metrics_update_from_datasource(self): with mock.patch.object(self.driver.monasca.metrics, "list") as metrics: metrics.return_value = self.mock_metrics['elements'] self.driver.update_from_datasource() expected = { 'dimensions': set([ ('e138b5d90a4265c7525f480dd988210b', 'component', 'monasca-persister'), ('e138b5d90a4265c7525f480dd988210b', 'service', 'monitoring'), ('e138b5d90a4265c7525f480dd988210b', 'hostname', 'ceilosca'), ('e138b5d90a4265c7525f480dd988210b', 'url', 'http://localhost:8091/metrics')]), 'metrics': set([ ('0', 'mem.used_buffers', 'e138b5d90a4265c7525f480dd988210b')]), 'statistics': set([]), 'statistics.data': set([]) } self.assertEqual(expected, self.driver.state) def test_execute(self): class MonascaClient(object): def __init__(self): self.testkey = None def getStatistics(self, arg1): self.testkey = 'arg1=%s' % arg1 monasca_client = MonascaClient() self.driver.monasca = monasca_client api_args = { 'positional': ['1'] } expected_ans = 'arg1=1' self.driver.execute('getStatistics', api_args) self.assertEqual(expected_ans, monasca_client.testkey) class TestMonascaWebhookDriver(base.TestCase): def setUp(self): super(TestMonascaWebhookDriver, self).setUp() self.monasca = monasca_driver.MonascaWebhookDriver('test-monasca') @mock.patch.object(monasca_driver.MonascaWebhookDriver, 'publish') def test_monasca_webhook_alarm(self, mocked_publish): test_alarm = { 'metrics': [ {u'dimensions': {u'hostname': u'openstack-13.local.lan', u'service': u'monitoring'}, u'id': None, u'name': u'load.avg_1_min'}], 'alarm_id': u'3beb4934-053d-4f8f-9704-273bffc2441b', 'state': u'ALARM', 'alarm_timestamp': 1531821822, 'tenant_id': u'3661888238874df098988deab07c599d', 'old_state': u'UNDETERMINED', 'alarm_description': u'', 'message': u'Thresholds were exceeded for the sub-alarms', 'alarm_definition_id': u'8e5d033f-28cc-459f-91d4-813307e4ca8a', 'alarm_name': u'alarmPerHost23'} self.monasca._webhook_handler(test_alarm) expected_rows = set([(u'3beb4934-053d-4f8f-9704-273bffc2441b', u'8e5d033f-28cc-459f-91d4-813307e4ca8a', u'alarmPerHost23', u'', 1531821822, u'ALARM', u'UNDETERMINED', u'Thresholds were exceeded for the sub-alarms', u'3661888238874df098988deab07c599d', None, u'load.avg_1_min', u'openstack-13.local.lan', u'monitoring')]) self.assertEqual(self.monasca.state['alarm_notification'], expected_rows) @mock.patch.object(monasca_driver.MonascaWebhookDriver, 'publish') def test_webhook_alarm_cleanup(self, mocked_publish): self.monasca = monasca_driver.MonascaWebhookDriver( 'test-monasca', args={'hours_to_keep_alarm': 1 / 3600}) # set to 1 sec for test test_alarm = { 'metrics': [ {u'dimensions': {u'hostname': u'openstack-13.local.lan', u'service': u'monitoring'}, u'id': None, u'name': u'load.avg_1_min'}], 'alarm_id': u'3beb4934-053d-4f8f-9704-273bffc2441b', 'state': u'ALARM', 'alarm_timestamp': 1531821822, 'tenant_id': u'3661888238874df098988deab07c599d', 'old_state': u'UNDETERMINED', 'alarm_description': u'', 'message': u'Thresholds were exceeded for the sub-alarms', 'alarm_definition_id': u'8e5d033f-28cc-459f-91d4-813307e4ca8a', 'alarm_name': u'alarmPerHost23'} self.monasca._webhook_handler(test_alarm) self.assertEqual(1, len(self.monasca.state['alarm_notification'])) time.sleep(3) self.assertEqual(0, len(self.monasca.state['alarm_notification']))