]> xenbits.xensource.com Git - libvirt.git/commitdiff
event: make deregister return value match docs
authorEric Blake <eblake@redhat.com>
Fri, 3 Jan 2014 21:21:17 +0000 (14:21 -0700)
committerEric Blake <eblake@redhat.com>
Tue, 7 Jan 2014 13:53:40 +0000 (06:53 -0700)
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID).  And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.

Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number).  Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.

But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time.  For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type].  Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.

For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers.  By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.

Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.

* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/libvirt.c
src/libxl/libxl_driver.c
src/lxc/lxc_driver.c
src/network/bridge_driver.c
src/test/test_driver.c
src/uml/uml_driver.c
src/vbox/vbox_tmpl.c
src/xen/xen_driver.c
tests/objecteventtest.c

index 5d88c78de81ac512d5f1ffd29c38b0fcef6c98d5..2f5f023d11604c1d54f6006a8ecb56b85d917063 100644 (file)
@@ -15564,7 +15564,9 @@ error:
  * The reference can be released once the object is no longer required
  * by calling virDomainFree.
  *
- * Returns 0 on success, -1 on failure.
+ * Returns 0 on success, -1 on failure.  Older versions of some hypervisors
+ * sometimes returned a positive number on success, but without any reliable
+ * semantics on what that number represents.
  */
 int
 virConnectDomainEventRegister(virConnectPtr conn,
@@ -15598,14 +15600,16 @@ error:
  * @conn: pointer to the connection
  * @cb: callback to the function handling domain events
  *
- * Removes a callback previously registered with the virConnectDomainEventRegister
- * function.
+ * Removes a callback previously registered with the
+ * virConnectDomainEventRegister() function.
  *
  * Use of this method is no longer recommended. Instead applications
  * should try virConnectDomainEventDeregisterAny() which has a more flexible
  * API contract
  *
- * Returns 0 on success, -1 on failure
+ * Returns 0 on success, -1 on failure.  Older versions of some hypervisors
+ * sometimes returned a positive number on success, but without any reliable
+ * semantics on what that number represents.
  */
 int
 virConnectDomainEventDeregister(virConnectPtr conn,
@@ -18509,8 +18513,9 @@ error:
  * Removes an event callback. The callbackID parameter should be the
  * value obtained from a previous virConnectDomainEventRegisterAny() method.
  *
- * Returns 0 on success, -1 on failure
- */
+ * Returns 0 on success, -1 on failure.  Older versions of some hypervisors
+ * sometimes returned a positive number on success, but without any reliable
+ * semantics on what that number represents. */
 int
 virConnectDomainEventDeregisterAny(virConnectPtr conn,
                                    int callbackID)
index b24c195c8226999e33c1d025e982cadc765e31cb..61e35165f89110b46c693256f2393bd9af3d830e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * libxl_driver.c: core driver methods for managing libxenlight domains
  *
- * Copyright (C) 2006-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2014 Red Hat, Inc.
  * Copyright (C) 2011-2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
  * Copyright (C) 2011 Univention GmbH.
  *
@@ -3643,20 +3643,21 @@ cleanup:
 
 static int
 libxlConnectDomainEventRegister(virConnectPtr conn,
-                                virConnectDomainEventCallback callback, void *opaque,
+                                virConnectDomainEventCallback callback,
+                                void *opaque,
                                 virFreeCallback freecb)
 {
     libxlDriverPrivatePtr driver = conn->privateData;
-    int ret;
 
     if (virConnectDomainEventRegisterEnsureACL(conn) < 0)
         return -1;
 
-    ret = virDomainEventStateRegister(conn,
-                                      driver->domainEventState,
-                                      callback, opaque, freecb);
+    if (virDomainEventStateRegister(conn,
+                                    driver->domainEventState,
+                                    callback, opaque, freecb) < 0)
+        return -1;
 
-    return ret;
+    return 0;
 }
 
 
@@ -3665,16 +3666,16 @@ libxlConnectDomainEventDeregister(virConnectPtr conn,
                                   virConnectDomainEventCallback callback)
 {
     libxlDriverPrivatePtr driver = conn->privateData;
-    int ret;
 
     if (virConnectDomainEventDeregisterEnsureACL(conn) < 0)
         return -1;
 
-    ret = virDomainEventStateDeregister(conn,
-                                        driver->domainEventState,
-                                        callback);
+    if (virDomainEventStateDeregister(conn,
+                                      driver->domainEventState,
+                                      callback) < 0)
+        return -1;
 
-    return ret;
+    return 0;
 }
 
 static int
@@ -4270,16 +4271,16 @@ static int
 libxlConnectDomainEventDeregisterAny(virConnectPtr conn, int callbackID)
 {
     libxlDriverPrivatePtr driver = conn->privateData;
-    int ret;
 
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
         return -1;
 
-    ret = virObjectEventStateDeregisterID(conn,
-                                          driver->domainEventState,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->domainEventState,
+                                        callbackID) < 0)
+        return -1;
 
-    return ret;
+    return 0;
 }
 
 
index e5984743691ce5b831471a3256e7685c6a9ab5ae..7e56a595394ebc9d82f81b7cc7f9687870079776 100644 (file)
@@ -1287,16 +1287,16 @@ lxcConnectDomainEventRegister(virConnectPtr conn,
                               virFreeCallback freecb)
 {
     virLXCDriverPtr driver = conn->privateData;
-    int ret;
 
     if (virConnectDomainEventRegisterEnsureACL(conn) < 0)
         return -1;
 
-    ret = virDomainEventStateRegister(conn,
-                                      driver->domainEventState,
-                                      callback, opaque, freecb);
+    if (virDomainEventStateRegister(conn,
+                                    driver->domainEventState,
+                                    callback, opaque, freecb) < 0)
+        return -1;
 
-    return ret;
+    return 0;
 }
 
 
@@ -1305,16 +1305,16 @@ lxcConnectDomainEventDeregister(virConnectPtr conn,
                                 virConnectDomainEventCallback callback)
 {
     virLXCDriverPtr driver = conn->privateData;
-    int ret;
 
     if (virConnectDomainEventDeregisterEnsureACL(conn) < 0)
         return -1;
 
-    ret = virDomainEventStateDeregister(conn,
-                                        driver->domainEventState,
-                                        callback);
+    if (virDomainEventStateDeregister(conn,
+                                      driver->domainEventState,
+                                      callback) < 0)
+        return -1;
 
-    return ret;
+    return 0;
 }
 
 
@@ -1347,16 +1347,16 @@ lxcConnectDomainEventDeregisterAny(virConnectPtr conn,
                                    int callbackID)
 {
     virLXCDriverPtr driver = conn->privateData;
-    int ret;
 
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
         return -1;
 
-    ret = virObjectEventStateDeregisterID(conn,
-                                          driver->domainEventState,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->domainEventState,
+                                        callbackID) < 0)
+        return -1;
 
-    return ret;
+    return 0;
 }
 
 
index 3e10758d5c96ae91914a0954f280318c76305a32..9dc1f7e22f0edd4fe1aa43238e52f31e1bbeca1e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bridge_driver.c: core driver methods for managing network
  *
- * Copyright (C) 2006-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2014 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -2329,9 +2329,12 @@ networkConnectNetworkEventDeregisterAny(virConnectPtr conn,
     if (virConnectNetworkEventDeregisterAnyEnsureACL(conn) < 0)
         goto cleanup;
 
-    ret = virObjectEventStateDeregisterID(conn,
-                                          driver->networkEventState,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->networkEventState,
+                                        callbackID) < 0)
+        goto cleanup;
+
+    ret = 0;
 
 cleanup:
     return ret;
index a48404a364656ca2a8641bf92bc83a77be905771..d0f3fa872b8cd5efda7a57e1aed32ce597096ee1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * test.c: A "mock" hypervisor for use by application unit tests
  *
- * Copyright (C) 2006-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2014 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -5993,12 +5993,13 @@ testConnectDomainEventRegister(virConnectPtr conn,
                                virFreeCallback freecb)
 {
     testConnPtr driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     testDriverLock(driver);
-    ret = virDomainEventStateRegister(conn,
-                                      driver->domainEventState,
-                                      callback, opaque, freecb);
+    if (virDomainEventStateRegister(conn,
+                                    driver->domainEventState,
+                                    callback, opaque, freecb) < 0)
+        ret = -1;
     testDriverUnlock(driver);
 
     return ret;
@@ -6010,12 +6011,13 @@ testConnectDomainEventDeregister(virConnectPtr conn,
                                  virConnectDomainEventCallback callback)
 {
     testConnPtr driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     testDriverLock(driver);
-    ret = virDomainEventStateDeregister(conn,
-                                        driver->domainEventState,
-                                        callback);
+    if (virDomainEventStateDeregister(conn,
+                                      driver->domainEventState,
+                                      callback) < 0)
+        ret = -1;
     testDriverUnlock(driver);
 
     return ret;
@@ -6049,12 +6051,13 @@ testConnectDomainEventDeregisterAny(virConnectPtr conn,
                                     int callbackID)
 {
     testConnPtr driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     testDriverLock(driver);
-    ret = virObjectEventStateDeregisterID(conn,
-                                          driver->domainEventState,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->domainEventState,
+                                        callbackID) < 0)
+        ret = -1;
     testDriverUnlock(driver);
 
     return ret;
@@ -6089,12 +6092,13 @@ testConnectNetworkEventDeregisterAny(virConnectPtr conn,
                                      int callbackID)
 {
     testConnPtr driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     testDriverLock(driver);
-    ret = virObjectEventStateDeregisterID(conn,
-                                          driver->domainEventState,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->domainEventState,
+                                        callbackID) < 0)
+        ret = -1;
     testDriverUnlock(driver);
 
     return ret;
index 1784eb596c5782e4ef1096101f08b0614ce09a42..ad29ebfb77bf4f3fac0a65c3a8c408400c5b5dfb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * uml_driver.c: core driver methods for managing UML guests
  *
- * Copyright (C) 2006-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2014 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -2610,15 +2610,16 @@ umlConnectDomainEventRegister(virConnectPtr conn,
                               virFreeCallback freecb)
 {
     struct uml_driver *driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     if (virConnectDomainEventRegisterEnsureACL(conn) < 0)
         return -1;
 
     umlDriverLock(driver);
-    ret = virDomainEventStateRegister(conn,
-                                      driver->domainEventState,
-                                      callback, opaque, freecb);
+    if (virDomainEventStateRegister(conn,
+                                    driver->domainEventState,
+                                    callback, opaque, freecb) < 0)
+        ret = -1;
     umlDriverUnlock(driver);
 
     return ret;
@@ -2629,15 +2630,16 @@ umlConnectDomainEventDeregister(virConnectPtr conn,
                                 virConnectDomainEventCallback callback)
 {
     struct uml_driver *driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     if (virConnectDomainEventDeregisterEnsureACL(conn) < 0)
         return -1;
 
     umlDriverLock(driver);
-    ret = virDomainEventStateDeregister(conn,
-                                        driver->domainEventState,
-                                        callback);
+    if (virDomainEventStateDeregister(conn,
+                                      driver->domainEventState,
+                                      callback) < 0)
+        ret = -1;
     umlDriverUnlock(driver);
 
     return ret;
@@ -2674,15 +2676,16 @@ umlConnectDomainEventDeregisterAny(virConnectPtr conn,
                                    int callbackID)
 {
     struct uml_driver *driver = conn->privateData;
-    int ret;
+    int ret = 0;
 
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
         return -1;
 
     umlDriverLock(driver);
-    ret = virObjectEventStateDeregisterID(conn,
-                                          driver->domainEventState,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->domainEventState,
+                                        callbackID) < 0)
+        ret = -1;
     umlDriverUnlock(driver);
 
     return ret;
index 385ee54e7c36b4d6c91b60e203f6e3bdf9ab6b2b..0fcaf8e70d9b1fed66c8e3beb62d99ee2a73d862 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /*
- * Copyright (C) 2010-2013 Red Hat, Inc.
+ * Copyright (C) 2010-2014 Red Hat, Inc.
  * Copyright (C) 2008-2009 Sun Microsystems, Inc.
  *
  * This file is part of a free software library; you can redistribute
@@ -7284,10 +7284,12 @@ static void vboxReadCallback(int watch ATTRIBUTE_UNUSED,
     }
 }
 
-static int vboxConnectDomainEventRegister(virConnectPtr conn,
-                                          virConnectDomainEventCallback callback,
-                                          void *opaque,
-                                          virFreeCallback freecb) {
+static int
+vboxConnectDomainEventRegister(virConnectPtr conn,
+                               virConnectDomainEventCallback callback,
+                               void *opaque,
+                               virFreeCallback freecb)
+{
     VBOX_OBJECT_CHECK(conn, int, -1);
     int vboxRet          = -1;
     nsresult rc;
@@ -7338,7 +7340,7 @@ static int vboxConnectDomainEventRegister(virConnectPtr conn,
     vboxDriverUnlock(data);
 
     if (ret >= 0) {
-        return ret;
+        return 0;
     } else {
         if (data->vboxObj && data->vboxCallback) {
             data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
@@ -7347,8 +7349,10 @@ static int vboxConnectDomainEventRegister(virConnectPtr conn,
     }
 }
 
-static int vboxConnectDomainEventDeregister(virConnectPtr conn,
-                                            virConnectDomainEventCallback callback) {
+static int
+vboxConnectDomainEventDeregister(virConnectPtr conn,
+                                 virConnectDomainEventCallback callback)
+{
     VBOX_OBJECT_CHECK(conn, int, -1);
     int cnt;
 
@@ -7371,6 +7375,9 @@ static int vboxConnectDomainEventDeregister(virConnectPtr conn,
 
     vboxDriverUnlock(data);
 
+    if (cnt >= 0)
+        ret = 0;
+
     return ret;
 }
 
@@ -7441,8 +7448,10 @@ static int vboxConnectDomainEventRegisterAny(virConnectPtr conn,
     }
 }
 
-static int vboxConnectDomainEventDeregisterAny(virConnectPtr conn,
-                                               int callbackID) {
+static int
+vboxConnectDomainEventDeregisterAny(virConnectPtr conn,
+                                    int callbackID)
+{
     VBOX_OBJECT_CHECK(conn, int, -1);
     int cnt;
 
@@ -7465,6 +7474,9 @@ static int vboxConnectDomainEventDeregisterAny(virConnectPtr conn,
 
     vboxDriverUnlock(data);
 
+    if (cnt >= 0)
+        ret = 0;
+
     return ret;
 }
 
index b5d67387c104ceb3a274a86fe69c8620e9c846a5..2c7aeaafbf981146c0394488c8c9ba4793b4cf36 100644 (file)
@@ -2312,7 +2312,7 @@ xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
                                      virFreeCallback freefunc)
 {
     xenUnifiedPrivatePtr priv = conn->privateData;
-    int ret;
+    int ret = 0;
 
     if (virConnectDomainEventRegisterEnsureACL(conn) < 0)
         return -1;
@@ -2325,8 +2325,9 @@ xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
         return -1;
     }
 
-    ret = virDomainEventStateRegister(conn, priv->domainEvents,
-                                      callback, opaque, freefunc);
+    if (virDomainEventStateRegister(conn, priv->domainEvents,
+                                    callback, opaque, freefunc) < 0)
+        ret = -1;
 
     xenUnifiedUnlock(priv);
     return ret;
@@ -2337,7 +2338,7 @@ static int
 xenUnifiedConnectDomainEventDeregister(virConnectPtr conn,
                                        virConnectDomainEventCallback callback)
 {
-    int ret;
+    int ret = 0;
     xenUnifiedPrivatePtr priv = conn->privateData;
 
     if (virConnectDomainEventDeregisterEnsureACL(conn) < 0)
@@ -2351,9 +2352,10 @@ xenUnifiedConnectDomainEventDeregister(virConnectPtr conn,
         return -1;
     }
 
-    ret = virDomainEventStateDeregister(conn,
-                                        priv->domainEvents,
-                                        callback);
+    if (virDomainEventStateDeregister(conn,
+                                      priv->domainEvents,
+                                      callback) < 0)
+        ret = -1;
 
     xenUnifiedUnlock(priv);
     return ret;
@@ -2395,7 +2397,7 @@ static int
 xenUnifiedConnectDomainEventDeregisterAny(virConnectPtr conn,
                                           int callbackID)
 {
-    int ret;
+    int ret = 0;
     xenUnifiedPrivatePtr priv = conn->privateData;
 
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
@@ -2409,9 +2411,10 @@ xenUnifiedConnectDomainEventDeregisterAny(virConnectPtr conn,
         return -1;
     }
 
-    ret = virObjectEventStateDeregisterID(conn,
-                                          priv->domainEvents,
-                                          callbackID);
+    if (virObjectEventStateDeregisterID(conn,
+                                        priv->domainEvents,
+                                        callbackID) < 0)
+        ret = -1;
 
     xenUnifiedUnlock(priv);
     return ret;
index ae29792abfa874597ab1945fed02dd6a808db192..833c0fc142af9575ef50f0b28cd3dc0aec3a8dc7 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2014 Red Hat, Inc.
  * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
  *
  * This library is free software; you can redistribute it and/or
@@ -125,36 +126,80 @@ networkLifecycleCb(virConnectPtr conn ATTRIBUTE_UNUSED,
 }
 
 
+static int
+testDomainCreateXMLOld(const void *data)
+{
+    const objecteventTest *test = data;
+    lifecycleEventCounter counter;
+    virDomainPtr dom = NULL;
+    int ret = -1;
+    bool registered = false;
+
+    lifecycleEventCounter_reset(&counter);
+
+    if (virConnectDomainEventRegister(test->conn,
+                                      domainLifecycleCb,
+                                      &counter, NULL) != 0)
+        goto cleanup;
+    registered = true;
+    dom = virDomainCreateXML(test->conn, domainDef, 0);
+
+    if (dom == NULL || virEventRunDefaultImpl() < 0)
+        goto cleanup;
+
+    if (counter.startEvents != 1 || counter.unexpectedEvents > 0)
+        goto cleanup;
+
+    if (virConnectDomainEventDeregister(test->conn, domainLifecycleCb) != 0)
+        goto cleanup;
+    registered = false;
+    ret = 0;
+
+cleanup:
+    if (registered)
+        virConnectDomainEventDeregister(test->conn, domainLifecycleCb);
+    if (dom) {
+        virDomainDestroy(dom);
+        virDomainFree(dom);
+    }
+
+    return ret;
+}
+
 static int
 testDomainCreateXML(const void *data)
 {
     const objecteventTest *test = data;
     lifecycleEventCounter counter;
     int eventId = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
-    virDomainPtr dom;
+    virDomainPtr dom = NULL;
     int id;
-    int ret = 0;
+    int ret = -1;
 
     lifecycleEventCounter_reset(&counter);
 
     id = virConnectDomainEventRegisterAny(test->conn, NULL, eventId,
                            VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
                            &counter, NULL);
+    if (id < 0)
+        goto cleanup;
     dom = virDomainCreateXML(test->conn, domainDef, 0);
 
-    if (dom == NULL || virEventRunDefaultImpl() < 0) {
-        ret = -1;
+    if (dom == NULL || virEventRunDefaultImpl() < 0)
         goto cleanup;
-    }
 
-    if (counter.startEvents != 1 || counter.unexpectedEvents > 0) {
-        ret = -1;
+    if (counter.startEvents != 1 || counter.unexpectedEvents > 0)
         goto cleanup;
-    }
+
+    if (virConnectDomainEventDeregisterAny(test->conn, id) != 0)
+        goto cleanup;
+    id = -1;
+    ret = 0;
 
 cleanup:
-    virConnectDomainEventDeregisterAny(test->conn, id);
-    if (dom != NULL) {
+    if (id >= 0)
+        virConnectDomainEventDeregisterAny(test->conn, id);
+    if (dom) {
         virDomainDestroy(dom);
         virDomainFree(dom);
     }
@@ -168,7 +213,7 @@ testDomainDefine(const void *data)
     const objecteventTest *test = data;
     lifecycleEventCounter counter;
     int eventId = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
-    virDomainPtr dom;
+    virDomainPtr dom = NULL;
     int id;
     int ret = 0;
 
@@ -388,7 +433,11 @@ mymain(void)
     virtTestQuiesceLibvirtErrors(false);
 
     /* Domain event tests */
-    if (virtTestRun("Domain createXML start event ", testDomainCreateXML, &test) < 0)
+    if (virtTestRun("Domain createXML start event (old API)",
+                    testDomainCreateXMLOld, &test) < 0)
+        ret = EXIT_FAILURE;
+    if (virtTestRun("Domain createXML start event (new API)",
+                    testDomainCreateXML, &test) < 0)
         ret = EXIT_FAILURE;
     if (virtTestRun("Domain (un)define events", testDomainDefine, &test) < 0)
         ret = EXIT_FAILURE;