summaryrefslogtreecommitdiff
path: root/nova/tests
diff options
context:
space:
mode:
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/functional/notification_sample_tests/notification_sample_base.py7
-rw-r--r--nova/tests/functional/notification_sample_tests/test_instance.py143
-rw-r--r--nova/tests/unit/notifications/objects/test_notification.py5
-rw-r--r--nova/tests/unit/test_notifications.py145
4 files changed, 270 insertions, 30 deletions
diff --git a/nova/tests/functional/notification_sample_tests/notification_sample_base.py b/nova/tests/functional/notification_sample_tests/notification_sample_base.py
index 8106404ddd..5f4d0b13e8 100644
--- a/nova/tests/functional/notification_sample_tests/notification_sample_base.py
+++ b/nova/tests/functional/notification_sample_tests/notification_sample_base.py
@@ -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]
diff --git a/nova/tests/functional/notification_sample_tests/test_instance.py b/nova/tests/functional/notification_sample_tests/test_instance.py
index 4d19bdba5a..17b4f3c953 100644
--- a/nova/tests/functional/notification_sample_tests/test_instance.py
+++ b/nova/tests/functional/notification_sample_tests/test_instance.py
@@ -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)
diff --git a/nova/tests/unit/notifications/objects/test_notification.py b/nova/tests/unit/notifications/objects/test_notification.py
index a698e9ab16..2f9e2afced 100644
--- a/nova/tests/unit/notifications/objects/test_notification.py
+++ b/nova/tests/unit/notifications/objects/test_notification.py
@@ -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',
diff --git a/nova/tests/unit/test_notifications.py b/nova/tests/unit/test_notifications.py
index 97d8fe02a9..a99fc25dfb 100644
--- a/nova/tests/unit/test_notifications.py
+++ b/nova/tests/unit/test_notifications.py
@@ -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))
-
- def test_vm_update_with_states(self):
+ self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))
+
+ 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)
-
- def test_task_update_with_states(self):
+ 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)
+
+ 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]