summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-20 08:42:04 +0000
committerGerrit Code Review <review@openstack.org>2013-02-20 08:42:04 +0000
commitad325523968a89db74d649553ccd8bb53908899a (patch)
tree9f47778ae2c5845b0408e6931385e29d6d4178ea /nova/tests
parent22a1cb330c63b82bf9bd4a1bb9649ed0143de961 (diff)
parentd63f7c1b47509f31c1e5aa8d27392d7f83e6dad2 (diff)
Merge "Add support for lifecycle events in the libvirt driver"
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/fakelibvirt.py38
-rw-r--r--nova/tests/test_libvirt.py84
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):