Add counter type mappings
- Add mappings between counter type in collectd and Ceilometer. Previously, all counters were given "gauge" type. Now, the following mappings are applied: - gauge -> gauge - derive -> delta - absolute, counter -> cumulative - Add unit tests Closes-Bug: #1583301 Change-Id: I13e75fcc57ed2b44c2b9a02ee9562f70748d01c2
This commit is contained in:
parent
77a2d9b965
commit
f3e73866bd
@ -16,6 +16,9 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from collectd_ceilometer.settings import Config
|
||||
import logging
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Meter(object):
|
||||
@ -45,3 +48,21 @@ class Meter(object):
|
||||
"""Get meter unit"""
|
||||
# pylint: disable=no-self-use
|
||||
return Config.instance().unit(vl.plugin, vl.type)
|
||||
|
||||
def sample_type(self, vl):
|
||||
"""Translate from collectd counter type to Ceilometer type"""
|
||||
types = {"gauge": "gauge",
|
||||
"derive": "delta",
|
||||
"absolute": "cumulative",
|
||||
"counter": "cumulative"}
|
||||
|
||||
try:
|
||||
# get_dataset -> [('value', 'derive', 0.0, None)]
|
||||
collectd_type = self._collectd.get_dataset(str(vl.type))[0][1]
|
||||
except Exception:
|
||||
LOGGER.warning(
|
||||
"Cannot map counter type '%s': using type 'gauge'.", vl.type,
|
||||
exc_info=1)
|
||||
collectd_type = "gauge"
|
||||
|
||||
return types[collectd_type]
|
||||
|
97
collectd_ceilometer/tests/test_meters_base.py
Normal file
97
collectd_ceilometer/tests/test_meters_base.py
Normal file
@ -0,0 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2010-2011 OpenStack Foundation
|
||||
# Copyright (c) 2015 Intel Corporation.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Plugin tests"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from collectd_ceilometer.meters.base import Meter
|
||||
from collectd_ceilometer.tests.base import TestCase
|
||||
import mock
|
||||
|
||||
|
||||
class Values(object):
|
||||
"""Stub class to replace collectd.Values"""
|
||||
def __init__(self, plugin="my_plugin", type="my_type"):
|
||||
self.plugin = plugin
|
||||
self.type = type
|
||||
|
||||
|
||||
class CollectdMock(object):
|
||||
"""Model for the collectd class to be mocked"""
|
||||
def get_dataset(self, string):
|
||||
pass
|
||||
|
||||
collectd_class = 'collectd_ceilometer.tests.test_meters_base.CollectdMock'
|
||||
|
||||
|
||||
class MetersTest(TestCase):
|
||||
"""Test the meters/base.py class"""
|
||||
|
||||
@mock.patch(collectd_class, spec=True)
|
||||
def setUp(self, collectd):
|
||||
super(MetersTest, self).setUp()
|
||||
self._collectd = collectd
|
||||
# need this as a parameter for sample_type()
|
||||
self.vl = Values()
|
||||
self.meter = Meter(self._collectd)
|
||||
|
||||
def test_sample_type_gauge(self):
|
||||
# sample_type uses get_dataset()[0][1]
|
||||
self._collectd.get_dataset.return_value = [('value', 'gauge', )]
|
||||
|
||||
actual = self.meter.sample_type(self.vl)
|
||||
|
||||
self._collectd.get_dataset.assert_called_once()
|
||||
self.assertEqual("gauge", actual)
|
||||
|
||||
def test_sample_type_derive(self):
|
||||
# sample_type uses get_dataset()[0][1]
|
||||
self._collectd.get_dataset.return_value = [('value', 'derive', )]
|
||||
|
||||
actual = self.meter.sample_type(self.vl)
|
||||
|
||||
self._collectd.get_dataset.assert_called_once()
|
||||
self.assertEqual("delta", actual)
|
||||
|
||||
def test_sample_type_absolute(self):
|
||||
# sample_type uses get_dataset()[0][1]
|
||||
self._collectd.get_dataset.return_value = [('value', 'absolute', )]
|
||||
|
||||
actual = self.meter.sample_type(self.vl)
|
||||
|
||||
self._collectd.get_dataset.assert_called_once()
|
||||
self.assertEqual("cumulative", actual)
|
||||
|
||||
def test_sample_type_counter(self):
|
||||
# sample_type uses get_dataset()[0][1]
|
||||
self._collectd.get_dataset.return_value = [('value', 'counter', )]
|
||||
|
||||
actual = self.meter.sample_type(self.vl)
|
||||
|
||||
self._collectd.get_dataset.assert_called_once()
|
||||
self.assertEqual("cumulative", actual)
|
||||
|
||||
@mock.patch('collectd_ceilometer.meters.base.LOGGER')
|
||||
def test_sample_type_invalid(self, LOGGER):
|
||||
self._collectd.get_dataset.side_effect = Exception("Boom!")
|
||||
|
||||
actual = self.meter.sample_type(self.vl)
|
||||
|
||||
self._collectd.get_dataset.assert_called_once()
|
||||
LOGGER.warning.assert_called_once()
|
||||
self.assertEqual("gauge", actual)
|
@ -29,14 +29,15 @@ LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Sample(namedtuple('Sample', ['value', 'timestamp', 'meta',
|
||||
'resource_id', 'unit', 'metername'])):
|
||||
'resource_id', 'unit',
|
||||
'metername', 'sample_type'])):
|
||||
"""Sample data"""
|
||||
|
||||
def to_payload(self):
|
||||
"""Return a payload dictionary"""
|
||||
return {
|
||||
'counter_name': self.metername,
|
||||
'counter_type': 'gauge',
|
||||
'counter_type': self.sample_type,
|
||||
'counter_unit': self.unit,
|
||||
'counter_volume': self.value,
|
||||
'timestamp': self.timestamp,
|
||||
@ -106,16 +107,18 @@ class Writer(object):
|
||||
metername = plugin.meter_name(vl)
|
||||
unit = plugin.unit(vl)
|
||||
timestamp = time.asctime(time.gmtime(vl.time))
|
||||
sample_type = plugin.sample_type(vl)
|
||||
|
||||
LOGGER.debug(
|
||||
'Writing: plugin="%s", metername="%s", unit="%s"',
|
||||
vl.plugin, metername, unit)
|
||||
'Writing: plugin="%s", metername="%s", unit="%s", type="%s"',
|
||||
vl.plugin, metername, unit, sample_type)
|
||||
|
||||
# store sample for every value
|
||||
data = [
|
||||
Sample(
|
||||
value=value, timestamp=timestamp, meta=vl.meta,
|
||||
resource_id=resource_id, unit=unit, metername=metername)
|
||||
resource_id=resource_id, unit=unit,
|
||||
metername=metername, sample_type=sample_type)
|
||||
for value in vl.values
|
||||
]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user