congress/congress/tests/datasources/test_monasca_driver.py

203 lines
8.0 KiB
Python

# 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']))