Switch to common notifiers.

- Added notifier files to openstack-common.conf, merged from common.
- Import notifiers from common rather than nova.
- Removed nova-specific notifier code.
- Update some driver paths to refer to the new location within nova.

Should be a no-op, as the common notification code is freshly copied from Nova.

Change-Id: Icdf892bc3826b683fc74f22ead00939beda2859f
This commit is contained in:
Andrew Bogott 2012-06-28 19:18:20 -05:00
parent e2ad48bdf8
commit a099f57857
22 changed files with 172 additions and 473 deletions

View File

@ -316,9 +316,6 @@ global_opts = [
cfg.StrOpt('node_availability_zone',
default='nova',
help='availability zone of this node'),
cfg.StrOpt('notification_driver',
default='nova.notifier.no_op_notifier',
help='Default driver for sending notifications'),
cfg.ListOpt('memcached_servers',
default=None,
help='Memcached servers or None for in process cache.'),

View File

@ -25,9 +25,9 @@ from nova import exception
from nova import flags
from nova import network
from nova.network import model as network_model
from nova.notifier import api as notifier_api
from nova.openstack.common import cfg
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

View File

@ -1,81 +0,0 @@
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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.
from nova import context
from nova import db
from nova.openstack.common import log as logging
LOG = logging.getLogger(__name__)
def notify(_context, message):
"""Look for specific compute manager events and interprete them
so as to keep the Capacity table up to date.
NOTE: the True/False return codes are only for testing.
"""
# The event_type must start with 'compute.instance.'
event_type = message.get('event_type', None)
preamble = 'compute.instance.'
if not event_type or not event_type.startswith(preamble):
return False
# Events we're interested in end with .start and .end
event = event_type[len(preamble):]
parts = event.split('.')
suffix = parts[-1].lower()
event = event[:(-len(suffix) - 1)]
if suffix not in ['start', 'end']:
return False
started = suffix == 'start'
ended = suffix == 'end'
if started and event == 'create':
# We've already updated this stuff in the scheduler. Don't redo the
# work here.
return False
work = 1 if started else -1
# Extract the host name from the publisher id ...
publisher_preamble = 'compute.'
publisher = message.get('publisher_id', None)
if not publisher or not publisher.startswith(publisher_preamble):
return False
host = publisher[len(publisher_preamble):]
# If we deleted an instance, make sure we reclaim the resources.
# We may need to do something explicit for rebuild/migrate.
free_ram_mb = 0
free_disk_gb = 0
vms = 0
if ended and event == 'delete':
vms = -1
payload = message.get('payload', {})
free_ram_mb = payload.get('memory_mb', 0)
free_disk_gb = payload.get('disk_gb', 0)
LOG.debug("EventType=%(event_type)s -> host %(host)s: "
"ram %(free_ram_mb)d, disk %(free_disk_gb)d, "
"work %(work)d, vms%(vms)d" % locals())
db.api.compute_node_utilization_update(context.get_admin_context(), host,
free_ram_mb_delta=free_ram_mb, free_disk_gb_delta=free_disk_gb,
work_delta=work, vm_delta=vms)
return True

View File

@ -0,0 +1,81 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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.
"""
Simple class that stores security context information in the web request.
Projects should subclass this class if they wish to enhance the request
context or provide additional information in their specific WSGI pipeline.
"""
import itertools
import uuid
def generate_request_id():
return 'req-' + str(uuid.uuid4())
class RequestContext(object):
"""
Stores information about the security context under which the user
accesses the system, as well as additional request information.
"""
def __init__(self, auth_tok=None, user=None, tenant=None, is_admin=False,
read_only=False, show_deleted=False, request_id=None):
self.auth_tok = auth_tok
self.user = user
self.tenant = tenant
self.is_admin = is_admin
self.read_only = read_only
self.show_deleted = show_deleted
if not request_id:
request_id = generate_request_id()
self.request_id = request_id
def to_dict(self):
return {'user': self.user,
'tenant': self.tenant,
'is_admin': self.is_admin,
'read_only': self.read_only,
'show_deleted': self.show_deleted,
'auth_token': self.auth_tok,
'request_id': self.request_id}
def get_admin_context(show_deleted="no"):
context = RequestContext(None,
tenant=None,
is_admin=True,
show_deleted=show_deleted)
return context
def get_context_from_function_and_args(function, args, kwargs):
"""Find an arg of type RequestContext and return it.
This is useful in a couple of decorators where we don't
know much about the function we're wrapping.
"""
for arg in itertools.chain(kwargs.values(), args):
if isinstance(arg, RequestContext):
return arg
return None

View File

@ -40,10 +40,10 @@ import stat
import sys
import traceback
from nova import notifier
from nova.openstack.common import cfg
from nova.openstack.common import jsonutils
from nova.openstack.common import local
from nova.openstack.common import notifier
log_opts = [

View File

@ -13,11 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import inspect
import uuid
from nova import exception
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import context
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
@ -27,6 +27,9 @@ from nova.openstack.common import timeutils
LOG = logging.getLogger(__name__)
notifier_opts = [
cfg.StrOpt('notification_driver',
default='nova.openstack.common.notifier.no_op_notifier',
help='Default driver for sending notifications'),
cfg.StrOpt('default_notification_level',
default='INFO',
help='Default notification level for outgoing notifications'),
@ -35,8 +38,8 @@ notifier_opts = [
help='Default publisher_id for outgoing notifications'),
]
FLAGS = flags.FLAGS
FLAGS.register_opts(notifier_opts)
CONF = cfg.CONF
CONF.register_opts(notifier_opts)
WARN = 'WARN'
INFO = 'INFO'
@ -68,11 +71,11 @@ def notify_decorator(name, fn):
for key in kwarg:
body['kwarg'][key] = kwarg[key]
context = exception.get_context_from_function_and_args(fn, args, kwarg)
notify(context,
FLAGS.default_publisher_id,
ctxt = context.get_context_from_function_and_args(fn, args, kwarg)
notify(ctxt,
CONF.default_publisher_id,
name,
FLAGS.default_notification_level,
CONF.default_notification_level,
body)
return fn(*args, **kwarg)
return wrapped_func
@ -80,7 +83,7 @@ def notify_decorator(name, fn):
def publisher_id(service, host=None):
if not host:
host = FLAGS.host
host = CONF.host
return "%s.%s" % (service, host)
@ -123,7 +126,7 @@ def notify(context, publisher_id, event_type, priority, payload):
# Ensure everything is JSON serializable.
payload = jsonutils.to_primitive(payload, convert_instances=True)
driver = importutils.import_module(FLAGS.notification_driver)
driver = importutils.import_module(CONF.notification_driver)
msg = dict(message_id=str(uuid.uuid4()),
publisher_id=publisher_id,
event_type=event_type,

View File

@ -13,18 +13,17 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
list_notifier_drivers_opt = cfg.MultiStrOpt('list_notifier_drivers',
default=['nova.notifier.no_op_notifier'],
default=['nova.openstack.common.notifier.no_op_notifier'],
help='List of drivers to send notifications')
FLAGS = flags.FLAGS
FLAGS.register_opt(list_notifier_drivers_opt)
CONF = cfg.CONF
CONF.register_opt(list_notifier_drivers_opt)
LOG = logging.getLogger(__name__)
@ -44,9 +43,9 @@ class ImportFailureNotifier(object):
def _get_drivers():
"""Instantiates and returns drivers based on the flag values."""
global drivers
if not drivers:
if drivers is None:
drivers = []
for notification_driver in FLAGS.list_notifier_drivers:
for notification_driver in CONF.list_notifier_drivers:
try:
drivers.append(importutils.import_module(notification_driver))
except ImportError as e:
@ -54,6 +53,53 @@ def _get_drivers():
return drivers
def add_driver(notification_driver):
"""Add a notification driver at runtime."""
# Make sure the driver list is initialized.
_get_drivers()
if isinstance(notification_driver, basestring):
# Load and add
try:
drivers.append(importutils.import_module(notification_driver))
except ImportError as e:
drivers.append(ImportFailureNotifier(e))
else:
# Driver is already loaded; just add the object.
drivers.append(notification_driver)
def _object_name(obj):
name = []
if hasattr(obj, '__module__'):
name.append(obj.__module__)
if hasattr(obj, '__name__'):
name.append(obj.__name__)
else:
name.append(obj.__class__.__name__)
return '.'.join(name)
def remove_driver(notification_driver):
"""Remove a notification driver at runtime."""
# Make sure the driver list is initialized.
_get_drivers()
removed = False
if notification_driver in drivers:
# We're removing an object. Easy.
drivers.remove(notification_driver)
removed = True
else:
# We're removing a driver by name. Search for it.
for driver in drivers:
if _object_name(driver) == notification_driver:
drivers.remove(driver)
removed = True
if not removed:
raise ValueError("Cannot remove; %s is not in list" %
notification_driver)
def notify(context, message):
"""Passes notification to multiple notifiers in a list."""
for driver in _get_drivers():

View File

@ -13,21 +13,22 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import flags
from nova.openstack.common import jsonutils
import json
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
FLAGS = flags.FLAGS
CONF = cfg.CONF
def notify(_context, message):
"""Notifies the recipient of the desired event given the model.
Log notifications using nova's default logging system"""
Log notifications using openstack's default logging system"""
priority = message.get('priority',
FLAGS.default_notification_level)
CONF.default_notification_level)
priority = priority.lower()
logger = logging.getLogger(
'nova.notification.%s' % message['event_type'])
getattr(logger, priority)(jsonutils.dumps(message))
'nova.openstack.common.notification.%s' % message['event_type'])
getattr(logger, priority)(json.dumps(message))

View File

@ -14,10 +14,8 @@
# under the License.
import nova.context
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import context as req_context
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
@ -25,20 +23,20 @@ LOG = logging.getLogger(__name__)
notification_topic_opt = cfg.ListOpt('notification_topics',
default=['notifications', ],
help='AMQP topic used for Nova notifications')
help='AMQP topic used for openstack notifications')
FLAGS = flags.FLAGS
FLAGS.register_opt(notification_topic_opt)
CONF = cfg.CONF
CONF.register_opt(notification_topic_opt)
def notify(context, message):
"""Sends a notification to the RabbitMQ"""
if not context:
context = nova.context.get_admin_context()
context = req_context.get_admin_context()
priority = message.get('priority',
FLAGS.default_notification_level)
CONF.default_notification_level)
priority = priority.lower()
for topic in FLAGS.notification_topics:
for topic in CONF.notification_topics:
topic = '%s.%s' % (topic, priority)
try:
rpc.notify(context, topic, message)

View File

@ -13,9 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import flags
FLAGS = flags.FLAGS
NOTIFICATIONS = []

View File

@ -23,9 +23,9 @@ import operator
from nova import exception
from nova import flags
from nova.notifier import api as notifier
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.scheduler import driver
from nova.scheduler import least_cost
from nova.scheduler import scheduler_options

View File

@ -29,11 +29,11 @@ from nova import exception
from nova import flags
from nova import manager
from nova import notifications
from nova.notifier import api as notifier
from nova.openstack.common import cfg
from nova.openstack.common import excutils
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 import quota

View File

@ -1,16 +0,0 @@
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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.
from nova.tests import *

View File

@ -1,59 +0,0 @@
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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 nova.db.api
from nova.notifier import capacity_notifier as cn
from nova.openstack.common import jsonutils
from nova import test
class CapacityNotifierTestCase(test.TestCase):
"""Test case for the Capacity updating notifier."""
def _make_msg(self, host, event):
usage_info = dict(memory_mb=123, disk_gb=456)
payload = jsonutils.to_primitive(usage_info, convert_instances=True)
return dict(
publisher_id="compute.%s" % host,
event_type="compute.instance.%s" % event,
payload=payload
)
def test_event_type(self):
msg = self._make_msg("myhost", "mymethod")
msg['event_type'] = 'random'
self.assertFalse(cn.notify(None, msg))
def test_bad_event_suffix(self):
msg = self._make_msg("myhost", "mymethod.badsuffix")
self.assertFalse(cn.notify(None, msg))
def test_bad_publisher_id(self):
msg = self._make_msg("myhost", "mymethod.start")
msg['publisher_id'] = 'badpublisher'
self.assertFalse(cn.notify(None, msg))
def test_update_called(self):
def _verify_called(host, context, free_ram_mb_delta,
free_disk_gb_delta, work_delta, vm_delta):
self.assertEquals(free_ram_mb_delta, 123)
self.assertEquals(free_disk_gb_delta, 456)
self.assertEquals(vm_delta, -1)
self.assertEquals(work_delta, -1)
self.stubs.Set(nova.db.api, "compute_node_utilization_update",
_verify_called)
msg = self._make_msg("myhost", "delete.end")
self.assertTrue(cn.notify(None, msg))

View File

@ -1,84 +0,0 @@
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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 nova
import nova.notifier.api
from nova.notifier import list_notifier
import nova.notifier.log_notifier
import nova.notifier.no_op_notifier
from nova.openstack.common import log as logging
from nova import test
class NotifierListTestCase(test.TestCase):
"""Test case for notifications"""
def setUp(self):
super(NotifierListTestCase, self).setUp()
list_notifier._reset_drivers()
# Mock log to add one to exception_count when log.exception is called
def mock_exception(cls, *args):
self.exception_count += 1
self.exception_count = 0
list_notifier_log = logging.getLogger('nova.notifier.list_notifier')
self.stubs.Set(list_notifier_log, "exception", mock_exception)
# Mock no_op notifier to add one to notify_count when called.
def mock_notify(cls, *args):
self.notify_count += 1
self.notify_count = 0
self.stubs.Set(nova.notifier.no_op_notifier, 'notify', mock_notify)
# Mock log_notifier to raise RuntimeError when called.
def mock_notify2(cls, *args):
raise RuntimeError("Bad notifier.")
self.stubs.Set(nova.notifier.log_notifier, 'notify', mock_notify2)
def tearDown(self):
list_notifier._reset_drivers()
super(NotifierListTestCase, self).tearDown()
def test_send_notifications_successfully(self):
self.flags(notification_driver='nova.notifier.list_notifier',
list_notifier_drivers=['nova.notifier.no_op_notifier',
'nova.notifier.no_op_notifier'])
nova.notifier.api.notify('contextarg', 'publisher_id', 'event_type',
nova.notifier.api.WARN, dict(a=3))
self.assertEqual(self.notify_count, 2)
self.assertEqual(self.exception_count, 0)
def test_send_notifications_with_errors(self):
self.flags(notification_driver='nova.notifier.list_notifier',
list_notifier_drivers=['nova.notifier.no_op_notifier',
'nova.notifier.log_notifier'])
nova.notifier.api.notify('contextarg', 'publisher_id',
'event_type', nova.notifier.api.WARN, dict(a=3))
self.assertEqual(self.notify_count, 1)
self.assertEqual(self.exception_count, 1)
def test_when_driver_fails_to_import(self):
self.flags(notification_driver='nova.notifier.list_notifier',
list_notifier_drivers=['nova.notifier.no_op_notifier',
'nova.notifier.logo_notifier',
'fdsjgsdfhjkhgsfkj'])
nova.notifier.api.notify('contextarg', 'publisher_id',
'event_type', nova.notifier.api.WARN, dict(a=3))
self.assertEqual(self.exception_count, 2)
self.assertEqual(self.notify_count, 1)

View File

@ -22,9 +22,9 @@ from nova.compute import utils as compute_utils
from nova import context
from nova import db
from nova import flags
from nova.notifier import test_notifier
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import test_notifier
from nova import test
from nova.tests import fake_network
import nova.tests.image.fake
@ -50,7 +50,7 @@ class UsageInfoTestCase(test.TestCase):
self.flags(compute_driver='nova.virt.fake.FakeDriver',
stub_network=True,
notification_driver='nova.notifier.test_notifier',
notification_driver='nova.openstack.common.notifier.test_notifier',
network_manager='nova.network.manager.FlatManager')
self.compute = importutils.import_object(FLAGS.compute_manager)
self.user_id = 'fake'

View File

@ -1,184 +0,0 @@
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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 nova
from nova import context
from nova import flags
from nova.notifier import api as notifier_api
import nova.notifier.no_op_notifier
from nova.openstack.common import log
from nova import test
ctxt = context.get_admin_context()
ctxt2 = context.get_admin_context()
class NotifierTestCase(test.TestCase):
"""Test case for notifications"""
def setUp(self):
super(NotifierTestCase, self).setUp()
self.flags(notification_driver='nova.notifier.no_op_notifier')
def test_send_notification(self):
self.notify_called = False
def mock_notify(cls, *args):
self.notify_called = True
self.stubs.Set(nova.notifier.no_op_notifier, 'notify',
mock_notify)
notifier_api.notify(ctxt, 'publisher_id', 'event_type',
nova.notifier.api.WARN, dict(a=3))
self.assertEqual(self.notify_called, True)
def test_verify_message_format(self):
"""A test to ensure changing the message format is prohibitively
annoying"""
def message_assert(context, message):
fields = [('publisher_id', 'publisher_id'),
('event_type', 'event_type'),
('priority', 'WARN'),
('payload', dict(a=3))]
for k, v in fields:
self.assertEqual(message[k], v)
self.assertTrue(len(message['message_id']) > 0)
self.assertTrue(len(message['timestamp']) > 0)
self.assertEqual(context, ctxt)
self.stubs.Set(nova.notifier.no_op_notifier, 'notify',
message_assert)
notifier_api.notify(ctxt, 'publisher_id', 'event_type',
nova.notifier.api.WARN, dict(a=3))
def test_send_rabbit_notification(self):
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
'nova.notifier.rabbit_notifier')
self.mock_notify = False
def mock_notify(cls, *args):
self.mock_notify = True
self.stubs.Set(nova.openstack.common.rpc, 'notify', mock_notify)
notifier_api.notify(ctxt, 'publisher_id', 'event_type',
nova.notifier.api.WARN, dict(a=3))
self.assertEqual(self.mock_notify, True)
def test_invalid_priority(self):
self.assertRaises(nova.notifier.api.BadPriorityException,
notifier_api.notify, ctxt, 'publisher_id',
'event_type', 'not a priority', dict(a=3))
def test_rabbit_priority_queue(self):
flags.DECLARE('notification_topics', 'nova.notifier.rabbit_notifier')
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
'nova.notifier.rabbit_notifier')
self.stubs.Set(nova.flags.FLAGS, 'notification_topics',
['testnotify', ])
self.test_topic = None
def mock_notify(context, topic, msg):
self.test_topic = topic
self.stubs.Set(nova.openstack.common.rpc, 'notify', mock_notify)
notifier_api.notify(ctxt, 'publisher_id',
'event_type', 'DEBUG', dict(a=3))
self.assertEqual(self.test_topic, 'testnotify.debug')
def test_error_notification(self):
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
'nova.notifier.rabbit_notifier')
self.stubs.Set(nova.flags.FLAGS, 'publish_errors', True)
LOG = log.getLogger('nova')
log.setup('nova')
msgs = []
def mock_notify(context, topic, data):
msgs.append(data)
self.stubs.Set(nova.openstack.common.rpc, 'notify', mock_notify)
LOG.error('foo')
self.assertEqual(1, len(msgs))
msg = msgs[0]
self.assertEqual(msg['event_type'], 'error_notification')
self.assertEqual(msg['priority'], 'ERROR')
self.assertEqual(msg['payload']['error'], 'foo')
def test_send_notification_by_decorator(self):
self.notify_called = False
def example_api(arg1, arg2):
return arg1 + arg2
example_api = nova.notifier.api.notify_decorator(
'example_api',
example_api)
def mock_notify(cls, *args):
self.notify_called = True
self.stubs.Set(nova.notifier.no_op_notifier, 'notify',
mock_notify)
self.assertEqual(3, example_api(1, 2))
self.assertEqual(self.notify_called, True)
def test_decorator_context(self):
"""Verify that the notify decorator can extract the 'context' arg."""
self.notify_called = False
self.context_arg = None
def example_api(arg1, arg2, context):
return arg1 + arg2
def example_api2(arg1, arg2, **kw):
return arg1 + arg2
example_api = nova.notifier.api.notify_decorator(
'example_api',
example_api)
example_api2 = nova.notifier.api.notify_decorator(
'example_api2',
example_api2)
def mock_notify(context, cls, _type, _priority, _payload):
self.notify_called = True
self.context_arg = context
self.stubs.Set(nova.notifier.api, 'notify',
mock_notify)
# Test positional context
self.assertEqual(3, example_api(1, 2, ctxt))
self.assertEqual(self.notify_called, True)
self.assertEqual(self.context_arg, ctxt)
self.notify_called = False
self.context_arg = None
# Test named context
self.assertEqual(3, example_api2(1, 2, context=ctxt2))
self.assertEqual(self.notify_called, True)
self.assertEqual(self.context_arg, ctxt2)
# Test missing context
self.assertEqual(3, example_api2(1, 2, bananas="delicious"))
self.assertEqual(self.notify_called, True)
self.assertEqual(self.context_arg, None)

View File

@ -28,9 +28,9 @@ from nova import context
from nova import db
from nova import exception
from nova import flags
from nova.notifier import test_notifier
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import test_notifier
from nova.openstack.common import rpc
import nova.policy
from nova import quota
@ -50,7 +50,7 @@ class VolumeTestCase(test.TestCase):
self.compute = importutils.import_object(FLAGS.compute_manager)
self.flags(compute_driver='nova.virt.fake.FakeDriver')
self.stubs.Set(nova.flags.FLAGS, 'notification_driver',
'nova.notifier.test_notifier')
'nova.openstack.common.notifier.test_notifier')
self.volume = importutils.import_object(FLAGS.volume_manager)
self.context = context.get_admin_context()
instance = db.instance_create(self.context, {})

View File

@ -20,9 +20,9 @@
from nova import context
from nova import db
from nova import flags
from nova.notifier import test_notifier
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import test_notifier
from nova import test
from nova.volume import utils as volume_utils
@ -39,7 +39,7 @@ class UsageInfoTestCase(test.TestCase):
stub_network=True,
host='fake')
self.stubs.Set(flags.FLAGS, 'notification_driver',
'nova.notifier.test_notifier')
'nova.openstack.common.notifier.test_notifier')
self.volume = importutils.import_object(FLAGS.volume_manager)
self.user_id = 'fake'
self.project_id = 'fake'

View File

@ -1,7 +1,7 @@
[DEFAULT]
# The list of modules to copy from openstack-common
modules=cfg,excutils,gettextutils,importutils,iniparser,jsonutils,local,log,policy,setup,timeutils,rpc
modules=cfg,context,excutils,gettextutils,importutils,iniparser,jsonutils,local,log,notifier,policy,setup,timeutils,rpc
# The base module to hold the copy of openstack.common
base=nova