New datasource to retrieve metrics that can be configured in a flexible way depending on the deployment. Current implemenation only works with InfluxDB. Slight changes to datasource manager were necessary because grafana metric_map can only be built at runtime. The yaml configuration file can still be used to define metrics but will require that five different attributes are specified per metric. Specific databases accesible through grafana can be defined by creating 'translators' for these specific databases. This patch introduces a base class for these translators and their methods. In addition the first translator specific for InfluxDB is created. Depends-on: I68475883529610e514aa82f1881105ab0cf24ec3 Depends-on: If1f27dc01e853c5b24bdb21f1e810f64eaee2e5c Implements: blueprint grafana-proxy-datasource Change-Id: Ib12b6a7882703e84a27c301e821c1a034b192508
106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
# -*- encoding: utf-8 -*-
|
|
# Copyright (c) 2019 European Organization for Nuclear Research (CERN)
|
|
#
|
|
# Authors: Corne Lukken <info@dantalion.nl>
|
|
#
|
|
# 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 oslo_config import cfg
|
|
from oslo_log import log
|
|
|
|
from watcher.common import exception
|
|
from watcher.datasources.grafana_translator import base as base_translator
|
|
from watcher.tests import base
|
|
|
|
CONF = cfg.CONF
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class TestGrafanaTranslatorBase(base.BaseTestCase):
|
|
"""Base class for all GrafanaTranslator test classes
|
|
|
|
Objects under test are preceded with t_ and mocked objects are preceded
|
|
with m_ , additionally, patched objects are preceded with p_ no object
|
|
under test should be created in setUp this can influence the results.
|
|
"""
|
|
|
|
def setUp(self):
|
|
super(TestGrafanaTranslatorBase, self).setUp()
|
|
|
|
"""Basic valid reference data"""
|
|
self.reference_data = {
|
|
'metric': 'host_cpu_usage',
|
|
'db': 'production',
|
|
'attribute': 'hostname',
|
|
'query': 'SHOW all_base FROM belong_to_us',
|
|
'resource': mock.Mock(hostname='hyperion'),
|
|
'resource_type': 'compute_node',
|
|
'period': '120',
|
|
'aggregate': 'mean',
|
|
'granularity': None
|
|
}
|
|
|
|
|
|
class TestBaseGrafanaTranslator(TestGrafanaTranslatorBase):
|
|
"""Test the GrafanaTranslator base class
|
|
|
|
Objects under test are preceded with t_ and mocked objects are preceded
|
|
with m_ , additionally, patched objects are preceded with p_ no object
|
|
under test should be created in setUp this can influence the results.
|
|
"""
|
|
|
|
def setUp(self):
|
|
super(TestBaseGrafanaTranslator, self).setUp()
|
|
|
|
def test_validate_data(self):
|
|
"""Initialize InfluxDBGrafanaTranslator and check data validation"""
|
|
|
|
t_base_translator = base_translator.BaseGrafanaTranslator(
|
|
data=self.reference_data)
|
|
|
|
self.assertIsInstance(t_base_translator,
|
|
base_translator.BaseGrafanaTranslator)
|
|
|
|
def test_validate_data_error(self):
|
|
"""Initialize InfluxDBGrafanaTranslator and check data validation"""
|
|
|
|
self.assertRaises(exception.InvalidParameter,
|
|
base_translator.BaseGrafanaTranslator,
|
|
data=[])
|
|
|
|
def test_extract_attribute(self):
|
|
"""Test that an attribute can be extracted from an object"""
|
|
|
|
m_object = mock.Mock(hostname='test')
|
|
|
|
t_base_translator = base_translator.BaseGrafanaTranslator(
|
|
data=self.reference_data)
|
|
|
|
self.assertEqual('test', t_base_translator._extract_attribute(
|
|
m_object, 'hostname'))
|
|
|
|
def test_extract_attribute_error(self):
|
|
"""Test error on attempt to extract none existing attribute"""
|
|
|
|
m_object = mock.Mock(hostname='test')
|
|
m_object.test = mock.PropertyMock(side_effect=AttributeError)
|
|
|
|
t_base_translator = base_translator.BaseGrafanaTranslator(
|
|
data=self.reference_data)
|
|
|
|
self.assertRaises(AttributeError, t_base_translator._extract_attribute(
|
|
m_object, 'test'))
|