Transform instance.update notification

Change-Id: I4e1ca357322bdbcb95e4803001f4a7dc1bd37f04
Implements: bp versioned-notification-transformation-newton
This commit is contained in:
Balazs Gibizer 2016-06-06 15:03:47 +02:00
parent 084478d417
commit 87e13112b1
8 changed files with 483 additions and 28 deletions

View File

@ -0,0 +1,65 @@
{
"event_type": "instance.update",
"payload": {
"nova_object.data": {
"architecture": "x86_64",
"audit_period": {
"nova_object.data": {
"audit_period_beginning": "2012-10-01T00:00:00Z",
"audit_period_ending": "2012-10-29T13:42:11Z"},
"nova_object.name": "AuditPeriodPayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.0"
},
"availability_zone": null,
"bandwidth": [],
"created_at": "2012-10-29T13:42:11Z",
"deleted_at": null,
"display_name": "some-server",
"host": "compute",
"host_name": "some-server",
"image_uuid": "155d900f-4e14-4e4c-a73d-069cbf4541e6",
"kernel_id": "",
"launched_at": null,
"metadata": {},
"node": "fake-mini",
"old_display_name": null,
"os_type": null,
"progress": 0,
"ramdisk_id": "",
"reservation_id": "r-sd3ygfjj",
"state": "building",
"task_state": "scheduling",
"power_state": "pending",
"ip_addresses": [],
"state_update": {
"nova_object.data": {
"new_task_state": null,
"old_state": "building",
"old_task_state": null,
"state": "building"},
"nova_object.name": "InstanceStateUpdatePayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.0"},
"tenant_id": "6f70656e737461636b20342065766572",
"terminated_at": null,
"flavor": {
"nova_object.name": "FlavorPayload",
"nova_object.data": {
"flavorid": "a22d5517-147c-4147-a0d1-e698df5cd4e3",
"root_gb": 1,
"vcpus": 1,
"ephemeral_gb": 0,
"memory_mb": 512
},
"nova_object.version": "1.0",
"nova_object.namespace": "nova"
},
"user_id": "fake",
"uuid": "c03c0bf9-f46e-4e4f-93f1-817568567ee2"},
"nova_object.name": "InstanceUpdatePayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.0"},
"priority": "INFO",
"publisher_id": "nova-compute:fake-mini"
}

View File

@ -33,11 +33,15 @@ from nova.i18n import _LE
from nova.image import glance
from nova import network
from nova.network import model as network_model
from nova.notifications.objects import base as notification_base
from nova.notifications.objects import instance as instance_notification
from nova import objects
from nova.objects import base as obj_base
from nova.objects import fields
from nova import rpc
from nova import utils
LOG = log.getLogger(__name__)
CONF = nova.conf.CONF
@ -244,6 +248,61 @@ def _send_instance_update_notification(context, instance, old_vm_state=None,
rpc.get_notifier(service, host).info(context,
'compute.instance.update', payload)
_send_versioned_instance_update(context, instance, payload, host, service)
def _map_service_to_binary(service):
if service == 'api':
binary = 'nova-api'
elif service == 'compute':
binary = 'nova-compute'
else:
binary = service
return binary
def _send_versioned_instance_update(context, instance, payload, host, service):
state_update = instance_notification.InstanceStateUpdatePayload(
old_state=payload.get('old_state'),
state=payload.get('state'),
old_task_state=payload.get('old_task_state'),
new_task_state=payload.get('new_task_state'))
audit_period = instance_notification.AuditPeriodPayload(
audit_period_beginning=payload.get('audit_period_beginning'),
audit_period_ending=payload.get('audit_period_ending'))
bandwidth = [instance_notification.BandwidthPayload(
network_name=label,
in_bytes=bw['bw_in'],
out_bytes=bw['bw_out'])
for label, bw in payload['bandwidth'].items()]
network_info = instance.info_cache.network_info
flavor = instance_notification.FlavorPayload(instance=instance)
versioned_payload = instance_notification.InstanceUpdatePayload(
instance=instance,
state_update=state_update,
audit_period=audit_period,
bandwidth=bandwidth,
ip_addresses=instance_notification.IpPayload.from_network_info(
network_info),
flavor=flavor,
old_display_name=payload.get('old_display_name'))
notification = instance_notification.InstanceUpdateNotification(
priority=fields.NotificationPriority.INFO,
event_type=notification_base.EventType(
object='instance',
action=fields.NotificationAction.UPDATE),
publisher=notification_base.NotificationPublisher(
host=host or CONF.host,
binary=_map_service_to_binary(service)),
payload=versioned_payload)
notification.emit(context)
def audit_period_bounds(current_period=False):
"""Get the start and end of the relevant audit usage period

View File

@ -105,6 +105,29 @@ class InstanceActionPayload(InstancePayload):
flavor=flavor)
@nova_base.NovaObjectRegistry.register_notification
class InstanceUpdatePayload(InstancePayload):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'state_update': fields.ObjectField('InstanceStateUpdatePayload'),
'audit_period': fields.ObjectField('AuditPeriodPayload'),
'bandwidth': fields.ListOfObjectsField('BandwidthPayload'),
'old_display_name': fields.StringField(nullable=True)
}
def __init__(self, instance, flavor, ip_addresses, state_update,
audit_period, bandwidth, old_display_name):
super(InstanceUpdatePayload, self).__init__(
instance=instance,
flavor=flavor,
ip_addresses=ip_addresses,
state_update=state_update,
audit_period=audit_period,
bandwidth=bandwidth,
old_display_name=old_display_name)
@nova_base.NovaObjectRegistry.register_notification
class IpPayload(base.NotificationPayloadBase):
# Version 1.0: Initial version
@ -119,6 +142,25 @@ class IpPayload(base.NotificationPayloadBase):
'device_name': fields.StringField(nullable=True)
}
@classmethod
def from_network_info(cls, network_info):
"""Returns a list of IpPayload object based on the passed
network_info.
"""
ips = []
if network_info is not None:
for vif in network_info:
for ip in vif.fixed_ips():
ips.append(cls(
label=vif["network"]["label"],
mac=vif["address"],
meta=vif["meta"],
port_uuid=vif["id"],
version=ip["version"],
address=ip["address"],
device_name=vif["devname"]))
return ips
@nova_base.NovaObjectRegistry.register_notification
class FlavorPayload(base.NotificationPayloadBase):
@ -146,6 +188,39 @@ class FlavorPayload(base.NotificationPayloadBase):
self.populate_schema(instance=instance, flavor=instance.flavor)
@nova_base.NovaObjectRegistry.register_notification
class BandwidthPayload(base.NotificationPayloadBase):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'network_name': fields.StringField(),
'in_bytes': fields.IntegerField(),
'out_bytes': fields.IntegerField(),
}
@nova_base.NovaObjectRegistry.register_notification
class AuditPeriodPayload(base.NotificationPayloadBase):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'audit_period_beginning': fields.DateTimeField(),
'audit_period_ending': fields.DateTimeField(),
}
@nova_base.NovaObjectRegistry.register_notification
class InstanceStateUpdatePayload(base.NotificationPayloadBase):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'old_state': fields.StringField(nullable=True),
'state': fields.StringField(nullable=True),
'old_task_state': fields.StringField(nullable=True),
'new_task_state': fields.StringField(nullable=True),
}
@base.notification_sample('instance-delete-start.json')
@base.notification_sample('instance-delete-end.json')
# @base.notification_sample('instance-pause-start.json')
@ -182,3 +257,14 @@ class InstanceActionNotification(base.NotificationBase):
fields = {
'payload': fields.ObjectField('InstanceActionPayload')
}
@base.notification_sample('instance-update.json')
@nova_base.NovaObjectRegistry.register_notification
class InstanceUpdateNotification(base.NotificationBase):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'payload': fields.ObjectField('InstanceUpdatePayload')
}

View File

@ -77,7 +77,7 @@ class NotificationSampleTestBase(test.TestCase,
self.start_service('conductor', manager=CONF.conductor.manager)
self.start_service('scheduler')
self.start_service('network')
self.start_service('compute')
self.compute = self.start_service('compute')
def _get_notification_sample(self, sample):
sample_dir = os.path.dirname(os.path.abspath(__file__))
@ -177,3 +177,8 @@ class NotificationSampleTestBase(test.TestCase,
self.fail('Server failed to delete.')
except api_client.OpenStackApiNotFoundException:
return
def _get_notifications(self, event_type):
return [notification for notification
in fake_notifier.VERSIONED_NOTIFICATIONS
if notification['event_type'] == event_type]

View File

@ -9,6 +9,7 @@
# 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.tests import fixtures
from nova.tests.functional.notification_sample_tests \
import notification_sample_base
@ -47,3 +48,145 @@ class TestInstanceNotificationSample(
notification_sample_base.NotificationSampleTestBase.ANY,
'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1])
def _verify_instance_update_steps(self, steps, notifications,
initial=None):
replacements = {}
if initial:
replacements = initial
for i, step in enumerate(steps):
replacements.update(step)
self._verify_notification(
'instance-update',
replacements=replacements,
actual=notifications[i])
return replacements
def test_create_delete_server_with_instance_update(self):
self.flags(notify_on_state_change='vm_and_task_state')
server = self._boot_a_server(
extra_params={'networks': [{'port': self.neutron.port_1['id']}]})
instance_updates = self._get_notifications('instance.update')
# The first notification comes from the nova-api the rest is from the
# nova-compute. To keep the test simpler assert this fact and then
# modify the publisher_id of the first notification to match the
# template
self.assertEqual('nova-api:fake-mini',
instance_updates[0]['publisher_id'])
instance_updates[0]['publisher_id'] = 'nova-compute:fake-mini'
self.assertEqual(7, len(instance_updates))
create_steps = [
# nothing -> scheduling
{'reservation_id':
notification_sample_base.NotificationSampleTestBase.ANY,
'uuid': server['id'],
'host': None,
'node': None,
'state_update.new_task_state': 'scheduling',
'state_update.old_task_state': 'scheduling',
'state_update.state': 'building',
'state_update.old_state': 'building',
'state': 'building'},
# scheduling -> building
{
'state_update.new_task_state': None,
'state_update.old_task_state': 'scheduling',
'task_state': None},
# scheduled
{'host': 'compute',
'node': 'fake-mini',
'state_update.old_task_state': None},
# building -> networking
{'state_update.new_task_state': 'networking',
'state_update.old_task_state': 'networking',
'task_state': 'networking'},
# networking -> block_device_mapping
{'state_update.new_task_state': 'block_device_mapping',
'state_update.old_task_state': 'networking',
'task_state': 'block_device_mapping',
},
# block_device_mapping -> spawning
{'state_update.new_task_state': 'spawning',
'state_update.old_task_state': 'block_device_mapping',
'task_state': 'spawning',
'ip_addresses': [{
"nova_object.name": "IpPayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.0",
"nova_object.data": {
"mac": "fa:16:3e:4c:2c:30",
"address": "192.168.1.3",
"port_uuid": "ce531f90-199f-48c0-816c-13e38010b442",
"meta": {},
"version": 4,
"label": "private-network",
"device_name": "tapce531f90-19"
}}]
},
# spawning -> active
{'state_update.new_task_state': None,
'state_update.old_task_state': 'spawning',
'state_update.state': 'active',
'launched_at': '2012-10-29T13:42:11Z',
'state': 'active',
'task_state': None,
'power_state': 'running'},
]
replacements = self._verify_instance_update_steps(
create_steps, instance_updates)
fake_notifier.reset()
# Let's generate some bandwidth usage data.
# Just call the periodic task directly for simplicity
self.compute.manager._poll_bandwidth_usage(context.get_admin_context())
self.api.delete_server(server['id'])
self._wait_until_deleted(server)
instance_updates = self._get_notifications('instance.update')
self.assertEqual(2, len(instance_updates))
delete_steps = [
# active -> deleting
{'state_update.new_task_state': 'deleting',
'state_update.old_task_state': 'deleting',
'state_update.old_state': 'active',
'state': 'active',
'task_state': 'deleting',
'bandwidth': [
{'nova_object.namespace': 'nova',
'nova_object.name': 'BandwidthPayload',
'nova_object.data':
{'network_name': 'private-network',
'out_bytes': 0,
'in_bytes': 0},
'nova_object.version': '1.0'}]
},
# deleting -> deleted
{'state_update.new_task_state': None,
'state_update.old_task_state': 'deleting',
'state_update.old_state': 'active',
'state_update.state': 'deleted',
'state': 'deleted',
'task_state': None,
'terminated_at': '2012-10-29T13:42:11Z',
'ip_addresses': [],
'power_state': 'pending',
'bandwidth': []},
]
self._verify_instance_update_steps(delete_steps, instance_updates,
initial=replacements)

View File

@ -255,6 +255,8 @@ class TestNotificationBase(test.NoDBTestCase):
notification_object_data = {
'AuditPeriodPayload': '1.0-28345f72ca9d805eeb61b2c2385805dd',
'BandwidthPayload': '1.0-49278639296f9939ff2c8947b2078a82',
'EventType': '1.3-6ef678bfe9a4ebfd669c96d2d2c124a5',
'ExceptionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'ExceptionPayload': '1.0-4516ae282a55fe2fd5c754967ee6248b',
@ -262,6 +264,9 @@ notification_object_data = {
'InstanceActionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'InstanceActionPayload': '1.0-aa6a322cf1a3a19d090259fee65d1094',
'InstancePayload': '1.0-878bbc5a7a20bdeac7c6570f438a53aa',
'InstanceStateUpdatePayload': '1.0-a934d04e1b314318e42e8062647edd11',
'InstanceUpdateNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'InstanceUpdatePayload': '1.0-c69e17e00400455bfe602e5573a61f0b',
'IpPayload': '1.0-26b40117c41ed95a61ae104f0fcb5fdc',
'NotificationPublisher': '1.0-bbbc1402fb0e443a3eb227cc52b61545',
'ServiceStatusNotification': '1.0-a73147b93b520ff0061865849d3dfa56',

View File

@ -200,6 +200,7 @@ class NotificationsTestCase(test.TestCase):
notifications.send_update(self.context, old, self.instance)
self.assertEqual(0, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))
def test_task_notif(self):
@ -220,12 +221,18 @@ class NotificationsTestCase(test.TestCase):
verify_states=True)
self.assertEqual(0, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))
# ok now enable task state notifications and re-try
self.flags(notify_on_state_change="vm_and_task_state")
notifications.send_update(self.context, old, self.instance)
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self.assertEqual(
'instance.update',
fake_notifier.VERSIONED_NOTIFICATIONS[0]['event_type'])
def test_send_no_notif(self):
@ -240,6 +247,7 @@ class NotificationsTestCase(test.TestCase):
service="compute", host=None, verify_states=True)
self.assertEqual(0, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))
def test_send_on_vm_change(self):
old = obj_base.obj_to_primitive(self.instance)
@ -253,6 +261,14 @@ class NotificationsTestCase(test.TestCase):
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEqual('compute.testhost', notif.publisher_id)
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self.assertEqual(
'nova-compute:testhost',
fake_notifier.VERSIONED_NOTIFICATIONS[0]['publisher_id'])
self.assertEqual(
'instance.update',
fake_notifier.VERSIONED_NOTIFICATIONS[0]['event_type'])
def test_send_on_task_change(self):
old = obj_base.obj_to_primitive(self.instance)
@ -262,6 +278,10 @@ class NotificationsTestCase(test.TestCase):
notifications.send_update(self.context, old, self.instance)
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self.assertEqual(
'instance.update',
fake_notifier.VERSIONED_NOTIFICATIONS[0]['event_type'])
def test_no_update_with_states(self):
@ -269,84 +289,146 @@ class NotificationsTestCase(test.TestCase):
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
task_states.SPAWNING, verify_states=True)
self.assertEqual(0, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))
def test_vm_update_with_states(self):
def get_fake_bandwidth(self):
usage = objects.BandwidthUsage(context=self.context)
usage.create(
self.instance.uuid,
mac='DE:AD:BE:EF:00:01',
bw_in=1,
bw_out=2,
last_ctr_in=0,
last_ctr_out=0,
start_period='2012-10-29T13:42:11Z')
return usage
@mock.patch.object(objects.BandwidthUsageList, 'get_by_uuids')
def test_vm_update_with_states(self, mock_bandwidth_list):
mock_bandwidth_list.return_value = [self.get_fake_bandwidth()]
fake_net_info = fake_network.fake_get_instance_nw_info(self, 1, 1)
self.instance.info_cache.network_info = fake_net_info
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._verify_notification()
def _verify_notification(self, expected_state=vm_states.ACTIVE,
expected_new_task_state=task_states.SPAWNING):
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self.assertEqual(
'instance.update',
fake_notifier.VERSIONED_NOTIFICATIONS[0]['event_type'])
access_ip_v4 = str(self.instance.access_ip_v4)
access_ip_v6 = str(self.instance.access_ip_v6)
display_name = self.instance.display_name
hostname = self.instance.hostname
node = self.instance.node
payload = fake_notifier.NOTIFICATIONS[0].payload
self.assertEqual(vm_states.BUILDING, payload["old_state"])
self.assertEqual(vm_states.ACTIVE, payload["state"])
self.assertEqual(expected_state, payload["state"])
self.assertEqual(task_states.SPAWNING, payload["old_task_state"])
self.assertEqual(task_states.SPAWNING, payload["new_task_state"])
self.assertEqual(expected_new_task_state, payload["new_task_state"])
self.assertEqual(payload["access_ip_v4"], access_ip_v4)
self.assertEqual(payload["access_ip_v6"], access_ip_v6)
self.assertEqual(payload["display_name"], display_name)
self.assertEqual(payload["hostname"], hostname)
self.assertEqual(payload["node"], node)
payload = fake_notifier.VERSIONED_NOTIFICATIONS[0][
'payload']['nova_object.data']
state_update = payload['state_update']['nova_object.data']
self.assertEqual(vm_states.BUILDING, state_update['old_state'])
self.assertEqual(expected_state, state_update["state"])
self.assertEqual(task_states.SPAWNING, state_update["old_task_state"])
self.assertEqual(expected_new_task_state,
state_update["new_task_state"])
self.assertEqual(payload["display_name"], display_name)
self.assertEqual(payload["host_name"], hostname)
self.assertEqual(payload["node"], node)
flavor = payload['flavor']['nova_object.data']
self.assertEqual(flavor['flavorid'], '1')
self.assertEqual(payload['image_uuid'], uuids.image_ref)
def test_task_update_with_states(self):
net_info = self.instance.info_cache.network_info
vif = net_info[0]
ip_addresses = payload['ip_addresses']
self.assertEqual(len(ip_addresses), 2)
for actual_ip, expected_ip in zip(ip_addresses, vif.fixed_ips()):
actual_ip = actual_ip['nova_object.data']
self.assertEqual(actual_ip['label'], vif['network']['label'])
self.assertEqual(actual_ip['mac'], vif['address'].lower())
self.assertEqual(actual_ip['port_uuid'], vif['id'])
self.assertEqual(actual_ip['device_name'], vif['devname'])
self.assertEqual(actual_ip['version'], expected_ip['version'])
self.assertEqual(actual_ip['address'], expected_ip['address'])
bandwidth = payload['bandwidth']
self.assertEqual(len(bandwidth), 1)
bandwidth = bandwidth[0]['nova_object.data']
self.assertEqual(bandwidth['in_bytes'], 1)
self.assertEqual(bandwidth['out_bytes'], 2)
self.assertEqual(bandwidth['network_name'], 'test1')
@mock.patch.object(objects.BandwidthUsageList, 'get_by_uuids')
def test_task_update_with_states(self, mock_bandwidth_list):
self.flags(notify_on_state_change="vm_and_task_state")
mock_bandwidth_list.return_value = [self.get_fake_bandwidth()]
fake_net_info = fake_network.fake_get_instance_nw_info(self, 1, 1)
self.instance.info_cache.network_info = fake_net_info
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
None, verify_states=True)
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
access_ip_v4 = str(self.instance.access_ip_v4)
access_ip_v6 = str(self.instance.access_ip_v6)
display_name = self.instance.display_name
hostname = self.instance.hostname
self.assertEqual(vm_states.BUILDING, payload["old_state"])
self.assertEqual(vm_states.BUILDING, payload["state"])
self.assertEqual(task_states.SPAWNING, payload["old_task_state"])
self.assertIsNone(payload["new_task_state"])
self.assertEqual(payload["access_ip_v4"], access_ip_v4)
self.assertEqual(payload["access_ip_v6"], access_ip_v6)
self.assertEqual(payload["display_name"], display_name)
self.assertEqual(payload["hostname"], hostname)
self._verify_notification(expected_state=vm_states.BUILDING,
expected_new_task_state=None)
def test_update_no_service_name(self):
notifications.send_update_with_states(self.context, self.instance,
vm_states.BUILDING, vm_states.BUILDING, task_states.SPAWNING,
None)
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
# service name should default to 'compute'
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEqual('compute.testhost', notif.publisher_id)
# in the versioned notification it defaults to nova-compute
notif = fake_notifier.VERSIONED_NOTIFICATIONS[0]
self.assertEqual('nova-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.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
# service name should default to 'compute'
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEqual('testservice.testhost', notif.publisher_id)
notif = fake_notifier.VERSIONED_NOTIFICATIONS[0]
self.assertEqual('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.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
# service name should default to 'compute'
notif = fake_notifier.NOTIFICATIONS[0]
self.assertEqual('compute.someotherhost', notif.publisher_id)
notif = fake_notifier.VERSIONED_NOTIFICATIONS[0]
self.assertEqual('nova-compute:someotherhost', notif['publisher_id'])
def test_payload_has_fixed_ip_labels(self):
info = notifications.info_from_instance(self.context, self.instance,
self.net_info, None)
@ -404,13 +486,18 @@ class NotificationsTestCase(test.TestCase):
new_name_inst = self._wrapped_create(params=param)
notifications.send_update(self.context, self.instance, new_name_inst)
self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
notif = fake_notifier.NOTIFICATIONS[0]
payload = notif.payload
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
old_display_name = self.instance.display_name
new_display_name = new_name_inst.display_name
self.assertEqual(payload["old_display_name"], old_display_name)
self.assertEqual(payload["display_name"], new_display_name)
for payload in [
fake_notifier.NOTIFICATIONS[0].payload,
fake_notifier.VERSIONED_NOTIFICATIONS[0][
'payload']['nova_object.data']]:
self.assertEqual(payload["old_display_name"], old_display_name)
self.assertEqual(payload["display_name"], new_display_name)
def test_send_no_state_change(self):
called = [False]

View File

@ -367,6 +367,11 @@ class FakeDriver(driver.ComputeDriver):
running VM.
"""
bw = []
for instance in instances:
bw.append({'uuid': instance.uuid,
'mac_address': 'fa:16:3e:4c:2c:30',
'bw_in': 0,
'bw_out': 0})
return bw
def get_all_volume_usage(self, context, compute_host_bdms):