diff --git a/.testr.conf b/.testr.conf index 97e0fd2..6d83b3c 100644 --- a/.testr.conf +++ b/.testr.conf @@ -2,6 +2,6 @@ test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ . -s collectd_ceilometer.tests $LISTOPT $IDOPTION + ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list diff --git a/collectd_ceilometer/ceilometer/__init__.py b/collectd_ceilometer/ceilometer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/collectd_ceilometer/plugin.py b/collectd_ceilometer/ceilometer/plugin.py similarity index 90% rename from collectd_ceilometer/plugin.py rename to collectd_ceilometer/ceilometer/plugin.py index bcc5a23..8c47ce2 100644 --- a/collectd_ceilometer/plugin.py +++ b/collectd_ceilometer/ceilometer/plugin.py @@ -23,10 +23,10 @@ except ImportError: collectd = None # when running unit tests collectd is not avaliable import collectd_ceilometer -from collectd_ceilometer.logger import CollectdLogHandler -from collectd_ceilometer.meters import MeterStorage -from collectd_ceilometer.settings import Config -from collectd_ceilometer.writer import Writer +from collectd_ceilometer.ceilometer.writer import Writer +from collectd_ceilometer.common.logger import CollectdLogHandler +from collectd_ceilometer.common.meters import MeterStorage +from collectd_ceilometer.common.settings import Config LOGGER = logging.getLogger(__name__) diff --git a/collectd_ceilometer/sender.py b/collectd_ceilometer/ceilometer/sender.py similarity index 96% rename from collectd_ceilometer/sender.py rename to collectd_ceilometer/ceilometer/sender.py index 8c00f42..a7c1c95 100644 --- a/collectd_ceilometer/sender.py +++ b/collectd_ceilometer/ceilometer/sender.py @@ -22,10 +22,10 @@ import threading import requests import six -from collectd_ceilometer.keystone_light import ClientV2 -from collectd_ceilometer.keystone_light import ClientV3 -from collectd_ceilometer.keystone_light import KeystoneException -from collectd_ceilometer.settings import Config +from collectd_ceilometer.common.keystone_light import ClientV2 +from collectd_ceilometer.common.keystone_light import ClientV3 +from collectd_ceilometer.common.keystone_light import KeystoneException +from collectd_ceilometer.common.settings import Config LOGGER = logging.getLogger(__name__) diff --git a/collectd_ceilometer/writer.py b/collectd_ceilometer/ceilometer/writer.py similarity index 98% rename from collectd_ceilometer/writer.py rename to collectd_ceilometer/ceilometer/writer.py index 81710ec..949b559 100644 --- a/collectd_ceilometer/writer.py +++ b/collectd_ceilometer/ceilometer/writer.py @@ -15,7 +15,7 @@ from __future__ import unicode_literals -from collectd_ceilometer.sender import Sender +from collectd_ceilometer.ceilometer.sender import Sender from collections import defaultdict from collections import namedtuple import json diff --git a/collectd_ceilometer/common/__init__.py b/collectd_ceilometer/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/collectd_ceilometer/keystone_light.py b/collectd_ceilometer/common/keystone_light.py similarity index 100% rename from collectd_ceilometer/keystone_light.py rename to collectd_ceilometer/common/keystone_light.py diff --git a/collectd_ceilometer/logger.py b/collectd_ceilometer/common/logger.py similarity index 100% rename from collectd_ceilometer/logger.py rename to collectd_ceilometer/common/logger.py diff --git a/collectd_ceilometer/meters/__init__.py b/collectd_ceilometer/common/meters/__init__.py similarity index 89% rename from collectd_ceilometer/meters/__init__.py rename to collectd_ceilometer/common/meters/__init__.py index d49220f..ba0df7d 100644 --- a/collectd_ceilometer/meters/__init__.py +++ b/collectd_ceilometer/common/meters/__init__.py @@ -15,4 +15,4 @@ from __future__ import unicode_literals -from collectd_ceilometer.meters.storage import MeterStorage # noqa +from collectd_ceilometer.common.meters.storage import MeterStorage # noqa diff --git a/collectd_ceilometer/meters/base.py b/collectd_ceilometer/common/meters/base.py similarity index 97% rename from collectd_ceilometer/meters/base.py rename to collectd_ceilometer/common/meters/base.py index b9e953b..3b80317 100644 --- a/collectd_ceilometer/meters/base.py +++ b/collectd_ceilometer/common/meters/base.py @@ -15,7 +15,7 @@ from __future__ import unicode_literals -from collectd_ceilometer.settings import Config +from collectd_ceilometer.common.settings import Config import logging LOGGER = logging.getLogger(__name__) diff --git a/collectd_ceilometer/meters/libvirt.py b/collectd_ceilometer/common/meters/libvirt.py similarity index 93% rename from collectd_ceilometer/meters/libvirt.py rename to collectd_ceilometer/common/meters/libvirt.py index 1c74b73..b6ca116 100644 --- a/collectd_ceilometer/meters/libvirt.py +++ b/collectd_ceilometer/common/meters/libvirt.py @@ -15,8 +15,8 @@ from __future__ import unicode_literals -from collectd_ceilometer.meters.base import Meter -from collectd_ceilometer.settings import Config +from collectd_ceilometer.common.meters.base import Meter +from collectd_ceilometer.common.settings import Config import libvirt import threading diff --git a/collectd_ceilometer/meters/storage.py b/collectd_ceilometer/common/meters/storage.py similarity index 91% rename from collectd_ceilometer/meters/storage.py rename to collectd_ceilometer/common/meters/storage.py index 0bdef2c..800e1b6 100644 --- a/collectd_ceilometer/meters/storage.py +++ b/collectd_ceilometer/common/meters/storage.py @@ -17,8 +17,8 @@ from __future__ import unicode_literals import six -from collectd_ceilometer.meters.base import Meter -from collectd_ceilometer.meters.libvirt import LibvirtMeter +from collectd_ceilometer.common.meters.base import Meter +from collectd_ceilometer.common.meters.libvirt import LibvirtMeter class MeterStorage(object): diff --git a/collectd_ceilometer/settings.py b/collectd_ceilometer/common/settings.py similarity index 98% rename from collectd_ceilometer/settings.py rename to collectd_ceilometer/common/settings.py index c41b7b1..012f518 100644 --- a/collectd_ceilometer/settings.py +++ b/collectd_ceilometer/common/settings.py @@ -15,8 +15,8 @@ from __future__ import unicode_literals -from collectd_ceilometer.singleton import Singleton -from collectd_ceilometer.units import UNITS +from collectd_ceilometer.common.singleton import Singleton +from collectd_ceilometer.common.units import UNITS from collections import namedtuple import logging import six diff --git a/collectd_ceilometer/singleton.py b/collectd_ceilometer/common/singleton.py similarity index 100% rename from collectd_ceilometer/singleton.py rename to collectd_ceilometer/common/singleton.py diff --git a/collectd_ceilometer/units.py b/collectd_ceilometer/common/units.py similarity index 100% rename from collectd_ceilometer/units.py rename to collectd_ceilometer/common/units.py diff --git a/collectd_ceilometer/tests/base.py b/collectd_ceilometer/tests/base.py index 5ac40b2..53c31f1 100644 --- a/collectd_ceilometer/tests/base.py +++ b/collectd_ceilometer/tests/base.py @@ -18,7 +18,6 @@ from __future__ import unicode_literals -from collectd_ceilometer.keystone_light import KeystoneException from collections import OrderedDict import logging from mock import Mock @@ -50,7 +49,7 @@ class TestConfig(object): default_values = OrderedDict([ ('BATCH_SIZE', 1,), - ('OS_IDENTITY_API_VERSION', '2.0'), + ('OS_IDENTITY_API_VERSION', '3'), ('OS_AUTH_URL', 'https://test-auth.url.tld/test',), ('CEILOMETER_URL_TYPE', 'internalURL',), ('CEILOMETER_TIMEOUT', 1000,), @@ -131,16 +130,10 @@ class TestCase(unittest.TestCase): super(TestCase, self).setUp() - modules = ['collectd', 'libvirt', 'collectd_ceilometer.keystone_light'] + modules = ['collectd', 'libvirt'] self._mocked = {module: Mock() for module in modules} - keystone = self.get_mock('collectd_ceilometer.keystone_light') - keystone.KeystoneException = KeystoneException - self._mocked.update( - {'collectd_ceilometer.keystone_light.KeystoneException': - keystone.KeystoneException}) - self._patchset = patch.dict('sys.modules', self._mocked) self._patchset.start() diff --git a/collectd_ceilometer/tests/ceilometer/__init__.py b/collectd_ceilometer/tests/ceilometer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/collectd_ceilometer/tests/test_plugin.py b/collectd_ceilometer/tests/ceilometer/test_plugin.py similarity index 99% rename from collectd_ceilometer/tests/test_plugin.py rename to collectd_ceilometer/tests/ceilometer/test_plugin.py index 3067fb9..f2fc7f8 100644 --- a/collectd_ceilometer/tests/test_plugin.py +++ b/collectd_ceilometer/tests/ceilometer/test_plugin.py @@ -25,9 +25,9 @@ import unittest import mock -from collectd_ceilometer import keystone_light -from collectd_ceilometer import plugin -from collectd_ceilometer import sender +from collectd_ceilometer.ceilometer import plugin +from collectd_ceilometer.ceilometer import sender +from collectd_ceilometer.common import keystone_light from collectd_ceilometer.tests import match diff --git a/collectd_ceilometer/tests/test_config.py b/collectd_ceilometer/tests/common/test_config.py similarity index 98% rename from collectd_ceilometer/tests/test_config.py rename to collectd_ceilometer/tests/common/test_config.py index 6ab9138..b86e3b1 100644 --- a/collectd_ceilometer/tests/test_config.py +++ b/collectd_ceilometer/tests/common/test_config.py @@ -22,11 +22,11 @@ from unittest import TestCase import mock import six -from collectd_ceilometer import settings +from collectd_ceilometer.common import settings def config_module( - values, units=None, module_name="collectd_ceilometer.plugin"): + values, units=None, module_name="collectd_ceilometer.ceilometer.plugin"): children = [config_value(key, value) for key, value in six.iteritems(values)] if units: diff --git a/collectd_ceilometer/tests/test_keystone_light.py b/collectd_ceilometer/tests/common/test_keystone_light.py similarity index 97% rename from collectd_ceilometer/tests/test_keystone_light.py rename to collectd_ceilometer/tests/common/test_keystone_light.py index 31de53e..92b2f20 100644 --- a/collectd_ceilometer/tests/test_keystone_light.py +++ b/collectd_ceilometer/tests/common/test_keystone_light.py @@ -395,7 +395,7 @@ class KeystoneLightTestV2(unittest.TestCase): self.mock_response = mock.Mock() self.mock_response.json.return_value = response - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_refresh(self, mock_post): """Test refresh""" @@ -424,7 +424,7 @@ class KeystoneLightTestV2(unittest.TestCase): self.assertEqual(mock_post.call_args[0], (u'test_auth_url/tokens',)) self.assertEqual(mock_post.call_args[1], expected_args) - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_getservice_endpoint(self, mock_post): """Test getservice endpoint""" @@ -447,7 +447,7 @@ class KeystoneLightTestV2(unittest.TestCase): with self.assertRaises(MissingServices): client.get_service_endpoint('badname') - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_getservice_endpoint_error(self, mock_post): """Test getservice endpoint error""" @@ -476,7 +476,7 @@ class KeystoneLightTestV2(unittest.TestCase): with self.assertRaises(MissingServices): client.get_service_endpoint('ceilometer') - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_invalidresponse_missing_access(self, mock_post): """Test invalid response: missing access""" @@ -492,7 +492,7 @@ class KeystoneLightTestV2(unittest.TestCase): with self.assertRaises(keystone_light.InvalidResponse): client.refresh() - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_invalidresponse_missing_servicecatalog(self, mock_post): """Test invalid response: missing servicecatalog""" @@ -511,7 +511,7 @@ class KeystoneLightTestV2(unittest.TestCase): with self.assertRaises(keystone_light.InvalidResponse): client.refresh() - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_invalidresponse_missing_token(self, mock_post): """Test invalid response: missing token""" @@ -529,7 +529,7 @@ class KeystoneLightTestV2(unittest.TestCase): with self.assertRaises(keystone_light.InvalidResponse): client.refresh() - @mock.patch('collectd_ceilometer.keystone_light.requests.post') + @mock.patch('collectd_ceilometer.common.keystone_light.requests.post') def test_invalidresponse_missing_id(self, mock_post): """Test invalid response: missing id""" diff --git a/collectd_ceilometer/tests/test_logger.py b/collectd_ceilometer/tests/common/test_logger.py similarity index 99% rename from collectd_ceilometer/tests/test_logger.py rename to collectd_ceilometer/tests/common/test_logger.py index f480c6c..dac64b6 100644 --- a/collectd_ceilometer/tests/test_logger.py +++ b/collectd_ceilometer/tests/common/test_logger.py @@ -16,7 +16,7 @@ import unittest import mock -from collectd_ceilometer.logger import CollectdLogHandler +from collectd_ceilometer.common.logger import CollectdLogHandler from collectd_ceilometer.tests.mocking import patch_class diff --git a/collectd_ceilometer/tests/common/test_meters_base.py b/collectd_ceilometer/tests/common/test_meters_base.py new file mode 100644 index 0000000..0eceafc --- /dev/null +++ b/collectd_ceilometer/tests/common/test_meters_base.py @@ -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.common.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.common.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) diff --git a/collectd_ceilometer/tests/meters/test_base.py b/collectd_ceilometer/tests/meters/test_base.py index dfffe29..4c78fee 100644 --- a/collectd_ceilometer/tests/meters/test_base.py +++ b/collectd_ceilometer/tests/meters/test_base.py @@ -21,7 +21,7 @@ from unittest import TestCase import mock -from collectd_ceilometer.meters.base import Meter +from collectd_ceilometer.common.meters.base import Meter from collectd_ceilometer.tests.mocking import patch_class @@ -88,7 +88,7 @@ class MetersTest(TestCase): collectd.get_dataset.assert_called_once() self.assertEqual("cumulative", actual) - @mock.patch('collectd_ceilometer.meters.base.LOGGER') + @mock.patch('collectd_ceilometer.common.meters.base.LOGGER') @patch_collectd def test_sample_type_invalid(self, collectd, LOGGER): collectd.get_dataset.side_effect = Exception("Boom!") diff --git a/etc/collectd.conf.d/collectd-ceilometer-plugin.conf b/etc/collectd.conf.d/collectd-ceilometer-plugin.conf index 724e1a6..8ae5a07 100644 --- a/etc/collectd.conf.d/collectd-ceilometer-plugin.conf +++ b/etc/collectd.conf.d/collectd-ceilometer-plugin.conf @@ -6,9 +6,9 @@ ModulePath "/opt/stack/collectd-ceilometer-plugin" LogTraces true Interactive false - Import "collectd_ceilometer.plugin" + Import "collectd_ceilometer.ceilometer.plugin" - + # Verbosity True|False VERBOSE False