summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-08-19 00:13:27 +0000
committerGerrit Code Review <review@openstack.org>2014-08-19 00:13:27 +0000
commit8f0e58aff9d5e52e0567910738d685ccc2dc7b52 (patch)
treef7f49dfb31125f6cf6e481dc7affe4ea72ce0025
parent5bd3276a80cc5b2857e019ad747ed3abbe223017 (diff)
parent6484fc6f0f4c8a67192804592150ef0185f6a7cc (diff)
downloadnova-8f0e58aff9d5e52e0567910738d685ccc2dc7b52.tar.gz
Merge "Fix bug with not implemented virConnect.registerCloseCallback" into stable/havana
-rw-r--r--nova/tests/virt/libvirt/fakelibvirt.py3
-rw-r--r--nova/tests/virt/libvirt/test_libvirt.py98
-rw-r--r--nova/virt/libvirt/driver.py31
3 files changed, 103 insertions, 29 deletions
diff --git a/nova/tests/virt/libvirt/fakelibvirt.py b/nova/tests/virt/libvirt/fakelibvirt.py
index ce129f0834..7ddabd4f76 100644
--- a/nova/tests/virt/libvirt/fakelibvirt.py
+++ b/nova/tests/virt/libvirt/fakelibvirt.py
@@ -636,6 +636,9 @@ class Connection(object):
def domainEventRegisterAny(self, dom, eventid, callback, opaque):
self._event_callbacks[eventid] = [callback, opaque]
+ def registerCloseCallback(self, cb, opaque):
+ pass
+
def getCapabilities(self):
"""Return spoofed capabilities."""
return '''<capabilities>
diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py
index be2f9af267..b88bcac053 100644
--- a/nova/tests/virt/libvirt/test_libvirt.py
+++ b/nova/tests/virt/libvirt/test_libvirt.py
@@ -673,8 +673,15 @@ class LibvirtConnTestCase(test.TestCase):
self.assertThat(expected, matchers.DictMatches(result))
def test_close_callback(self):
- def get_lib_version_stub():
- return (1 * 1000 * 1000) + (0 * 1000) + 1
+ class FakeConn(object):
+ def getLibVersion(self):
+ return (1 * 1000 * 1000) + (0 * 1000) + 1
+
+ def domainEventRegisterAny(self, *args, **kwargs):
+ pass
+
+ def registerCloseCallback(self, cb, opaque):
+ pass
self.close_callback = None
@@ -682,26 +689,71 @@ class LibvirtConnTestCase(test.TestCase):
self.close_callback = cb
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
- self.stubs.Set(self.conn, "getLibVersion", get_lib_version_stub)
+ conn._wrapped_conn = FakeConn()
+
self.mox.StubOutWithMock(conn, '_connect')
- self.mox.StubOutWithMock(self.conn, 'registerCloseCallback')
-
- conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.conn)
- self.conn.registerCloseCallback(
- mox.IgnoreArg(), mox.IgnoreArg()).WithSideEffects(
- set_close_callback)
- conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.conn)
- self.conn.registerCloseCallback(mox.IgnoreArg(), mox.IgnoreArg())
+ self.mox.StubOutWithMock(conn._conn, 'registerCloseCallback')
+
+ conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn._conn)
+ conn._conn.registerCloseCallback(
+ mox.IgnoreArg(), mox.IgnoreArg()
+ ).WithSideEffects(set_close_callback)
+ conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn._conn)
+ conn._conn.registerCloseCallback(mox.IgnoreArg(), mox.IgnoreArg())
self.mox.ReplayAll()
# verify that the driver registers for the close callback
# and re-connects after receiving the callback
- conn._get_connection()
+ conn._get_new_connection()
self.assertTrue(self.close_callback)
- self.close_callback(self.conn, 1, None)
+ self.close_callback(conn._conn, 1, None)
conn._get_connection()
+ self.mox.UnsetStubs()
+
+ def test_close_callback_bad_signature(self):
+ class FakeConn(object):
+ def getLibVersion(self):
+ return (1 * 1000 * 1000) + (0 * 1000) + 0
+
+ def domainEventRegisterAny(self, *args, **kwargs):
+ pass
+
+ def registerCloseCallback(self, cb, opaque, *args, **kwargs):
+ pass
+
+ conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
+ conn._wrapped_conn = FakeConn()
+
+ self.mox.StubOutWithMock(conn, '_connect')
+ self.mox.StubOutWithMock(conn._conn, 'registerCloseCallback')
+
+ conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn._conn)
+ conn._conn.registerCloseCallback(
+ mox.IgnoreArg(), mox.IgnoreArg()).AndRaise(TypeError)
+
+ self.mox.ReplayAll()
+ conn._get_new_connection()
+
+ def test_close_callback_not_defined(self):
+ class FakeConn():
+ def getLibVersion(self):
+ return (0 * 1000 * 1000) + (9 * 1000) + 0
+
+ def domainEventRegisterAny(self, *args, **kwargs):
+ pass
+
+ conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
+ conn._wrapped_conn = FakeConn()
+
+ self.mox.StubOutWithMock(conn, '_connect')
+
+ conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
+ conn._wrapped_conn)
+
+ self.mox.ReplayAll()
+ conn._get_new_connection()
def test_get_guest_config(self):
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
@@ -7392,12 +7444,26 @@ class LibvirtNonblockingTestCase(test.TestCase):
jsonutils.to_primitive(connection._conn, convert_instances=True)
def test_tpool_execute_calls_libvirt(self):
- self.mox.StubOutWithMock(eventlet.tpool, 'execute')
conn = libvirt.virConnect()
conn.is_expected = True
+
+ self.mox.StubOutWithMock(eventlet.tpool, 'execute')
+ eventlet.tpool.execute(
+ libvirt.openAuth,
+ 'test:///default',
+ mox.IgnoreArg(),
+ mox.IgnoreArg()).AndReturn(conn)
eventlet.tpool.execute(
- libvirt.openAuth, 'test:///default',
- mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn)
+ conn.domainEventRegisterAny,
+ None,
+ libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+ mox.IgnoreArg(),
+ mox.IgnoreArg())
+ if hasattr(libvirt.virConnect, 'registerCloseCallback'):
+ eventlet.tpool.execute(
+ conn.registerCloseCallback,
+ mox.IgnoreArg(),
+ mox.IgnoreArg())
self.mox.ReplayAll()
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 72848a46e3..04d131c2cc 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -285,7 +285,6 @@ MIN_LIBVIRT_VERSION = (0, 9, 6)
# When the above version matches/exceeds this version
# delete it & corresponding code using it
MIN_LIBVIRT_HOST_CPU_VERSION = (0, 9, 10)
-MIN_LIBVIRT_CLOSE_CALLBACK_VERSION = (1, 0, 1)
MIN_LIBVIRT_DEVICE_CALLBACK_VERSION = (1, 1, 1)
# Live snapshot requirements
REQ_HYPERVISOR_LIVESNAPSHOT = "QEMU"
@@ -588,7 +587,7 @@ class LibvirtDriver(driver.ComputeDriver):
self._wrapped_conn = wrapped_conn
try:
- LOG.debug(_("Registering for lifecycle events %s") % str(self))
+ LOG.debug(_("Registering for lifecycle events %s"), self)
wrapped_conn.domainEventRegisterAny(
None,
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
@@ -598,17 +597,23 @@ class LibvirtDriver(driver.ComputeDriver):
LOG.warn(_("URI %(uri)s does not support events: %(error)s"),
{'uri': self.uri(), 'error': e})
- if self._has_min_version(wrapped_conn,
- MIN_LIBVIRT_CLOSE_CALLBACK_VERSION):
- try:
- LOG.debug(_("Registering for connection events: %s") %
- str(self))
- wrapped_conn.registerCloseCallback(
- self._close_callback, None)
- except libvirt.libvirtError as e:
- LOG.warn(_("URI %(uri)s does not support connection"
- " events: %(error)s"),
- {'uri': self.uri(), 'error': e})
+ try:
+ LOG.debug(_("Registering for connection events: %s") %
+ str(self))
+ wrapped_conn.registerCloseCallback(self._close_callback, None)
+ except (TypeError, AttributeError) as e:
+ # NOTE: The registerCloseCallback of python-libvirt 1.0.1+
+ # is defined with 3 arguments, and the above registerClose-
+ # Callback succeeds. However, the one of python-libvirt 1.0.0
+ # is defined with 4 arguments and TypeError happens here.
+ # Then python-libvirt 0.9 does not define a method register-
+ # CloseCallback.
+ LOG.debug(_("The version of python-libvirt does not support "
+ "registerCloseCallback or is too old: %s"), e)
+ except libvirt.libvirtError as e:
+ LOG.warn(_("URI %(uri)s does not support connection"
+ " events: %(error)s"),
+ {'uri': self.uri(), 'error': e})
return wrapped_conn