"Fossies" - the Fresh Open Source Software Archive

Member "cloudkitty-13.0.0/cloudkitty/tests/collectors/test_prometheus.py" (14 Oct 2020, 11268 Bytes) of package /linux/misc/openstack/cloudkitty-13.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_prometheus.py": 12.1.0_vs_13.0.0.

    1 # -*- coding: utf-8 -*-
    2 # Copyright 2018 Objectif Libre
    3 #
    4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    5 #    not use this file except in compliance with the License. You may obtain
    6 #    a copy of the License at
    7 #
    8 #         http://www.apache.org/licenses/LICENSE-2.0
    9 #
   10 #    Unless required by applicable law or agreed to in writing, software
   11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   13 #    License for the specific language governing permissions and limitations
   14 #    under the License.
   15 #
   16 from decimal import Decimal
   17 from unittest import mock
   18 
   19 from cloudkitty import collector
   20 from cloudkitty.collector import exceptions
   21 from cloudkitty.collector import prometheus
   22 from cloudkitty.common.prometheus_client import PrometheusResponseError
   23 from cloudkitty import dataframe
   24 from cloudkitty import tests
   25 from cloudkitty.tests import samples
   26 
   27 
   28 class PrometheusCollectorTest(tests.TestCase):
   29     def setUp(self):
   30         super(PrometheusCollectorTest, self).setUp()
   31         self._tenant_id = samples.TENANT
   32         args = {
   33             'period': 3600,
   34             'scope_key': 'namespace',
   35             'conf': {
   36                 'metrics': {
   37                     'http_requests_total': {
   38                         'unit': 'instance',
   39                         'groupby': [
   40                             'foo',
   41                             'bar',
   42                         ],
   43                         'metadata': [
   44                             'code',
   45                             'instance',
   46                         ],
   47                         'extra_args': {
   48                             'aggregation_method': 'avg'
   49                         },
   50                     },
   51                 }
   52             }
   53         }
   54         args_range_function = {
   55             'period': 3600,
   56             'scope_key': 'namespace',
   57             'conf': {
   58                 'metrics': {
   59                     'http_requests_total': {
   60                         'unit': 'instance',
   61                         'groupby': [
   62                             'foo',
   63                             'bar',
   64                         ],
   65                         'metadata': [
   66                             'code',
   67                             'instance',
   68                         ],
   69                         'extra_args': {
   70                             'aggregation_method': 'avg',
   71                             'query_function': 'abs',
   72                         },
   73                     },
   74                 }
   75             }
   76         }
   77         args_query_function = {
   78             'period': 3600,
   79             'scope_key': 'namespace',
   80             'conf': {
   81                 'metrics': {
   82                     'http_requests_total': {
   83                         'unit': 'instance',
   84                         'groupby': [
   85                             'foo',
   86                             'bar',
   87                         ],
   88                         'metadata': [
   89                             'code',
   90                             'instance',
   91                         ],
   92                         'extra_args': {
   93                             'aggregation_method': 'avg',
   94                             'range_function': 'delta',
   95                         },
   96                     },
   97                 }
   98             }
   99         }
  100         args_all = {
  101             'period': 3600,
  102             'scope_key': 'namespace',
  103             'conf': {
  104                 'metrics': {
  105                     'http_requests_total': {
  106                         'unit': 'instance',
  107                         'groupby': [
  108                             'foo',
  109                             'bar',
  110                         ],
  111                         'metadata': [
  112                             'code',
  113                             'instance',
  114                         ],
  115                         'extra_args': {
  116                             'aggregation_method': 'avg',
  117                             'range_function': 'delta',
  118                             'query_function': 'abs',
  119                         },
  120                     },
  121                 }
  122             }
  123         }
  124         self.collector_mandatory = prometheus.PrometheusCollector(**args)
  125         self.collector_without_range_function = prometheus.PrometheusCollector(
  126             **args_range_function)
  127         self.collector_without_query_function = prometheus.PrometheusCollector(
  128             **args_query_function)
  129         self.collector_all = prometheus.PrometheusCollector(**args_all)
  130 
  131     def test_fetch_all_build_query_only_mandatory(self):
  132         query = (
  133             'avg(avg_over_time(http_requests_total'
  134             '{project_id="f266f30b11f246b589fd266f85eeec39"}[3600s]'
  135             ')) by (foo, bar, project_id, code, instance)'
  136         )
  137 
  138         with mock.patch.object(
  139             prometheus.PrometheusClient, 'get_instant',
  140         ) as mock_get:
  141             self.collector_mandatory.fetch_all(
  142                 'http_requests_total',
  143                 samples.FIRST_PERIOD_BEGIN,
  144                 samples.FIRST_PERIOD_END,
  145                 self._tenant_id,
  146             )
  147             mock_get.assert_called_once_with(
  148                 query,
  149                 samples.FIRST_PERIOD_END.isoformat(),
  150             )
  151 
  152     def test_fetch_all_build_query_without_range_function(self):
  153         query = (
  154             'avg(abs(avg_over_time(http_requests_total'
  155             '{project_id="f266f30b11f246b589fd266f85eeec39"}[3600s]'
  156             '))) by (foo, bar, project_id, code, instance)'
  157         )
  158 
  159         with mock.patch.object(
  160             prometheus.PrometheusClient, 'get_instant',
  161         ) as mock_get:
  162             self.collector_without_range_function.fetch_all(
  163                 'http_requests_total',
  164                 samples.FIRST_PERIOD_BEGIN,
  165                 samples.FIRST_PERIOD_END,
  166                 self._tenant_id,
  167             )
  168             mock_get.assert_called_once_with(
  169                 query,
  170                 samples.FIRST_PERIOD_END.isoformat(),
  171             )
  172 
  173     def test_fetch_all_build_query_without_query_function(self):
  174         query = (
  175             'avg(delta(http_requests_total'
  176             '{project_id="f266f30b11f246b589fd266f85eeec39"}[3600s]'
  177             ')) by (foo, bar, project_id, code, instance)'
  178         )
  179 
  180         with mock.patch.object(
  181             prometheus.PrometheusClient, 'get_instant',
  182         ) as mock_get:
  183             self.collector_without_query_function.fetch_all(
  184                 'http_requests_total',
  185                 samples.FIRST_PERIOD_BEGIN,
  186                 samples.FIRST_PERIOD_END,
  187                 self._tenant_id,
  188             )
  189             mock_get.assert_called_once_with(
  190                 query,
  191                 samples.FIRST_PERIOD_END.isoformat(),
  192             )
  193 
  194     def test_fetch_all_build_query_all(self):
  195         query = (
  196             'avg(abs(delta(http_requests_total'
  197             '{project_id="f266f30b11f246b589fd266f85eeec39"}[3600s]'
  198             '))) by (foo, bar, project_id, code, instance)'
  199         )
  200 
  201         with mock.patch.object(
  202             prometheus.PrometheusClient, 'get_instant',
  203         ) as mock_get:
  204             self.collector_all.fetch_all(
  205                 'http_requests_total',
  206                 samples.FIRST_PERIOD_BEGIN,
  207                 samples.FIRST_PERIOD_END,
  208                 self._tenant_id,
  209             )
  210             mock_get.assert_called_once_with(
  211                 query,
  212                 samples.FIRST_PERIOD_END.isoformat(),
  213             )
  214 
  215     def test_format_data_instant_query(self):
  216         expected = ({
  217             'code': '200',
  218             'instance': 'localhost:9090',
  219         }, {
  220             'bar': '',
  221             'foo': '',
  222             'project_id': ''
  223         }, Decimal('7'))
  224 
  225         params = {
  226             'metric_name': 'http_requests_total',
  227             'scope_key': 'project_id',
  228             'scope_id': self._tenant_id,
  229             'start': samples.FIRST_PERIOD_BEGIN,
  230             'end': samples.FIRST_PERIOD_END,
  231             'data': samples.PROMETHEUS_RESP_INSTANT_QUERY['data']['result'][0],
  232         }
  233         actual = self.collector_mandatory._format_data(**params)
  234         self.assertEqual(expected, actual)
  235 
  236     def test_format_data_instant_query_2(self):
  237         expected = ({
  238             'code': '200',
  239             'instance': 'localhost:9090',
  240         }, {
  241             'bar': '',
  242             'foo': '',
  243             'project_id': ''
  244         }, Decimal('42'))
  245 
  246         params = {
  247             'metric_name': 'http_requests_total',
  248             'scope_key': 'project_id',
  249             'scope_id': self._tenant_id,
  250             'start': samples.FIRST_PERIOD_BEGIN,
  251             'end': samples.FIRST_PERIOD_END,
  252             'data': samples.PROMETHEUS_RESP_INSTANT_QUERY['data']['result'][1],
  253         }
  254         actual = self.collector_mandatory._format_data(**params)
  255         self.assertEqual(expected, actual)
  256 
  257     def test_format_retrieve(self):
  258         expected_name = 'http_requests_total'
  259         expected_data = [
  260             dataframe.DataPoint(
  261                 'instance', '7', '0',
  262                 {'bar': '', 'foo': '', 'project_id': ''},
  263                 {'code': '200', 'instance': 'localhost:9090'}),
  264             dataframe.DataPoint(
  265                 'instance', '42', '0',
  266                 {'bar': '', 'foo': '', 'project_id': ''},
  267                 {'code': '200', 'instance': 'localhost:9090'}),
  268         ]
  269 
  270         no_response = mock.patch(
  271             'cloudkitty.common.prometheus_client.PrometheusClient.get_instant',
  272             return_value=samples.PROMETHEUS_RESP_INSTANT_QUERY,
  273         )
  274 
  275         with no_response:
  276             actual_name, actual_data = self.collector_mandatory.retrieve(
  277                 metric_name='http_requests_total',
  278                 start=samples.FIRST_PERIOD_BEGIN,
  279                 end=samples.FIRST_PERIOD_END,
  280                 project_id=samples.TENANT,
  281                 q_filter=None,
  282             )
  283 
  284         self.assertEqual(expected_name, actual_name)
  285         self.assertEqual(expected_data, actual_data)
  286 
  287     def test_format_retrieve_raise_NoDataCollected(self):
  288         no_response = mock.patch(
  289             'cloudkitty.common.prometheus_client.PrometheusClient.get_instant',
  290             return_value=samples.PROMETHEUS_EMPTY_RESP_INSTANT_QUERY,
  291         )
  292 
  293         with no_response:
  294             self.assertRaises(
  295                 collector.NoDataCollected,
  296                 self.collector_mandatory.retrieve,
  297                 metric_name='http_requests_total',
  298                 start=samples.FIRST_PERIOD_BEGIN,
  299                 end=samples.FIRST_PERIOD_END,
  300                 project_id=samples.TENANT,
  301                 q_filter=None,
  302             )
  303 
  304     def test_format_retrieve_all_raises_exception(self):
  305         invalid_response = mock.patch(
  306             'cloudkitty.common.prometheus_client.PrometheusClient.get_instant',
  307             side_effect=PrometheusResponseError,
  308         )
  309 
  310         with invalid_response:
  311             self.assertRaises(
  312                 exceptions.CollectError,
  313                 self.collector_mandatory.retrieve,
  314                 metric_name='http_requests_total',
  315                 start=samples.FIRST_PERIOD_BEGIN,
  316                 end=samples.FIRST_PERIOD_END,
  317                 project_id=samples.TENANT,
  318                 q_filter=None,
  319             )