2013-11-25 16:43:46 +00:00
|
|
|
/*
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
* Copyright (C) 2014 Red Hat, Inc.
|
2013-11-25 16:43:46 +00:00
|
|
|
* Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Author: Cedric Bosdonnat <cbosdonnat@suse.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "testutils.h"
|
|
|
|
|
|
|
|
#include "virerror.h"
|
|
|
|
#include "virxml.h"
|
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
|
|
|
|
|
|
|
static const char domainDef[] =
|
|
|
|
"<domain type='test'>"
|
|
|
|
" <name>test-domain</name>"
|
|
|
|
" <uuid>77a6fc12-07b5-9415-8abb-a803613f2a40</uuid>"
|
|
|
|
" <memory>8388608</memory>"
|
|
|
|
" <currentMemory>2097152</currentMemory>"
|
|
|
|
" <vcpu>2</vcpu>"
|
|
|
|
" <os>"
|
|
|
|
" <type>hvm</type>"
|
|
|
|
" </os>"
|
|
|
|
"</domain>";
|
|
|
|
|
2013-12-11 10:38:00 +00:00
|
|
|
static const char networkDef[] =
|
|
|
|
"<network>\n"
|
|
|
|
" <name>test</name>\n"
|
|
|
|
" <bridge name=\"virbr0\"/>\n"
|
|
|
|
" <forward/>\n"
|
|
|
|
" <ip address=\"192.168.122.1\" netmask=\"255.255.255.0\">\n"
|
|
|
|
" <dhcp>\n"
|
|
|
|
" <range start=\"192.168.122.2\" end=\"192.168.122.254\"/>\n"
|
|
|
|
" </dhcp>\n"
|
|
|
|
" </ip>\n"
|
|
|
|
"</network>\n";
|
|
|
|
|
2013-11-25 16:43:46 +00:00
|
|
|
typedef struct {
|
|
|
|
int startEvents;
|
|
|
|
int stopEvents;
|
|
|
|
int defineEvents;
|
|
|
|
int undefineEvents;
|
|
|
|
int unexpectedEvents;
|
|
|
|
} lifecycleEventCounter;
|
|
|
|
|
|
|
|
static void
|
|
|
|
lifecycleEventCounter_reset(lifecycleEventCounter *counter)
|
|
|
|
{
|
|
|
|
counter->startEvents = 0;
|
|
|
|
counter->stopEvents = 0;
|
|
|
|
counter->defineEvents = 0;
|
|
|
|
counter->undefineEvents = 0;
|
|
|
|
counter->unexpectedEvents = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
virConnectPtr conn;
|
2013-12-11 10:38:00 +00:00
|
|
|
virNetworkPtr net;
|
2013-11-25 16:43:46 +00:00
|
|
|
} objecteventTest;
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
domainLifecycleCb(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
virDomainPtr dom ATTRIBUTE_UNUSED,
|
|
|
|
int event,
|
|
|
|
int detail ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
lifecycleEventCounter *counter = opaque;
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
case VIR_DOMAIN_EVENT_STARTED:
|
|
|
|
counter->startEvents++;
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_EVENT_STOPPED:
|
|
|
|
counter->stopEvents++;
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_EVENT_DEFINED:
|
|
|
|
counter->defineEvents++;
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_EVENT_UNDEFINED:
|
|
|
|
counter->undefineEvents++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Ignore other events */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-12-11 10:38:00 +00:00
|
|
|
static void
|
|
|
|
networkLifecycleCb(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
virNetworkPtr net ATTRIBUTE_UNUSED,
|
|
|
|
int event,
|
|
|
|
int detail ATTRIBUTE_UNUSED,
|
|
|
|
void* opaque)
|
|
|
|
{
|
|
|
|
lifecycleEventCounter *counter = opaque;
|
|
|
|
|
|
|
|
if (event == VIR_NETWORK_EVENT_STARTED)
|
|
|
|
counter->startEvents++;
|
|
|
|
else if (event == VIR_NETWORK_EVENT_STOPPED)
|
|
|
|
counter->stopEvents++;
|
|
|
|
else if (event == VIR_NETWORK_EVENT_DEFINED)
|
|
|
|
counter->defineEvents++;
|
|
|
|
else if (event == VIR_NETWORK_EVENT_UNDEFINED)
|
|
|
|
counter->undefineEvents++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-11-25 16:43:46 +00:00
|
|
|
static int
|
event: don't let old-style events clobber per-domain events
Right now, the older virConnectDomainEventRegister (takes a
function pointer, returns 0 on success) and the newer
virConnectDomainEventRegisterID (takes an eventID, returns a
callbackID) share the underlying implementation (the older
API ends up consuming a callbackID for eventID 0 under the
hood). We implemented that by a lot of copy and pasted
code between object_event.c and domain_event.c, according to
whether we are dealing with a function pointer or an eventID.
However, our copy and paste is not symmetric. Consider this
sequence:
id1 = virConnectDomainEventRegisterAny(conn, dom,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback), NULL, NULL);
virConnectDomainEventRegister(conn, callback, NULL, NULL);
virConnectDomainEventDeregister(conn, callback);
virConnectDomainEventDeregsiterAny(conn, id1);
the first three calls would succeed, but the third call ended
up nuking the id1 callbackID (the per-domain new-style handler),
then the fourth call failed with an error about an unknown
callbackID, leaving us with the global handler (old-style) still
live and receiving events. It required another old-style
deregister to clean up the mess. Root cause was that
virDomainEventCallbackList{Remove,MarkDelete} were only
checking for function pointer match, rather than also checking
for whether the registration was global.
Rather than playing with the guts of object_event ourselves
in domain_event, it is nicer to add a mapping function for the
internal callback id, then share common code for event removal.
For now, the function-to-id mapping is used only internally;
I thought about whether a new public API to let a user learn
the callback would be useful, but decided exposing this to the
user is probably a disservice, since we already publicly
document that they should avoid the old style, and since this
patch already demonstrates that older libvirt versions have
weird behavior when mixing old and new styles.
And like all good bug fix patches, I enhanced the testsuite,
validating that the changes in tests/ expose the failure
without the rest of the patch.
* src/conf/object_event.c (virObjectEventCallbackLookup)
(virObjectEventStateCallbackID): New functions.
(virObjectEventCallbackLookup): Use helper function.
* src/conf/object_event_private.h (virObjectEventStateCallbackID):
Declare new function.
* src/conf/domain_event.c (virDomainEventStateRegister)
(virDomainEventStateDeregister): Let common code handle the
complexity.
(virDomainEventCallbackListRemove)
(virDomainEventCallbackListMarkDelete)
(virDomainEventCallbackListAdd): Drop unused functions.
* tests/objecteventtest.c (testDomainCreateXMLMixed): New test.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 23:50:14 +00:00
|
|
|
testDomainCreateXMLNew(const void *data)
|
2013-11-25 16:43:46 +00:00
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
int eventId = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
virDomainPtr dom = NULL;
|
2013-11-25 16:43:46 +00:00
|
|
|
int id;
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
int ret = -1;
|
2013-11-25 16:43:46 +00:00
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
id = virConnectDomainEventRegisterAny(test->conn, NULL, eventId,
|
|
|
|
VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
|
|
|
|
&counter, NULL);
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
if (id < 0)
|
|
|
|
goto cleanup;
|
2013-11-25 16:43:46 +00:00
|
|
|
dom = virDomainCreateXML(test->conn, domainDef, 0);
|
|
|
|
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
if (dom == NULL || virEventRunDefaultImpl() < 0)
|
2013-11-25 16:43:46 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
if (counter.startEvents != 1 || counter.unexpectedEvents > 0)
|
2013-11-25 16:43:46 +00:00
|
|
|
goto cleanup;
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
|
|
|
|
if (virConnectDomainEventDeregisterAny(test->conn, id) != 0)
|
|
|
|
goto cleanup;
|
|
|
|
id = -1;
|
|
|
|
ret = 0;
|
2013-11-25 16:43:46 +00:00
|
|
|
|
|
|
|
cleanup:
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
if (id >= 0)
|
|
|
|
virConnectDomainEventDeregisterAny(test->conn, id);
|
|
|
|
if (dom) {
|
2013-11-25 16:43:46 +00:00
|
|
|
virDomainDestroy(dom);
|
|
|
|
virDomainFree(dom);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
event: don't let old-style events clobber per-domain events
Right now, the older virConnectDomainEventRegister (takes a
function pointer, returns 0 on success) and the newer
virConnectDomainEventRegisterID (takes an eventID, returns a
callbackID) share the underlying implementation (the older
API ends up consuming a callbackID for eventID 0 under the
hood). We implemented that by a lot of copy and pasted
code between object_event.c and domain_event.c, according to
whether we are dealing with a function pointer or an eventID.
However, our copy and paste is not symmetric. Consider this
sequence:
id1 = virConnectDomainEventRegisterAny(conn, dom,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback), NULL, NULL);
virConnectDomainEventRegister(conn, callback, NULL, NULL);
virConnectDomainEventDeregister(conn, callback);
virConnectDomainEventDeregsiterAny(conn, id1);
the first three calls would succeed, but the third call ended
up nuking the id1 callbackID (the per-domain new-style handler),
then the fourth call failed with an error about an unknown
callbackID, leaving us with the global handler (old-style) still
live and receiving events. It required another old-style
deregister to clean up the mess. Root cause was that
virDomainEventCallbackList{Remove,MarkDelete} were only
checking for function pointer match, rather than also checking
for whether the registration was global.
Rather than playing with the guts of object_event ourselves
in domain_event, it is nicer to add a mapping function for the
internal callback id, then share common code for event removal.
For now, the function-to-id mapping is used only internally;
I thought about whether a new public API to let a user learn
the callback would be useful, but decided exposing this to the
user is probably a disservice, since we already publicly
document that they should avoid the old style, and since this
patch already demonstrates that older libvirt versions have
weird behavior when mixing old and new styles.
And like all good bug fix patches, I enhanced the testsuite,
validating that the changes in tests/ expose the failure
without the rest of the patch.
* src/conf/object_event.c (virObjectEventCallbackLookup)
(virObjectEventStateCallbackID): New functions.
(virObjectEventCallbackLookup): Use helper function.
* src/conf/object_event_private.h (virObjectEventStateCallbackID):
Declare new function.
* src/conf/domain_event.c (virDomainEventStateRegister)
(virDomainEventStateDeregister): Let common code handle the
complexity.
(virDomainEventCallbackListRemove)
(virDomainEventCallbackListMarkDelete)
(virDomainEventCallbackListAdd): Drop unused functions.
* tests/objecteventtest.c (testDomainCreateXMLMixed): New test.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 23:50:14 +00:00
|
|
|
static int
|
|
|
|
testDomainCreateXMLMixed(const void *data)
|
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
virDomainPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
int id = -1;
|
|
|
|
bool registered = false;
|
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
/* Fun with mixing old and new API. Handler should be fired twice,
|
|
|
|
* once for each registration. */
|
2014-01-07 16:14:09 +00:00
|
|
|
if (!(dom = virDomainCreateXML(test->conn, domainDef, 0)))
|
event: don't let old-style events clobber per-domain events
Right now, the older virConnectDomainEventRegister (takes a
function pointer, returns 0 on success) and the newer
virConnectDomainEventRegisterID (takes an eventID, returns a
callbackID) share the underlying implementation (the older
API ends up consuming a callbackID for eventID 0 under the
hood). We implemented that by a lot of copy and pasted
code between object_event.c and domain_event.c, according to
whether we are dealing with a function pointer or an eventID.
However, our copy and paste is not symmetric. Consider this
sequence:
id1 = virConnectDomainEventRegisterAny(conn, dom,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback), NULL, NULL);
virConnectDomainEventRegister(conn, callback, NULL, NULL);
virConnectDomainEventDeregister(conn, callback);
virConnectDomainEventDeregsiterAny(conn, id1);
the first three calls would succeed, but the third call ended
up nuking the id1 callbackID (the per-domain new-style handler),
then the fourth call failed with an error about an unknown
callbackID, leaving us with the global handler (old-style) still
live and receiving events. It required another old-style
deregister to clean up the mess. Root cause was that
virDomainEventCallbackList{Remove,MarkDelete} were only
checking for function pointer match, rather than also checking
for whether the registration was global.
Rather than playing with the guts of object_event ourselves
in domain_event, it is nicer to add a mapping function for the
internal callback id, then share common code for event removal.
For now, the function-to-id mapping is used only internally;
I thought about whether a new public API to let a user learn
the callback would be useful, but decided exposing this to the
user is probably a disservice, since we already publicly
document that they should avoid the old style, and since this
patch already demonstrates that older libvirt versions have
weird behavior when mixing old and new styles.
And like all good bug fix patches, I enhanced the testsuite,
validating that the changes in tests/ expose the failure
without the rest of the patch.
* src/conf/object_event.c (virObjectEventCallbackLookup)
(virObjectEventStateCallbackID): New functions.
(virObjectEventCallbackLookup): Use helper function.
* src/conf/object_event_private.h (virObjectEventStateCallbackID):
Declare new function.
* src/conf/domain_event.c (virDomainEventStateRegister)
(virDomainEventStateDeregister): Let common code handle the
complexity.
(virDomainEventCallbackListRemove)
(virDomainEventCallbackListMarkDelete)
(virDomainEventCallbackListAdd): Drop unused functions.
* tests/objecteventtest.c (testDomainCreateXMLMixed): New test.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 23:50:14 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
id = virConnectDomainEventRegisterAny(test->conn, dom,
|
|
|
|
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
|
|
|
VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
|
|
|
|
&counter, NULL);
|
|
|
|
if (id < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (virDomainDestroy(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
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 != 2 || counter.unexpectedEvents > 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virConnectDomainEventDeregister(test->conn, domainLifecycleCb) != 0)
|
|
|
|
goto cleanup;
|
|
|
|
registered = false;
|
|
|
|
if (virConnectDomainEventDeregisterAny(test->conn, id) != 0)
|
|
|
|
goto cleanup;
|
|
|
|
id = -1;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (id >= 0)
|
|
|
|
virConnectDomainEventDeregisterAny(test->conn, id);
|
|
|
|
if (registered)
|
|
|
|
virConnectDomainEventDeregister(test->conn, domainLifecycleCb);
|
|
|
|
if (dom != NULL) {
|
|
|
|
virDomainUndefine(dom);
|
|
|
|
virDomainDestroy(dom);
|
|
|
|
virDomainFree(dom);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-25 16:43:46 +00:00
|
|
|
static int
|
|
|
|
testDomainDefine(const void *data)
|
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
int eventId = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
virDomainPtr dom = NULL;
|
2013-11-25 16:43:46 +00:00
|
|
|
int id;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
id = virConnectDomainEventRegisterAny(test->conn, NULL, eventId,
|
|
|
|
VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
|
|
|
|
&counter, NULL);
|
|
|
|
|
|
|
|
/* Make sure the define event is triggered */
|
|
|
|
dom = virDomainDefineXML(test->conn, domainDef);
|
|
|
|
|
|
|
|
if (dom == NULL || virEventRunDefaultImpl() < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter.defineEvents != 1 || counter.unexpectedEvents > 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure the undefine event is triggered */
|
|
|
|
virDomainUndefine(dom);
|
|
|
|
|
|
|
|
if (virEventRunDefaultImpl() < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter.undefineEvents != 1 || counter.unexpectedEvents > 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virConnectDomainEventDeregisterAny(test->conn, id);
|
|
|
|
if (dom != NULL)
|
|
|
|
virDomainFree(dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
testDomainStartStopEvent(const void *data)
|
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
int eventId = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
|
|
|
|
int id;
|
2014-01-01 16:30:12 +00:00
|
|
|
int ret = -1;
|
2013-11-25 16:43:46 +00:00
|
|
|
virDomainPtr dom;
|
2014-01-01 16:30:12 +00:00
|
|
|
virConnectPtr conn2 = NULL;
|
|
|
|
virDomainPtr dom2 = NULL;
|
2013-11-25 16:43:46 +00:00
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
dom = virDomainLookupByName(test->conn, "test");
|
|
|
|
if (dom == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
id = virConnectDomainEventRegisterAny(test->conn, dom, eventId,
|
|
|
|
VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
|
|
|
|
&counter, NULL);
|
|
|
|
|
|
|
|
/* Test domain is started */
|
|
|
|
virDomainDestroy(dom);
|
|
|
|
virDomainCreate(dom);
|
|
|
|
|
2014-01-01 16:30:12 +00:00
|
|
|
if (virEventRunDefaultImpl() < 0)
|
2013-11-25 16:43:46 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (counter.startEvents != 1 || counter.stopEvents != 1 ||
|
2014-01-01 16:30:12 +00:00
|
|
|
counter.unexpectedEvents > 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* Repeat the test, but this time, trigger the events via an
|
|
|
|
* alternate connection. */
|
|
|
|
if (!(conn2 = virConnectOpen("test:///default")))
|
|
|
|
goto cleanup;
|
|
|
|
if (!(dom2 = virDomainLookupByName(conn2, "test")))
|
2013-11-25 16:43:46 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2014-01-01 16:30:12 +00:00
|
|
|
if (virDomainDestroy(dom2) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (virDomainCreate(dom2) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virEventRunDefaultImpl() < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (counter.startEvents != 2 || counter.stopEvents != 2 ||
|
|
|
|
counter.unexpectedEvents > 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
2013-11-25 16:43:46 +00:00
|
|
|
cleanup:
|
|
|
|
virConnectDomainEventDeregisterAny(test->conn, id);
|
|
|
|
virDomainFree(dom);
|
2014-01-01 16:30:12 +00:00
|
|
|
if (dom2)
|
|
|
|
virDomainFree(dom2);
|
|
|
|
if (conn2)
|
|
|
|
virConnectClose(conn2);
|
2013-11-25 16:43:46 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-12-11 10:38:00 +00:00
|
|
|
static int
|
|
|
|
testNetworkCreateXML(const void *data)
|
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
virNetworkPtr net;
|
|
|
|
int id;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
id = virConnectNetworkEventRegisterAny(test->conn, NULL,
|
|
|
|
VIR_NETWORK_EVENT_ID_LIFECYCLE,
|
|
|
|
VIR_NETWORK_EVENT_CALLBACK(&networkLifecycleCb),
|
|
|
|
&counter, NULL);
|
|
|
|
net = virNetworkCreateXML(test->conn, networkDef);
|
|
|
|
|
|
|
|
if (virEventRunDefaultImpl() < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter.startEvents != 1 || counter.unexpectedEvents > 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virConnectNetworkEventDeregisterAny(test->conn, id);
|
|
|
|
virNetworkDestroy(net);
|
|
|
|
|
|
|
|
virNetworkFree(net);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
testNetworkDefine(const void *data)
|
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
virNetworkPtr net;
|
|
|
|
int id;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
id = virConnectNetworkEventRegisterAny(test->conn, NULL,
|
|
|
|
VIR_NETWORK_EVENT_ID_LIFECYCLE,
|
|
|
|
VIR_NETWORK_EVENT_CALLBACK(&networkLifecycleCb),
|
|
|
|
&counter, NULL);
|
|
|
|
|
|
|
|
/* Make sure the define event is triggered */
|
|
|
|
net = virNetworkDefineXML(test->conn, networkDef);
|
|
|
|
|
|
|
|
if (virEventRunDefaultImpl() < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter.defineEvents != 1 || counter.unexpectedEvents > 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure the undefine event is triggered */
|
|
|
|
virNetworkUndefine(net);
|
|
|
|
|
|
|
|
if (virEventRunDefaultImpl() < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter.undefineEvents != 1 || counter.unexpectedEvents > 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virConnectNetworkEventDeregisterAny(test->conn, id);
|
|
|
|
virNetworkFree(net);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
testNetworkStartStopEvent(const void *data)
|
|
|
|
{
|
|
|
|
const objecteventTest *test = data;
|
|
|
|
lifecycleEventCounter counter;
|
|
|
|
int id;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
lifecycleEventCounter_reset(&counter);
|
|
|
|
|
|
|
|
id = virConnectNetworkEventRegisterAny(test->conn, test->net,
|
|
|
|
VIR_NETWORK_EVENT_ID_LIFECYCLE,
|
|
|
|
VIR_NETWORK_EVENT_CALLBACK(&networkLifecycleCb),
|
|
|
|
&counter, NULL);
|
|
|
|
virNetworkCreate(test->net);
|
|
|
|
virNetworkDestroy(test->net);
|
|
|
|
|
|
|
|
if (virEventRunDefaultImpl() < 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (counter.startEvents != 1 || counter.stopEvents != 1 ||
|
|
|
|
counter.unexpectedEvents > 0) {
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
cleanup:
|
|
|
|
virConnectNetworkEventDeregisterAny(test->conn, id);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-01-01 16:30:12 +00:00
|
|
|
static void
|
|
|
|
timeout(int id ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
fputs("test taking too long; giving up", stderr);
|
|
|
|
_exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2013-11-25 16:43:46 +00:00
|
|
|
static int
|
|
|
|
mymain(void)
|
|
|
|
{
|
|
|
|
objecteventTest test;
|
|
|
|
int ret = EXIT_SUCCESS;
|
2014-01-01 16:30:12 +00:00
|
|
|
int timer;
|
2013-11-25 16:43:46 +00:00
|
|
|
|
|
|
|
virEventRegisterDefaultImpl();
|
|
|
|
|
2014-01-01 16:30:12 +00:00
|
|
|
/* Set up a timer to abort this test if it takes 10 seconds. */
|
|
|
|
if ((timer = virEventAddTimeout(10 * 1000, timeout, NULL, NULL)) < 0)
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2013-11-25 16:43:46 +00:00
|
|
|
if (!(test.conn = virConnectOpen("test:///default")))
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
|
|
|
virtTestQuiesceLibvirtErrors(false);
|
|
|
|
|
|
|
|
/* Domain event tests */
|
event: make deregister return value match docs
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>
2014-01-03 21:21:17 +00:00
|
|
|
if (virtTestRun("Domain createXML start event (old API)",
|
|
|
|
testDomainCreateXMLOld, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
if (virtTestRun("Domain createXML start event (new API)",
|
event: don't let old-style events clobber per-domain events
Right now, the older virConnectDomainEventRegister (takes a
function pointer, returns 0 on success) and the newer
virConnectDomainEventRegisterID (takes an eventID, returns a
callbackID) share the underlying implementation (the older
API ends up consuming a callbackID for eventID 0 under the
hood). We implemented that by a lot of copy and pasted
code between object_event.c and domain_event.c, according to
whether we are dealing with a function pointer or an eventID.
However, our copy and paste is not symmetric. Consider this
sequence:
id1 = virConnectDomainEventRegisterAny(conn, dom,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback), NULL, NULL);
virConnectDomainEventRegister(conn, callback, NULL, NULL);
virConnectDomainEventDeregister(conn, callback);
virConnectDomainEventDeregsiterAny(conn, id1);
the first three calls would succeed, but the third call ended
up nuking the id1 callbackID (the per-domain new-style handler),
then the fourth call failed with an error about an unknown
callbackID, leaving us with the global handler (old-style) still
live and receiving events. It required another old-style
deregister to clean up the mess. Root cause was that
virDomainEventCallbackList{Remove,MarkDelete} were only
checking for function pointer match, rather than also checking
for whether the registration was global.
Rather than playing with the guts of object_event ourselves
in domain_event, it is nicer to add a mapping function for the
internal callback id, then share common code for event removal.
For now, the function-to-id mapping is used only internally;
I thought about whether a new public API to let a user learn
the callback would be useful, but decided exposing this to the
user is probably a disservice, since we already publicly
document that they should avoid the old style, and since this
patch already demonstrates that older libvirt versions have
weird behavior when mixing old and new styles.
And like all good bug fix patches, I enhanced the testsuite,
validating that the changes in tests/ expose the failure
without the rest of the patch.
* src/conf/object_event.c (virObjectEventCallbackLookup)
(virObjectEventStateCallbackID): New functions.
(virObjectEventCallbackLookup): Use helper function.
* src/conf/object_event_private.h (virObjectEventStateCallbackID):
Declare new function.
* src/conf/domain_event.c (virDomainEventStateRegister)
(virDomainEventStateDeregister): Let common code handle the
complexity.
(virDomainEventCallbackListRemove)
(virDomainEventCallbackListMarkDelete)
(virDomainEventCallbackListAdd): Drop unused functions.
* tests/objecteventtest.c (testDomainCreateXMLMixed): New test.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 23:50:14 +00:00
|
|
|
testDomainCreateXMLNew, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
if (virtTestRun("Domain createXML start event (both API)",
|
|
|
|
testDomainCreateXMLMixed, &test) < 0)
|
2013-11-25 16:43:46 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
if (virtTestRun("Domain (un)define events", testDomainDefine, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
if (virtTestRun("Domain start stop events", testDomainStartStopEvent, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
|
2013-12-11 10:38:00 +00:00
|
|
|
/* Network event tests */
|
|
|
|
/* Tests requiring the test network not to be set up*/
|
|
|
|
if (virtTestRun("Network createXML start event ", testNetworkCreateXML, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
if (virtTestRun("Network (un)define events", testNetworkDefine, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
|
|
|
|
/* Define a test network */
|
|
|
|
test.net = virNetworkDefineXML(test.conn, networkDef);
|
|
|
|
if (virtTestRun("Network start stop events ", testNetworkStartStopEvent, &test) < 0)
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
virNetworkUndefine(test.net);
|
|
|
|
virNetworkFree(test.net);
|
2013-11-25 16:43:46 +00:00
|
|
|
virConnectClose(test.conn);
|
2014-01-01 16:30:12 +00:00
|
|
|
virEventRemoveTimeout(timer);
|
2013-11-25 16:43:46 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIRT_TEST_MAIN(mymain)
|