Update meter publish with pipeline framework
With multiple publisher support, change meter publish to utilize this framework. for bp multi-publisher Change-Id: I6c2cba15ebadd3dabfb99296fab060cae23d3cf7 Signed-off-by: Yunhong, Jiang <yunhong.jiang@intel.com>
This commit is contained in:
parent
1486b29d00
commit
3340461656
@ -16,9 +16,10 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from ceilometer import publish
|
from stevedore import dispatch
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
from ceilometer.openstack.common import log
|
from ceilometer.openstack.common import log
|
||||||
|
from ceilometer import pipeline
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -26,7 +27,15 @@ LOG = log.getLogger(__name__)
|
|||||||
class AgentManager(object):
|
class AgentManager(object):
|
||||||
|
|
||||||
def __init__(self, extension_manager):
|
def __init__(self, extension_manager):
|
||||||
self.ext_manager = extension_manager
|
publisher_manager = dispatch.NameDispatchExtensionManager(
|
||||||
|
namespace=pipeline.PUBLISHER_NAMESPACE,
|
||||||
|
check_func=lambda x: True,
|
||||||
|
invoke_on_load=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.pipeline_manager = pipeline.setup_pipeline(publisher_manager)
|
||||||
|
|
||||||
|
self.pollster_manager = extension_manager
|
||||||
|
|
||||||
def publish_counters_from_one_pollster(self, ext, manager, context,
|
def publish_counters_from_one_pollster(self, ext, manager, context,
|
||||||
*args, **kwargs):
|
*args, **kwargs):
|
||||||
@ -36,11 +45,10 @@ class AgentManager(object):
|
|||||||
LOG.info('Polling %s', ext.name)
|
LOG.info('Polling %s', ext.name)
|
||||||
for c in ext.obj.get_counters(manager, *args, **kwargs):
|
for c in ext.obj.get_counters(manager, *args, **kwargs):
|
||||||
LOG.debug('Publishing counter: %s', c)
|
LOG.debug('Publishing counter: %s', c)
|
||||||
publish.publish_counter(context, c,
|
manager.pipeline_manager.publish_counter(
|
||||||
cfg.CONF.metering_topic,
|
context, c,
|
||||||
cfg.CONF.metering_secret,
|
cfg.CONF.counter_source)
|
||||||
cfg.CONF.counter_source,
|
|
||||||
)
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.warning('Continuing after error from %s: %s',
|
LOG.warning('Continuing after error from %s: %s',
|
||||||
ext.name, err)
|
ext.name, err)
|
||||||
|
@ -50,7 +50,7 @@ class AgentManager(agent.AgentManager):
|
|||||||
tenant_name=cfg.CONF.os_tenant_name,
|
tenant_name=cfg.CONF.os_tenant_name,
|
||||||
auth_url=cfg.CONF.os_auth_url)
|
auth_url=cfg.CONF.os_auth_url)
|
||||||
|
|
||||||
self.ext_manager.map(self.publish_counters_from_one_pollster,
|
self.pollster_manager.map(self.publish_counters_from_one_pollster,
|
||||||
manager=self,
|
manager=self,
|
||||||
context=context,
|
context=context,
|
||||||
)
|
)
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from stevedore import extension
|
from stevedore import dispatch
|
||||||
|
|
||||||
from ceilometer.collector import meter
|
from ceilometer.collector import meter
|
||||||
from ceilometer import extension_manager
|
from ceilometer import extension_manager
|
||||||
from ceilometer import publish
|
from ceilometer import pipeline
|
||||||
from ceilometer import service
|
from ceilometer import service
|
||||||
from ceilometer import storage
|
from ceilometer import storage
|
||||||
from ceilometer.openstack.common import context
|
from ceilometer.openstack.common import context
|
||||||
@ -56,16 +56,23 @@ class CollectorService(service.PeriodicService):
|
|||||||
|
|
||||||
def initialize_service_hook(self, service):
|
def initialize_service_hook(self, service):
|
||||||
'''Consumers must be declared before consume_thread start.'''
|
'''Consumers must be declared before consume_thread start.'''
|
||||||
self.ext_manager = extension_manager.ActivatedExtensionManager(
|
publisher_manager = dispatch.NameDispatchExtensionManager(
|
||||||
|
namespace=pipeline.PUBLISHER_NAMESPACE,
|
||||||
|
check_func=lambda x: True,
|
||||||
|
invoke_on_load=True,
|
||||||
|
)
|
||||||
|
self.pipeline_manager = pipeline.setup_pipeline(publisher_manager)
|
||||||
|
|
||||||
|
self.notification_manager = \
|
||||||
|
extension_manager.ActivatedExtensionManager(
|
||||||
namespace=self.COLLECTOR_NAMESPACE,
|
namespace=self.COLLECTOR_NAMESPACE,
|
||||||
disabled_names=cfg.CONF.disabled_notification_listeners,
|
disabled_names=cfg.CONF.disabled_notification_listeners,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not list(self.ext_manager):
|
if not list(self.notification_manager):
|
||||||
LOG.warning('Failed to load any notification handlers for %s',
|
LOG.warning('Failed to load any notification handlers for %s',
|
||||||
self.COLLECTOR_NAMESPACE)
|
self.COLLECTOR_NAMESPACE)
|
||||||
|
self.notification_manager.map(self._setup_subscription)
|
||||||
self.ext_manager.map(self._setup_subscription)
|
|
||||||
|
|
||||||
# Set ourselves up as a separate worker for the metering data,
|
# Set ourselves up as a separate worker for the metering data,
|
||||||
# since the default for service is to use create_consumer().
|
# since the default for service is to use create_consumer().
|
||||||
@ -95,7 +102,7 @@ class CollectorService(service.PeriodicService):
|
|||||||
def process_notification(self, notification):
|
def process_notification(self, notification):
|
||||||
"""Make a notification processed by an handler."""
|
"""Make a notification processed by an handler."""
|
||||||
LOG.debug('notification %r', notification.get('event_type'))
|
LOG.debug('notification %r', notification.get('event_type'))
|
||||||
self.ext_manager.map(self._process_notification_for_ext,
|
self.notification_manager.map(self._process_notification_for_ext,
|
||||||
notification=notification,
|
notification=notification,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -107,13 +114,10 @@ class CollectorService(service.PeriodicService):
|
|||||||
# FIXME(dhellmann): Spawn green thread?
|
# FIXME(dhellmann): Spawn green thread?
|
||||||
self.publish_counter(c)
|
self.publish_counter(c)
|
||||||
|
|
||||||
@staticmethod
|
def publish_counter(self, counter):
|
||||||
def publish_counter(counter):
|
|
||||||
"""Create a metering message for the counter and publish it."""
|
"""Create a metering message for the counter and publish it."""
|
||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
publish.publish_counter(ctxt, counter,
|
self.pipeline_manager.publish_counter(ctxt, counter,
|
||||||
cfg.CONF.metering_topic,
|
|
||||||
cfg.CONF.metering_secret,
|
|
||||||
cfg.CONF.counter_source)
|
cfg.CONF.counter_source)
|
||||||
|
|
||||||
def record_metering_data(self, context, data):
|
def record_metering_data(self, context, data):
|
||||||
|
@ -66,7 +66,7 @@ class AgentManager(agent.AgentManager):
|
|||||||
|
|
||||||
def poll_instance(self, context, instance):
|
def poll_instance(self, context, instance):
|
||||||
"""Poll one instance."""
|
"""Poll one instance."""
|
||||||
self.ext_manager.map(self.publish_counters_from_one_pollster,
|
self.pollster_manager.map(self.publish_counters_from_one_pollster,
|
||||||
manager=self,
|
manager=self,
|
||||||
context=context,
|
context=context,
|
||||||
instance=instance)
|
instance=instance)
|
||||||
|
@ -20,11 +20,13 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from ceilometer import publish
|
from stevedore import dispatch
|
||||||
|
|
||||||
from ceilometer import counter
|
from ceilometer import counter
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
from ceilometer.openstack.common import context
|
from ceilometer.openstack.common import context
|
||||||
from ceilometer.openstack.common import timeutils
|
from ceilometer.openstack.common import timeutils
|
||||||
|
from ceilometer import pipeline
|
||||||
|
|
||||||
from swift.common.utils import split_path
|
from swift.common.utils import split_path
|
||||||
|
|
||||||
@ -50,6 +52,13 @@ class CeilometerMiddleware(object):
|
|||||||
def __init__(self, app, conf):
|
def __init__(self, app, conf):
|
||||||
self.app = app
|
self.app = app
|
||||||
cfg.CONF([], project='ceilometer')
|
cfg.CONF([], project='ceilometer')
|
||||||
|
publisher_manager = dispatch.NameDispatchExtensionManager(
|
||||||
|
namespace=pipeline.PUBLISHER_NAMESPACE,
|
||||||
|
check_func=lambda x: True,
|
||||||
|
invoke_on_load=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.pipeline_manager = pipeline.setup_pipeline(publisher_manager)
|
||||||
|
|
||||||
def __call__(self, env, start_response):
|
def __call__(self, env, start_response):
|
||||||
start_response_args = [None]
|
start_response_args = [None]
|
||||||
@ -81,14 +90,14 @@ class CeilometerMiddleware(object):
|
|||||||
else:
|
else:
|
||||||
return iter_response(iterable)
|
return iter_response(iterable)
|
||||||
|
|
||||||
@staticmethod
|
def publish_counter(self, env, bytes_received, bytes_sent):
|
||||||
def publish_counter(env, bytes_received, bytes_sent):
|
|
||||||
req = Request(env)
|
req = Request(env)
|
||||||
version, account, container, obj = split_path(req.path, 1, 4, True)
|
version, account, container, obj = split_path(req.path, 1, 4, True)
|
||||||
now = timeutils.utcnow().isoformat()
|
now = timeutils.utcnow().isoformat()
|
||||||
|
|
||||||
if bytes_received:
|
if bytes_received:
|
||||||
publish.publish_counter(context.get_admin_context(),
|
self.pipeline_manager.publish_counter(
|
||||||
|
context.get_admin_context(),
|
||||||
counter.Counter(
|
counter.Counter(
|
||||||
name='storage.objects.incoming.bytes',
|
name='storage.objects.incoming.bytes',
|
||||||
type='delta',
|
type='delta',
|
||||||
@ -96,22 +105,19 @@ class CeilometerMiddleware(object):
|
|||||||
volume=bytes_received,
|
volume=bytes_received,
|
||||||
user_id=env.get('HTTP_X_USER_ID'),
|
user_id=env.get('HTTP_X_USER_ID'),
|
||||||
project_id=env.get('HTTP_X_TENANT_ID'),
|
project_id=env.get('HTTP_X_TENANT_ID'),
|
||||||
resource_id=account.partition(
|
resource_id=account.partition('AUTH_')[2],
|
||||||
'AUTH_')[2],
|
|
||||||
timestamp=now,
|
timestamp=now,
|
||||||
resource_metadata={
|
resource_metadata={
|
||||||
"path": req.path,
|
"path": req.path,
|
||||||
"version": version,
|
"version": version,
|
||||||
"container": container,
|
"container": container,
|
||||||
"object": obj,
|
"object": obj,
|
||||||
},
|
}, ),
|
||||||
),
|
|
||||||
cfg.CONF.metering_topic,
|
|
||||||
cfg.CONF.metering_secret,
|
|
||||||
cfg.CONF.counter_source)
|
cfg.CONF.counter_source)
|
||||||
|
|
||||||
if bytes_sent:
|
if bytes_sent:
|
||||||
publish.publish_counter(context.get_admin_context(),
|
self.pipeline_manager.publish_counter(
|
||||||
|
context.get_admin_context(),
|
||||||
counter.Counter(
|
counter.Counter(
|
||||||
name='storage.objects.outgoing.bytes',
|
name='storage.objects.outgoing.bytes',
|
||||||
type='delta',
|
type='delta',
|
||||||
@ -119,8 +125,7 @@ class CeilometerMiddleware(object):
|
|||||||
volume=bytes_sent,
|
volume=bytes_sent,
|
||||||
user_id=env.get('HTTP_X_USER_ID'),
|
user_id=env.get('HTTP_X_USER_ID'),
|
||||||
project_id=env.get('HTTP_X_TENANT_ID'),
|
project_id=env.get('HTTP_X_TENANT_ID'),
|
||||||
resource_id=account.partition(
|
resource_id=account.partition('AUTH_')[2],
|
||||||
'AUTH_')[2],
|
|
||||||
timestamp=now,
|
timestamp=now,
|
||||||
resource_metadata={
|
resource_metadata={
|
||||||
"path": req.path,
|
"path": req.path,
|
||||||
@ -128,8 +133,6 @@ class CeilometerMiddleware(object):
|
|||||||
"container": container,
|
"container": container,
|
||||||
"object": obj,
|
"object": obj,
|
||||||
}),
|
}),
|
||||||
cfg.CONF.metering_topic,
|
|
||||||
cfg.CONF.metering_secret,
|
|
||||||
cfg.CONF.counter_source)
|
cfg.CONF.counter_source)
|
||||||
|
|
||||||
|
|
||||||
|
0
ceilometer/publisher/__init__.py
Normal file
0
ceilometer/publisher/__init__.py
Normal file
@ -22,6 +22,7 @@ from ceilometer.collector import meter
|
|||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
from ceilometer.openstack.common import log
|
from ceilometer.openstack.common import log
|
||||||
from ceilometer.openstack.common import rpc
|
from ceilometer.openstack.common import rpc
|
||||||
|
from ceilometer import plugin
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -42,18 +43,21 @@ def register_opts(config):
|
|||||||
register_opts(cfg.CONF)
|
register_opts(cfg.CONF)
|
||||||
|
|
||||||
|
|
||||||
def publish_counter(context, counter, topic, secret, source):
|
class MeterPublisher(plugin.PublisherBase):
|
||||||
"""Send a metering message for the data represented by the counter.
|
def publish_counter(self, context, counter, source):
|
||||||
|
"""Send a metering message for publishing
|
||||||
|
|
||||||
:param context: Execution context from the service or RPC call
|
:param context: Execution context from the service or RPC call
|
||||||
:param counter: ceilometer.counter.Counter instance
|
:param counter: Counter from pipeline after transformation
|
||||||
:param source: counter source
|
:param source: counter source
|
||||||
"""
|
"""
|
||||||
|
topic = cfg.CONF.metering_topic
|
||||||
msg = {
|
msg = {
|
||||||
'method': 'record_metering_data',
|
'method': 'record_metering_data',
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
'args': {'data': meter.meter_message_from_counter(counter,
|
'args': {'data': meter.meter_message_from_counter(
|
||||||
secret,
|
counter,
|
||||||
|
cfg.CONF.metering_secret,
|
||||||
source),
|
source),
|
||||||
},
|
},
|
||||||
}
|
}
|
9
etc/ceilometer/pipeline.yaml
Normal file
9
etc/ceilometer/pipeline.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
-
|
||||||
|
name: meter_pipeline
|
||||||
|
interval: 60
|
||||||
|
counters:
|
||||||
|
- "*"
|
||||||
|
transformers:
|
||||||
|
publishers:
|
||||||
|
- meter_publisher
|
5
setup.py
5
setup.py
@ -130,6 +130,11 @@ setuptools.setup(
|
|||||||
[ceilometer.compute.virt]
|
[ceilometer.compute.virt]
|
||||||
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
||||||
|
|
||||||
|
[ceilometer.transformer]
|
||||||
|
|
||||||
|
[ceilometer.publisher]
|
||||||
|
meter_publisher = ceilometer.publisher.meter_publish:MeterPublisher
|
||||||
|
|
||||||
[paste.filter_factory]
|
[paste.filter_factory]
|
||||||
swift=ceilometer.objectstore.swift_middleware:filter_factory
|
swift=ceilometer.objectstore.swift_middleware:filter_factory
|
||||||
"""),
|
"""),
|
||||||
|
@ -19,20 +19,22 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import mock
|
||||||
from stevedore import extension
|
from stevedore import extension
|
||||||
|
|
||||||
from ceilometer.central import manager
|
from ceilometer.central import manager
|
||||||
from ceilometer import counter
|
from ceilometer import counter
|
||||||
from ceilometer import publish
|
from ceilometer import pipeline
|
||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
|
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
from keystoneclient.v2_0 import client as ksclient
|
from keystoneclient.v2_0 import client as ksclient
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def test_load_plugins():
|
def test_load_plugins():
|
||||||
mgr = manager.AgentManager()
|
mgr = manager.AgentManager()
|
||||||
assert list(mgr.ext_manager), 'Failed to load any plugins'
|
assert list(mgr.pollster_manager), 'Failed to load any plugins'
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@ -56,23 +58,21 @@ class TestRunTasks(base.TestCase):
|
|||||||
self.counters.append((manager, self.test_data))
|
self.counters.append((manager, self.test_data))
|
||||||
return [self.test_data]
|
return [self.test_data]
|
||||||
|
|
||||||
def faux_notify(self, context, msg, topic, secret, source):
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
self.notifications.append((msg, topic, secret, source))
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestRunTasks, self).setUp()
|
super(TestRunTasks, self).setUp()
|
||||||
self.notifications = []
|
|
||||||
self.stubs.Set(publish, 'publish_counter', self.faux_notify)
|
|
||||||
self.stubs.Set(ksclient, 'Client', lambda *args, **kwargs: None)
|
self.stubs.Set(ksclient, 'Client', lambda *args, **kwargs: None)
|
||||||
self.mgr = manager.AgentManager()
|
self.mgr = manager.AgentManager()
|
||||||
self.mgr.ext_manager = extension.ExtensionManager('fake',
|
|
||||||
|
self.mgr.pollster_manager = extension.ExtensionManager(
|
||||||
|
'fake',
|
||||||
invoke_on_load=False,
|
invoke_on_load=False,
|
||||||
)
|
)
|
||||||
self.mgr.ext_manager.extensions = [extension.Extension('test',
|
self.mgr.pollster_manager.extensions = [
|
||||||
|
extension.Extension('test',
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.Pollster(),
|
self.Pollster(), ),
|
||||||
),
|
|
||||||
]
|
]
|
||||||
# Invoke the periodic tasks to call the pollsters.
|
# Invoke the periodic tasks to call the pollsters.
|
||||||
self.mgr.periodic_tasks(None)
|
self.mgr.periodic_tasks(None)
|
||||||
@ -87,8 +87,7 @@ class TestRunTasks(base.TestCase):
|
|||||||
self.Pollster.test_data)
|
self.Pollster.test_data)
|
||||||
|
|
||||||
def test_notifications(self):
|
def test_notifications(self):
|
||||||
actual = self.notifications
|
self.assertTrue(self.mgr.pipeline_manager.publish_counter.called)
|
||||||
self.assertEqual(list(actual[0]), [self.Pollster.test_data,
|
args, _ = self.mgr.pipeline_manager.publish_counter.call_args
|
||||||
cfg.CONF.metering_topic,
|
self.assertEqual(args[1], self.Pollster.test_data)
|
||||||
cfg.CONF.metering_secret,
|
self.assertEqual(args[2], cfg.CONF.counter_source)
|
||||||
cfg.CONF.counter_source])
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
from mock import MagicMock
|
||||||
|
|
||||||
from stevedore import extension
|
from stevedore import extension
|
||||||
from stevedore.tests import manager as test_manager
|
from stevedore.tests import manager as test_manager
|
||||||
@ -28,6 +29,7 @@ from stevedore.tests import manager as test_manager
|
|||||||
from ceilometer.collector import meter
|
from ceilometer.collector import meter
|
||||||
from ceilometer.collector import service
|
from ceilometer.collector import service
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
|
from ceilometer import pipeline
|
||||||
from ceilometer.storage import base
|
from ceilometer.storage import base
|
||||||
from ceilometer.tests import base as tests_base
|
from ceilometer.tests import base as tests_base
|
||||||
from ceilometer.compute import notifications
|
from ceilometer.compute import notifications
|
||||||
@ -91,6 +93,7 @@ class TestCollectorService(tests_base.TestCase):
|
|||||||
self.ctx = None
|
self.ctx = None
|
||||||
#cfg.CONF.metering_secret = 'not-so-secret'
|
#cfg.CONF.metering_secret = 'not-so-secret'
|
||||||
|
|
||||||
|
@patch('ceilometer.pipeline.setup_pipeline', MagicMock())
|
||||||
def test_init_host(self):
|
def test_init_host(self):
|
||||||
cfg.CONF.database_connection = 'log://localhost'
|
cfg.CONF.database_connection = 'log://localhost'
|
||||||
# If we try to create a real RPC connection, init_host() never
|
# If we try to create a real RPC connection, init_host() never
|
||||||
@ -181,15 +184,14 @@ class TestCollectorService(tests_base.TestCase):
|
|||||||
self.srv.record_metering_data(self.ctx, msg)
|
self.srv.record_metering_data(self.ctx, msg)
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
@patch('ceilometer.pipeline.setup_pipeline', MagicMock())
|
||||||
def test_process_notification(self):
|
def test_process_notification(self):
|
||||||
# If we try to create a real RPC connection, init_host() never
|
# If we try to create a real RPC connection, init_host() never
|
||||||
# returns. Mock it out so we can establish the manager
|
# returns. Mock it out so we can establish the manager
|
||||||
# configuration.
|
# configuration.
|
||||||
with patch('ceilometer.openstack.common.rpc.create_connection'):
|
with patch('ceilometer.openstack.common.rpc.create_connection'):
|
||||||
self.srv.start()
|
self.srv.start()
|
||||||
results = []
|
self.srv.notification_manager = test_manager.TestExtensionManager(
|
||||||
self.stubs.Set(self.srv, 'publish_counter', results.append)
|
|
||||||
self.srv.ext_manager = test_manager.TestExtensionManager(
|
|
||||||
[extension.Extension('test',
|
[extension.Extension('test',
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -197,4 +199,4 @@ class TestCollectorService(tests_base.TestCase):
|
|||||||
),
|
),
|
||||||
])
|
])
|
||||||
self.srv.process_notification(TEST_NOTICE)
|
self.srv.process_notification(TEST_NOTICE)
|
||||||
self.assert_(len(results) >= 1)
|
assert self.srv.pipeline_manager.publish_counter.called
|
||||||
|
@ -44,6 +44,7 @@ class FauxInstance(object):
|
|||||||
|
|
||||||
class TestLocationMetadata(unittest.TestCase):
|
class TestLocationMetadata(unittest.TestCase):
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.manager = manager.AgentManager()
|
self.manager = manager.AgentManager()
|
||||||
super(TestLocationMetadata, self).setUp()
|
super(TestLocationMetadata, self).setUp()
|
||||||
|
@ -19,21 +19,22 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import mock
|
||||||
from stevedore import extension
|
from stevedore import extension
|
||||||
|
|
||||||
from ceilometer import nova_client
|
from ceilometer import nova_client
|
||||||
from ceilometer.compute import manager
|
from ceilometer.compute import manager
|
||||||
from ceilometer import counter
|
from ceilometer import counter
|
||||||
from ceilometer import publish
|
from ceilometer import pipeline
|
||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
|
|
||||||
from ceilometer.openstack.common import cfg
|
from ceilometer.openstack.common import cfg
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def test_load_plugins():
|
def test_load_plugins():
|
||||||
mgr = manager.AgentManager()
|
mgr = manager.AgentManager()
|
||||||
assert list(mgr.ext_manager), 'Failed to load any plugins'
|
assert list(mgr.pollster_manager), 'Failed to load any plugins'
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@ -57,23 +58,21 @@ class TestRunTasks(base.TestCase):
|
|||||||
self.counters.append((manager, instance))
|
self.counters.append((manager, instance))
|
||||||
return [self.test_data]
|
return [self.test_data]
|
||||||
|
|
||||||
def faux_notify(self, context, msg, topic, secret, source):
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
self.notifications.append((msg, topic, secret, source))
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestRunTasks, self).setUp()
|
super(TestRunTasks, self).setUp()
|
||||||
self.notifications = []
|
|
||||||
self.stubs.Set(publish, 'publish_counter', self.faux_notify)
|
|
||||||
self.mgr = manager.AgentManager()
|
self.mgr = manager.AgentManager()
|
||||||
self.mgr.ext_manager = extension.ExtensionManager('fake',
|
self.mgr.pollster_manager = extension.ExtensionManager(
|
||||||
|
'fake',
|
||||||
invoke_on_load=False,
|
invoke_on_load=False,
|
||||||
)
|
)
|
||||||
self.mgr.ext_manager.extensions = [extension.Extension('test',
|
self.mgr.pollster_manager.extensions = [
|
||||||
|
extension.Extension('test',
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.Pollster(),
|
self.Pollster(), ),
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Set up a fake instance value to be returned by
|
# Set up a fake instance value to be returned by
|
||||||
# instance_get_all_by_host() so when the manager gets the list
|
# instance_get_all_by_host() so when the manager gets the list
|
||||||
# of instances to poll we can control the results.
|
# of instances to poll we can control the results.
|
||||||
@ -96,8 +95,7 @@ class TestRunTasks(base.TestCase):
|
|||||||
self.assertTrue(self.Pollster.counters[0][1] is self.instance)
|
self.assertTrue(self.Pollster.counters[0][1] is self.instance)
|
||||||
|
|
||||||
def test_notifications(self):
|
def test_notifications(self):
|
||||||
actual = self.notifications
|
self.assertTrue(self.mgr.pipeline_manager.publish_counter.called)
|
||||||
self.assertEqual(list(actual[0]), [self.Pollster.test_data,
|
args, _ = self.mgr.pipeline_manager.publish_counter.call_args
|
||||||
cfg.CONF.metering_topic,
|
self.assertEqual(args[1], self.Pollster.test_data)
|
||||||
cfg.CONF.metering_secret,
|
self.assertEqual(args[2], cfg.CONF.counter_source)
|
||||||
cfg.CONF.counter_source])
|
|
||||||
|
@ -44,7 +44,6 @@ except ImportError:
|
|||||||
notifier_api = None
|
notifier_api = None
|
||||||
|
|
||||||
|
|
||||||
from ceilometer import publish
|
|
||||||
from ceilometer import counter
|
from ceilometer import counter
|
||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
from ceilometer.tests import skip
|
from ceilometer.tests import skip
|
||||||
@ -86,6 +85,7 @@ class TestNovaNotifier(base.TestCase):
|
|||||||
def fake_db_instance_system_metadata_get(context, uuid):
|
def fake_db_instance_system_metadata_get(context, uuid):
|
||||||
return dict(meta_a=123, meta_b="foobar")
|
return dict(meta_a=123, meta_b="foobar")
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
@skip.skip_unless(notifier_api, "Notifier API not found")
|
@skip.skip_unless(notifier_api, "Notifier API not found")
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestNovaNotifier, self).setUp()
|
super(TestNovaNotifier, self).setUp()
|
||||||
@ -133,9 +133,8 @@ class TestNovaNotifier(base.TestCase):
|
|||||||
lambda context, uuid, kwargs: (self.instance,
|
lambda context, uuid, kwargs: (self.instance,
|
||||||
self.instance))
|
self.instance))
|
||||||
|
|
||||||
self.stubs.Set(publish, 'publish_counter', self.do_nothing)
|
|
||||||
agent_manager = manager.AgentManager()
|
agent_manager = manager.AgentManager()
|
||||||
agent_manager.ext_manager = \
|
agent_manager.pollster_manager = \
|
||||||
test_manager.TestExtensionManager([
|
test_manager.TestExtensionManager([
|
||||||
extension.Extension('test',
|
extension.Extension('test',
|
||||||
None,
|
None,
|
||||||
|
@ -51,6 +51,7 @@ class TestInstancePollster(TestPollsterBase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestInstancePollster, self).setUp()
|
super(TestInstancePollster, self).setUp()
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def test_get_counters(self):
|
def test_get_counters(self):
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ class TestDiskIOPollster(TestPollsterBase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestDiskIOPollster, self).setUp()
|
super(TestDiskIOPollster, self).setUp()
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def test_get_counters(self):
|
def test_get_counters(self):
|
||||||
disks = [
|
disks = [
|
||||||
(virt_inspector.Disk(device='vda'),
|
(virt_inspector.Disk(device='vda'),
|
||||||
@ -102,6 +104,7 @@ class TestNetPollster(TestPollsterBase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestNetPollster, self).setUp()
|
super(TestNetPollster, self).setUp()
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def test_get_counters(self):
|
def test_get_counters(self):
|
||||||
vnic0 = virt_inspector.Interface(
|
vnic0 = virt_inspector.Interface(
|
||||||
name='vnet0',
|
name='vnet0',
|
||||||
@ -157,6 +160,7 @@ class TestCPUPollster(TestPollsterBase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestCPUPollster, self).setUp()
|
super(TestCPUPollster, self).setUp()
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def test_get_counters(self):
|
def test_get_counters(self):
|
||||||
self.inspector.inspect_cpus(self.instance.name).AndReturn(
|
self.inspector.inspect_cpus(self.instance.name).AndReturn(
|
||||||
virt_inspector.CPUStats(time=1 * (10 ** 6), number=2))
|
virt_inspector.CPUStats(time=1 * (10 ** 6), number=2))
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import mock
|
||||||
|
|
||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
from ceilometer.energy import kwapi
|
from ceilometer.energy import kwapi
|
||||||
@ -60,6 +61,7 @@ class TestKwapiPollster(base.TestCase):
|
|||||||
probe_dict['id'] = key
|
probe_dict['id'] = key
|
||||||
yield probe_dict
|
yield probe_dict
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestKwapiPollster, self).setUp()
|
super(TestKwapiPollster, self).setUp()
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
from ceilometer.image import glance
|
from ceilometer.image import glance
|
||||||
from ceilometer.central import manager
|
from ceilometer.central import manager
|
||||||
@ -96,6 +98,7 @@ class TestImagePollster(base.TestCase):
|
|||||||
def fake_glance_iter_images(self, ksclient):
|
def fake_glance_iter_images(self, ksclient):
|
||||||
return iter(IMAGE_LIST)
|
return iter(IMAGE_LIST)
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestImagePollster, self).setUp()
|
super(TestImagePollster, self).setUp()
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
@ -28,6 +28,7 @@ from ceilometer.tests import base
|
|||||||
|
|
||||||
class TestFloatingIPPollster(base.TestCase):
|
class TestFloatingIPPollster(base.TestCase):
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestFloatingIPPollster, self).setUp()
|
super(TestFloatingIPPollster, self).setUp()
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import mock
|
||||||
from ceilometer.central import manager
|
from ceilometer.central import manager
|
||||||
from ceilometer.objectstore import swift
|
from ceilometer.objectstore import swift
|
||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
@ -45,6 +46,7 @@ class TestSwiftPollster(base.TestCase):
|
|||||||
for i in ACCOUNTS:
|
for i in ACCOUNTS:
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
|
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSwiftPollster, self).setUp()
|
super(TestSwiftPollster, self).setUp()
|
||||||
self.pollster = swift.SwiftPollster()
|
self.pollster = swift.SwiftPollster()
|
||||||
|
@ -23,6 +23,7 @@ from webob import Request
|
|||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
from ceilometer.objectstore import swift_middleware
|
from ceilometer.objectstore import swift_middleware
|
||||||
from ceilometer.openstack.common import rpc
|
from ceilometer.openstack.common import rpc
|
||||||
|
from ceilometer import pipeline
|
||||||
|
|
||||||
|
|
||||||
class FakeApp(object):
|
class FakeApp(object):
|
||||||
@ -41,30 +42,37 @@ class FakeApp(object):
|
|||||||
|
|
||||||
class TestSwiftMiddleware(base.TestCase):
|
class TestSwiftMiddleware(base.TestCase):
|
||||||
|
|
||||||
|
class _faux_pipeline_manager():
|
||||||
|
def __init__(self):
|
||||||
|
self.counters = []
|
||||||
|
|
||||||
|
def publish_counter(self, context, counter, source):
|
||||||
|
self.counters.append(counter)
|
||||||
|
|
||||||
|
def _faux_setup_pipeline(self, publisher_manager):
|
||||||
|
return self.pipeline_manager
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSwiftMiddleware, self).setUp()
|
super(TestSwiftMiddleware, self).setUp()
|
||||||
self.notifications = []
|
self.pipeline_manager = self._faux_pipeline_manager()
|
||||||
self.stubs.Set(rpc, 'cast', self._faux_notify)
|
self.stubs.Set(pipeline, 'setup_pipeline', self._faux_setup_pipeline)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start_response(*args):
|
def start_response(*args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _faux_notify(self, context, topic, msg):
|
|
||||||
self.notifications.append((topic, msg))
|
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
app = swift_middleware.CeilometerMiddleware(FakeApp(), {})
|
app = swift_middleware.CeilometerMiddleware(FakeApp(), {})
|
||||||
req = Request.blank('/1.0/account/container/obj',
|
req = Request.blank('/1.0/account/container/obj',
|
||||||
environ={'REQUEST_METHOD': 'GET'})
|
environ={'REQUEST_METHOD': 'GET'})
|
||||||
resp = app(req.environ, self.start_response)
|
resp = app(req.environ, self.start_response)
|
||||||
self.assertEqual(list(resp), ["This string is 28 bytes long"])
|
self.assertEqual(list(resp), ["This string is 28 bytes long"])
|
||||||
self.assertEqual(len(self.notifications), 2)
|
self.assertEqual(len(self.pipeline_manager.counters), 1)
|
||||||
data = self.notifications[0][1]['args']['data']
|
data = self.pipeline_manager.counters[0]
|
||||||
self.assertEqual(data['counter_volume'], 28)
|
self.assertEqual(data.volume, 28)
|
||||||
self.assertEqual(data['resource_metadata']['version'], '1.0')
|
self.assertEqual(data.resource_metadata['version'], '1.0')
|
||||||
self.assertEqual(data['resource_metadata']['container'], 'container')
|
self.assertEqual(data.resource_metadata['container'], 'container')
|
||||||
self.assertEqual(data['resource_metadata']['object'], 'obj')
|
self.assertEqual(data.resource_metadata['object'], 'obj')
|
||||||
|
|
||||||
def test_put(self):
|
def test_put(self):
|
||||||
app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {})
|
app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {})
|
||||||
@ -73,12 +81,12 @@ class TestSwiftMiddleware(base.TestCase):
|
|||||||
'wsgi.input':
|
'wsgi.input':
|
||||||
StringIO.StringIO('some stuff')})
|
StringIO.StringIO('some stuff')})
|
||||||
resp = list(app(req.environ, self.start_response))
|
resp = list(app(req.environ, self.start_response))
|
||||||
self.assertEqual(len(self.notifications), 2)
|
self.assertEqual(len(self.pipeline_manager.counters), 1)
|
||||||
data = self.notifications[0][1]['args']['data']
|
data = self.pipeline_manager.counters[0]
|
||||||
self.assertEqual(data['counter_volume'], 10)
|
self.assertEqual(data.volume, 10)
|
||||||
self.assertEqual(data['resource_metadata']['version'], '1.0')
|
self.assertEqual(data.resource_metadata['version'], '1.0')
|
||||||
self.assertEqual(data['resource_metadata']['container'], 'container')
|
self.assertEqual(data.resource_metadata['container'], 'container')
|
||||||
self.assertEqual(data['resource_metadata']['object'], 'obj')
|
self.assertEqual(data.resource_metadata['object'], 'obj')
|
||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {})
|
app = swift_middleware.CeilometerMiddleware(FakeApp(body=['']), {})
|
||||||
@ -87,21 +95,21 @@ class TestSwiftMiddleware(base.TestCase):
|
|||||||
'wsgi.input':
|
'wsgi.input':
|
||||||
StringIO.StringIO('some other stuff')})
|
StringIO.StringIO('some other stuff')})
|
||||||
resp = list(app(req.environ, self.start_response))
|
resp = list(app(req.environ, self.start_response))
|
||||||
self.assertEqual(len(self.notifications), 2)
|
self.assertEqual(len(self.pipeline_manager.counters), 1)
|
||||||
data = self.notifications[0][1]['args']['data']
|
data = self.pipeline_manager.counters[0]
|
||||||
self.assertEqual(data['counter_volume'], 16)
|
self.assertEqual(data.volume, 16)
|
||||||
self.assertEqual(data['resource_metadata']['version'], '1.0')
|
self.assertEqual(data.resource_metadata['version'], '1.0')
|
||||||
self.assertEqual(data['resource_metadata']['container'], 'container')
|
self.assertEqual(data.resource_metadata['container'], 'container')
|
||||||
self.assertEqual(data['resource_metadata']['object'], 'obj')
|
self.assertEqual(data.resource_metadata['object'], 'obj')
|
||||||
|
|
||||||
def test_get_container(self):
|
def test_get_container(self):
|
||||||
app = swift_middleware.CeilometerMiddleware(FakeApp(), {})
|
app = swift_middleware.CeilometerMiddleware(FakeApp(), {})
|
||||||
req = Request.blank('/1.0/account/container',
|
req = Request.blank('/1.0/account/container',
|
||||||
environ={'REQUEST_METHOD': 'GET'})
|
environ={'REQUEST_METHOD': 'GET'})
|
||||||
resp = list(app(req.environ, self.start_response))
|
resp = list(app(req.environ, self.start_response))
|
||||||
self.assertEqual(len(self.notifications), 2)
|
self.assertEqual(len(self.pipeline_manager.counters), 1)
|
||||||
data = self.notifications[0][1]['args']['data']
|
data = self.pipeline_manager.counters[0]
|
||||||
self.assertEqual(data['counter_volume'], 28)
|
self.assertEqual(data.volume, 28)
|
||||||
self.assertEqual(data['resource_metadata']['version'], '1.0')
|
self.assertEqual(data.resource_metadata['version'], '1.0')
|
||||||
self.assertEqual(data['resource_metadata']['container'], 'container')
|
self.assertEqual(data.resource_metadata['container'], 'container')
|
||||||
self.assertEqual(data['resource_metadata']['object'], None)
|
self.assertEqual(data.resource_metadata['object'], None)
|
||||||
|
0
tests/publisher/__init__.py
Normal file
0
tests/publisher/__init__.py
Normal file
@ -24,7 +24,7 @@ from ceilometer.openstack.common import rpc
|
|||||||
from ceilometer.tests import base
|
from ceilometer.tests import base
|
||||||
|
|
||||||
from ceilometer import counter
|
from ceilometer import counter
|
||||||
from ceilometer import publish
|
from ceilometer.publisher import meter_publish
|
||||||
|
|
||||||
|
|
||||||
class TestPublish(base.TestCase):
|
class TestPublish(base.TestCase):
|
||||||
@ -48,10 +48,9 @@ class TestPublish(base.TestCase):
|
|||||||
super(TestPublish, self).setUp()
|
super(TestPublish, self).setUp()
|
||||||
self.notifications = []
|
self.notifications = []
|
||||||
self.stubs.Set(rpc, 'cast', self.faux_notify)
|
self.stubs.Set(rpc, 'cast', self.faux_notify)
|
||||||
publish.publish_counter(None,
|
publisher = meter_publish.MeterPublisher()
|
||||||
|
publisher.publish_counter(None,
|
||||||
self.test_data,
|
self.test_data,
|
||||||
'metering',
|
|
||||||
'not-so-secret',
|
|
||||||
'test',
|
'test',
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user