Port to oslo.messaging.Notifier API

Add a temporary nova.notifier.Notifier helper class which translates
oslo.messaging.Notifier compatible calls into openstack.common.notifier
compatible calls.

This allows us to port the notifier code over to the oslo.messaging API
before actually switching over oslo.messaging fully.

This patch contains no functional changes at all, except that all
notifications go through this temporary helper class.

Some notes on the new API:

  * The notifier API is changed so that what was previously global state
    is now encapsulated in a Notifier object. This object also includes
    the publisher_id and has error()/info()/etc. methods rather than
    just notify().

  * The notify_decorator() helper wasn't carried across to the new API
    because its semantics are a bit weird. Something along these lines
    could be added in future, though.

  * We use a fake Notifier implementation for tests because there's no
    API in oslo.messaging to actually get the notifications queued
    up in the fake notification driver, which is a bit dumb. However,
    this feels like the right thing to do anyway. We're not wanting
    to test oslo.messaging.Notifier itself, but rather we want to test
    how we call it.

blueprint: oslo-messaging
Change-Id: I262163c7e05e6a6fb79265e904ce761fc3ac5806
This commit is contained in:
Mark McLoughlin 2013-08-29 22:38:31 +01:00
parent 11f6413dc9
commit 60a91f475a
24 changed files with 536 additions and 389 deletions

View File

@ -260,7 +260,7 @@
#monkey_patch=false
# List of modules/decorators to monkey patch (list value)
#monkey_patch_modules=nova.api.ec2.cloud:nova.openstack.common.notifier.api.notify_decorator,nova.compute.api:nova.openstack.common.notifier.api.notify_decorator
#monkey_patch_modules=nova.api.ec2.cloud:nova.notifications.notify_decorator,nova.compute.api:nova.notifications.notify_decorator
# Length of generated instance admin passwords (integer value)
#password_length=12

View File

@ -50,6 +50,7 @@ from nova.network import model as network_model
from nova.network.security_group import openstack_driver
from nova.network.security_group import security_group_base
from nova import notifications
from nova import notifier
from nova.objects import aggregate as aggregate_obj
from nova.objects import base as obj_base
from nova.objects import instance as instance_obj
@ -62,7 +63,6 @@ from nova.objects import service as service_obj
from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common import strutils
from nova.openstack.common import timeutils
from nova.openstack.common import uuidutils
@ -75,11 +75,9 @@ from nova import volume
LOG = logging.getLogger(__name__)
wrap_exception = functools.partial(
exception.wrap_exception,
notifier=notifier, publisher_id=notifier.publisher_id('aggregate'))
get_notifier = functools.partial(notifier.get_notifier, service='aggregate')
wrap_exception = functools.partial(exception.wrap_exception,
get_notifier=get_notifier)
compute_opts = [
cfg.BoolOpt('allow_resize_to_same_host',
@ -236,6 +234,7 @@ class API(base.Base):
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
self._compute_task_api = None
self.servicegroup_api = servicegroup.API()
self.notifier = notifier.get_notifier('compute', CONF.host)
super(API, self).__init__(**kwargs)
@ -1418,7 +1417,7 @@ class API(base.Base):
instance_uuid = instance['uuid']
instance.info_cache.delete()
compute_utils.notify_about_instance_usage(
context, instance, "%s.start" % delete_type)
self.notifier, context, instance, "%s.start" % delete_type)
elevated = context.elevated()
if self.cell_type != 'api':
@ -1445,7 +1444,7 @@ class API(base.Base):
cb(context, instance, bdms, local=True)
instance.destroy()
compute_utils.notify_about_instance_usage(
context, instance, "%s.end" % delete_type,
self.notifier, context, instance, "%s.end" % delete_type,
system_metadata=system_meta)
def _do_delete(self, context, instance, bdms, reservations=None,

View File

@ -60,6 +60,7 @@ from nova import manager
from nova import network
from nova.network import model as network_model
from nova.network.security_group import openstack_driver
from nova import notifier
from nova.objects import base as obj_base
from nova.objects import instance as instance_obj
from nova.objects import migration as migration_obj
@ -67,7 +68,6 @@ from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common import periodic_task
from nova.openstack.common import rpc
from nova.openstack.common.rpc import common as rpc_common
@ -214,10 +214,9 @@ CONF.import_opt('enable', 'nova.cells.opts', group='cells')
LOG = logging.getLogger(__name__)
wrap_exception = functools.partial(
exception.wrap_exception,
notifier=notifier, publisher_id=notifier.publisher_id('compute'))
get_notifier = functools.partial(notifier.get_notifier, service='compute')
wrap_exception = functools.partial(exception.wrap_exception,
get_notifier=get_notifier)
def reverts_task_state(function):
@ -1364,14 +1363,11 @@ class ComputeManager(manager.SchedulerDependentManager):
def _notify_about_instance_usage(self, context, instance, event_suffix,
network_info=None, system_metadata=None,
extra_usage_info=None):
# NOTE(sirp): The only thing this wrapper function does extra is handle
# the passing in of `self.host`. Ordinarily this will just be
# CONF.host`, but `Manager`'s gets a chance to override this in its
# `__init__`.
compute_utils.notify_about_instance_usage(
context, instance, event_suffix, network_info=network_info,
system_metadata=system_metadata,
extra_usage_info=extra_usage_info, host=self.host)
self.notifier, context, instance, event_suffix,
network_info=network_info,
system_metadata=system_metadata,
extra_usage_info=extra_usage_info)
def _deallocate_network(self, context, instance,
requested_networks=None):

View File

@ -27,10 +27,10 @@ from nova.compute import flavors
from nova import exception
from nova.network import model as network_model
from nova import notifications
from nova import notifier as notify
from nova.objects import instance as instance_obj
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common import timeutils
from nova import utils
from nova.virt import driver
@ -191,12 +191,14 @@ def _get_unused_letter(used_letters):
return letters[0]
def notify_usage_exists(context, instance_ref, current_period=False,
def notify_usage_exists(notifier, context, instance_ref, current_period=False,
ignore_missing_network_data=True,
system_metadata=None, extra_usage_info=None):
"""Generates 'exists' notification for an instance for usage auditing
purposes.
:param notifier: a messaging.Notifier
:param current_period: if True, this will generate a usage for the
current usage period; if False, this will generate a usage for the
previous audit period.
@ -228,29 +230,24 @@ def notify_usage_exists(context, instance_ref, current_period=False,
if extra_usage_info:
extra_info.update(extra_usage_info)
notify_about_instance_usage(context, instance_ref, 'exists',
notify_about_instance_usage(notifier, context, instance_ref, 'exists',
system_metadata=system_metadata, extra_usage_info=extra_info)
def notify_about_instance_usage(context, instance, event_suffix,
def notify_about_instance_usage(notifier, context, instance, event_suffix,
network_info=None, system_metadata=None,
extra_usage_info=None, host=None):
extra_usage_info=None):
"""
Send a notification about an instance.
:param notifier: a messaging.Notifier
:param event_suffix: Event type like "delete.start" or "exists"
:param network_info: Networking information, if provided.
:param system_metadata: system_metadata DB entries for the instance,
if provided.
:param extra_usage_info: Dictionary containing extra values to add or
override in the notification.
:param host: Compute host for the instance, if specified. Default is
CONF.host
"""
if not host:
host = CONF.host
if not extra_usage_info:
extra_usage_info = {}
@ -258,13 +255,11 @@ def notify_about_instance_usage(context, instance, event_suffix,
network_info, system_metadata, **extra_usage_info)
if event_suffix.endswith("error"):
level = notifier_api.ERROR
method = notifier.error
else:
level = notifier_api.INFO
method = notifier.info
notifier_api.notify(context, 'compute.%s' % host,
'compute.instance.%s' % event_suffix, level,
usage_info)
method(context, 'compute.instance.%s' % event_suffix, usage_info)
def notify_about_aggregate_update(context, event_suffix, aggregate_payload):
@ -282,9 +277,10 @@ def notify_about_aggregate_update(context, event_suffix, aggregate_payload):
"notification and it will be ignored"))
return
notifier_api.notify(context, 'aggregate.%s' % aggregate_identifier,
'aggregate.%s' % event_suffix, notifier_api.INFO,
aggregate_payload)
notifier = notify.get_notifier(service='aggregate',
host=aggregate_identifier)
notifier.info(context, 'aggregate.%s' % event_suffix, aggregate_payload)
def get_nw_info_for_instance(instance):

View File

@ -39,7 +39,6 @@ from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
from nova import quota
@ -401,9 +400,8 @@ class ConductorManager(manager.Manager):
update_totals)
# We have just updated the database, so send the notification now
notifier.notify(context, 'conductor.%s' % self.host, 'volume.usage',
notifier.INFO,
compute_utils.usage_volume_info(vol_usage))
self.notifier.info(context, 'volume.usage',
compute_utils.usage_volume_info(vol_usage))
@rpc_common.client_exceptions(exception.ComputeHostNotFound,
exception.HostBinaryNotFound)
@ -482,7 +480,8 @@ class ConductorManager(manager.Manager):
def notify_usage_exists(self, context, instance, current_period=False,
ignore_missing_network_data=True,
system_metadata=None, extra_usage_info=None):
compute_utils.notify_usage_exists(context, instance, current_period,
compute_utils.notify_usage_exists(self.notifier, context, instance,
current_period,
ignore_missing_network_data,
system_metadata, extra_usage_info)

View File

@ -60,14 +60,11 @@ def _cleanse_dict(original):
return dict((k, v) for k, v in original.iteritems() if not "_pass" in k)
def wrap_exception(notifier, publisher_id):
def wrap_exception(notifier=None, get_notifier=None):
"""This decorator wraps a method to catch any exceptions that may
get thrown. It logs the exception as well as optionally sending
it to the notification system.
"""
# TODO(sandy): Find a way to import nova.notifier.api so we don't have
# to pass it in as a parameter. Otherwise we get a cyclic import of
# nova.notifier.api -> nova.utils -> nova.exception :(
def inner(f):
def wrapped(self, context, *args, **kw):
# Don't store self or context in the payload, it now seems to
@ -76,16 +73,20 @@ def wrap_exception(notifier, publisher_id):
return f(self, context, *args, **kw)
except Exception as e:
with excutils.save_and_reraise_exception():
payload = dict(exception=e)
call_dict = safe_utils.getcallargs(f, *args, **kw)
cleansed = _cleanse_dict(call_dict)
payload.update({'args': cleansed})
if notifier or get_notifier:
payload = dict(exception=e)
call_dict = safe_utils.getcallargs(f, *args, **kw)
cleansed = _cleanse_dict(call_dict)
payload.update({'args': cleansed})
level = notifier.ERROR
event_type = f.__name__
# If f has multiple decorators, they must use
# functools.wraps to ensure the name is
# propagated.
event_type = f.__name__
notifier.notify(context, publisher_id,
event_type, level, payload)
(notifier or get_notifier()).error(context,
event_type,
payload)
return functools.wraps(f)(wrapped)
return inner

View File

@ -57,6 +57,7 @@ from oslo.config import cfg
from nova import baserpc
from nova.db import base
from nova import notifier
from nova.objects import base as objects_base
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
@ -80,6 +81,7 @@ class Manager(base.Base, periodic_task.PeriodicTasks):
self.host = host
self.backdoor_port = None
self.service_name = service_name
self.notifier = notifier.get_notifier(self.service_name, self.host)
super(Manager, self).__init__(db_driver)
def create_rpc_dispatcher(self, backdoor_port=None, additional_apis=None):

View File

@ -23,11 +23,11 @@ from nova import context
from nova.db import base
from nova import exception
from nova.network import rpcapi as network_rpcapi
from nova import notifier
from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common import processutils
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import uuidutils
@ -224,10 +224,8 @@ class FloatingIP(object):
floating_ip = self.db.floating_ip_allocate_address(
context, project_id, pool, auto_assigned=auto_assigned)
payload = dict(project_id=project_id, floating_ip=floating_ip)
notifier.notify(context,
notifier.publisher_id("network"),
'network.floating_ip.allocate',
notifier.INFO, payload)
self.notifier.info(context,
'network.floating_ip.allocate', payload)
# Commit the reservations
if use_quota:
@ -263,10 +261,7 @@ class FloatingIP(object):
floating_ip['address'])
payload = dict(project_id=floating_ip['project_id'],
floating_ip=floating_ip['address'])
notifier.notify(context,
notifier.publisher_id("network"),
'network.floating_ip.deallocate',
notifier.INFO, payload=payload)
self.notifier.info(context, 'network.floating_ip.deallocate', payload)
# Get reservations...
try:
@ -375,10 +370,8 @@ class FloatingIP(object):
payload = dict(project_id=context.project_id,
instance_id=instance_uuid,
floating_ip=floating_address)
notifier.notify(context,
notifier.publisher_id("network"),
'network.floating_ip.associate',
notifier.INFO, payload=payload)
self.notifier.info(context,
'network.floating_ip.associate', payload)
do_associate()
@rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
@ -461,10 +454,8 @@ class FloatingIP(object):
payload = dict(project_id=context.project_id,
instance_id=instance_uuid,
floating_ip=address)
notifier.notify(context,
notifier.publisher_id("network"),
'network.floating_ip.disassociate',
notifier.INFO, payload=payload)
self.notifier.info(context,
'network.floating_ip.disassociate', payload)
do_disassociate()
@rpc_common.client_exceptions(exception.FloatingIpNotFound)
@ -699,3 +690,4 @@ class LocalManager(base.Base, FloatingIP):
CONF.floating_ip_dns_manager)
self.instance_dns_manager = importutils.import_object(
CONF.instance_dns_manager)
self.notifier = notifier.get_notifier('network', CONF.host)

View File

@ -2,6 +2,7 @@
# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -29,10 +30,11 @@ from nova import db
from nova.image import glance
from nova import network
from nova.network import model as network_model
from nova import notifier as notify
from nova.openstack.common import context as common_context
from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common import timeutils
from nova import utils
@ -53,6 +55,40 @@ notify_opts = [
CONF = cfg.CONF
CONF.register_opts(notify_opts)
CONF.import_opt('default_notification_level',
'nova.openstack.common.notifier.api')
CONF.import_opt('default_publisher_id',
'nova.openstack.common.notifier.api')
def notify_decorator(name, fn):
"""Decorator for notify which is used from utils.monkey_patch().
:param name: name of the function
:param function: - object of the function
:returns: function -- decorated function
"""
def wrapped_func(*args, **kwarg):
body = {}
body['args'] = []
body['kwarg'] = {}
for arg in args:
body['args'].append(arg)
for key in kwarg:
body['kwarg'][key] = kwarg[key]
ctxt = common_context.get_context_from_function_and_args(
fn, args, kwarg)
notifier = notify.get_notifier(publisher_id=(CONF.default_publisher_id
or CONF.host))
method = notifier.getattr(CONF.default_notification_level.lower(),
'info')
method(ctxt, name, body)
return fn(*args, **kwarg)
return wrapped_func
def send_api_fault(url, status, exception):
@ -63,10 +99,7 @@ def send_api_fault(url, status, exception):
payload = {'url': url, 'exception': str(exception), 'status': status}
publisher_id = notifier_api.publisher_id("api")
notifier_api.notify(None, publisher_id, 'api.fault', notifier_api.ERROR,
payload)
notify.get_notifier('api').error(None, 'api.fault', payload)
def send_update(context, old_instance, new_instance, service=None, host=None):
@ -192,10 +225,8 @@ def _send_instance_update_notification(context, instance, old_vm_state=None,
if old_display_name:
payload["old_display_name"] = old_display_name
publisher_id = notifier_api.publisher_id(service, host)
notifier_api.notify(context, publisher_id, 'compute.instance.update',
notifier_api.INFO, payload)
notify.get_notifier(service, host).info(context,
'compute.instance.update', payload)
def audit_period_bounds(current_period=False):

73
nova/notifier.py Normal file
View File

@ -0,0 +1,73 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Red Hat, Inc.
#
# 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.
"""
A temporary helper which emulates oslo.messaging.Notifier.
This helper method allows us to do the tedious porting to the new Notifier API
as a standalone commit so that the commit which switches us to oslo.messaging
is smaller and easier to review. This file will be removed as part of that
commit.
"""
from oslo.config import cfg
from nova.openstack.common.notifier import api as notifier_api
CONF = cfg.CONF
class Notifier(object):
def __init__(self, publisher_id):
super(Notifier, self).__init__()
self.publisher_id = publisher_id
_marker = object()
def prepare(self, publisher_id=_marker):
ret = self.__class__(self.publisher_id)
if publisher_id is not self._marker:
ret.publisher_id = publisher_id
return ret
def _notify(self, ctxt, event_type, payload, priority):
notifier_api.notify(ctxt,
self.publisher_id,
event_type,
priority,
payload)
def debug(self, ctxt, event_type, payload):
self._notify(ctxt, event_type, payload, 'DEBUG')
def info(self, ctxt, event_type, payload):
self._notify(ctxt, event_type, payload, 'INFO')
def warn(self, ctxt, event_type, payload):
self._notify(ctxt, event_type, payload, 'WARN')
def error(self, ctxt, event_type, payload):
self._notify(ctxt, event_type, payload, 'ERROR')
def critical(self, ctxt, event_type, payload):
self._notify(ctxt, event_type, payload, 'CRITICAL')
def get_notifier(service=None, host=None, publisher_id=None):
if not publisher_id:
publisher_id = "%s.%s" % (service, host or CONF.host)
return Notifier(publisher_id)

View File

@ -31,10 +31,10 @@ from nova.conductor import api as conductor_api
from nova import db
from nova import exception
from nova import notifications
from nova import notifier
from nova.openstack.common.gettextutils import _
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common import timeutils
from nova import servicegroup
@ -78,8 +78,8 @@ def handle_schedule_error(context, ex, instance_uuid, request_spec):
method='run_instance',
reason=ex)
notifier.notify(context, notifier.publisher_id("scheduler"),
'scheduler.run_instance', notifier.ERROR, payload)
notifier.get_notifier('scheduler').error(context,
'scheduler.run_instance', payload)
def instance_update_db(context, instance_uuid, extra_values=None):

View File

@ -27,9 +27,9 @@ from nova.compute import flavors
from nova.compute import rpcapi as compute_rpcapi
from nova import db
from nova import exception
from nova import notifier
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.pci import pci_request
from nova.scheduler import driver
from nova.scheduler import scheduler_options
@ -61,6 +61,7 @@ class FilterScheduler(driver.Scheduler):
super(FilterScheduler, self).__init__(*args, **kwargs)
self.options = scheduler_options.SchedulerOptions()
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
self.notifier = notifier.get_notifier('scheduler')
def schedule_run_instance(self, context, request_spec,
admin_password, injected_files,
@ -73,8 +74,7 @@ class FilterScheduler(driver.Scheduler):
Returns a list of the instances created.
"""
payload = dict(request_spec=request_spec)
notifier.notify(context, notifier.publisher_id("scheduler"),
'scheduler.run_instance.start', notifier.INFO, payload)
self.notifier.info(context, 'scheduler.run_instance.start', payload)
instance_uuids = request_spec.get('instance_uuids')
LOG.info(_("Attempting to build %(num_instances)d instance(s) "
@ -127,8 +127,7 @@ class FilterScheduler(driver.Scheduler):
retry = filter_properties.get('retry', {})
retry['hosts'] = []
notifier.notify(context, notifier.publisher_id("scheduler"),
'scheduler.run_instance.end', notifier.INFO, payload)
self.notifier.info(context, 'scheduler.run_instance.end', payload)
def select_hosts(self, context, request_spec, filter_properties):
"""Selects a filtered set of hosts."""
@ -164,9 +163,8 @@ class FilterScheduler(driver.Scheduler):
payload = dict(request_spec=request_spec,
weighted_host=weighed_host.to_dict(),
instance_id=instance_uuid)
notifier.notify(context, notifier.publisher_id("scheduler"),
'scheduler.run_instance.scheduled', notifier.INFO,
payload)
self.notifier.info(context,
'scheduler.run_instance.scheduled', payload)
# Update the metadata if necessary
scheduler_hints = filter_properties.get('scheduler_hints') or {}

View File

@ -20,10 +20,10 @@ from nova.compute import flavors
from nova.compute import utils as compute_utils
from nova import db
from nova import notifications
from nova import notifier as notify
from nova.openstack.common.gettextutils import _
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
LOG = logging.getLogger(__name__)
@ -69,6 +69,8 @@ def set_vm_state_and_notify(context, service, method, updates, ex,
# verify that uuid is always set.
uuids = [properties.get('uuid')]
from nova.conductor import api as conductor_api
conductor = conductor_api.LocalAPI()
notifier = notify.get_notifier(service)
for instance_uuid in request_spec.get('instance_uuids') or uuids:
if instance_uuid:
state = vm_state.upper()
@ -81,7 +83,7 @@ def set_vm_state_and_notify(context, service, method, updates, ex,
notifications.send_update(context, old_ref, new_ref,
service=service)
compute_utils.add_instance_fault_from_exc(context,
conductor_api.LocalAPI(),
conductor,
new_ref, ex, sys.exc_info())
payload = dict(request_spec=request_spec,
@ -92,8 +94,7 @@ def set_vm_state_and_notify(context, service, method, updates, ex,
reason=ex)
event_type = '%s.%s' % (service, method)
notifier.notify(context, notifier.publisher_id(service),
event_type, notifier.ERROR, payload)
notifier.error(context, event_type, payload)
def populate_filter_properties(filter_properties, host_state):

View File

@ -4,6 +4,7 @@
# Administrator of the National Aeronautics and Space Administration.
# Copyright 2011 Piston Cloud Computing, Inc.
# All Rights Reserved.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -60,8 +61,6 @@ from nova.openstack.common.gettextutils import _
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common.notifier import test_notifier
from nova.openstack.common import rpc
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
@ -75,6 +74,7 @@ from nova.tests import fake_instance
from nova.tests import fake_instance_actions
from nova.tests import fake_network
from nova.tests import fake_network_cache_model
from nova.tests import fake_notifier
from nova.tests.image import fake as fake_image
from nova.tests import matchers
from nova.tests.objects import test_migration
@ -147,13 +147,14 @@ class BaseTestCase(test.TestCase):
def setUp(self):
super(BaseTestCase, self).setUp()
notifier_api._reset_drivers()
self.addCleanup(notifier_api._reset_drivers)
self.flags(compute_driver='nova.virt.fake.FakeDriver',
notification_driver=[test_notifier.__name__],
network_manager='nova.network.manager.FlatManager')
fake.set_nodes([NODENAME])
self.flags(use_local=True, group='conductor')
fake_notifier.stub_notifier(self.stubs)
self.addCleanup(fake_notifier.reset)
self.compute = importutils.import_object(CONF.compute_manager)
# override tracker with a version that doesn't need the database:
@ -201,7 +202,6 @@ class BaseTestCase(test.TestCase):
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id,
self.project_id)
test_notifier.NOTIFICATIONS = []
def fake_show(meh, context, id):
if id:
@ -581,19 +581,18 @@ class ComputeVolumeTestCase(BaseTestCase):
CONF.volume_usage_poll_interval = 10
self.compute._poll_volume_usage(self.context)
# Check that a volume.usage and volume.attach notification was sent
self.assertEqual(2, len(test_notifier.NOTIFICATIONS))
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(2, len(fake_notifier.NOTIFICATIONS))
self.compute.detach_volume(self.context, 1, instance)
# Check that volume.attach, 2 volume.usage, and volume.detach
# notifications were sent
self.assertEquals(4, len(test_notifier.NOTIFICATIONS))
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals('compute.instance.volume.attach', msg['event_type'])
msg = test_notifier.NOTIFICATIONS[2]
self.assertEquals('volume.usage', msg['event_type'])
payload = msg['payload']
self.assertEquals(4, len(fake_notifier.NOTIFICATIONS))
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals('compute.instance.volume.attach', msg.event_type)
msg = fake_notifier.NOTIFICATIONS[2]
self.assertEquals('volume.usage', msg.event_type)
payload = msg.payload
self.assertEquals(instance['uuid'], payload['instance_id'])
self.assertEquals('fake', payload['user_id'])
self.assertEquals('fake', payload['tenant_id'])
@ -602,8 +601,8 @@ class ComputeVolumeTestCase(BaseTestCase):
self.assertEquals(1, payload['writes'])
self.assertEquals(20, payload['write_bytes'])
self.assertEquals(None, payload['availability_zone'])
msg = test_notifier.NOTIFICATIONS[3]
self.assertEquals('compute.instance.volume.detach', msg['event_type'])
msg = fake_notifier.NOTIFICATIONS[3]
self.assertEquals('compute.instance.volume.detach', msg.event_type)
# Check the database for the
volume_usages = db.vol_get_usage_by_time(self.context, 0)
@ -2601,11 +2600,11 @@ class ComputeTestCase(BaseTestCase):
instance = jsonutils.to_primitive(self._create_fake_instance())
self.assertEquals(len(test_notifier.NOTIFICATIONS), 0)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 0)
self.compute.add_fixed_ip_to_instance(self.context, network_id=1,
instance=instance)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 2)
self.compute.terminate_instance(self.context, instance=instance)
def test_remove_fixed_ip_usage_notification(self):
@ -2621,11 +2620,11 @@ class ComputeTestCase(BaseTestCase):
instance = jsonutils.to_primitive(self._create_fake_instance())
self.assertEquals(len(test_notifier.NOTIFICATIONS), 0)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 0)
self.compute.remove_fixed_ip_from_instance(self.context, 1,
instance=instance)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 2)
self.compute.terminate_instance(self.context, instance=instance)
def test_run_instance_usage_notification(self):
@ -2633,16 +2632,16 @@ class ComputeTestCase(BaseTestCase):
instance = jsonutils.to_primitive(self._create_fake_instance())
instance_uuid = instance['uuid']
self.compute.run_instance(self.context, instance=instance)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 2)
inst_ref = db.instance_get_by_uuid(self.context, instance_uuid)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'], 'compute.instance.create.start')
self.assertEquals(msg['payload']['image_name'], 'fake_name')
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type, 'compute.instance.create.start')
self.assertEquals(msg.payload['image_name'], 'fake_name')
# The last event is the one with the sugar in it.
msg = test_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.create.end')
payload = msg['payload']
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'compute.instance.create.end')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['image_name'], 'fake_name')
self.assertEquals(payload['user_id'], self.user_id)
@ -2674,14 +2673,14 @@ class ComputeTestCase(BaseTestCase):
self.stubs.Set(self.compute, '_build_instance', build_inst_abort)
self.compute.run_instance(self.context, instance=instance)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'], 'compute.instance.create.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type, 'compute.instance.create.start')
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['event_type'], 'compute.instance.create.end')
self.assertEquals('INFO', msg['priority'])
payload = msg['payload']
self.assertEquals(msg.event_type, 'compute.instance.create.end')
self.assertEquals('INFO', msg.priority)
payload = msg.payload
message = payload['message']
self.assertTrue(message.find("already deleted") != -1)
@ -2698,14 +2697,14 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=instance)
self.assertTrue(len(test_notifier.NOTIFICATIONS) >= 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'], 'compute.instance.create.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertTrue(len(fake_notifier.NOTIFICATIONS) >= 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type, 'compute.instance.create.start')
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['event_type'], 'compute.instance.create.error')
self.assertEquals('ERROR', msg['priority'])
payload = msg['payload']
self.assertEquals(msg.event_type, 'compute.instance.create.error')
self.assertEquals('ERROR', msg.priority)
payload = msg.payload
message = payload['message']
self.assertTrue(message.find("something bad happened") != -1)
@ -2722,14 +2721,14 @@ class ComputeTestCase(BaseTestCase):
self.assertRaises(test.TestingException, self.compute.run_instance,
self.context, instance=instance)
self.assertTrue(len(test_notifier.NOTIFICATIONS) >= 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'], 'compute.instance.create.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertTrue(len(fake_notifier.NOTIFICATIONS) >= 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type, 'compute.instance.create.start')
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['event_type'], 'compute.instance.create.error')
self.assertEquals('ERROR', msg['priority'])
payload = msg['payload']
self.assertEquals(msg.event_type, 'compute.instance.create.error')
self.assertEquals('ERROR', msg.priority)
payload = msg.payload
message = payload['message']
self.assertTrue(message.find("i'm dying") != -1)
@ -2741,23 +2740,22 @@ class ComputeTestCase(BaseTestCase):
instance = jsonutils.to_primitive(self._create_fake_instance())
self.compute.run_instance(self.context, instance=instance)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
timeutils.set_time_override(cur_time)
self.compute.terminate_instance(self.context, instance=instance)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 4)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 4)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.delete.start')
msg1 = test_notifier.NOTIFICATIONS[1]
self.assertEquals(msg1['event_type'],
'compute.instance.shutdown.start')
msg1 = test_notifier.NOTIFICATIONS[2]
self.assertEquals(msg1['event_type'], 'compute.instance.shutdown.end')
msg1 = test_notifier.NOTIFICATIONS[3]
self.assertEquals(msg1['event_type'], 'compute.instance.delete.end')
payload = msg1['payload']
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'compute.instance.delete.start')
msg1 = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg1.event_type, 'compute.instance.shutdown.start')
msg1 = fake_notifier.NOTIFICATIONS[2]
self.assertEquals(msg1.event_type, 'compute.instance.shutdown.end')
msg1 = fake_notifier.NOTIFICATIONS[3]
self.assertEquals(msg1.event_type, 'compute.instance.delete.end')
payload = msg1.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance['uuid'])
@ -3502,7 +3500,7 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=inst_ref)
timeutils.set_time_override(cur_time)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
instance = db.instance_get_by_uuid(self.context, inst_ref['uuid'])
orig_sys_metadata = db.instance_system_metadata_get(self.context,
inst_ref['uuid'])
@ -3530,21 +3528,21 @@ class ComputeTestCase(BaseTestCase):
image_ref_url = glance.generate_image_url(image_ref)
new_image_ref_url = glance.generate_image_url(new_image_ref)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 3)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'],
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 3)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type,
'compute.instance.exists')
self.assertEquals(msg['payload']['image_ref_url'], image_ref_url)
msg = test_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['event_type'],
self.assertEquals(msg.payload['image_ref_url'], image_ref_url)
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg.event_type,
'compute.instance.rebuild.start')
self.assertEquals(msg['payload']['image_ref_url'], new_image_ref_url)
self.assertEquals(msg['payload']['image_name'], 'fake_name')
msg = test_notifier.NOTIFICATIONS[2]
self.assertEquals(msg['event_type'],
self.assertEquals(msg.payload['image_ref_url'], new_image_ref_url)
self.assertEquals(msg.payload['image_name'], 'fake_name')
msg = fake_notifier.NOTIFICATIONS[2]
self.assertEquals(msg.event_type,
'compute.instance.rebuild.end')
self.assertEquals(msg['priority'], 'INFO')
payload = msg['payload']
self.assertEquals(msg.priority, 'INFO')
payload = msg.payload
self.assertEquals(payload['image_name'], 'fake_name')
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
@ -3587,7 +3585,7 @@ class ComputeTestCase(BaseTestCase):
self.compute.resize_instance(self.context, instance=instance,
migration=migration, image={}, instance_type=new_type)
timeutils.set_time_override(cur_time)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
instance_p = obj_base.obj_to_primitive(instance)
migration_p = obj_base.obj_to_primitive(migration)
@ -3595,15 +3593,15 @@ class ComputeTestCase(BaseTestCase):
migration=migration_p,
disk_info={}, image={}, instance=instance_p)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'],
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type,
'compute.instance.finish_resize.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg.event_type,
'compute.instance.finish_resize.end')
self.assertEquals(msg['priority'], 'INFO')
payload = msg['payload']
self.assertEquals(msg.priority, 'INFO')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance.uuid)
@ -3627,7 +3625,7 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=instance)
timeutils.set_time_override(cur_time)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
instance.host = 'foo'
instance.task_state = task_states.RESIZE_PREP
@ -3640,18 +3638,18 @@ class ComputeTestCase(BaseTestCase):
instance.uuid,
'pre-migrating')
self.assertEquals(len(test_notifier.NOTIFICATIONS), 3)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['event_type'],
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 3)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.event_type,
'compute.instance.exists')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEquals(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEquals(msg.event_type,
'compute.instance.resize.prep.start')
msg = test_notifier.NOTIFICATIONS[2]
self.assertEquals(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[2]
self.assertEquals(msg.event_type,
'compute.instance.resize.prep.end')
self.assertEquals(msg['priority'], 'INFO')
payload = msg['payload']
self.assertEquals(msg.priority, 'INFO')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance.uuid)
@ -4186,7 +4184,7 @@ class ComputeTestCase(BaseTestCase):
self.compute.network_api.setup_networks_on_host(c, instance,
self.compute.host)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
# start test
self.mox.ReplayAll()
migrate_data = {'is_shared_storage': False}
@ -4194,12 +4192,12 @@ class ComputeTestCase(BaseTestCase):
block_migration=False,
migrate_data=migrate_data)
self.assertEqual(ret, None)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'compute.instance.live_migration.pre.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'compute.instance.live_migration.pre.end')
# cleanup
@ -4218,7 +4216,6 @@ class ComputeTestCase(BaseTestCase):
fake_bdms = [dict(volume_id='vol1-id'), dict(volume_id='vol2-id')]
# creating mocks
self.mox.StubOutWithMock(rpc, 'call')
self.mox.StubOutWithMock(self.compute.driver,
'get_instance_disk_info')
self.mox.StubOutWithMock(self.compute.compute_rpcapi,
@ -4430,18 +4427,18 @@ class ComputeTestCase(BaseTestCase):
self.compute.network_api.setup_networks_on_host(self.admin_ctxt,
mox.IgnoreArg(), self.compute.host)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
self.mox.ReplayAll()
self.compute.post_live_migration_at_destination(self.admin_ctxt,
self.instance)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'compute.instance.live_migration.post.dest.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'compute.instance.live_migration.post.dest.end')
return self.compute.conductor_api.instance_get_by_uuid(self.admin_ctxt,
@ -4477,7 +4474,7 @@ class ComputeTestCase(BaseTestCase):
inst_id = instance_ref['id']
instance = jsonutils.to_primitive(db.instance_get(c, inst_id))
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
self.mox.StubOutWithMock(self.compute.network_api,
'setup_networks_on_host')
@ -4490,12 +4487,12 @@ class ComputeTestCase(BaseTestCase):
ret = self.compute.rollback_live_migration_at_destination(c,
instance=instance)
self.assertEqual(ret, None)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'compute.instance.live_migration.rollback.dest.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'compute.instance.live_migration.rollback.dest.end')
# cleanup
@ -6547,9 +6544,9 @@ class ComputeAPITestCase(BaseTestCase):
self.assertEqual(metadata, {'key1': 'value1', 'key2': 'value2'})
self.assertEqual(meta_changes, [{'key2': ['+', 'value2']}])
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
msg = test_notifier.NOTIFICATIONS[0]
payload = msg['payload']
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 1)
msg = fake_notifier.NOTIFICATIONS[0]
payload = msg.payload
self.assertTrue('metadata' in payload)
self.assertEquals(payload['metadata'], metadata)
@ -6564,9 +6561,9 @@ class ComputeAPITestCase(BaseTestCase):
'key3': ['+', 'value3'],
}])
self.assertEquals(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[1]
payload = msg['payload']
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[1]
payload = msg.payload
self.assertTrue('metadata' in payload)
self.assertEquals(payload['metadata'], metadata)
@ -6575,9 +6572,9 @@ class ComputeAPITestCase(BaseTestCase):
self.assertEqual(metadata, {'key3': 'value3'})
self.assertEqual(meta_changes, [{'key2': ['-']}])
self.assertEquals(len(test_notifier.NOTIFICATIONS), 3)
msg = test_notifier.NOTIFICATIONS[2]
payload = msg['payload']
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 3)
msg = fake_notifier.NOTIFICATIONS[2]
payload = msg.payload
self.assertTrue('metadata' in payload)
self.assertEquals(payload['metadata'], {})
@ -7859,16 +7856,16 @@ class ComputeAPIAggrTestCase(BaseTestCase):
# Ensure metadata can be updated.
aggr = self.api.create_aggregate(self.context, 'fake_aggregate',
'fake_zone')
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
aggr = self.api.update_aggregate(self.context, aggr['id'],
{'name': 'new_fake_aggregate'})
self.assertEqual(availability_zones._get_cache().get('cache'), None)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'aggregate.updateprop.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'aggregate.updateprop.end')
def test_update_aggregate_metadata(self):
@ -7877,15 +7874,15 @@ class ComputeAPIAggrTestCase(BaseTestCase):
'fake_zone')
metadata = {'foo_key1': 'foo_value1',
'foo_key2': 'foo_value2', }
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
aggr = self.api.update_aggregate_metadata(self.context, aggr['id'],
metadata)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'aggregate.updatemetadata.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'aggregate.updatemetadata.end')
metadata['foo_key1'] = None
expected = self.api.update_aggregate_metadata(self.context,
@ -7896,24 +7893,24 @@ class ComputeAPIAggrTestCase(BaseTestCase):
def test_delete_aggregate(self):
# Ensure we can delete an aggregate.
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
aggr = self.api.create_aggregate(self.context, 'fake_aggregate',
'fake_zone')
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'aggregate.create.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'aggregate.create.end')
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
self.api.delete_aggregate(self.context, aggr['id'])
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'aggregate.delete.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'aggregate.delete.end')
db.aggregate_get(self.context.elevated(read_deleted='yes'),
aggr['id'])
@ -7945,15 +7942,15 @@ class ComputeAPIAggrTestCase(BaseTestCase):
self.stubs.Set(self.api.compute_rpcapi, 'add_aggregate_host',
fake_add_aggregate_host)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
aggr = self.api.add_host_to_aggregate(self.context,
aggr['id'], fake_host)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'aggregate.addhost.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'aggregate.addhost.end')
self.assertEqual(len(aggr['hosts']), 1)
@ -8047,16 +8044,16 @@ class ComputeAPIAggrTestCase(BaseTestCase):
self.stubs.Set(self.api.compute_rpcapi, 'remove_aggregate_host',
fake_remove_aggregate_host)
test_notifier.NOTIFICATIONS = []
fake_notifier.NOTIFICATIONS = []
expected = self.api.remove_host_from_aggregate(self.context,
aggr['id'],
host_to_remove)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual(msg.event_type,
'aggregate.removehost.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
msg = fake_notifier.NOTIFICATIONS[1]
self.assertEqual(msg.event_type,
'aggregate.removehost.end')
self.assertEqual(len(aggr['hosts']) - 1, len(expected['hosts']))

View File

@ -422,7 +422,8 @@ class _ComputeAPIUnitTestMixIn(object):
if inst.host == 'down-host':
inst.info_cache.delete()
compute_utils.notify_about_instance_usage(self.context,
compute_utils.notify_about_instance_usage(mox.IgnoreArg(),
self.context,
inst,
'%s.start' % delete_type)
if not self.is_cells:
@ -445,6 +446,7 @@ class _ComputeAPIUnitTestMixIn(object):
reservations=None)
db.instance_destroy(self.context, inst.uuid, constraint=None)
compute_utils.notify_about_instance_usage(
mox.IgnoreArg(),
self.context, inst, '%s.end' % delete_type,
system_metadata='sys-meta')

View File

@ -2,6 +2,7 @@
# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -28,13 +29,13 @@ from nova import db
from nova import exception
from nova.image import glance
from nova.network import api as network_api
from nova import notifier as notify
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common.notifier import test_notifier
from nova import test
from nova.tests import fake_instance_actions
from nova.tests import fake_network
from nova.tests import fake_notifier
import nova.tests.image.fake
CONF = cfg.CONF
@ -236,17 +237,16 @@ class UsageInfoTestCase(test.TestCase):
self.stubs.Set(network_api.API, 'get_instance_nw_info',
fake_get_nw_info)
notifier_api._reset_drivers()
self.addCleanup(notifier_api._reset_drivers)
fake_notifier.stub_notifier(self.stubs)
self.addCleanup(fake_notifier.reset)
self.flags(use_local=True, group='conductor')
self.flags(compute_driver='nova.virt.fake.FakeDriver',
notification_driver=[test_notifier.__name__],
network_manager='nova.network.manager.FlatManager')
self.compute = importutils.import_object(CONF.compute_manager)
self.user_id = 'fake'
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id, self.project_id)
test_notifier.NOTIFICATIONS = []
def fake_show(meh, context, id):
return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1}}
@ -284,12 +284,13 @@ class UsageInfoTestCase(test.TestCase):
db.instance_system_metadata_update(self.context, instance['uuid'],
sys_metadata, False)
instance = db.instance_get(self.context, instance_id)
compute_utils.notify_usage_exists(self.context, instance)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.exists')
payload = msg['payload']
compute_utils.notify_usage_exists(
notify.get_notifier('compute'), self.context, instance)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 1)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'compute.instance.exists')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance['uuid'])
@ -323,11 +324,12 @@ class UsageInfoTestCase(test.TestCase):
jsonutils.to_primitive(instance))
instance = db.instance_get(self.context.elevated(read_deleted='yes'),
instance_id)
compute_utils.notify_usage_exists(self.context, instance)
msg = test_notifier.NOTIFICATIONS[-1]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.exists')
payload = msg['payload']
compute_utils.notify_usage_exists(
notify.get_notifier('compute'), self.context, instance)
msg = fake_notifier.NOTIFICATIONS[-1]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'compute.instance.exists')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance['uuid'])
@ -351,11 +353,12 @@ class UsageInfoTestCase(test.TestCase):
instance = db.instance_get(self.context, instance_id)
self.compute.terminate_instance(self.context,
jsonutils.to_primitive(instance))
compute_utils.notify_usage_exists(self.context, instance)
msg = test_notifier.NOTIFICATIONS[-1]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.exists')
payload = msg['payload']
compute_utils.notify_usage_exists(
notify.get_notifier('compute'), self.context, instance)
msg = fake_notifier.NOTIFICATIONS[-1]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'compute.instance.exists')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance['uuid'])
@ -385,13 +388,15 @@ class UsageInfoTestCase(test.TestCase):
# NOTE(russellb) Make sure our instance has the latest system_metadata
# in it.
instance = db.instance_get(self.context, instance_id)
compute_utils.notify_about_instance_usage(self.context, instance,
'create.start', extra_usage_info=extra_usage_info)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.create.start')
payload = msg['payload']
compute_utils.notify_about_instance_usage(
notify.get_notifier('compute'),
self.context, instance, 'create.start',
extra_usage_info=extra_usage_info)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 1)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'compute.instance.create.start')
payload = msg.payload
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance['uuid'])
@ -416,11 +421,11 @@ class UsageInfoTestCase(test.TestCase):
compute_utils.notify_about_aggregate_update(self.context,
"create.end",
aggregate_payload)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'aggregate.create.end')
payload = msg['payload']
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 1)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'aggregate.create.end')
payload = msg.payload
self.assertEquals(payload['aggregate_id'], 1)
def test_notify_about_aggregate_update_with_name(self):
@ -429,11 +434,11 @@ class UsageInfoTestCase(test.TestCase):
compute_utils.notify_about_aggregate_update(self.context,
"create.start",
aggregate_payload)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'aggregate.create.start')
payload = msg['payload']
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 1)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(msg.priority, 'INFO')
self.assertEquals(msg.event_type, 'aggregate.create.start')
payload = msg.payload
self.assertEquals(payload['name'], 'fakegroup')
def test_notify_about_aggregate_update_without_name_id(self):
@ -442,4 +447,4 @@ class UsageInfoTestCase(test.TestCase):
compute_utils.notify_about_aggregate_update(self.context,
"create.start",
aggregate_payload)
self.assertEquals(len(test_notifier.NOTIFICATIONS), 0)
self.assertEquals(len(fake_notifier.NOTIFICATIONS), 0)

View File

@ -1,4 +1,5 @@
# Copyright 2012 IBM Corp.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -34,8 +35,6 @@ from nova import notifications
from nova.objects import instance as instance_obj
from nova.objects import migration as migration_obj
from nova.openstack.common import jsonutils
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common.notifier import test_notifier
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
from nova import quota
@ -44,6 +43,7 @@ from nova import test
from nova.tests.compute import test_compute
from nova.tests import fake_instance
from nova.tests import fake_instance_actions
from nova.tests import fake_notifier
from nova.tests.objects import test_migration
from nova import utils
@ -67,10 +67,8 @@ class _BaseTestCase(object):
self.project_id = 'fake'
self.context = FakeContext(self.user_id, self.project_id)
notifier_api._reset_drivers()
self.addCleanup(notifier_api._reset_drivers)
self.flags(notification_driver=[test_notifier.__name__])
test_notifier.NOTIFICATIONS = []
fake_notifier.stub_notifier(self.stubs)
self.addCleanup(fake_notifier.reset)
def _create_fake_instance(self, params=None, type_name='m1.tiny'):
if not params:
@ -352,7 +350,6 @@ class _BaseTestCase(object):
def test_vol_usage_update(self):
self.mox.StubOutWithMock(db, 'vol_usage_update')
self.mox.StubOutWithMock(test_notifier, 'notify')
self.mox.StubOutWithMock(compute_utils, 'usage_volume_info')
fake_inst = {'uuid': 'fake-uuid',
@ -368,10 +365,6 @@ class _BaseTestCase(object):
fake_inst['availability_zone'],
False).AndReturn('fake-usage')
compute_utils.usage_volume_info('fake-usage').AndReturn('fake-info')
notifier_api.notify(self.context,
'conductor.%s' % self.conductor_manager.host,
'volume.usage', notifier_api.INFO,
'fake-info')
self.mox.ReplayAll()
@ -379,6 +372,14 @@ class _BaseTestCase(object):
22, 33, 44, 55, fake_inst,
'fake-update-time', False)
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
msg = fake_notifier.NOTIFICATIONS[0]
self.assertEqual('conductor.%s' % self.conductor_manager.host,
msg.publisher_id)
self.assertEqual('volume.usage', msg.event_type)
self.assertEqual('INFO', msg.priority)
self.assertEqual('fake-info', msg.payload)
def test_compute_node_create(self):
self.mox.StubOutWithMock(db, 'compute_node_create')
db.compute_node_create(self.context, 'fake-values').AndReturn(
@ -471,7 +472,9 @@ class _BaseTestCase(object):
notifications.audit_period_bounds(False).AndReturn(('start', 'end'))
notifications.bandwidth_usage(instance, 'start', True).AndReturn(
'bw_usage')
compute_utils.notify_about_instance_usage(self.context, instance,
notifier = self.conductor_manager.notifier
compute_utils.notify_about_instance_usage(notifier,
self.context, instance,
'exists',
system_metadata={},
extra_usage_info=info)

View File

@ -0,0 +1,53 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Red Hat, Inc.
#
# 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 collections
import functools
from nova import notifier
NOTIFICATIONS = []
def reset():
del NOTIFICATIONS[:]
FakeMessage = collections.namedtuple('Message',
['publisher_id', 'priority',
'event_type', 'payload'])
class FakeNotifier(object):
def __init__(self, publisher_id):
self.publisher_id = publisher_id
for priority in ['debug', 'info', 'warn', 'error', 'critical']:
setattr(self, priority,
functools.partial(self._notify, priority.upper()))
def prepare(self, publisher_id=None):
if publisher_id is None:
publisher_id = self.publisher_id
return self.__class__(publisher_id)
def _notify(self, priority, ctxt, event_type, payload):
msg = FakeMessage(self.publisher_id, priority, event_type, payload)
NOTIFICATIONS.append(msg)
def stub_notifier(stubs):
stubs.Set(notifier, 'Notifier', FakeNotifier)

View File

@ -20,6 +20,7 @@ Tests For Scheduler
"""
import mox
from oslo.config import cfg
from nova.compute import api as compute_api
from nova.compute import task_states
@ -31,8 +32,8 @@ from nova import context
from nova import db
from nova import exception
from nova.image import glance
from nova import notifier as notify
from nova.objects import instance as instance_obj
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common.rpc import common as rpc_common
from nova.scheduler import driver
from nova.scheduler import manager
@ -45,6 +46,8 @@ from nova.tests import matchers
from nova.tests.scheduler import fakes
from nova import utils
CONF = cfg.CONF
class SchedulerManagerTestCase(test.NoDBTestCase):
"""Test case for scheduler manager."""
@ -433,13 +436,15 @@ class SchedulerManagerTestCase(test.NoDBTestCase):
self.mox.StubOutWithMock(db, 'instance_update_and_get_original')
self.mox.StubOutWithMock(db, 'instance_fault_create')
self.mox.StubOutWithMock(notifier, 'notify')
self.mox.StubOutWithMock(notify, 'get_notifier')
notifier = self.mox.CreateMockAnything()
notify.get_notifier('conductor', CONF.host).AndReturn(notifier)
notify.get_notifier('scheduler').AndReturn(notifier)
db.instance_update_and_get_original(self.context, 'fake-uuid',
updates).AndReturn((None,
fake_inst))
db.instance_fault_create(self.context, mox.IgnoreArg())
notifier.notify(self.context, mox.IgnoreArg(), 'scheduler.foo',
notifier.ERROR, mox.IgnoreArg())
notifier.error(self.context, 'scheduler.foo', mox.IgnoreArg())
self.mox.ReplayAll()
self.manager._set_vm_state_and_notify('foo', {'vm_state': 'foo'},
@ -557,14 +562,15 @@ class SchedulerTestCase(test.NoDBTestCase):
instance = {'uuid': 'fake-uuid'}
self.mox.StubOutWithMock(db, 'instance_update_and_get_original')
self.mox.StubOutWithMock(db, 'instance_fault_create')
self.mox.StubOutWithMock(notifier, 'notify')
db.instance_update_and_get_original(self.context, instance['uuid'],
mox.IgnoreArg()).AndReturn(
(None, instance))
db.instance_fault_create(self.context, mox.IgnoreArg())
notifier.notify(self.context, mox.IgnoreArg(),
'scheduler.run_instance',
notifier.ERROR, mox.IgnoreArg())
self.mox.StubOutWithMock(notify, 'get_notifier')
notifier = self.mox.CreateMockAnything()
notify.get_notifier('conductor', CONF.host).AndReturn(notifier)
notify.get_notifier('scheduler').AndReturn(notifier)
notifier.error(self.context, 'scheduler.run_instance', mox.IgnoreArg())
self.mox.ReplayAll()
driver.handle_schedule_error(self.context,

View File

@ -16,15 +16,18 @@
Tests For Scheduler Utils
"""
import mox
from oslo.config import cfg
from nova.compute import utils as compute_utils
from nova.conductor import api as conductor_api
from nova import db
from nova import notifications
from nova.openstack.common.notifier import api as notifier
from nova import notifier as notify
from nova.scheduler import utils as scheduler_utils
from nova import test
CONF = cfg.CONF
class SchedulerUtilsTestCase(test.NoDBTestCase):
"""Test case for scheduler utils methods."""
@ -38,13 +41,16 @@ class SchedulerUtilsTestCase(test.NoDBTestCase):
service = 'fake-service'
method = 'fake-method'
exc_info = 'exc_info'
publisher_id = 'fake-publisher-id'
self.mox.StubOutWithMock(compute_utils,
'add_instance_fault_from_exc')
self.mox.StubOutWithMock(notifications, 'send_update')
self.mox.StubOutWithMock(db, 'instance_update_and_get_original')
self.mox.StubOutWithMock(notifier, 'publisher_id')
self.mox.StubOutWithMock(notify, 'get_notifier')
notifier = self.mox.CreateMockAnything()
notify.get_notifier('conductor', CONF.host).AndReturn(notifier)
notify.get_notifier(service).AndReturn(notifier)
old_ref = 'old_ref'
new_ref = 'new_ref'
@ -61,15 +67,13 @@ class SchedulerUtilsTestCase(test.NoDBTestCase):
payload = dict(request_spec=request_spec,
instance_properties=request_spec.get(
'instance_properties'),
'instance_properties', {}),
instance_id=uuid,
state='fake-vm-state',
method=method,
reason=exc_info)
event_type = '%s.%s' % (service, method)
notifier.publisher_id(service).AndReturn(publisher_id)
notifier.notify(self.context, publisher_id,
event_type, notifier.ERROR, payload)
notifier.error(self.context, event_type, payload)
self.mox.ReplayAll()

View File

@ -22,21 +22,17 @@ from nova import test
class FakeNotifier(object):
"""Acts like the nova.notifier.api module."""
ERROR = 88
"""Acts like messaging.Notifier."""
def __init__(self):
self.provided_publisher = None
self.provided_context = None
self.provided_event = None
self.provided_priority = None
self.provided_payload = None
def notify(self, context, publisher, event, priority, payload):
self.provided_publisher = publisher
self.provided_event = event
self.provided_priority = priority
self.provided_payload = payload
def error(self, context, event, payload):
self.provided_context = context
self.provided_event = event
self.provided_payload = payload
def good_function(self, context):
@ -49,18 +45,16 @@ def bad_function_exception(self, context, extra, blah="a", boo="b", zoo=None):
class WrapExceptionTestCase(test.TestCase):
def test_wrap_exception_good_return(self):
wrapped = exception.wrap_exception('foo', 'bar')
wrapped = exception.wrap_exception('foo')
self.assertEquals(99, wrapped(good_function)(1, 2))
def test_wrap_exception_with_notifier(self):
notifier = FakeNotifier()
wrapped = exception.wrap_exception(notifier, "publisher")
wrapped = exception.wrap_exception(notifier)
ctxt = context.get_admin_context()
self.assertRaises(test.TestingException,
wrapped(bad_function_exception), 1, ctxt, 3, zoo=3)
self.assertEquals(notifier.provided_publisher, "publisher")
self.assertEquals(notifier.provided_event, "bad_function_exception")
self.assertEquals(notifier.provided_priority, notifier.ERROR)
self.assertEquals(notifier.provided_context, ctxt)
for key in ['exception', 'args']:
self.assertTrue(key in notifier.provided_payload.keys())

View File

@ -28,10 +28,9 @@ from nova import context
from nova import db
from nova.network import api as network_api
from nova import notifications
from nova.openstack.common.notifier import api as notifier_api
from nova.openstack.common.notifier import test_notifier
from nova import test
from nova.tests import fake_network
from nova.tests import fake_notifier
CONF = cfg.CONF
CONF.import_opt('compute_driver', 'nova.virt.driver')
@ -53,10 +52,10 @@ class NotificationsTestCase(test.TestCase):
fake_get_nw_info)
fake_network.set_stub_network_methods(self.stubs)
notifier_api._reset_drivers()
self.addCleanup(notifier_api._reset_drivers)
fake_notifier.stub_notifier(self.stubs)
self.addCleanup(fake_notifier.reset)
self.flags(compute_driver='nova.virt.fake.FakeDriver',
notification_driver=[test_notifier.__name__],
network_manager='nova.network.manager.FlatManager',
notify_on_state_change="vm_and_task_state",
host='testhost')
@ -64,7 +63,6 @@ class NotificationsTestCase(test.TestCase):
self.user_id = 'fake'
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id, self.project_id)
test_notifier.NOTIFICATIONS = []
self.instance = self._wrapped_create()
@ -91,7 +89,7 @@ class NotificationsTestCase(test.TestCase):
def test_send_api_fault_disabled(self):
self.flags(notify_api_faults=False)
notifications.send_api_fault("http://example.com/foo", 500, None)
self.assertEquals(0, len(test_notifier.NOTIFICATIONS))
self.assertEquals(0, len(fake_notifier.NOTIFICATIONS))
def test_send_api_fault(self):
self.flags(notify_api_faults=True)
@ -104,13 +102,13 @@ class NotificationsTestCase(test.TestCase):
notifications.send_api_fault("http://example.com/foo", 500, exception)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
n = test_notifier.NOTIFICATIONS[0]
self.assertEquals(n['priority'], 'ERROR')
self.assertEquals(n['event_type'], 'api.fault')
self.assertEquals(n['payload']['url'], 'http://example.com/foo')
self.assertEquals(n['payload']['status'], 500)
self.assertTrue(n['payload']['exception'] is not None)
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
n = fake_notifier.NOTIFICATIONS[0]
self.assertEquals(n.priority, 'ERROR')
self.assertEquals(n.event_type, 'api.fault')
self.assertEquals(n.payload['url'], 'http://example.com/foo')
self.assertEquals(n.payload['status'], 500)
self.assertTrue(n.payload['exception'] is not None)
def test_notif_disabled(self):
@ -130,7 +128,7 @@ class NotificationsTestCase(test.TestCase):
verify_states=True)
notifications.send_update(self.context, old, self.instance)
self.assertEquals(0, len(test_notifier.NOTIFICATIONS))
self.assertEquals(0, len(fake_notifier.NOTIFICATIONS))
def test_task_notif(self):
@ -150,13 +148,13 @@ class NotificationsTestCase(test.TestCase):
old_vm_state, new_vm_state, old_task_state, new_task_state,
verify_states=True)
self.assertEquals(0, len(test_notifier.NOTIFICATIONS))
self.assertEquals(0, len(fake_notifier.NOTIFICATIONS))
# ok now enable task state notifcations and re-try
self.flags(notify_on_state_change="vm_and_task_state")
notifications.send_update(self.context, old, self.instance)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
def test_send_no_notif(self):
@ -170,7 +168,7 @@ class NotificationsTestCase(test.TestCase):
old_vm_state, new_vm_state, old_task_state, new_task_state,
service="compute", host=None, verify_states=True)
self.assertEquals(0, len(test_notifier.NOTIFICATIONS))
self.assertEquals(0, len(fake_notifier.NOTIFICATIONS))
def test_send_on_vm_change(self):
@ -180,7 +178,7 @@ class NotificationsTestCase(test.TestCase):
self.instance['uuid'], params)
notifications.send_update(self.context, old_ref, new_ref)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
def test_send_on_task_change(self):
@ -190,23 +188,23 @@ class NotificationsTestCase(test.TestCase):
self.instance['uuid'], params)
notifications.send_update(self.context, old_ref, new_ref)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
def test_no_update_with_states(self):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
task_states.SPAWNING, verify_states=True)
self.assertEquals(0, len(test_notifier.NOTIFICATIONS))
self.assertEquals(0, len(fake_notifier.NOTIFICATIONS))
def test_vm_update_with_states(self):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.ACTIVE, task_states.SPAWNING,
task_states.SPAWNING, verify_states=True)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
notif = test_notifier.NOTIFICATIONS[0]
payload = notif["payload"]
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
access_ip_v4 = self.instance["access_ip_v4"]
access_ip_v6 = self.instance["access_ip_v6"]
display_name = self.instance["display_name"]
@ -229,9 +227,9 @@ class NotificationsTestCase(test.TestCase):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
None, verify_states=True)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
notif = test_notifier.NOTIFICATIONS[0]
payload = notif["payload"]
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
access_ip_v4 = self.instance["access_ip_v4"]
access_ip_v6 = self.instance["access_ip_v6"]
display_name = self.instance["display_name"]
@ -250,31 +248,31 @@ class NotificationsTestCase(test.TestCase):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
None)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
# service name should default to 'compute'
notif = test_notifier.NOTIFICATIONS[0]
self.assertEquals('compute.testhost', notif['publisher_id'])
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEquals('compute.testhost', notif.publisher_id)
def test_update_with_service_name(self):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
None, service="testservice")
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
# service name should default to 'compute'
notif = test_notifier.NOTIFICATIONS[0]
self.assertEquals('testservice.testhost', notif['publisher_id'])
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEquals('testservice.testhost', notif.publisher_id)
def test_update_with_host_name(self):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
None, host="someotherhost")
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
# service name should default to 'compute'
notif = test_notifier.NOTIFICATIONS[0]
self.assertEquals('compute.someotherhost', notif['publisher_id'])
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEquals('compute.someotherhost', notif.publisher_id)
def test_payload_has_fixed_ip_labels(self):
info = notifications.info_from_instance(self.context, self.instance,
@ -284,9 +282,9 @@ class NotificationsTestCase(test.TestCase):
def test_send_access_ip_update(self):
notifications.send_update(self.context, self.instance, self.instance)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
notif = test_notifier.NOTIFICATIONS[0]
payload = notif["payload"]
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
access_ip_v4 = self.instance["access_ip_v4"]
access_ip_v6 = self.instance["access_ip_v6"]
@ -297,9 +295,9 @@ class NotificationsTestCase(test.TestCase):
param = {"display_name": "new_display_name"}
new_name_inst = self._wrapped_create(params=param)
notifications.send_update(self.context, self.instance, new_name_inst)
self.assertEquals(1, len(test_notifier.NOTIFICATIONS))
notif = test_notifier.NOTIFICATIONS[0]
payload = notif["payload"]
self.assertEquals(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
old_display_name = self.instance["display_name"]
new_display_name = new_name_inst["display_name"]
@ -323,4 +321,4 @@ class NotificationsTestCase(test.TestCase):
fail_sending)
notifications.send_update(self.context, self.instance, self.instance)
self.assertEquals(0, len(test_notifier.NOTIFICATIONS))
self.assertEquals(0, len(fake_notifier.NOTIFICATIONS))

View File

@ -52,7 +52,7 @@ from nova.openstack.common import processutils
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
notify_decorator = 'nova.openstack.common.notifier.api.notify_decorator'
notify_decorator = 'nova.notifications.notify_decorator'
monkey_patch_opts = [
cfg.BoolOpt('monkey_patch',
@ -719,10 +719,10 @@ def monkey_patch():
using CONF.monkey_patch_modules.
The format is "Module path:Decorator function".
Example:
'nova.api.ec2.cloud:nova.openstack.common.notifier.api.notify_decorator'
'nova.api.ec2.cloud:nova.notifications.notify_decorator'
Parameters of the decorator is as follows.
(See nova.openstack.common.notifier.api.notify_decorator)
(See nova.notifications.notify_decorator)
name - name of the function
function - object of the function

View File

@ -70,6 +70,7 @@ from nova.compute import vm_mode
from nova import context as nova_context
from nova import exception
from nova.image import glance
from nova import notifier
from nova.objects import instance as instance_obj
from nova.openstack.common import excutils
from nova.openstack.common import fileutils
@ -78,7 +79,6 @@ from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common import loopingcall
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common import processutils
from nova.openstack.common import xmlutils
from nova.pci import pci_whitelist
@ -676,12 +676,9 @@ class LibvirtDriver(driver.ComputeDriver):
payload = dict(ip=LibvirtDriver.get_host_ip_addr(),
method='_connect',
reason=ex)
notifier.notify(nova_context.get_admin_context(),
notifier.publisher_id('compute'),
'compute.libvirt.error',
notifier.ERROR,
payload)
pass
notifier.get_notifier('compute').error(
nova_context.get_admin_context(),
'compute.libvirt.error', payload)
def get_num_instances(self):
"""Efficient override of base instance_exists method."""