diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-02-20 08:42:04 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-02-20 08:42:04 +0000 |
| commit | ad325523968a89db74d649553ccd8bb53908899a (patch) | |
| tree | 9f47778ae2c5845b0408e6931385e29d6d4178ea /nova/tests | |
| parent | 22a1cb330c63b82bf9bd4a1bb9649ed0143de961 (diff) | |
| parent | d63f7c1b47509f31c1e5aa8d27392d7f83e6dad2 (diff) | |
Merge "Add support for lifecycle events in the libvirt driver"
Diffstat (limited to 'nova/tests')
| -rw-r--r-- | nova/tests/fakelibvirt.py | 38 | ||||
| -rw-r--r-- | nova/tests/test_libvirt.py | 84 |
2 files changed, 121 insertions, 1 deletions
diff --git a/nova/tests/fakelibvirt.py b/nova/tests/fakelibvirt.py index 6abe7771c..69a4e677e 100644 --- a/nova/tests/fakelibvirt.py +++ b/nova/tests/fakelibvirt.py @@ -70,6 +70,17 @@ VIR_DOMAIN_CRASHED = 6 VIR_DOMAIN_XML_SECURE = 1 +VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0 + +VIR_DOMAIN_EVENT_DEFINED = 0 +VIR_DOMAIN_EVENT_UNDEFINED = 1 +VIR_DOMAIN_EVENT_STARTED = 2 +VIR_DOMAIN_EVENT_SUSPENDED = 3 +VIR_DOMAIN_EVENT_RESUMED = 4 +VIR_DOMAIN_EVENT_STOPPED = 5 +VIR_DOMAIN_EVENT_SHUTDOWN = 6 +VIR_DOMAIN_EVENT_PMSUSPENDED = 7 + VIR_DOMAIN_UNDEFINE_MANAGED_SAVE = 1 VIR_DOMAIN_AFFECT_CURRENT = 0 @@ -506,6 +517,7 @@ class Connection(object): self._running_vms = {} self._id_counter = 1 # libvirt reserves 0 for the hypervisor. self._nwfilters = {} + self._event_callbacks = {} self.fakeLibVersion = version self.fakeVersion = version @@ -517,6 +529,7 @@ class Connection(object): def _mark_running(self, dom): self._running_vms[self._id_counter] = dom + self._emit_lifecycle(dom, VIR_DOMAIN_EVENT_STARTED, 0) self._id_counter += 1 def _mark_not_running(self, dom): @@ -528,10 +541,13 @@ class Connection(object): for (k, v) in self._running_vms.iteritems(): if v == dom: del self._running_vms[k] + self._emit_lifecycle(dom, VIR_DOMAIN_EVENT_STOPPED, 0) return def _undefine(self, dom): del self._vms[dom.name()] + if not dom._transient: + self._emit_lifecycle(dom, VIR_DOMAIN_EVENT_UNDEFINED, 0) def getInfo(self): return [node_arch, @@ -563,14 +579,25 @@ class Connection(object): 'name "%s"' % name, VIR_ERR_NO_DOMAIN, VIR_FROM_QEMU) + def _emit_lifecycle(self, dom, event, detail): + if VIR_DOMAIN_EVENT_ID_LIFECYCLE not in self._event_callbacks: + return + + cbinfo = self._event_callbacks[VIR_DOMAIN_EVENT_ID_LIFECYCLE] + callback = cbinfo[0] + opaque = cbinfo[1] + callback(self, dom, event, detail, opaque) + def defineXML(self, xml): dom = Domain(connection=self, running=False, transient=False, xml=xml) self._vms[dom.name()] = dom + self._emit_lifecycle(dom, VIR_DOMAIN_EVENT_DEFINED, 0) return dom def createXML(self, xml, flags): dom = Domain(connection=self, running=True, transient=True, xml=xml) self._vms[dom.name()] = dom + self._emit_lifecycle(dom, VIR_DOMAIN_EVENT_STARTED, 0) return dom def getType(self): @@ -586,6 +613,9 @@ class Connection(object): def getHostname(self): return 'compute1' + def domainEventRegisterAny(self, dom, eventid, callback, opaque): + self._event_callbacks[eventid] = [callback, opaque] + def getCapabilities(self): return '''<capabilities> <host> @@ -875,6 +905,14 @@ def openAuth(uri, auth, flags): return Connection(uri, readonly=False) +def virEventRunDefaultImpl(): + time.sleep(1) + + +def virEventRegisterDefaultImpl(): + pass + + virDomain = Domain diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 8ac74aabd..abb2b0c20 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -53,6 +53,7 @@ from nova import utils from nova import version from nova.virt.disk import api as disk from nova.virt import driver +from nova.virt import event as virtevent from nova.virt import fake from nova.virt import firewall as base_firewall from nova.virt import images @@ -100,7 +101,8 @@ class FakeVirDomainSnapshot(object): class FakeVirtDomain(object): - def __init__(self, fake_xml=None): + def __init__(self, fake_xml=None, uuidstr=None): + self.uuidstr = uuidstr if fake_xml: self._fake_dom_xml = fake_xml else: @@ -132,6 +134,9 @@ class FakeVirtDomain(object): def XMLDesc(self, *args): return self._fake_dom_xml + def UUIDString(self): + return self.uuidstr + class CacheConcurrencyTestCase(test.TestCase): def setUp(self): @@ -3350,6 +3355,83 @@ class LibvirtConnTestCase(test.TestCase): got = conn.get_instance_capabilities() self.assertEqual(want, got) + def test_event_dispatch(self): + # Validate that the libvirt self-pipe for forwarding + # events between threads is working sanely + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + got_events = [] + + def handler(event): + got_events.append(event) + + conn.register_event_listener(handler) + + conn._init_events_pipe() + + event1 = virtevent.LifecycleEvent( + "cef19ce0-0ca2-11df-855d-b19fbce37686", + virtevent.EVENT_LIFECYCLE_STARTED) + event2 = virtevent.LifecycleEvent( + "cef19ce0-0ca2-11df-855d-b19fbce37686", + virtevent.EVENT_LIFECYCLE_PAUSED) + conn._queue_event(event1) + conn._queue_event(event2) + conn._dispatch_events() + + want_events = [event1, event2] + self.assertEqual(want_events, got_events) + + event3 = virtevent.LifecycleEvent( + "cef19ce0-0ca2-11df-855d-b19fbce37686", + virtevent.EVENT_LIFECYCLE_RESUMED) + event4 = virtevent.LifecycleEvent( + "cef19ce0-0ca2-11df-855d-b19fbce37686", + virtevent.EVENT_LIFECYCLE_STOPPED) + + conn._queue_event(event3) + conn._queue_event(event4) + conn._dispatch_events() + + want_events = [event1, event2, event3, event4] + self.assertEqual(want_events, got_events) + + def test_event_lifecycle(self): + # Validate that libvirt events are correctly translated + # to Nova events + conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) + got_events = [] + + def handler(event): + got_events.append(event) + + conn.register_event_listener(handler) + conn._init_events_pipe() + fake_dom_xml = """ + <domain type='kvm'> + <uuid>cef19ce0-0ca2-11df-855d-b19fbce37686</uuid> + <devices> + <disk type='file'> + <source file='filename'/> + </disk> + </devices> + </domain> + """ + dom = FakeVirtDomain(fake_dom_xml, + "cef19ce0-0ca2-11df-855d-b19fbce37686") + + conn._event_lifecycle_callback(conn._conn, + dom, + libvirt.VIR_DOMAIN_EVENT_STOPPED, + 0, + conn) + conn._dispatch_events() + self.assertEqual(len(got_events), 1) + self.assertEqual(type(got_events[0]), virtevent.LifecycleEvent) + self.assertEqual(got_events[0].uuid, + "cef19ce0-0ca2-11df-855d-b19fbce37686") + self.assertEqual(got_events[0].transition, + virtevent.EVENT_LIFECYCLE_STOPPED) + class HostStateTestCase(test.TestCase): |
