Notification and CDM partial update
In this changeset, I implemented the notification handling (Rx only) system for consuming incoming notifications, more especially the Nova ones. The notifications handlers also contain the logic which incrementally updates the Compute model. Change-Id: Ia036a5a2be6caa64b7f180de38821b57c624300c Partially-implements: blueprint cluster-model-objects-wrapper
This commit is contained in:
@@ -73,9 +73,9 @@ class TestOneShotAuditHandler(base.DbTestCase):
|
||||
'audit_uuid': self.audit.uuid})
|
||||
|
||||
calls = [call_on_going, call_succeeded]
|
||||
messaging.status_topic_handler.publish_event.assert_has_calls(calls)
|
||||
messaging.publish_status_event.assert_has_calls(calls)
|
||||
self.assertEqual(
|
||||
2, messaging.status_topic_handler.publish_event.call_count)
|
||||
2, messaging.publish_status_event.call_count)
|
||||
|
||||
|
||||
class TestContinuousAuditHandler(base.DbTestCase):
|
||||
|
||||
@@ -23,6 +23,10 @@ from watcher.tests import base as test_base
|
||||
|
||||
class DummyClusterDataModelCollector(base.BaseClusterDataModelCollector):
|
||||
|
||||
@property
|
||||
def notification_endpoints(self):
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
model = model_root.ModelRoot()
|
||||
# Do something here...
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"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": "active",
|
||||
"task_state": "scheduling",
|
||||
"power_state": "pending",
|
||||
"ip_addresses": [],
|
||||
"state_update": {
|
||||
"nova_object.version": "1.0",
|
||||
"nova_object.name": "InstanceStateUpdatePayload",
|
||||
"nova_object.namespace": "nova",
|
||||
"nova_object.data": {
|
||||
"old_state": "building",
|
||||
"new_task_state": null,
|
||||
"old_task_state": "spawning",
|
||||
"state": "active"
|
||||
}
|
||||
},
|
||||
"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:compute"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"event_type":"instance.delete.end",
|
||||
"payload":{
|
||||
"nova_object.data":{
|
||||
"architecture":"x86_64",
|
||||
"availability_zone":null,
|
||||
"created_at":"2012-10-29T13:42:11Z",
|
||||
"deleted_at":"2012-10-29T13:42:11Z",
|
||||
"display_name":"some-server",
|
||||
"fault":null,
|
||||
"host":"compute",
|
||||
"host_name":"some-server",
|
||||
"ip_addresses":[],
|
||||
"kernel_id":"",
|
||||
"launched_at":"2012-10-29T13:42:11Z",
|
||||
"image_uuid": "155d900f-4e14-4e4c-a73d-069cbf4541e6",
|
||||
"metadata":{},
|
||||
"node":"fake-mini",
|
||||
"os_type":null,
|
||||
"progress":0,
|
||||
"ramdisk_id":"",
|
||||
"reservation_id":"r-npxv0e40",
|
||||
"state":"deleted",
|
||||
"task_state":null,
|
||||
"power_state":"pending",
|
||||
"tenant_id":"6f70656e737461636b20342065766572",
|
||||
"terminated_at":"2012-10-29T13:42:11Z",
|
||||
"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":"178b0921-8f85-4257-88b6-2e743b5a975c"
|
||||
},
|
||||
"nova_object.name":"InstanceActionPayload",
|
||||
"nova_object.namespace":"nova",
|
||||
"nova_object.version":"1.0"
|
||||
},
|
||||
"priority":"INFO",
|
||||
"publisher_id":"nova-compute:compute"
|
||||
}
|
||||
@@ -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": "active",
|
||||
"task_state": "scheduling",
|
||||
"power_state": "pending",
|
||||
"ip_addresses": [],
|
||||
"state_update": {
|
||||
"nova_object.data": {
|
||||
"new_task_state": null,
|
||||
"old_state": null,
|
||||
"old_task_state": null,
|
||||
"state": "active"},
|
||||
"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:compute"
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"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": "Node_0",
|
||||
"host_name": "some-server",
|
||||
"image_uuid": "155d900f-4e14-4e4c-a73d-069cbf4541e6",
|
||||
"kernel_id": "",
|
||||
"launched_at": null,
|
||||
"metadata": {},
|
||||
"node": "hostname_0",
|
||||
"old_display_name": null,
|
||||
"os_type": null,
|
||||
"progress": 0,
|
||||
"ramdisk_id": "",
|
||||
"reservation_id": "r-sd3ygfjj",
|
||||
"state": "active",
|
||||
"task_state": "scheduling",
|
||||
"power_state": "pending",
|
||||
"ip_addresses": [],
|
||||
"state_update": {
|
||||
"nova_object.version": "1.0",
|
||||
"nova_object.name": "InstanceStateUpdatePayload",
|
||||
"nova_object.namespace": "nova",
|
||||
"nova_object.data": {
|
||||
"old_state": "building",
|
||||
"new_task_state": null,
|
||||
"old_task_state": "spawning",
|
||||
"state": "active"
|
||||
}
|
||||
},
|
||||
"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:Node_0"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"event_type":"instance.delete.end",
|
||||
"payload":{
|
||||
"nova_object.data":{
|
||||
"architecture":"x86_64",
|
||||
"availability_zone":null,
|
||||
"created_at":"2012-10-29T13:42:11Z",
|
||||
"deleted_at":"2012-10-29T13:42:11Z",
|
||||
"display_name":"some-server",
|
||||
"fault":null,
|
||||
"host":"Node_0",
|
||||
"host_name":"some-server",
|
||||
"ip_addresses":[],
|
||||
"kernel_id":"",
|
||||
"launched_at":"2012-10-29T13:42:11Z",
|
||||
"image_uuid": "155d900f-4e14-4e4c-a73d-069cbf4541e6",
|
||||
"metadata":{},
|
||||
"node":"fake-mini",
|
||||
"os_type":null,
|
||||
"progress":0,
|
||||
"ramdisk_id":"",
|
||||
"reservation_id":"r-npxv0e40",
|
||||
"state":"deleted",
|
||||
"task_state":null,
|
||||
"power_state":"pending",
|
||||
"tenant_id":"6f70656e737461636b20342065766572",
|
||||
"terminated_at":"2012-10-29T13:42:11Z",
|
||||
"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":"73b09e16-35b7-4922-804e-e8f5d9b740fc"
|
||||
},
|
||||
"nova_object.name":"InstanceActionPayload",
|
||||
"nova_object.namespace":"nova",
|
||||
"nova_object.version":"1.0"
|
||||
},
|
||||
"priority":"INFO",
|
||||
"publisher_id":"nova-compute:Node_0"
|
||||
}
|
||||
@@ -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": "NEW_INSTANCE0",
|
||||
"host": "Node_0",
|
||||
"host_name": "NEW_INSTANCE0",
|
||||
"image_uuid": "155d900f-4e14-4e4c-a73d-069cbf4541e6",
|
||||
"kernel_id": "",
|
||||
"launched_at": null,
|
||||
"metadata": {},
|
||||
"node": "hostname_0",
|
||||
"old_display_name": null,
|
||||
"os_type": null,
|
||||
"progress": 0,
|
||||
"ramdisk_id": "",
|
||||
"reservation_id": "r-sd3ygfjj",
|
||||
"state": "paused",
|
||||
"task_state": "scheduling",
|
||||
"power_state": "pending",
|
||||
"ip_addresses": [],
|
||||
"state_update": {
|
||||
"nova_object.data": {
|
||||
"old_task_state": null,
|
||||
"new_task_state": null,
|
||||
"old_state": "paused",
|
||||
"state": "paused"},
|
||||
"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": "73b09e16-35b7-4922-804e-e8f5d9b740fc"},
|
||||
"nova_object.name": "InstanceUpdatePayload",
|
||||
"nova_object.namespace": "nova",
|
||||
"nova_object.version": "1.0"},
|
||||
"priority": "INFO",
|
||||
"publisher_id": "nova-compute:Node_0"
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"event_type": "compute.instance.create.end",
|
||||
"metadata": {
|
||||
"message_id": "577bfd11-88e0-4044-b8ae-496e3257efe2",
|
||||
"timestamp": "2016-08-19 10:20:59.279903"
|
||||
},
|
||||
"payload": {
|
||||
"access_ip_v4": null,
|
||||
"access_ip_v6": null,
|
||||
"architecture": null,
|
||||
"availability_zone": "nova",
|
||||
"cell_name": "",
|
||||
"created_at": "2016-08-19 10:20:49+00:00",
|
||||
"deleted_at": "",
|
||||
"disk_gb": 1,
|
||||
"display_name": "INSTANCE_0",
|
||||
"ephemeral_gb": 0,
|
||||
"fixed_ips": [
|
||||
{
|
||||
"address": "192.168.1.197",
|
||||
"floating_ips": [],
|
||||
"label": "demo-net",
|
||||
"meta": {},
|
||||
"type": "fixed",
|
||||
"version": 4,
|
||||
"vif_mac": "fa:16:3e:a3:c0:0f"
|
||||
}
|
||||
],
|
||||
"host": "Node_0",
|
||||
"hostname": "INSTANCE_0",
|
||||
"image_meta": {
|
||||
"base_image_ref": "205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"container_format": "bare",
|
||||
"disk_format": "qcow2",
|
||||
"min_disk": "1",
|
||||
"min_ram": "0"
|
||||
},
|
||||
"image_ref_url": "http://127.0.0.1:9292/images/205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"instance_flavor_id": "1",
|
||||
"instance_id": "c03c0bf9-f46e-4e4f-93f1-817568567ee2",
|
||||
"instance_type": "m1.tiny",
|
||||
"instance_type_id": 2,
|
||||
"kernel_id": "",
|
||||
"launched_at": "2016-08-19T10:20:59.135390",
|
||||
"memory_mb": 512,
|
||||
"message": "Success",
|
||||
"metadata": {},
|
||||
"node": "Node_0",
|
||||
"os_type": null,
|
||||
"progress": "",
|
||||
"ramdisk_id": "",
|
||||
"reservation_id": "r-56edz88e",
|
||||
"root_gb": 1,
|
||||
"state": "active",
|
||||
"state_description": "",
|
||||
"tenant_id": "57ab04ad6d3b495789a58258bc00842b",
|
||||
"terminated_at": "",
|
||||
"user_id": "cd7d93be51e4460ab51514b2a925b23a",
|
||||
"vcpus": 1
|
||||
},
|
||||
"publisher_id": "compute.Node_0"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"publisher_id": "compute:compute",
|
||||
"event_type": "compute.instance.delete.end",
|
||||
"payload": {
|
||||
"access_ip_v4": null,
|
||||
"access_ip_v6": null,
|
||||
"architecture": null,
|
||||
"availability_zone": "nova",
|
||||
"cell_name": "",
|
||||
"created_at": "2016-08-17 15:10:12+00:00",
|
||||
"deleted_at": "2016-08-17T15:10:33.000000",
|
||||
"disk_gb": 1,
|
||||
"display_name": "some-server",
|
||||
"ephemeral_gb": 0,
|
||||
"host": "Node_0",
|
||||
"hostname": "some-server",
|
||||
"image_meta": {
|
||||
"base_image_ref": "205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"container_format": "bare",
|
||||
"disk_format": "qcow2",
|
||||
"min_disk": "1",
|
||||
"min_ram": "0"
|
||||
},
|
||||
"image_ref_url": "http://10.50.254.222:9292/images/205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"instance_flavor_id": "1",
|
||||
"instance_id": "73b09e16-35b7-4922-804e-e8f5d9b740fc",
|
||||
"instance_type": "m1.tiny",
|
||||
"instance_type_id": 2,
|
||||
"kernel_id": "",
|
||||
"launched_at": "2016-08-17T15:10:23.000000",
|
||||
"memory_mb": 512,
|
||||
"metadata": {},
|
||||
"node": "Node_0",
|
||||
"os_type": null,
|
||||
"progress": "",
|
||||
"ramdisk_id": "",
|
||||
"reservation_id": "r-z76fnsyy",
|
||||
"root_gb": 1,
|
||||
"state": "deleted",
|
||||
"state_description": "",
|
||||
"tenant_id": "15995ea2694e4268b3631db32e38678b",
|
||||
"terminated_at": "2016-08-17T15:10:33.008164",
|
||||
"user_id": "cd7d93be51e4460ab51514b2a925b23a",
|
||||
"vcpus": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"publisher_id": "compute:Node_0",
|
||||
"event_type": "compute.instance.update",
|
||||
"payload": {
|
||||
"access_ip_v4": null,
|
||||
"access_ip_v6": null,
|
||||
"architecture": null,
|
||||
"audit_period_beginning": "2016-08-17T13:00:00.000000",
|
||||
"audit_period_ending": "2016-08-17T13:56:05.262440",
|
||||
"availability_zone": "nova",
|
||||
"bandwidth": {},
|
||||
"cell_name": "",
|
||||
"created_at": "2016-08-17 13:53:23+00:00",
|
||||
"deleted_at": "",
|
||||
"disk_gb": 1,
|
||||
"display_name": "NEW_INSTANCE0",
|
||||
"ephemeral_gb": 0,
|
||||
"host": "Node_0",
|
||||
"hostname": "NEW_INSTANCE0",
|
||||
"image_meta": {
|
||||
"base_image_ref": "205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"container_format": "bare",
|
||||
"disk_format": "qcow2",
|
||||
"min_disk": "1",
|
||||
"min_ram": "0"
|
||||
},
|
||||
"image_ref_url": "http://10.50.0.222:9292/images/205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"instance_flavor_id": "1",
|
||||
"instance_id": "73b09e16-35b7-4922-804e-e8f5d9b740fc",
|
||||
"instance_type": "m1.tiny",
|
||||
"instance_type_id": 2,
|
||||
"kernel_id": "",
|
||||
"launched_at": "2016-08-17T13:53:35.000000",
|
||||
"memory_mb": 512,
|
||||
"metadata": {},
|
||||
"new_task_state": null,
|
||||
"node": "hostname_0",
|
||||
"old_state": "paused",
|
||||
"old_task_state": null,
|
||||
"os_type": null,
|
||||
"progress": "",
|
||||
"ramdisk_id": "",
|
||||
"reservation_id": "r-0822ymml",
|
||||
"root_gb": 1,
|
||||
"state": "paused",
|
||||
"state_description": "paused",
|
||||
"tenant_id": "a4b4772d93c74d5e8b7c68cdd2a014e1",
|
||||
"terminated_at": "",
|
||||
"user_id": "ce64facc93354bbfa90f4f9f9a3e1e75",
|
||||
"vcpus": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"event_type": "compute.instance.live_migration.post.dest.end",
|
||||
"metadata": {
|
||||
"message_id": "9f58cad4-ff90-40f8-a8e4-633807f4a995",
|
||||
"timestamp": "2016-08-19 10:13:44.645575"
|
||||
},
|
||||
"payload": {
|
||||
"access_ip_v4": null,
|
||||
"access_ip_v6": null,
|
||||
"architecture": null,
|
||||
"availability_zone": "nova",
|
||||
"cell_name": "",
|
||||
"created_at": "2016-08-18 09:49:23+00:00",
|
||||
"deleted_at": "",
|
||||
"disk_gb": 1,
|
||||
"display_name": "INSTANCE_0",
|
||||
"ephemeral_gb": 0,
|
||||
"fixed_ips": [
|
||||
{
|
||||
"address": "192.168.1.196",
|
||||
"floating_ips": [],
|
||||
"label": "demo-net",
|
||||
"meta": {},
|
||||
"type": "fixed",
|
||||
"version": 4,
|
||||
"vif_mac": "fa:16:3e:cc:ba:81"
|
||||
}
|
||||
],
|
||||
"host": "Node_1",
|
||||
"hostname": "INSTANCE_0",
|
||||
"image_meta": {
|
||||
"base_image_ref": "205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"container_format": "bare",
|
||||
"disk_format": "qcow2",
|
||||
"min_disk": "1",
|
||||
"min_ram": "0"
|
||||
},
|
||||
"image_ref_url": "http://10.50.254.222:9292/images/205f96f5-91f9-42eb-9138-03fffcea2b97",
|
||||
"instance_flavor_id": "1",
|
||||
"instance_id": "73b09e16-35b7-4922-804e-e8f5d9b740fc",
|
||||
"instance_type": "m1.tiny",
|
||||
"instance_type_id": 2,
|
||||
"kernel_id": "",
|
||||
"launched_at": "2016-08-18T09:49:33.000000",
|
||||
"memory_mb": 512,
|
||||
"metadata": {},
|
||||
"node": "Node_1",
|
||||
"os_type": null,
|
||||
"progress": "",
|
||||
"ramdisk_id": "",
|
||||
"reservation_id": "r-he04tfco",
|
||||
"root_gb": 1,
|
||||
"state": "active",
|
||||
"state_description": "",
|
||||
"tenant_id": "57ab04ad6d3b495789a58258bc00842b",
|
||||
"terminated_at": "",
|
||||
"user_id": "cd7d93be51e4460ab51514b2a925b23a",
|
||||
"vcpus": 1
|
||||
},
|
||||
"publisher_id": "compute.Node_1"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"priority": "INFO",
|
||||
"payload": {
|
||||
"nova_object.namespace": "nova",
|
||||
"nova_object.name": "ServiceStatusPayload",
|
||||
"nova_object.version": "1.0",
|
||||
"nova_object.data": {
|
||||
"host": "Node_0",
|
||||
"disabled": true,
|
||||
"last_seen_up": "2012-10-29T13:42:05Z",
|
||||
"binary": "nova-compute",
|
||||
"topic": "compute",
|
||||
"disabled_reason": null,
|
||||
"report_count": 1,
|
||||
"forced_down": true,
|
||||
"version": 15
|
||||
}
|
||||
},
|
||||
"event_type": "service.update",
|
||||
"publisher_id": "nova-compute:Node_0"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"priority": "INFO",
|
||||
"payload": {
|
||||
"nova_object.namespace": "nova",
|
||||
"nova_object.name": "ServiceStatusPayload",
|
||||
"nova_object.version": "1.0",
|
||||
"nova_object.data": {
|
||||
"host": "host1",
|
||||
"disabled": false,
|
||||
"last_seen_up": "2012-10-29T13:42:05Z",
|
||||
"binary": "nova-compute",
|
||||
"topic": "compute",
|
||||
"disabled_reason": null,
|
||||
"report_count": 1,
|
||||
"forced_down": false,
|
||||
"version": 15
|
||||
}
|
||||
},
|
||||
"event_type": "service.update",
|
||||
"publisher_id": "nova-compute:host1"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# Authors: Vincent FRANCOISE <vincent.francoise@b-com.com>
|
||||
#
|
||||
# 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 watcher.decision_engine.model.notification import nova as novanotification
|
||||
from watcher.tests.decision_engine.strategy.strategies \
|
||||
import faker_cluster_state
|
||||
|
||||
|
||||
class FakeManager(object):
|
||||
|
||||
API_VERSION = '1.0'
|
||||
|
||||
def __init__(self):
|
||||
self.api_version = self.API_VERSION
|
||||
|
||||
# fake cluster instead on Nova CDM
|
||||
self.fake_cdmc = faker_cluster_state.FakerModelCollector()
|
||||
|
||||
self.publisher_id = 'test_publisher_id'
|
||||
self.conductor_topic = 'test_conductor_topic'
|
||||
self.status_topic = 'test_status_topic'
|
||||
self.notification_topics = ['nova']
|
||||
|
||||
self.conductor_endpoints = [] # Disable audit endpoint
|
||||
self.status_endpoints = []
|
||||
|
||||
self.notification_endpoints = [
|
||||
novanotification.ServiceUpdated(self.fake_cdmc),
|
||||
|
||||
novanotification.InstanceCreated(self.fake_cdmc),
|
||||
novanotification.InstanceUpdated(self.fake_cdmc),
|
||||
novanotification.InstanceDeletedEnd(self.fake_cdmc),
|
||||
|
||||
novanotification.LegacyInstanceCreatedEnd(self.fake_cdmc),
|
||||
novanotification.LegacyInstanceUpdated(self.fake_cdmc),
|
||||
novanotification.LegacyLiveMigratedEnd(self.fake_cdmc),
|
||||
novanotification.LegacyInstanceDeletedEnd(self.fake_cdmc),
|
||||
]
|
||||
@@ -0,0 +1,106 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# Authors: Vincent FRANCOISE <vincent.francoise@b-com.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from watcher.common import context
|
||||
from watcher.common import service as watcher_service
|
||||
from watcher.decision_engine.model.notification import base
|
||||
from watcher.decision_engine.model.notification import filtering
|
||||
from watcher.tests import base as base_test
|
||||
from watcher.tests.decision_engine.model.notification import fake_managers
|
||||
|
||||
|
||||
class DummyManager(fake_managers.FakeManager):
|
||||
|
||||
def __init__(self):
|
||||
super(DummyManager, self).__init__()
|
||||
self.notification_endpoints = [DummyNotification(self.fake_cdmc)]
|
||||
|
||||
|
||||
class DummyNotification(base.NotificationEndpoint):
|
||||
|
||||
@property
|
||||
def filter_rule(self):
|
||||
return filtering.NotificationFilter(
|
||||
publisher_id=r'.*',
|
||||
event_type=r'compute.dummy',
|
||||
payload={'data': {'nested': r'^T.*'}},
|
||||
)
|
||||
|
||||
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||
pass
|
||||
|
||||
|
||||
class NotificationTestCase(base_test.TestCase):
|
||||
|
||||
def load_message(self, filename):
|
||||
cwd = os.path.abspath(os.path.dirname(__file__))
|
||||
data_folder = os.path.join(cwd, "data")
|
||||
|
||||
with open(os.path.join(data_folder, filename), 'rb') as json_file:
|
||||
json_data = jsonutils.load(json_file)
|
||||
|
||||
return json_data
|
||||
|
||||
|
||||
class TestReceiveNotifications(NotificationTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestReceiveNotifications, self).setUp()
|
||||
|
||||
p_from_dict = mock.patch.object(context.RequestContext, 'from_dict')
|
||||
m_from_dict = p_from_dict.start()
|
||||
m_from_dict.return_value = self.context
|
||||
self.addCleanup(p_from_dict.stop)
|
||||
|
||||
@mock.patch.object(DummyNotification, 'info')
|
||||
def test_receive_dummy_notification(self, m_info):
|
||||
message = {
|
||||
'publisher_id': 'nova-compute',
|
||||
'event_type': 'compute.dummy',
|
||||
'payload': {'data': {'nested': 'TEST'}},
|
||||
'priority': 'INFO',
|
||||
}
|
||||
de_service = watcher_service.Service(DummyManager)
|
||||
incoming = mock.Mock(ctxt=self.context.to_dict(), message=message)
|
||||
|
||||
de_service.notification_handler.dispatcher.dispatch(incoming)
|
||||
|
||||
m_info.assert_called_once_with(
|
||||
self.context, 'nova-compute', 'compute.dummy',
|
||||
{'data': {'nested': 'TEST'}},
|
||||
{'message_id': None, 'timestamp': None})
|
||||
|
||||
@mock.patch.object(DummyNotification, 'info')
|
||||
def test_skip_unwanted_notification(self, m_info):
|
||||
message = {
|
||||
'publisher_id': 'nova-compute',
|
||||
'event_type': 'compute.dummy',
|
||||
'payload': {'data': {'nested': 'unwanted'}},
|
||||
'priority': 'INFO',
|
||||
}
|
||||
de_service = watcher_service.Service(DummyManager)
|
||||
incoming = mock.Mock(ctxt=self.context.to_dict(), message=message)
|
||||
|
||||
de_service.notification_handler.dispatcher.dispatch(incoming)
|
||||
|
||||
self.assertEqual(0, m_info.call_count)
|
||||
@@ -0,0 +1,450 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# Authors: Vincent FRANCOISE <vincent.francoise@b-com.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from watcher.common import context
|
||||
from watcher.common import exception
|
||||
from watcher.common import service as watcher_service
|
||||
from watcher.decision_engine.model import element
|
||||
from watcher.decision_engine.model import model_root
|
||||
from watcher.decision_engine.model.notification import nova as novanotification
|
||||
from watcher.tests import base as base_test
|
||||
from watcher.tests.decision_engine.model.notification import fake_managers
|
||||
from watcher.tests.decision_engine.strategy.strategies \
|
||||
import faker_cluster_state
|
||||
|
||||
|
||||
class NotificationTestCase(base_test.TestCase):
|
||||
|
||||
def load_message(self, filename):
|
||||
cwd = os.path.abspath(os.path.dirname(__file__))
|
||||
data_folder = os.path.join(cwd, "data")
|
||||
|
||||
with open(os.path.join(data_folder, filename), 'rb') as json_file:
|
||||
json_data = jsonutils.load(json_file)
|
||||
|
||||
return json_data
|
||||
|
||||
|
||||
class TestReceiveNovaNotifications(NotificationTestCase):
|
||||
|
||||
FAKE_METADATA = {'message_id': None, 'timestamp': None}
|
||||
|
||||
def setUp(self):
|
||||
super(TestReceiveNovaNotifications, self).setUp()
|
||||
|
||||
p_from_dict = mock.patch.object(context.RequestContext, 'from_dict')
|
||||
m_from_dict = p_from_dict.start()
|
||||
m_from_dict.return_value = self.context
|
||||
self.addCleanup(p_from_dict.stop)
|
||||
|
||||
@mock.patch.object(novanotification.ServiceUpdated, 'info')
|
||||
def test_nova_receive_service_update(self, m_info):
|
||||
message = self.load_message('service-update.json')
|
||||
expected_message = message['payload']
|
||||
|
||||
de_service = watcher_service.Service(fake_managers.FakeManager)
|
||||
incoming = mock.Mock(ctxt=self.context.to_dict(), message=message)
|
||||
|
||||
de_service.notification_handler.dispatcher.dispatch(incoming)
|
||||
m_info.assert_called_once_with(
|
||||
self.context, 'nova-compute:host1', 'service.update',
|
||||
expected_message, self.FAKE_METADATA)
|
||||
|
||||
@mock.patch.object(novanotification.InstanceCreated, 'info')
|
||||
def test_nova_receive_instance_create(self, m_info):
|
||||
message = self.load_message('instance-create.json')
|
||||
expected_message = message['payload']
|
||||
|
||||
de_service = watcher_service.Service(fake_managers.FakeManager)
|
||||
incoming = mock.Mock(ctxt=self.context.to_dict(), message=message)
|
||||
|
||||
de_service.notification_handler.dispatcher.dispatch(incoming)
|
||||
m_info.assert_called_once_with(
|
||||
self.context, 'nova-compute:compute', 'instance.update',
|
||||
expected_message, self.FAKE_METADATA)
|
||||
|
||||
@mock.patch.object(novanotification.InstanceUpdated, 'info')
|
||||
def test_nova_receive_instance_update(self, m_info):
|
||||
message = self.load_message('instance-update.json')
|
||||
expected_message = message['payload']
|
||||
|
||||
de_service = watcher_service.Service(fake_managers.FakeManager)
|
||||
incoming = mock.Mock(ctxt=self.context.to_dict(), message=message)
|
||||
|
||||
de_service.notification_handler.dispatcher.dispatch(incoming)
|
||||
m_info.assert_called_once_with(
|
||||
self.context, 'nova-compute:compute', 'instance.update',
|
||||
expected_message, self.FAKE_METADATA)
|
||||
|
||||
@mock.patch.object(novanotification.InstanceDeletedEnd, 'info')
|
||||
def test_nova_receive_instance_delete_end(self, m_info):
|
||||
message = self.load_message('instance-delete-end.json')
|
||||
expected_message = message['payload']
|
||||
|
||||
de_service = watcher_service.Service(fake_managers.FakeManager)
|
||||
incoming = mock.Mock(ctxt=self.context.to_dict(), message=message)
|
||||
|
||||
de_service.notification_handler.dispatcher.dispatch(incoming)
|
||||
m_info.assert_called_once_with(
|
||||
self.context, 'nova-compute:compute', 'instance.delete.end',
|
||||
expected_message, self.FAKE_METADATA)
|
||||
|
||||
|
||||
class TestNovaNotifications(NotificationTestCase):
|
||||
|
||||
FAKE_METADATA = {'message_id': None, 'timestamp': None}
|
||||
|
||||
def setUp(self):
|
||||
super(TestNovaNotifications, self).setUp()
|
||||
# fake cluster
|
||||
self.fake_cdmc = faker_cluster_state.FakerModelCollector()
|
||||
|
||||
def test_nova_service_update(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.ServiceUpdated(self.fake_cdmc)
|
||||
|
||||
node0_uuid = 'Node_0'
|
||||
node0 = compute_model.get_node_from_id(node0_uuid)
|
||||
|
||||
message = self.load_message('scenario3_service-update.json')
|
||||
|
||||
self.assertEqual('hostname_0', node0.hostname)
|
||||
self.assertEqual(element.ServiceState.ONLINE.value, node0.state)
|
||||
self.assertEqual(element.ServiceState.ENABLED.value, node0.status)
|
||||
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
self.assertEqual('Node_0', node0.hostname)
|
||||
self.assertEqual(element.ServiceState.OFFLINE.value, node0.state)
|
||||
self.assertEqual(element.ServiceState.DISABLED.value, node0.status)
|
||||
|
||||
def test_nova_instance_update(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.InstanceUpdated(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
|
||||
message = self.load_message('scenario3_instance-update.json')
|
||||
|
||||
self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state)
|
||||
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
self.assertEqual(element.InstanceState.PAUSED.value, instance0.state)
|
||||
|
||||
def test_nova_instance_update_notfound_creates(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.InstanceUpdated(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
|
||||
message = self.load_message('scenario3_instance-update.json')
|
||||
|
||||
with mock.patch.object(
|
||||
model_root.ModelRoot, 'get_instance_from_id'
|
||||
) as m_get_instance_from_id:
|
||||
m_get_instance_from_id.side_effect = exception.InstanceNotFound(
|
||||
name='TEST')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
cpu_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.cpu_cores)
|
||||
disk_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.disk)
|
||||
memory_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.memory)
|
||||
|
||||
self.assertEqual(element.InstanceState.PAUSED.value, instance0.state)
|
||||
self.assertEqual(1, cpu_capacity.get_capacity(instance0))
|
||||
self.assertEqual(1, disk_capacity.get_capacity(instance0))
|
||||
self.assertEqual(512, memory_capacity.get_capacity(instance0))
|
||||
|
||||
def test_nova_instance_create(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.InstanceCreated(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = 'c03c0bf9-f46e-4e4f-93f1-817568567ee2'
|
||||
|
||||
self.assertRaises(
|
||||
exception.InstanceNotFound,
|
||||
compute_model.get_instance_from_id, instance0_uuid)
|
||||
|
||||
message = self.load_message('scenario3_instance-create.json')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
cpu_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.cpu_cores)
|
||||
disk_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.disk)
|
||||
memory_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.memory)
|
||||
|
||||
self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state)
|
||||
self.assertEqual(1, cpu_capacity.get_capacity(instance0))
|
||||
self.assertEqual(1, disk_capacity.get_capacity(instance0))
|
||||
self.assertEqual(512, memory_capacity.get_capacity(instance0))
|
||||
|
||||
def test_nova_instance_delete_end(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.InstanceDeletedEnd(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
|
||||
# Before
|
||||
self.assertTrue(compute_model.get_instance_from_id(instance0_uuid))
|
||||
for resource in compute_model.resource.values():
|
||||
self.assertIn(instance0_uuid, resource.mapping)
|
||||
|
||||
message = self.load_message('scenario3_instance-delete-end.json')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
# After
|
||||
self.assertRaises(
|
||||
exception.InstanceNotFound,
|
||||
compute_model.get_instance_from_id, instance0_uuid)
|
||||
|
||||
for resource in compute_model.resource.values():
|
||||
self.assertNotIn(instance0_uuid, resource.mapping)
|
||||
|
||||
|
||||
class TestLegacyNovaNotifications(NotificationTestCase):
|
||||
|
||||
FAKE_METADATA = {'message_id': None, 'timestamp': None}
|
||||
|
||||
def setUp(self):
|
||||
super(TestLegacyNovaNotifications, self).setUp()
|
||||
# fake cluster
|
||||
self.fake_cdmc = faker_cluster_state.FakerModelCollector()
|
||||
|
||||
def test_legacy_instance_created_end(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.LegacyInstanceCreatedEnd(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = 'c03c0bf9-f46e-4e4f-93f1-817568567ee2'
|
||||
self.assertRaises(
|
||||
exception.InstanceNotFound,
|
||||
compute_model.get_instance_from_id, instance0_uuid)
|
||||
|
||||
message = self.load_message(
|
||||
'scenario3_legacy_instance-create-end.json')
|
||||
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
cpu_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.cpu_cores)
|
||||
disk_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.disk)
|
||||
memory_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.memory)
|
||||
|
||||
self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state)
|
||||
self.assertEqual(1, cpu_capacity.get_capacity(instance0))
|
||||
self.assertEqual(1, disk_capacity.get_capacity(instance0))
|
||||
self.assertEqual(512, memory_capacity.get_capacity(instance0))
|
||||
|
||||
def test_legacy_instance_updated(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.LegacyInstanceUpdated(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
|
||||
message = self.load_message('scenario3_legacy_instance-update.json')
|
||||
|
||||
self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state)
|
||||
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
self.assertEqual(element.InstanceState.PAUSED.value, instance0.state)
|
||||
|
||||
def test_legacy_instance_update_notfound_creates(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.LegacyInstanceUpdated(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
|
||||
message = self.load_message('scenario3_legacy_instance-update.json')
|
||||
|
||||
with mock.patch.object(
|
||||
model_root.ModelRoot, 'get_instance_from_id'
|
||||
) as m_get_instance_from_id:
|
||||
m_get_instance_from_id.side_effect = exception.InstanceNotFound(
|
||||
name='TEST')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
self.assertEqual(element.InstanceState.PAUSED.value, instance0.state)
|
||||
|
||||
def test_legacy_instance_update_node_notfound_stil_creates(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.LegacyInstanceUpdated(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
|
||||
message = self.load_message('scenario3_legacy_instance-update.json')
|
||||
|
||||
with mock.patch.object(
|
||||
model_root.ModelRoot, 'get_instance_from_id'
|
||||
) as m_get_instance_from_id:
|
||||
m_get_instance_from_id.side_effect = exception.InstanceNotFound(
|
||||
name='TEST')
|
||||
with mock.patch.object(
|
||||
model_root.ModelRoot, 'get_node_from_id'
|
||||
) as m_get_node_from_id:
|
||||
m_get_node_from_id.side_effect = exception.ComputeNodeNotFound(
|
||||
name='TEST')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
cpu_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.cpu_cores)
|
||||
disk_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.disk)
|
||||
memory_capacity = compute_model.get_resource_from_id(
|
||||
element.ResourceType.memory)
|
||||
|
||||
self.assertEqual(element.InstanceState.PAUSED.value, instance0.state)
|
||||
self.assertEqual(1, cpu_capacity.get_capacity(instance0))
|
||||
self.assertEqual(1, disk_capacity.get_capacity(instance0))
|
||||
self.assertEqual(512, memory_capacity.get_capacity(instance0))
|
||||
|
||||
def test_legacy_live_migrated_end(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.LegacyLiveMigratedEnd(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
instance0 = compute_model.get_instance_from_id(instance0_uuid)
|
||||
|
||||
node = compute_model.get_node_from_instance_id(instance0_uuid)
|
||||
self.assertEqual('Node_0', node.uuid)
|
||||
|
||||
message = self.load_message(
|
||||
'scenario3_legacy_livemigration-post-dest-end.json')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
node = compute_model.get_node_from_instance_id(instance0_uuid)
|
||||
self.assertEqual('Node_1', node.uuid)
|
||||
self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state)
|
||||
|
||||
def test_legacy_instance_deleted_end(self):
|
||||
compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes()
|
||||
self.fake_cdmc.cluster_data_model = compute_model
|
||||
handler = novanotification.LegacyInstanceDeletedEnd(self.fake_cdmc)
|
||||
|
||||
instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc'
|
||||
|
||||
# Before
|
||||
self.assertTrue(compute_model.get_instance_from_id(instance0_uuid))
|
||||
for resource in compute_model.resource.values():
|
||||
self.assertIn(instance0_uuid, resource.mapping)
|
||||
|
||||
message = self.load_message(
|
||||
'scenario3_legacy_instance-delete-end.json')
|
||||
handler.info(
|
||||
ctxt=self.context,
|
||||
publisher_id=message['publisher_id'],
|
||||
event_type=message['event_type'],
|
||||
payload=message['payload'],
|
||||
metadata=self.FAKE_METADATA,
|
||||
)
|
||||
|
||||
# After
|
||||
self.assertRaises(
|
||||
exception.InstanceNotFound,
|
||||
compute_model.get_instance_from_id, instance0_uuid)
|
||||
|
||||
for resource in compute_model.resource.values():
|
||||
self.assertNotIn(instance0_uuid, resource.mapping)
|
||||
@@ -80,16 +80,16 @@ class TestMapping(base.TestCase):
|
||||
|
||||
self.assertEqual(
|
||||
False,
|
||||
model.mapping.migrate_instance(instance1, node1, node1))
|
||||
model.migrate_instance(instance1, node1, node1))
|
||||
self.assertEqual(
|
||||
False,
|
||||
model.mapping.migrate_instance(instance1, node0, node0))
|
||||
model.migrate_instance(instance1, node0, node0))
|
||||
self.assertEqual(
|
||||
True,
|
||||
model.mapping.migrate_instance(instance1, node1, node0))
|
||||
model.migrate_instance(instance1, node1, node0))
|
||||
self.assertEqual(
|
||||
True,
|
||||
model.mapping.migrate_instance(instance1, node0, node1))
|
||||
model.migrate_instance(instance1, node0, node1))
|
||||
|
||||
def test_unmap_from_id_log_warning(self):
|
||||
model = self.fake_cluster.generate_scenario_3_with_2_nodes()
|
||||
|
||||
@@ -73,11 +73,11 @@ class TestModel(base.TestCase):
|
||||
node.uuid = id_
|
||||
model.add_node(node)
|
||||
|
||||
self.assertIsInstance(node.state, element.ServiceState)
|
||||
self.assertIn(node.state, [el.value for el in element.ServiceState])
|
||||
|
||||
node = model.get_node_from_id(id_)
|
||||
node.state = element.ServiceState.OFFLINE
|
||||
self.assertIsInstance(node.state, element.ServiceState)
|
||||
node.state = element.ServiceState.OFFLINE.value
|
||||
self.assertIn(node.state, [el.value for el in element.ServiceState])
|
||||
|
||||
def test_node_from_id_raise(self):
|
||||
model = model_root.ModelRoot()
|
||||
|
||||
@@ -31,6 +31,10 @@ class FakerModelCollector(base.BaseClusterDataModelCollector):
|
||||
config = mock.Mock()
|
||||
super(FakerModelCollector, self).__init__(config)
|
||||
|
||||
@property
|
||||
def notification_endpoints(self):
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
return self.generate_scenario_1()
|
||||
|
||||
|
||||
@@ -30,8 +30,12 @@ class FakerModelCollector(base.BaseClusterDataModelCollector):
|
||||
config = mock.Mock(period=777)
|
||||
super(FakerModelCollector, self).__init__(config)
|
||||
|
||||
@property
|
||||
def notification_endpoints(self):
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
return self.generate_scenario_1()
|
||||
return self._cluster_data_model or self.generate_scenario_1()
|
||||
|
||||
def generate_scenario_1(self):
|
||||
instances = []
|
||||
|
||||
@@ -95,10 +95,12 @@ class TestUniformAirflow(base.TestCase):
|
||||
self.strategy.threshold_inlet_t = 22
|
||||
n1, n2 = self.strategy.group_hosts_by_airflow()
|
||||
instance_to_mig = self.strategy.choose_instance_to_migrate(n1)
|
||||
|
||||
self.assertEqual(instance_to_mig[0].uuid, 'Node_0')
|
||||
self.assertEqual(len(instance_to_mig[1]), 1)
|
||||
self.assertEqual(instance_to_mig[1][0].uuid,
|
||||
"cae81432-1631-4d4e-b29c-6f3acdcde906")
|
||||
self.assertIn(instance_to_mig[1][0].uuid,
|
||||
{'cae81432-1631-4d4e-b29c-6f3acdcde906',
|
||||
'73b09e16-35b7-4922-804e-e8f5d9b740fc'})
|
||||
|
||||
def test_choose_instance_to_migrate_all(self):
|
||||
model = self.fake_cluster.generate_scenario_7_with_2_nodes()
|
||||
@@ -107,10 +109,12 @@ class TestUniformAirflow(base.TestCase):
|
||||
self.strategy.threshold_inlet_t = 25
|
||||
n1, n2 = self.strategy.group_hosts_by_airflow()
|
||||
instance_to_mig = self.strategy.choose_instance_to_migrate(n1)
|
||||
|
||||
self.assertEqual(instance_to_mig[0].uuid, 'Node_0')
|
||||
self.assertEqual(len(instance_to_mig[1]), 2)
|
||||
self.assertEqual(instance_to_mig[1][1].uuid,
|
||||
"73b09e16-35b7-4922-804e-e8f5d9b740fc")
|
||||
self.assertEqual({'cae81432-1631-4d4e-b29c-6f3acdcde906',
|
||||
'73b09e16-35b7-4922-804e-e8f5d9b740fc'},
|
||||
{inst.uuid for inst in instance_to_mig[1]})
|
||||
|
||||
def test_choose_instance_notfound(self):
|
||||
model = self.fake_cluster.generate_scenario_7_with_2_nodes()
|
||||
@@ -132,10 +136,12 @@ class TestUniformAirflow(base.TestCase):
|
||||
instance_to_mig = self.strategy.choose_instance_to_migrate(n1)
|
||||
dest_hosts = self.strategy.filter_destination_hosts(
|
||||
n2, instance_to_mig[1])
|
||||
|
||||
self.assertEqual(len(dest_hosts), 1)
|
||||
self.assertEqual(dest_hosts[0]['node'].uuid, 'Node_1')
|
||||
self.assertEqual(dest_hosts[0]['instance'].uuid,
|
||||
'cae81432-1631-4d4e-b29c-6f3acdcde906')
|
||||
self.assertIn(instance_to_mig[1][0].uuid,
|
||||
{'cae81432-1631-4d4e-b29c-6f3acdcde906',
|
||||
'73b09e16-35b7-4922-804e-e8f5d9b740fc'})
|
||||
|
||||
def test_exception_model(self):
|
||||
self.m_model.return_value = None
|
||||
|
||||
Reference in New Issue
Block a user