]> xenbits.xensource.com Git - libvirt.git/commitdiff
Move test driver into src/test/
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 15 Sep 2009 17:38:50 +0000 (18:38 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 21 Sep 2009 13:41:44 +0000 (14:41 +0100)
* src/Makefile.am, src/libvirt.c: Adjust for changed paths
* src/test.c: Rename to src/test/test_driver.c,
* src/test.h: Rename to src/test/test_driver.h

src/Makefile.am
src/libvirt.c
src/test.c [deleted file]
src/test.h [deleted file]
src/test/test_driver.c [new file with mode: 0644]
src/test/test_driver.h [new file with mode: 0644]

index 81c40e45a89a0e5cefeb9306bc5d582320a4add6..b2c2ca6187e702593513ebc704e54e40bc6526aa 100644 (file)
@@ -104,7 +104,7 @@ REMOTE_DRIVER_SOURCES =                                             \
 
 # Mock driver, covering domains, storage, networks, etc
 TEST_DRIVER_SOURCES =                                          \
-               test.c test.h
+               test/test_driver.c test/test_driver.h
 
 
 
index 6a0fb00a64c7d1b8b45cc999c3299b788d6da8bf..98f17ffc985a2f6b457f1e571f025cd1f257b20a 100644 (file)
@@ -44,7 +44,7 @@
 
 #ifndef WITH_DRIVER_MODULES
 #ifdef WITH_TEST
-#include "test.h"
+#include "test/test_driver.h"
 #endif
 #ifdef WITH_XEN
 #include "xen/xen_driver.h"
diff --git a/src/test.c b/src/test.c
deleted file mode 100644 (file)
index 368a3cb..0000000
+++ /dev/null
@@ -1,4375 +0,0 @@
-/*
- * test.c: A "mock" hypervisor for use by application unit tests
- *
- * Copyright (C) 2006-2009 Red Hat, Inc.
- * Copyright (C) 2006 Daniel P. Berrange
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- *
- * Daniel Berrange <berrange@redhat.com>
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <libxml/xmlsave.h>
-
-
-#include "virterror_internal.h"
-#include "datatypes.h"
-#include "test.h"
-#include "buf.h"
-#include "util.h"
-#include "uuid.h"
-#include "capabilities.h"
-#include "memory.h"
-#include "network_conf.h"
-#include "interface_conf.h"
-#include "domain_conf.h"
-#include "domain_event.h"
-#include "event.h"
-#include "storage_conf.h"
-#include "xml.h"
-#include "threads.h"
-#include "logging.h"
-
-#define VIR_FROM_THIS VIR_FROM_TEST
-
-#define MAX_CPUS 128
-
-struct _testCell {
-    unsigned long mem;
-    int numCpus;
-    int cpus[MAX_CPUS];
-};
-typedef struct _testCell testCell;
-typedef struct _testCell *testCellPtr;
-
-#define MAX_CELLS 128
-
-struct _testConn {
-    virMutex lock;
-
-    char path[PATH_MAX];
-    int nextDomID;
-    virCapsPtr caps;
-    virNodeInfo nodeInfo;
-    virDomainObjList domains;
-    virNetworkObjList networks;
-    virInterfaceObjList ifaces;
-    virStoragePoolObjList pools;
-    int numCells;
-    testCell cells[MAX_CELLS];
-
-
-    /* An array of callbacks */
-    virDomainEventCallbackListPtr domainEventCallbacks;
-    virDomainEventQueuePtr domainEventQueue;
-    int domainEventTimer;
-    int domainEventDispatching;
-};
-typedef struct _testConn testConn;
-typedef struct _testConn *testConnPtr;
-
-#define TEST_MODEL "i686"
-#define TEST_MODEL_WORDSIZE 32
-#define TEST_EMULATOR "/usr/bin/test-hv"
-
-static const virNodeInfo defaultNodeInfo = {
-    TEST_MODEL,
-    1024*1024*3, /* 3 GB */
-    16,
-    1400,
-    2,
-    2,
-    2,
-    2,
-};
-
-
-#define testError(conn, code, fmt...)                               \
-        virReportErrorHelper(conn, VIR_FROM_TEST, code, __FILE__, \
-                               __FUNCTION__, __LINE__, fmt)
-
-static int testClose(virConnectPtr conn);
-static void testDomainEventFlush(int timer, void *opaque);
-static void testDomainEventQueue(testConnPtr driver,
-                                 virDomainEventPtr event);
-
-
-static void testDriverLock(testConnPtr driver)
-{
-    virMutexLock(&driver->lock);
-}
-
-static void testDriverUnlock(testConnPtr driver)
-{
-    virMutexUnlock(&driver->lock);
-}
-
-static virCapsPtr
-testBuildCapabilities(virConnectPtr conn) {
-    testConnPtr privconn = conn->privateData;
-    virCapsPtr caps;
-    virCapsGuestPtr guest;
-    const char *const guest_types[] = { "hvm", "xen" };
-    int i;
-
-    if ((caps = virCapabilitiesNew(TEST_MODEL, 0, 0)) == NULL)
-        goto no_memory;
-
-    if (virCapabilitiesAddHostFeature(caps, "pae") < 0)
-        goto no_memory;
-    if (virCapabilitiesAddHostFeature(caps ,"nonpae") < 0)
-        goto no_memory;
-
-    for (i = 0; i < privconn->numCells; i++) {
-        if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].numCpus,
-                                           privconn->cells[i].cpus) < 0)
-            goto no_memory;
-    }
-
-    for (i = 0; i < ARRAY_CARDINALITY(guest_types) ; i++) {
-        if ((guest = virCapabilitiesAddGuest(caps,
-                                             guest_types[i],
-                                             TEST_MODEL,
-                                             TEST_MODEL_WORDSIZE,
-                                             TEST_EMULATOR,
-                                             NULL,
-                                             0,
-                                             NULL)) == NULL)
-            goto no_memory;
-
-        if (virCapabilitiesAddGuestDomain(guest,
-                                          "test",
-                                          NULL,
-                                          NULL,
-                                          0,
-                                          NULL) == NULL)
-            goto no_memory;
-
-        if (virCapabilitiesAddGuestFeature(guest, "pae", 1, 1) == NULL)
-            goto no_memory;
-        if (virCapabilitiesAddGuestFeature(guest ,"nonpae", 1, 1) == NULL)
-            goto no_memory;
-    }
-
-    return caps;
-
-no_memory:
-    virReportOOMError(conn);
-    virCapabilitiesFree(caps);
-    return NULL;
-}
-
-
-static const char *defaultDomainXML =
-"<domain type='test'>"
-"  <name>test</name>"
-"  <memory>8388608</memory>"
-"  <currentMemory>2097152</currentMemory>"
-"  <vcpu>2</vcpu>"
-"  <os>"
-"    <type>hvm</type>"
-"  </os>"
-"</domain>";
-
-
-static const char *defaultNetworkXML =
-"<network>"
-"  <name>default</name>"
-"  <bridge name='virbr0' />"
-"  <forward/>"
-"  <ip address='192.168.122.1' netmask='255.255.255.0'>"
-"    <dhcp>"
-"      <range start='192.168.122.2' end='192.168.122.254' />"
-"    </dhcp>"
-"  </ip>"
-"</network>";
-
-static const char *defaultInterfaceXML =
-"<interface type=\"ethernet\" name=\"eth1\">"
-"  <start mode=\"onboot\"/>"
-"  <mac address=\"aa:bb:cc:dd:ee:ff\"/>"
-"  <mtu size=\"1492\"/>"
-"  <protocol family=\"ipv4\">"
-"    <ip address=\"192.168.0.5\" prefix=\"24\"/>"
-"    <route gateway=\"192.168.0.1\"/>"
-"  </protocol>"
-"</interface>";
-
-static const char *defaultPoolXML =
-"<pool type='dir'>"
-"  <name>default-pool</name>"
-"  <target>"
-"    <path>/default-pool</path>"
-"  </target>"
-"</pool>";
-
-static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull);
-static const unsigned long long defaultPoolAlloc = 0;
-
-static int testStoragePoolObjSetDefaults(virConnectPtr conn, virStoragePoolObjPtr pool);
-
-static char *
-testDomainGenerateIfname(virConnectPtr conn,
-                         virDomainDefPtr domdef) {
-    int maxif = 1024;
-    int ifctr, i;
-
-    for (ifctr = 0; ifctr < maxif; ++ifctr) {
-        char *ifname;
-        int found = 0;
-
-        if (virAsprintf(&ifname, "testnet%d", ifctr) < 0) {
-            virReportOOMError(conn);
-            return NULL;
-        }
-
-        /* Generate network interface names */
-        for (i = 0 ; i < domdef->nnets ; i++) {
-            if (domdef->nets[i]->ifname &&
-                STREQ (domdef->nets[i]->ifname, ifname)) {
-                found = 1;
-                break;
-            }
-        }
-
-        if (!found)
-            return ifname;
-    }
-
-    testError(conn, VIR_ERR_INTERNAL_ERROR,
-              _("Exceeded max iface limit %d"), maxif);
-    return NULL;
-}
-
-static int
-testDomainGenerateIfnames(virConnectPtr conn,
-                          virDomainDefPtr domdef)
-{
-    int i = 0;
-
-    for (i = 0; i < domdef->nnets; i++) {
-        char *ifname;
-        if (domdef->nets[i]->ifname)
-            continue;
-
-        ifname = testDomainGenerateIfname(conn, domdef);
-        if (!ifname)
-            return -1;
-
-        domdef->nets[i]->ifname = ifname;
-    }
-
-    return 0;
-}
-
-
-static int testOpenDefault(virConnectPtr conn) {
-    int u;
-    struct timeval tv;
-    testConnPtr privconn;
-    virDomainDefPtr domdef = NULL;
-    virDomainObjPtr domobj = NULL;
-    virNetworkDefPtr netdef = NULL;
-    virNetworkObjPtr netobj = NULL;
-    virInterfaceDefPtr interfacedef = NULL;
-    virInterfaceObjPtr interfaceobj = NULL;
-    virStoragePoolDefPtr pooldef = NULL;
-    virStoragePoolObjPtr poolobj = NULL;
-
-    if (VIR_ALLOC(privconn) < 0) {
-        virReportOOMError(conn);
-        return VIR_DRV_OPEN_ERROR;
-    }
-    if (virMutexInit(&privconn->lock) < 0) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("cannot initialize mutex"));
-        VIR_FREE(privconn);
-        return VIR_DRV_OPEN_ERROR;
-    }
-
-    testDriverLock(privconn);
-    conn->privateData = privconn;
-
-    if (gettimeofday(&tv, NULL) < 0) {
-        virReportSystemError(conn, errno,
-                             "%s", _("getting time of day"));
-        goto error;
-    }
-
-    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
-
-    // Numa setup
-    privconn->numCells = 2;
-    for (u = 0; u < 2; ++u) {
-        privconn->cells[u].numCpus = 8;
-        privconn->cells[u].mem = (u + 1) * 2048 * 1024;
-    }
-    for (u = 0 ; u < 16 ; u++) {
-        privconn->cells[u % 2].cpus[(u / 2)] = u;
-    }
-
-    if (!(privconn->caps = testBuildCapabilities(conn)))
-        goto error;
-
-    privconn->nextDomID = 1;
-
-    if (!(domdef = virDomainDefParseString(conn, privconn->caps,
-                                           defaultDomainXML,
-                                           VIR_DOMAIN_XML_INACTIVE)))
-        goto error;
-    if (testDomainGenerateIfnames(conn, domdef) < 0)
-        goto error;
-    if (!(domobj = virDomainAssignDef(conn, &privconn->domains, domdef)))
-        goto error;
-    domdef = NULL;
-    domobj->def->id = privconn->nextDomID++;
-    domobj->state = VIR_DOMAIN_RUNNING;
-    domobj->persistent = 1;
-    virDomainObjUnlock(domobj);
-
-    if (!(netdef = virNetworkDefParseString(conn, defaultNetworkXML)))
-        goto error;
-    if (!(netobj = virNetworkAssignDef(conn, &privconn->networks, netdef))) {
-        virNetworkDefFree(netdef);
-        goto error;
-    }
-    netobj->active = 1;
-    netobj->persistent = 1;
-    virNetworkObjUnlock(netobj);
-
-    if (!(interfacedef = virInterfaceDefParseString(conn, defaultInterfaceXML)))
-        goto error;
-    if (!(interfaceobj = virInterfaceAssignDef(conn, &privconn->ifaces, interfacedef))) {
-        virInterfaceDefFree(interfacedef);
-        goto error;
-    }
-    interfaceobj->active = 1;
-    virInterfaceObjUnlock(interfaceobj);
-
-    if (!(pooldef = virStoragePoolDefParseString(conn, defaultPoolXML)))
-        goto error;
-
-    if (!(poolobj = virStoragePoolObjAssignDef(conn, &privconn->pools,
-                                               pooldef))) {
-        virStoragePoolDefFree(pooldef);
-        goto error;
-    }
-
-    if (testStoragePoolObjSetDefaults(conn, poolobj) == -1) {
-        virStoragePoolObjUnlock(poolobj);
-        goto error;
-    }
-    poolobj->active = 1;
-    virStoragePoolObjUnlock(poolobj);
-
-    testDriverUnlock(privconn);
-
-    return VIR_DRV_OPEN_SUCCESS;
-
-error:
-    virDomainObjListFree(&privconn->domains);
-    virNetworkObjListFree(&privconn->networks);
-    virInterfaceObjListFree(&privconn->ifaces);
-    virStoragePoolObjListFree(&privconn->pools);
-    virCapabilitiesFree(privconn->caps);
-    testDriverUnlock(privconn);
-    conn->privateData = NULL;
-    VIR_FREE(privconn);
-    virDomainDefFree(domdef);
-    return VIR_DRV_OPEN_ERROR;
-}
-
-
-static char *testBuildFilename(const char *relativeTo,
-                               const char *filename) {
-    char *offset;
-    int baseLen;
-    if (!filename || filename[0] == '\0')
-        return (NULL);
-    if (filename[0] == '/')
-        return strdup(filename);
-
-    offset = strrchr(relativeTo, '/');
-    if ((baseLen = (offset-relativeTo+1))) {
-        char *absFile;
-        if (VIR_ALLOC_N(absFile, baseLen + strlen(filename) + 1) < 0)
-            return NULL;
-        strncpy(absFile, relativeTo, baseLen);
-        absFile[baseLen] = '\0';
-        strcat(absFile, filename);
-        return absFile;
-    } else {
-        return strdup(filename);
-    }
-}
-
-static int testOpenVolumesForPool(virConnectPtr conn,
-                                  xmlDocPtr xml,
-                                  xmlXPathContextPtr ctxt,
-                                  const char *file,
-                                  virStoragePoolObjPtr pool,
-                                  int poolidx) {
-    char *vol_xpath;
-    int i, ret, func_ret = -1;
-    xmlNodePtr *vols = NULL;
-    virStorageVolDefPtr def = NULL;
-
-    /* Find storage volumes */
-    if (virAsprintf(&vol_xpath, "/node/pool[%d]/volume", poolidx) < 0) {
-        virReportOOMError(NULL);
-        goto error;
-    }
-
-    ret = virXPathNodeSet(conn, vol_xpath, ctxt, &vols);
-    VIR_FREE(vol_xpath);
-    if (ret < 0) {
-        testError(NULL, VIR_ERR_XML_ERROR,
-                  _("node vol list for pool '%s'"), pool->def->name);
-        goto error;
-    }
-
-    for (i = 0 ; i < ret ; i++) {
-        char *relFile = virXMLPropString(vols[i], "file");
-        if (relFile != NULL) {
-            char *absFile = testBuildFilename(file, relFile);
-            VIR_FREE(relFile);
-            if (!absFile) {
-                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
-                          _("resolving volume filename"));
-                goto error;
-            }
-
-            def = virStorageVolDefParseFile(conn, pool->def, absFile);
-            VIR_FREE(absFile);
-            if (!def)
-                goto error;
-        } else {
-            if ((def = virStorageVolDefParseNode(conn, pool->def, xml,
-                                                 vols[i])) == NULL) {
-                goto error;
-            }
-        }
-
-        if (VIR_REALLOC_N(pool->volumes.objs,
-                          pool->volumes.count+1) < 0) {
-            virReportOOMError(conn);
-            goto error;
-        }
-
-        if (virAsprintf(&def->target.path, "%s/%s",
-                        pool->def->target.path,
-                        def->name) == -1) {
-            virReportOOMError(conn);
-            goto error;
-        }
-
-        def->key = strdup(def->target.path);
-        if (def->key == NULL) {
-            virReportOOMError(conn);
-            goto error;
-        }
-
-        pool->def->allocation += def->allocation;
-        pool->def->available = (pool->def->capacity -
-                                pool->def->allocation);
-
-        pool->volumes.objs[pool->volumes.count++] = def;
-        def = NULL;
-    }
-
-    func_ret = 0;
-error:
-    virStorageVolDefFree(def);
-    VIR_FREE(vols);
-    return func_ret;
-}
-
-static int testOpenFromFile(virConnectPtr conn,
-                            const char *file) {
-    int fd = -1, i, ret;
-    long l;
-    char *str;
-    xmlDocPtr xml = NULL;
-    xmlNodePtr root = NULL;
-    xmlNodePtr *domains = NULL, *networks = NULL, *ifaces = NULL, *pools = NULL;
-    xmlXPathContextPtr ctxt = NULL;
-    virNodeInfoPtr nodeInfo;
-    virNetworkObjPtr net;
-    virInterfaceObjPtr iface;
-    virDomainObjPtr dom;
-    testConnPtr privconn;
-    if (VIR_ALLOC(privconn) < 0) {
-        virReportOOMError(conn);
-        return VIR_DRV_OPEN_ERROR;
-    }
-    if (virMutexInit(&privconn->lock) < 0) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("cannot initialize mutex"));
-        VIR_FREE(privconn);
-        return VIR_DRV_OPEN_ERROR;
-    }
-
-    testDriverLock(privconn);
-    conn->privateData = privconn;
-
-    if (!(privconn->caps = testBuildCapabilities(conn)))
-        goto error;
-
-    if ((fd = open(file, O_RDONLY)) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("loading host definition file '%s'"),
-                             file);
-        goto error;
-    }
-
-    if (!(xml = xmlReadFd(fd, file, NULL,
-                          XML_PARSE_NOENT | XML_PARSE_NONET |
-                          XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
-        testError(NULL, VIR_ERR_INTERNAL_ERROR,
-                  _("Invalid XML in file '%s'"), file);
-        goto error;
-    }
-    close(fd);
-    fd = -1;
-
-    root = xmlDocGetRootElement(xml);
-    if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s",
-                  _("Root element is not 'node'"));
-        goto error;
-    }
-
-    ctxt = xmlXPathNewContext(xml);
-    if (ctxt == NULL) {
-        testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
-                  _("creating xpath context"));
-        goto error;
-    }
-
-    privconn->nextDomID = 1;
-    privconn->numCells = 0;
-    strncpy(privconn->path, file, PATH_MAX-1);
-    privconn->path[PATH_MAX-1] = '\0';
-    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
-
-    nodeInfo = &privconn->nodeInfo;
-    ret = virXPathLong(conn, "string(/node/cpu/nodes[1])", ctxt, &l);
-    if (ret == 0) {
-        nodeInfo->nodes = l;
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu numa nodes"));
-        goto error;
-    }
-
-    ret = virXPathLong(conn, "string(/node/cpu/sockets[1])", ctxt, &l);
-    if (ret == 0) {
-        nodeInfo->sockets = l;
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu sockets"));
-        goto error;
-    }
-
-    ret = virXPathLong(conn, "string(/node/cpu/cores[1])", ctxt, &l);
-    if (ret == 0) {
-        nodeInfo->cores = l;
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu cores"));
-        goto error;
-    }
-
-    ret = virXPathLong(conn, "string(/node/cpu/threads[1])", ctxt, &l);
-    if (ret == 0) {
-        nodeInfo->threads = l;
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu threads"));
-        goto error;
-    }
-
-    nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
-    ret = virXPathLong(conn, "string(/node/cpu/active[1])", ctxt, &l);
-    if (ret == 0) {
-        if (l < nodeInfo->cpus) {
-            nodeInfo->cpus = l;
-        }
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node active cpu"));
-        goto error;
-    }
-    ret = virXPathLong(conn, "string(/node/cpu/mhz[1])", ctxt, &l);
-    if (ret == 0) {
-        nodeInfo->mhz = l;
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu mhz"));
-        goto error;
-    }
-
-    str = virXPathString(conn, "string(/node/cpu/model[1])", ctxt);
-    if (str != NULL) {
-        strncpy(nodeInfo->model, str, sizeof(nodeInfo->model)-1);
-        nodeInfo->model[sizeof(nodeInfo->model)-1] = '\0';
-        VIR_FREE(str);
-    }
-
-    ret = virXPathLong(conn, "string(/node/memory[1])", ctxt, &l);
-    if (ret == 0) {
-        nodeInfo->memory = l;
-    } else if (ret == -2) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node memory"));
-        goto error;
-    }
-
-    ret = virXPathNodeSet(conn, "/node/domain", ctxt, &domains);
-    if (ret < 0) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node domain list"));
-        goto error;
-    }
-
-    for (i = 0 ; i < ret ; i++) {
-        virDomainDefPtr def;
-        char *relFile = virXMLPropString(domains[i], "file");
-        if (relFile != NULL) {
-            char *absFile = testBuildFilename(file, relFile);
-            VIR_FREE(relFile);
-            if (!absFile) {
-                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving domain filename"));
-                goto error;
-            }
-            def = virDomainDefParseFile(conn, privconn->caps, absFile,
-                                        VIR_DOMAIN_XML_INACTIVE);
-            VIR_FREE(absFile);
-            if (!def)
-                goto error;
-        } else {
-            if ((def = virDomainDefParseNode(conn, privconn->caps, xml, domains[i],
-                                   VIR_DOMAIN_XML_INACTIVE)) == NULL)
-                goto error;
-        }
-
-        if (testDomainGenerateIfnames(conn, def) < 0 ||
-            !(dom = virDomainAssignDef(conn, &privconn->domains, def))) {
-            virDomainDefFree(def);
-            goto error;
-        }
-
-        dom->state = VIR_DOMAIN_RUNNING;
-        dom->def->id = privconn->nextDomID++;
-        dom->persistent = 1;
-        virDomainObjUnlock(dom);
-    }
-    VIR_FREE(domains);
-
-    ret = virXPathNodeSet(conn, "/node/network", ctxt, &networks);
-    if (ret < 0) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node network list"));
-        goto error;
-    }
-    for (i = 0 ; i < ret ; i++) {
-        virNetworkDefPtr def;
-        char *relFile = virXMLPropString(networks[i], "file");
-        if (relFile != NULL) {
-            char *absFile = testBuildFilename(file, relFile);
-            VIR_FREE(relFile);
-            if (!absFile) {
-                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving network filename"));
-                goto error;
-            }
-
-            def = virNetworkDefParseFile(conn, absFile);
-            VIR_FREE(absFile);
-            if (!def)
-                goto error;
-        } else {
-            if ((def = virNetworkDefParseNode(conn, xml, networks[i])) == NULL)
-                goto error;
-        }
-        if (!(net = virNetworkAssignDef(conn, &privconn->networks,
-                                        def))) {
-            virNetworkDefFree(def);
-            goto error;
-        }
-        net->persistent = 1;
-        net->active = 1;
-        virNetworkObjUnlock(net);
-    }
-    VIR_FREE(networks);
-
-    /* Parse interface definitions */
-    ret = virXPathNodeSet(conn, "/node/interface", ctxt, &ifaces);
-    if (ret < 0) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node interface list"));
-        goto error;
-    }
-    for (i = 0 ; i < ret ; i++) {
-        virInterfaceDefPtr def;
-        char *relFile = virXMLPropString(ifaces[i], "file");
-        if (relFile != NULL) {
-            char *absFile = testBuildFilename(file, relFile);
-            VIR_FREE(relFile);
-            if (!absFile) {
-                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving interface filename"));
-                goto error;
-            }
-
-            def = virInterfaceDefParseFile(conn, absFile);
-            VIR_FREE(absFile);
-            if (!def)
-                goto error;
-        } else {
-        if ((def = virInterfaceDefParseNode(conn, xml, ifaces[i])) == NULL)
-                goto error;
-        }
-        if (!(iface = virInterfaceAssignDef(conn, &privconn->ifaces, def))) {
-            virInterfaceDefFree(def);
-            goto error;
-        }
-        virInterfaceObjUnlock(iface);
-    }
-    VIR_FREE(ifaces);
-
-    /* Parse Storage Pool list */
-    ret = virXPathNodeSet(conn, "/node/pool", ctxt, &pools);
-    if (ret < 0) {
-        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node pool list"));
-        goto error;
-    }
-    for (i = 0 ; i < ret ; i++) {
-        virStoragePoolDefPtr def;
-        virStoragePoolObjPtr pool;
-        char *relFile = virXMLPropString(pools[i], "file");
-        if (relFile != NULL) {
-            char *absFile = testBuildFilename(file, relFile);
-            VIR_FREE(relFile);
-            if (!absFile) {
-                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
-                          _("resolving pool filename"));
-                goto error;
-            }
-
-            def = virStoragePoolDefParseFile(conn, absFile);
-            VIR_FREE(absFile);
-            if (!def)
-                goto error;
-        } else {
-            if ((def = virStoragePoolDefParseNode(conn, xml,
-                                                  pools[i])) == NULL) {
-                goto error;
-            }
-        }
-
-        if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools,
-                                                def))) {
-            virStoragePoolDefFree(def);
-            goto error;
-        }
-
-        if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
-            virStoragePoolObjUnlock(pool);
-            goto error;
-        }
-        pool->active = 1;
-
-        /* Find storage volumes */
-        if (testOpenVolumesForPool(conn, xml, ctxt, file, pool, i+1) < 0) {
-            virStoragePoolObjUnlock(pool);
-            goto error;
-        }
-
-        virStoragePoolObjUnlock(pool);
-    }
-    VIR_FREE(pools);
-
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
-    testDriverUnlock(privconn);
-
-    return (0);
-
- error:
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
-    VIR_FREE(domains);
-    VIR_FREE(networks);
-    VIR_FREE(ifaces);
-    VIR_FREE(pools);
-    if (fd != -1)
-        close(fd);
-    virDomainObjListFree(&privconn->domains);
-    virNetworkObjListFree(&privconn->networks);
-    virInterfaceObjListFree(&privconn->ifaces);
-    virStoragePoolObjListFree(&privconn->pools);
-    testDriverUnlock(privconn);
-    VIR_FREE(privconn);
-    conn->privateData = NULL;
-    return VIR_DRV_OPEN_ERROR;
-}
-
-
-static virDrvOpenStatus testOpen(virConnectPtr conn,
-                    virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                    int flags ATTRIBUTE_UNUSED)
-{
-    int ret;
-
-    if (!conn->uri)
-        return VIR_DRV_OPEN_DECLINED;
-
-    if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "test"))
-        return VIR_DRV_OPEN_DECLINED;
-
-    /* Remote driver should handle these. */
-    if (conn->uri->server)
-        return VIR_DRV_OPEN_DECLINED;
-
-    /* From this point on, the connection is for us. */
-    if (!conn->uri->path
-        || conn->uri->path[0] == '\0'
-        || (conn->uri->path[0] == '/' && conn->uri->path[1] == '\0')) {
-        testError (NULL, VIR_ERR_INVALID_ARG,
-                   "%s", _("testOpen: supply a path or use test:///default"));
-        return VIR_DRV_OPEN_ERROR;
-    }
-
-    if (STREQ(conn->uri->path, "/default"))
-        ret = testOpenDefault(conn);
-    else
-        ret = testOpenFromFile(conn,
-                               conn->uri->path);
-
-    if (ret == VIR_DRV_OPEN_SUCCESS) {
-        testConnPtr privconn = conn->privateData;
-        testDriverLock(privconn);
-        /* Init callback list */
-        if (VIR_ALLOC(privconn->domainEventCallbacks) < 0 ||
-            !(privconn->domainEventQueue = virDomainEventQueueNew())) {
-            virReportOOMError(NULL);
-            testDriverUnlock(privconn);
-            testClose(conn);
-            return VIR_DRV_OPEN_ERROR;
-        }
-
-        if ((privconn->domainEventTimer =
-             virEventAddTimeout(-1, testDomainEventFlush, privconn, NULL)) < 0)
-            DEBUG0("virEventAddTimeout failed: No addTimeoutImpl defined. "
-                   "continuing without events.");
-        testDriverUnlock(privconn);
-    }
-
-    return (ret);
-}
-
-static int testClose(virConnectPtr conn)
-{
-    testConnPtr privconn = conn->privateData;
-    testDriverLock(privconn);
-    virCapabilitiesFree(privconn->caps);
-    virDomainObjListFree(&privconn->domains);
-    virNetworkObjListFree(&privconn->networks);
-    virInterfaceObjListFree(&privconn->ifaces);
-    virStoragePoolObjListFree(&privconn->pools);
-
-    virDomainEventCallbackListFree(privconn->domainEventCallbacks);
-    virDomainEventQueueFree(privconn->domainEventQueue);
-
-    if (privconn->domainEventTimer != -1)
-        virEventRemoveTimeout(privconn->domainEventTimer);
-
-    testDriverUnlock(privconn);
-    virMutexDestroy(&privconn->lock);
-
-    VIR_FREE (privconn);
-    conn->privateData = NULL;
-    return 0;
-}
-
-static int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
-                          unsigned long *hvVer)
-{
-    *hvVer = 2;
-    return (0);
-}
-
-static char *testGetHostname (virConnectPtr conn)
-{
-    char *result;
-
-    result = virGetHostname();
-    if (result == NULL) {
-        virReportSystemError(conn, errno,
-                             "%s", _("cannot lookup hostname"));
-        return NULL;
-    }
-    /* Caller frees this string. */
-    return result;
-}
-
-static int testGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
-                           const char *type ATTRIBUTE_UNUSED)
-{
-    return 32;
-}
-
-static int testNodeGetInfo(virConnectPtr conn,
-                           virNodeInfoPtr info)
-{
-    testConnPtr privconn = conn->privateData;
-    testDriverLock(privconn);
-    memcpy(info, &privconn->nodeInfo, sizeof(virNodeInfo));
-    testDriverUnlock(privconn);
-    return (0);
-}
-
-static char *testGetCapabilities (virConnectPtr conn)
-{
-    testConnPtr privconn = conn->privateData;
-    char *xml;
-    testDriverLock(privconn);
-    if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
-        virReportOOMError(conn);
-    testDriverUnlock(privconn);
-    return xml;
-}
-
-static int testNumOfDomains(virConnectPtr conn)
-{
-    testConnPtr privconn = conn->privateData;
-    unsigned int numActive = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->domains.count ; i++)
-        if (virDomainIsActive(privconn->domains.objs[i]))
-            numActive++;
-    testDriverUnlock(privconn);
-
-    return numActive;
-}
-
-static virDomainPtr
-testDomainCreateXML(virConnectPtr conn, const char *xml,
-                      unsigned int flags ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = conn->privateData;
-    virDomainPtr ret = NULL;
-    virDomainDefPtr def;
-    virDomainObjPtr dom = NULL;
-    virDomainEventPtr event = NULL;
-
-    testDriverLock(privconn);
-    if ((def = virDomainDefParseString(conn, privconn->caps, xml,
-                                       VIR_DOMAIN_XML_INACTIVE)) == NULL)
-        goto cleanup;
-
-    if (testDomainGenerateIfnames(conn, def) < 0)
-        goto cleanup;
-    if (!(dom = virDomainAssignDef(conn, &privconn->domains, def)))
-        goto cleanup;
-    def = NULL;
-    dom->state = VIR_DOMAIN_RUNNING;
-    dom->def->id = privconn->nextDomID++;
-
-    event = virDomainEventNewFromObj(dom,
-                                     VIR_DOMAIN_EVENT_STARTED,
-                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);
-
-    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
-    if (ret)
-        ret->id = dom->def->id;
-
-cleanup:
-    if (dom)
-        virDomainObjUnlock(dom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    if (def)
-        virDomainDefFree(def);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-
-static virDomainPtr testLookupDomainByID(virConnectPtr conn,
-                                         int id)
-{
-    testConnPtr privconn = conn->privateData;
-    virDomainPtr ret = NULL;
-    virDomainObjPtr dom;
-
-    testDriverLock(privconn);
-    dom = virDomainFindByID(&privconn->domains, id);
-    testDriverUnlock(privconn);
-
-    if (dom == NULL) {
-        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
-    if (ret)
-        ret->id = dom->def->id;
-
-cleanup:
-    if (dom)
-        virDomainObjUnlock(dom);
-    return ret;
-}
-
-static virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
-                                           const unsigned char *uuid)
-{
-    testConnPtr privconn = conn->privateData;
-    virDomainPtr ret = NULL;
-    virDomainObjPtr dom ;
-
-    testDriverLock(privconn);
-    dom = virDomainFindByUUID(&privconn->domains, uuid);
-    testDriverUnlock(privconn);
-
-    if (dom == NULL) {
-        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
-    if (ret)
-        ret->id = dom->def->id;
-
-cleanup:
-    if (dom)
-        virDomainObjUnlock(dom);
-    return ret;
-}
-
-static virDomainPtr testLookupDomainByName(virConnectPtr conn,
-                                           const char *name)
-{
-    testConnPtr privconn = conn->privateData;
-    virDomainPtr ret = NULL;
-    virDomainObjPtr dom;
-
-    testDriverLock(privconn);
-    dom = virDomainFindByName(&privconn->domains, name);
-    testDriverUnlock(privconn);
-
-    if (dom == NULL) {
-        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
-    if (ret)
-        ret->id = dom->def->id;
-
-cleanup:
-    if (dom)
-        virDomainObjUnlock(dom);
-    return ret;
-}
-
-static int testListDomains (virConnectPtr conn,
-                            int *ids,
-                            int maxids)
-{
-    testConnPtr privconn = conn->privateData;
-    unsigned int n = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->domains.count && n < maxids ; i++) {
-        virDomainObjLock(privconn->domains.objs[i]);
-        if (virDomainIsActive(privconn->domains.objs[i]))
-            ids[n++] = privconn->domains.objs[i]->def->id;
-        virDomainObjUnlock(privconn->domains.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-}
-
-static int testDestroyDomain (virDomainPtr domain)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privdom->state = VIR_DOMAIN_SHUTOFF;
-    privdom->def->id = -1;
-    domain->id = -1;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_STOPPED,
-                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
-    if (!privdom->persistent) {
-        virDomainRemoveInactive(&privconn->domains,
-                                privdom);
-        privdom = NULL;
-    }
-
-
-    ret = 0;
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testResumeDomain (virDomainPtr domain)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (privdom->state != VIR_DOMAIN_PAUSED) {
-        testError(domain->conn,
-                  VIR_ERR_INTERNAL_ERROR, _("domain '%s' not paused"),
-                  domain->name);
-        goto cleanup;
-    }
-
-    privdom->state = VIR_DOMAIN_RUNNING;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_RESUMED,
-                                     VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event) {
-        testDriverLock(privconn);
-        testDomainEventQueue(privconn, event);
-        testDriverUnlock(privconn);
-    }
-    return ret;
-}
-
-static int testPauseDomain (virDomainPtr domain)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (privdom->state == VIR_DOMAIN_SHUTOFF ||
-        privdom->state == VIR_DOMAIN_PAUSED) {
-        testError(domain->conn,
-                  VIR_ERR_INTERNAL_ERROR, _("domain '%s' not running"),
-                  domain->name);
-        goto cleanup;
-    }
-
-    privdom->state = VIR_DOMAIN_PAUSED;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_SUSPENDED,
-                                     VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-
-    if (event) {
-        testDriverLock(privconn);
-        testDomainEventQueue(privconn, event);
-        testDriverUnlock(privconn);
-    }
-    return ret;
-}
-
-static int testShutdownDomain (virDomainPtr domain)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (privdom->state == VIR_DOMAIN_SHUTOFF) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("domain '%s' not running"), domain->name);
-        goto cleanup;
-    }
-
-    privdom->state = VIR_DOMAIN_SHUTOFF;
-    domain->id = -1;
-    privdom->def->id = -1;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_STOPPED,
-                                     VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
-    if (!privdom->persistent) {
-        virDomainRemoveInactive(&privconn->domains,
-                                privdom);
-        privdom = NULL;
-    }
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-/* Similar behaviour as shutdown */
-static int testRebootDomain (virDomainPtr domain,
-                             unsigned int action ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privdom->state = VIR_DOMAIN_SHUTDOWN;
-    switch (privdom->def->onReboot) {
-    case VIR_DOMAIN_LIFECYCLE_DESTROY:
-        privdom->state = VIR_DOMAIN_SHUTOFF;
-        domain->id = -1;
-        privdom->def->id = -1;
-        break;
-
-    case VIR_DOMAIN_LIFECYCLE_RESTART:
-        privdom->state = VIR_DOMAIN_RUNNING;
-        break;
-
-    case VIR_DOMAIN_LIFECYCLE_PRESERVE:
-        privdom->state = VIR_DOMAIN_SHUTOFF;
-        domain->id = -1;
-        privdom->def->id = -1;
-        break;
-
-    case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME:
-        privdom->state = VIR_DOMAIN_RUNNING;
-        break;
-
-    default:
-        privdom->state = VIR_DOMAIN_SHUTOFF;
-        domain->id = -1;
-        privdom->def->id = -1;
-        break;
-    }
-
-    if (privdom->state == VIR_DOMAIN_SHUTOFF) {
-        event = virDomainEventNewFromObj(privdom,
-                                         VIR_DOMAIN_EVENT_STOPPED,
-                                         VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
-        if (!privdom->persistent) {
-            virDomainRemoveInactive(&privconn->domains,
-                                    privdom);
-            privdom = NULL;
-        }
-    }
-
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testGetDomainInfo (virDomainPtr domain,
-                              virDomainInfoPtr info)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    struct timeval tv;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (gettimeofday(&tv, NULL) < 0) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("getting time of day"));
-        goto cleanup;
-    }
-
-    info->state = privdom->state;
-    info->memory = privdom->def->memory;
-    info->maxMem = privdom->def->maxmem;
-    info->nrVirtCpu = privdom->def->vcpus;
-    info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll  * 1000ll) + (tv.tv_usec * 1000ll));
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-#define TEST_SAVE_MAGIC "TestGuestMagic"
-
-static int testDomainSave(virDomainPtr domain,
-                          const char *path)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    char *xml = NULL;
-    int fd = -1;
-    int len;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    xml = virDomainDefFormat(domain->conn,
-                             privdom->def,
-                             VIR_DOMAIN_XML_SECURE);
-
-    if (xml == NULL) {
-        virReportSystemError(domain->conn, errno,
-                             _("saving domain '%s' failed to allocate space for metadata"),
-                             domain->name);
-        goto cleanup;
-    }
-
-    if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("saving domain '%s' to '%s': open failed"),
-                             domain->name, path);
-        goto cleanup;
-    }
-    len = strlen(xml);
-    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("saving domain '%s' to '%s': write failed"),
-                             domain->name, path);
-        goto cleanup;
-    }
-    if (safewrite(fd, (char*)&len, sizeof(len)) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("saving domain '%s' to '%s': write failed"),
-                             domain->name, path);
-        goto cleanup;
-    }
-    if (safewrite(fd, xml, len) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("saving domain '%s' to '%s': write failed"),
-                             domain->name, path);
-        goto cleanup;
-    }
-
-    if (close(fd) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("saving domain '%s' to '%s': write failed"),
-                             domain->name, path);
-        goto cleanup;
-    }
-    fd = -1;
-
-    privdom->state = VIR_DOMAIN_SHUTOFF;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_STOPPED,
-                                     VIR_DOMAIN_EVENT_STOPPED_SAVED);
-    if (!privdom->persistent) {
-        virDomainRemoveInactive(&privconn->domains,
-                                privdom);
-        privdom = NULL;
-    }
-    ret = 0;
-
-cleanup:
-    VIR_FREE(xml);
-
-    /* Don't report failure in close or unlink, because
-     * in either case we're already in a failure scenario
-     * and have reported a earlier error */
-    if (ret != 0) {
-        if (fd != -1)
-            close(fd);
-        unlink(path);
-    }
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testDomainRestore(virConnectPtr conn,
-                             const char *path)
-{
-    testConnPtr privconn = conn->privateData;
-    char *xml = NULL;
-    char magic[15];
-    int fd = -1;
-    int len;
-    virDomainDefPtr def = NULL;
-    virDomainObjPtr dom = NULL;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    if ((fd = open(path, O_RDONLY)) < 0) {
-        virReportSystemError(conn, errno,
-                             _("cannot read domain image '%s'"),
-                             path);
-        goto cleanup;
-    }
-    if (saferead(fd, magic, sizeof(magic)) != sizeof(magic)) {
-        virReportSystemError(conn, errno,
-                             _("incomplete save header in '%s'"),
-                             path);
-        goto cleanup;
-    }
-    if (memcmp(magic, TEST_SAVE_MAGIC, sizeof(magic))) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("mismatched header magic"));
-        goto cleanup;
-    }
-    if (saferead(fd, (char*)&len, sizeof(len)) != sizeof(len)) {
-        virReportSystemError(conn, errno,
-                             _("failed to read metadata length in '%s'"),
-                             path);
-        goto cleanup;
-    }
-    if (len < 1 || len > 8192) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("length of metadata out of range"));
-        goto cleanup;
-    }
-    if (VIR_ALLOC_N(xml, len+1) < 0) {
-        virReportOOMError(conn);
-        goto cleanup;
-    }
-    if (saferead(fd, xml, len) != len) {
-        virReportSystemError(conn, errno,
-                             _("incomplete metdata in '%s'"), path);
-        goto cleanup;
-    }
-    xml[len] = '\0';
-
-    testDriverLock(privconn);
-    def = virDomainDefParseString(conn, privconn->caps, xml,
-                                  VIR_DOMAIN_XML_INACTIVE);
-    if (!def)
-        goto cleanup;
-
-    if (testDomainGenerateIfnames(conn, def) < 0)
-        goto cleanup;
-    if (!(dom = virDomainAssignDef(conn, &privconn->domains, def)))
-        goto cleanup;
-    def = NULL;
-
-    dom->state = VIR_DOMAIN_RUNNING;
-    dom->def->id = privconn->nextDomID++;
-    event = virDomainEventNewFromObj(dom,
-                                     VIR_DOMAIN_EVENT_STARTED,
-                                     VIR_DOMAIN_EVENT_STARTED_RESTORED);
-    ret = 0;
-
-cleanup:
-    virDomainDefFree(def);
-    VIR_FREE(xml);
-    if (fd != -1)
-        close(fd);
-    if (dom)
-        virDomainObjUnlock(dom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testDomainCoreDump(virDomainPtr domain,
-                              const char *to,
-                              int flags ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    int fd = -1;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if ((fd = open(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("domain '%s' coredump: failed to open %s"),
-                             domain->name, to);
-        goto cleanup;
-    }
-    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("domain '%s' coredump: failed to write header to %s"),
-                             domain->name, to);
-        goto cleanup;
-    }
-    if (close(fd) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             _("domain '%s' coredump: write failed: %s"),
-                             domain->name, to);
-        goto cleanup;
-    }
-    privdom->state = VIR_DOMAIN_SHUTOFF;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_STOPPED,
-                                     VIR_DOMAIN_EVENT_STOPPED_CRASHED);
-    if (!privdom->persistent) {
-        virDomainRemoveInactive(&privconn->domains,
-                                privdom);
-        privdom = NULL;
-    }
-    ret = 0;
-
-cleanup:
-    if (fd != -1)
-        close(fd);
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static char *testGetOSType(virDomainPtr dom) {
-    char *ret = strdup("linux");
-    if (!ret)
-        virReportOOMError(dom->conn);
-    return ret;
-}
-
-static unsigned long testGetMaxMemory(virDomainPtr domain) {
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    unsigned long ret = 0;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    ret = privdom->def->maxmem;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static int testSetMaxMemory(virDomainPtr domain,
-                            unsigned long memory)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    /* XXX validate not over host memory wrt to other domains */
-    privdom->def->maxmem = memory;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static int testSetMemory(virDomainPtr domain,
-                         unsigned long memory)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (memory > privdom->def->maxmem) {
-        testError(domain->conn,
-                  VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privdom->def->memory = memory;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static int testSetVcpus(virDomainPtr domain,
-                        unsigned int nrCpus) {
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    /* We allow more cpus in guest than host */
-    if (nrCpus > 32) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privdom->def->vcpus = nrCpus;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static char *testDomainDumpXML(virDomainPtr domain, int flags)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainDefPtr def;
-    virDomainObjPtr privdom;
-    char *ret = NULL;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
-        privdom->newDef ? privdom->newDef : privdom->def;
-
-    ret = virDomainDefFormat(domain->conn,
-                             def,
-                             flags);
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static int testNumOfDefinedDomains(virConnectPtr conn) {
-    testConnPtr privconn = conn->privateData;
-    unsigned int numInactive = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->domains.count ; i++) {
-        virDomainObjLock(privconn->domains.objs[i]);
-        if (!virDomainIsActive(privconn->domains.objs[i]))
-            numInactive++;
-        virDomainObjUnlock(privconn->domains.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return numInactive;
-}
-
-static int testListDefinedDomains(virConnectPtr conn,
-                                  char **const names,
-                                  int maxnames) {
-    testConnPtr privconn = conn->privateData;
-    unsigned int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*maxnames);
-    for (i = 0 ; i < privconn->domains.count && n < maxnames ; i++) {
-        virDomainObjLock(privconn->domains.objs[i]);
-        if (!virDomainIsActive(privconn->domains.objs[i]) &&
-            !(names[n++] = strdup(privconn->domains.objs[i]->def->name))) {
-            virDomainObjUnlock(privconn->domains.objs[i]);
-            goto no_memory;
-        }
-        virDomainObjUnlock(privconn->domains.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < maxnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-static virDomainPtr testDomainDefineXML(virConnectPtr conn,
-                                        const char *xml) {
-    testConnPtr privconn = conn->privateData;
-    virDomainPtr ret = NULL;
-    virDomainDefPtr def;
-    virDomainObjPtr dom = NULL;
-    virDomainEventPtr event = NULL;
-
-    testDriverLock(privconn);
-    if ((def = virDomainDefParseString(conn, privconn->caps, xml,
-                                       VIR_DOMAIN_XML_INACTIVE)) == NULL)
-        goto cleanup;
-
-    if (testDomainGenerateIfnames(conn, def) < 0)
-        goto cleanup;
-    if (!(dom = virDomainAssignDef(conn, &privconn->domains, def)))
-        goto cleanup;
-    def = NULL;
-    dom->persistent = 1;
-
-    event = virDomainEventNewFromObj(dom,
-                                     VIR_DOMAIN_EVENT_DEFINED,
-                                     VIR_DOMAIN_EVENT_DEFINED_ADDED);
-
-    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
-    if (ret)
-        ret->id = dom->def->id;
-
-cleanup:
-    virDomainDefFree(def);
-    if (dom)
-        virDomainObjUnlock(dom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testNodeGetCellsFreeMemory(virConnectPtr conn,
-                                      unsigned long long *freemems,
-                                      int startCell, int maxCells) {
-    testConnPtr privconn = conn->privateData;
-    int i, j;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    if (startCell > privconn->numCells) {
-        testError(conn, VIR_ERR_INVALID_ARG,
-                  "%s", _("Range exceeds available cells"));
-        goto cleanup;
-    }
-
-    for (i = startCell, j = 0;
-         (i < privconn->numCells && j < maxCells) ;
-         ++i, ++j) {
-        freemems[j] = privconn->cells[i].mem;
-    }
-    ret = j;
-
-cleanup:
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-
-static int testDomainCreate(virDomainPtr domain) {
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (privdom->state != VIR_DOMAIN_SHUTOFF) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Domain '%s' is already running"), domain->name);
-        goto cleanup;
-    }
-
-    domain->id = privdom->def->id = privconn->nextDomID++;
-    privdom->state = VIR_DOMAIN_RUNNING;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_STARTED,
-                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testDomainUndefine(virDomainPtr domain) {
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (privdom->state != VIR_DOMAIN_SHUTOFF) {
-        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Domain '%s' is still running"), domain->name);
-        goto cleanup;
-    }
-
-    privdom->state = VIR_DOMAIN_SHUTOFF;
-    event = virDomainEventNewFromObj(privdom,
-                                     VIR_DOMAIN_EVENT_UNDEFINED,
-                                     VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
-    virDomainRemoveInactive(&privconn->domains,
-                            privdom);
-    privdom = NULL;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    if (event)
-        testDomainEventQueue(privconn, event);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testDomainGetAutostart(virDomainPtr domain,
-                                  int *autostart)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    *autostart = privdom->autostart;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-
-static int testDomainSetAutostart(virDomainPtr domain,
-                                  int autostart)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privdom->autostart = autostart ? 1 : 0;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static char *testDomainGetSchedulerType(virDomainPtr domain,
-                                        int *nparams)
-{
-    char *type = NULL;
-
-    *nparams = 1;
-    type = strdup("fair");
-    if (!type)
-        virReportOOMError(domain->conn);
-
-    return type;
-}
-
-static int testDomainGetSchedulerParams(virDomainPtr domain,
-                                        virSchedParameterPtr params,
-                                        int *nparams)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (*nparams != 1) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, "nparams");
-        goto cleanup;
-    }
-    strcpy(params[0].field, "weight");
-    params[0].type = VIR_DOMAIN_SCHED_FIELD_UINT;
-    /* XXX */
-    /*params[0].value.ui = privdom->weight;*/
-    params[0].value.ui = 50;
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-
-static int testDomainSetSchedulerParams(virDomainPtr domain,
-                                        virSchedParameterPtr params,
-                                        int nparams)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (nparams != 1) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, "nparams");
-        goto cleanup;
-    }
-    if (STRNEQ(params[0].field, "weight")) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, "field");
-        goto cleanup;
-    }
-    if (params[0].type != VIR_DOMAIN_SCHED_FIELD_UINT) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, "type");
-        goto cleanup;
-    }
-    /* XXX */
-    /*privdom->weight = params[0].value.ui;*/
-    ret = 0;
-
-cleanup:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static int testDomainBlockStats(virDomainPtr domain,
-                                const char *path,
-                                struct _virDomainBlockStats *stats)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    struct timeval tv;
-    unsigned long long statbase;
-    int i, found = 0, ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto error;
-    }
-
-    for (i = 0 ; i < privdom->def->ndisks ; i++) {
-        if (STREQ(path, privdom->def->disks[i]->dst)) {
-            found = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG,
-                  _("invalid path: %s"), path);
-        goto error;
-    }
-
-    if (gettimeofday(&tv, NULL) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             "%s", _("getting time of day"));
-        goto error;
-    }
-
-    /* No significance to these numbers, just enough to mix it up*/
-    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
-    stats->rd_req = statbase / 10;
-    stats->rd_bytes = statbase / 20;
-    stats->wr_req = statbase / 30;
-    stats->wr_bytes = statbase / 40;
-    stats->errs = tv.tv_sec / 2;
-
-    ret = 0;
-error:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static int testDomainInterfaceStats(virDomainPtr domain,
-                                    const char *path,
-                                    struct _virDomainInterfaceStats *stats)
-{
-    testConnPtr privconn = domain->conn->privateData;
-    virDomainObjPtr privdom;
-    struct timeval tv;
-    unsigned long long statbase;
-    int i, found = 0, ret = -1;
-
-    testDriverLock(privconn);
-    privdom = virDomainFindByName(&privconn->domains,
-                                  domain->name);
-    testDriverUnlock(privconn);
-
-    if (privdom == NULL) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto error;
-    }
-
-    for (i = 0 ; i < privdom->def->nnets ; i++) {
-        if (privdom->def->nets[i]->ifname &&
-            STREQ (privdom->def->nets[i]->ifname, path)) {
-            found = 1;
-            break;
-        }
-    }
-
-    if (!found) {
-        testError(domain->conn, VIR_ERR_INVALID_ARG,
-                  _("invalid path, '%s' is not a known interface"), path);
-        goto error;
-    }
-
-    if (gettimeofday(&tv, NULL) < 0) {
-        virReportSystemError(domain->conn, errno,
-                             "%s", _("getting time of day"));
-        goto error;
-    }
-
-    /* No significance to these numbers, just enough to mix it up*/
-    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
-    stats->rx_bytes = statbase / 10;
-    stats->rx_packets = statbase / 100;
-    stats->rx_errs = tv.tv_sec / 1;
-    stats->rx_drop = tv.tv_sec / 2;
-    stats->tx_bytes = statbase / 20;
-    stats->tx_packets = statbase / 110;
-    stats->tx_errs = tv.tv_sec / 3;
-    stats->tx_drop = tv.tv_sec / 4;
-
-    ret = 0;
-error:
-    if (privdom)
-        virDomainObjUnlock(privdom);
-    return ret;
-}
-
-static virDrvOpenStatus testOpenNetwork(virConnectPtr conn,
-                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                                        int flags ATTRIBUTE_UNUSED) {
-    if (STRNEQ(conn->driver->name, "Test"))
-        return VIR_DRV_OPEN_DECLINED;
-
-    conn->networkPrivateData = conn->privateData;
-    return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int testCloseNetwork(virConnectPtr conn) {
-    conn->networkPrivateData = NULL;
-    return 0;
-}
-
-
-static virNetworkPtr testLookupNetworkByUUID(virConnectPtr conn,
-                                           const unsigned char *uuid)
-{
-    testConnPtr privconn = conn->privateData;
-    virNetworkObjPtr net;
-    virNetworkPtr ret = NULL;
-
-    testDriverLock(privconn);
-    net = virNetworkFindByUUID(&privconn->networks, uuid);
-    testDriverUnlock(privconn);
-
-    if (net == NULL) {
-        testError (conn, VIR_ERR_NO_NETWORK, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
-
-cleanup:
-    if (net)
-        virNetworkObjUnlock(net);
-    return ret;
-}
-
-static virNetworkPtr testLookupNetworkByName(virConnectPtr conn,
-                                             const char *name)
-{
-    testConnPtr privconn = conn->privateData;
-    virNetworkObjPtr net;
-    virNetworkPtr ret = NULL;
-
-    testDriverLock(privconn);
-    net = virNetworkFindByName(&privconn->networks, name);
-    testDriverUnlock(privconn);
-
-    if (net == NULL) {
-        testError (conn, VIR_ERR_NO_NETWORK, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
-
-cleanup:
-    if (net)
-        virNetworkObjUnlock(net);
-    return ret;
-}
-
-
-static int testNumNetworks(virConnectPtr conn) {
-    testConnPtr privconn = conn->privateData;
-    int numActive = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->networks.count ; i++) {
-        virNetworkObjLock(privconn->networks.objs[i]);
-        if (virNetworkIsActive(privconn->networks.objs[i]))
-            numActive++;
-        virNetworkObjUnlock(privconn->networks.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return numActive;
-}
-
-static int testListNetworks(virConnectPtr conn, char **const names, int nnames) {
-    testConnPtr privconn = conn->privateData;
-    int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*nnames);
-    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
-        virNetworkObjLock(privconn->networks.objs[i]);
-        if (virNetworkIsActive(privconn->networks.objs[i]) &&
-            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
-            virNetworkObjUnlock(privconn->networks.objs[i]);
-            goto no_memory;
-        }
-        virNetworkObjUnlock(privconn->networks.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < nnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-static int testNumDefinedNetworks(virConnectPtr conn) {
-    testConnPtr privconn = conn->privateData;
-    int numInactive = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->networks.count ; i++) {
-        virNetworkObjLock(privconn->networks.objs[i]);
-        if (!virNetworkIsActive(privconn->networks.objs[i]))
-            numInactive++;
-        virNetworkObjUnlock(privconn->networks.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return numInactive;
-}
-
-static int testListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
-    testConnPtr privconn = conn->privateData;
-    int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*nnames);
-    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
-        virNetworkObjLock(privconn->networks.objs[i]);
-        if (!virNetworkIsActive(privconn->networks.objs[i]) &&
-            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
-            virNetworkObjUnlock(privconn->networks.objs[i]);
-            goto no_memory;
-        }
-        virNetworkObjUnlock(privconn->networks.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < nnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-static virNetworkPtr testNetworkCreate(virConnectPtr conn, const char *xml) {
-    testConnPtr privconn = conn->privateData;
-    virNetworkDefPtr def;
-    virNetworkObjPtr net = NULL;
-    virNetworkPtr ret = NULL;
-
-    testDriverLock(privconn);
-    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
-        goto cleanup;
-
-    if ((net = virNetworkAssignDef(conn, &privconn->networks, def)) == NULL)
-        goto cleanup;
-    def = NULL;
-    net->active = 1;
-
-    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
-
-cleanup:
-    virNetworkDefFree(def);
-    if (net)
-        virNetworkObjUnlock(net);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static virNetworkPtr testNetworkDefine(virConnectPtr conn, const char *xml) {
-    testConnPtr privconn = conn->privateData;
-    virNetworkDefPtr def;
-    virNetworkObjPtr net = NULL;
-    virNetworkPtr ret = NULL;
-
-    testDriverLock(privconn);
-    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
-        goto cleanup;
-
-    if ((net = virNetworkAssignDef(conn, &privconn->networks, def)) == NULL)
-        goto cleanup;
-    def = NULL;
-    net->persistent = 1;
-
-    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
-
-cleanup:
-    virNetworkDefFree(def);
-    if (net)
-        virNetworkObjUnlock(net);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testNetworkUndefine(virNetworkPtr network) {
-    testConnPtr privconn = network->conn->privateData;
-    virNetworkObjPtr privnet;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (virNetworkIsActive(privnet)) {
-        testError(network->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Network '%s' is still running"), network->name);
-        goto cleanup;
-    }
-
-    virNetworkRemoveInactive(&privconn->networks,
-                             privnet);
-    privnet = NULL;
-    ret = 0;
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testNetworkStart(virNetworkPtr network) {
-    testConnPtr privconn = network->conn->privateData;
-    virNetworkObjPtr privnet;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-    testDriverUnlock(privconn);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (virNetworkIsActive(privnet)) {
-        testError(network->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Network '%s' is already running"), network->name);
-        goto cleanup;
-    }
-
-    privnet->active = 1;
-    ret = 0;
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    return ret;
-}
-
-static int testNetworkDestroy(virNetworkPtr network) {
-    testConnPtr privconn = network->conn->privateData;
-    virNetworkObjPtr privnet;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privnet->active = 0;
-    if (!privnet->persistent) {
-        virNetworkRemoveInactive(&privconn->networks,
-                                 privnet);
-        privnet = NULL;
-    }
-    ret = 0;
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static char *testNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = network->conn->privateData;
-    virNetworkObjPtr privnet;
-    char *ret = NULL;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-    testDriverUnlock(privconn);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    ret = virNetworkDefFormat(network->conn, privnet->def);
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    return ret;
-}
-
-static char *testNetworkGetBridgeName(virNetworkPtr network) {
-    testConnPtr privconn = network->conn->privateData;
-    char *bridge = NULL;
-    virNetworkObjPtr privnet;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-    testDriverUnlock(privconn);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (privnet->def->bridge &&
-        !(bridge = strdup(privnet->def->bridge))) {
-        virReportOOMError(network->conn);
-        goto cleanup;
-    }
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    return bridge;
-}
-
-static int testNetworkGetAutostart(virNetworkPtr network,
-                                   int *autostart) {
-    testConnPtr privconn = network->conn->privateData;
-    virNetworkObjPtr privnet;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-    testDriverUnlock(privconn);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    *autostart = privnet->autostart;
-    ret = 0;
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    return ret;
-}
-
-static int testNetworkSetAutostart(virNetworkPtr network,
-                                   int autostart) {
-    testConnPtr privconn = network->conn->privateData;
-    virNetworkObjPtr privnet;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privnet = virNetworkFindByName(&privconn->networks,
-                                   network->name);
-    testDriverUnlock(privconn);
-
-    if (privnet == NULL) {
-        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privnet->autostart = autostart ? 1 : 0;
-    ret = 0;
-
-cleanup:
-    if (privnet)
-        virNetworkObjUnlock(privnet);
-    return ret;
-}
-
-
-/*
- * Physical host interface routines
- */
-
-static virDrvOpenStatus testOpenInterface(virConnectPtr conn,
-                                          virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                                          int flags ATTRIBUTE_UNUSED)
-{
-    if (STRNEQ(conn->driver->name, "Test"))
-        return VIR_DRV_OPEN_DECLINED;
-
-    conn->interfacePrivateData = conn->privateData;
-    return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int testCloseInterface(virConnectPtr conn)
-{
-    conn->interfacePrivateData = NULL;
-    return 0;
-}
-
-
-static int testNumOfInterfaces(virConnectPtr conn)
-{
-    testConnPtr privconn = conn->privateData;
-    int i, count = 0;
-
-    testDriverLock(privconn);
-    for (i = 0 ; (i < privconn->ifaces.count); i++) {
-        virInterfaceObjLock(privconn->ifaces.objs[i]);
-        if (virInterfaceIsActive(privconn->ifaces.objs[i])) {
-            count++;
-        }
-        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
-    }
-    testDriverUnlock(privconn);
-    return count;
-}
-
-static int testListInterfaces(virConnectPtr conn, char **const names, int nnames)
-{
-    testConnPtr privconn = conn->privateData;
-    int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*nnames);
-    for (i = 0 ; (i < privconn->ifaces.count) && (n < nnames); i++) {
-        virInterfaceObjLock(privconn->ifaces.objs[i]);
-        if (virInterfaceIsActive(privconn->ifaces.objs[i])) {
-            if (!(names[n++] = strdup(privconn->ifaces.objs[i]->def->name))) {
-                virInterfaceObjUnlock(privconn->ifaces.objs[i]);
-                goto no_memory;
-            }
-        }
-        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < nnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-static int testNumOfDefinedInterfaces(virConnectPtr conn)
-{
-    testConnPtr privconn = conn->privateData;
-    int i, count = 0;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->ifaces.count; i++) {
-        virInterfaceObjLock(privconn->ifaces.objs[i]);
-        if (!virInterfaceIsActive(privconn->ifaces.objs[i])) {
-            count++;
-        }
-        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
-    }
-    testDriverUnlock(privconn);
-    return count;
-}
-
-static int testListDefinedInterfaces(virConnectPtr conn, char **const names, int nnames)
-{
-    testConnPtr privconn = conn->privateData;
-    int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*nnames);
-    for (i = 0 ; (i < privconn->ifaces.count) && (n < nnames); i++) {
-        virInterfaceObjLock(privconn->ifaces.objs[i]);
-        if (!virInterfaceIsActive(privconn->ifaces.objs[i])) {
-            if (!(names[n++] = strdup(privconn->ifaces.objs[i]->def->name))) {
-                virInterfaceObjUnlock(privconn->ifaces.objs[i]);
-                goto no_memory;
-            }
-        }
-        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < nnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-static virInterfacePtr testLookupInterfaceByName(virConnectPtr conn,
-                                                 const char *name)
-{
-    testConnPtr privconn = conn->privateData;
-    virInterfaceObjPtr iface;
-    virInterfacePtr ret = NULL;
-
-    testDriverLock(privconn);
-    iface = virInterfaceFindByName(&privconn->ifaces, name);
-    testDriverUnlock(privconn);
-
-    if (iface == NULL) {
-        testError (conn, VIR_ERR_NO_INTERFACE, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetInterface(conn, iface->def->name, iface->def->mac);
-
-cleanup:
-    if (iface)
-        virInterfaceObjUnlock(iface);
-    return ret;
-}
-
-static virInterfacePtr testLookupInterfaceByMACString(virConnectPtr conn,
-                                                      const char *mac)
-{
-    testConnPtr privconn = conn->privateData;
-    virInterfaceObjPtr iface;
-    int ifacect;
-    virInterfacePtr ret = NULL;
-
-    testDriverLock(privconn);
-    ifacect = virInterfaceFindByMACString(&privconn->ifaces, mac, &iface, 1);
-    testDriverUnlock(privconn);
-
-    if (ifacect == 0) {
-        testError (conn, VIR_ERR_NO_INTERFACE, NULL);
-        goto cleanup;
-    }
-
-    if (ifacect > 1) {
-        testError (conn, VIR_ERR_MULTIPLE_INTERFACES, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetInterface(conn, iface->def->name, iface->def->mac);
-
-cleanup:
-    if (iface)
-        virInterfaceObjUnlock(iface);
-    return ret;
-}
-
-static char *testInterfaceGetXMLDesc(virInterfacePtr iface,
-                                     unsigned int flags ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = iface->conn->privateData;
-    virInterfaceObjPtr privinterface;
-    char *ret = NULL;
-
-    testDriverLock(privconn);
-    privinterface = virInterfaceFindByName(&privconn->ifaces,
-                                           iface->name);
-    testDriverUnlock(privconn);
-
-    if (privinterface == NULL) {
-        testError(iface->conn, VIR_ERR_NO_INTERFACE, __FUNCTION__);
-        goto cleanup;
-    }
-
-    ret = virInterfaceDefFormat(iface->conn, privinterface->def);
-
-cleanup:
-    if (privinterface)
-        virInterfaceObjUnlock(privinterface);
-    return ret;
-}
-
-
-static virInterfacePtr testInterfaceDefineXML(virConnectPtr conn, const char *xmlStr,
-                                              unsigned int flags ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = conn->privateData;
-    virInterfaceDefPtr def;
-    virInterfaceObjPtr iface = NULL;
-    virInterfacePtr ret = NULL;
-
-    testDriverLock(privconn);
-    if ((def = virInterfaceDefParseString(conn, xmlStr)) == NULL)
-        goto cleanup;
-
-    if ((iface = virInterfaceAssignDef(conn, &privconn->ifaces, def)) == NULL)
-        goto cleanup;
-    def = NULL;
-
-    ret = virGetInterface(conn, iface->def->name, iface->def->mac);
-
-cleanup:
-    virInterfaceDefFree(def);
-    if (iface)
-        virInterfaceObjUnlock(iface);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testInterfaceUndefine(virInterfacePtr iface)
-{
-    testConnPtr privconn = iface->conn->privateData;
-    virInterfaceObjPtr privinterface;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privinterface = virInterfaceFindByName(&privconn->ifaces,
-                                           iface->name);
-
-    if (privinterface == NULL) {
-        testError (iface->conn, VIR_ERR_NO_INTERFACE, NULL);
-        goto cleanup;
-    }
-
-    virInterfaceRemove(&privconn->ifaces,
-                       privinterface);
-    ret = 0;
-
-cleanup:
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testInterfaceCreate(virInterfacePtr iface,
-                               unsigned int flags ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = iface->conn->privateData;
-    virInterfaceObjPtr privinterface;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privinterface = virInterfaceFindByName(&privconn->ifaces,
-                                           iface->name);
-
-    if (privinterface == NULL) {
-        testError (iface->conn, VIR_ERR_NO_INTERFACE, NULL);
-        goto cleanup;
-    }
-
-    if (privinterface->active != 0) {
-        testError (iface->conn, VIR_ERR_OPERATION_INVALID, NULL);
-        goto cleanup;
-    }
-
-    privinterface->active = 1;
-    ret = 0;
-
-cleanup:
-    if (privinterface)
-        virInterfaceObjUnlock(privinterface);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int testInterfaceDestroy(virInterfacePtr iface,
-                                unsigned int flags ATTRIBUTE_UNUSED)
-{
-    testConnPtr privconn = iface->conn->privateData;
-    virInterfaceObjPtr privinterface;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privinterface = virInterfaceFindByName(&privconn->ifaces,
-                                           iface->name);
-
-    if (privinterface == NULL) {
-        testError (iface->conn, VIR_ERR_NO_INTERFACE, NULL);
-        goto cleanup;
-    }
-
-    if (privinterface->active == 0) {
-        testError (iface->conn, VIR_ERR_OPERATION_INVALID, NULL);
-        goto cleanup;
-    }
-
-    privinterface->active = 0;
-    ret = 0;
-
-cleanup:
-    if (privinterface)
-        virInterfaceObjUnlock(privinterface);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-
-
-/*
- * Storage Driver routines
- */
-
-static int testStoragePoolObjSetDefaults(virConnectPtr conn,
-                                         virStoragePoolObjPtr pool) {
-
-    pool->def->capacity = defaultPoolCap;
-    pool->def->allocation = defaultPoolAlloc;
-    pool->def->available = defaultPoolCap - defaultPoolAlloc;
-
-    pool->configFile = strdup("\0");
-    if (!pool->configFile) {
-        virReportOOMError(conn);
-        return -1;
-    }
-
-    return 0;
-}
-
-static virDrvOpenStatus testStorageOpen(virConnectPtr conn,
-                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                                        int flags ATTRIBUTE_UNUSED) {
-    if (STRNEQ(conn->driver->name, "Test"))
-        return VIR_DRV_OPEN_DECLINED;
-
-    conn->storagePrivateData = conn->privateData;
-    return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int testStorageClose(virConnectPtr conn) {
-    conn->storagePrivateData = NULL;
-    return 0;
-}
-
-static virStoragePoolPtr
-testStoragePoolLookupByUUID(virConnectPtr conn,
-                            const unsigned char *uuid) {
-    testConnPtr privconn = conn->privateData;
-    virStoragePoolObjPtr pool;
-    virStoragePoolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    pool = virStoragePoolObjFindByUUID(&privconn->pools, uuid);
-    testDriverUnlock(privconn);
-
-    if (pool == NULL) {
-        testError (conn, VIR_ERR_NO_STORAGE_POOL, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
-
-cleanup:
-    if (pool)
-        virStoragePoolObjUnlock(pool);
-    return ret;
-}
-
-static virStoragePoolPtr
-testStoragePoolLookupByName(virConnectPtr conn,
-                            const char *name) {
-    testConnPtr privconn = conn->privateData;
-    virStoragePoolObjPtr pool;
-    virStoragePoolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    pool = virStoragePoolObjFindByName(&privconn->pools, name);
-    testDriverUnlock(privconn);
-
-    if (pool == NULL) {
-        testError (conn, VIR_ERR_NO_STORAGE_POOL, NULL);
-        goto cleanup;
-    }
-
-    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
-
-cleanup:
-    if (pool)
-        virStoragePoolObjUnlock(pool);
-    return ret;
-}
-
-static virStoragePoolPtr
-testStoragePoolLookupByVolume(virStorageVolPtr vol) {
-    return testStoragePoolLookupByName(vol->conn, vol->pool);
-}
-
-static int
-testStorageNumPools(virConnectPtr conn) {
-    testConnPtr privconn = conn->privateData;
-    int numActive = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->pools.count ; i++)
-        if (virStoragePoolObjIsActive(privconn->pools.objs[i]))
-            numActive++;
-    testDriverUnlock(privconn);
-
-    return numActive;
-}
-
-static int
-testStorageListPools(virConnectPtr conn,
-                     char **const names,
-                     int nnames) {
-    testConnPtr privconn = conn->privateData;
-    int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*nnames);
-    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
-        virStoragePoolObjLock(privconn->pools.objs[i]);
-        if (virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
-            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
-            virStoragePoolObjUnlock(privconn->pools.objs[i]);
-            goto no_memory;
-        }
-        virStoragePoolObjUnlock(privconn->pools.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < nnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-static int
-testStorageNumDefinedPools(virConnectPtr conn) {
-    testConnPtr privconn = conn->privateData;
-    int numInactive = 0, i;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->pools.count ; i++) {
-        virStoragePoolObjLock(privconn->pools.objs[i]);
-        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]))
-            numInactive++;
-        virStoragePoolObjUnlock(privconn->pools.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return numInactive;
-}
-
-static int
-testStorageListDefinedPools(virConnectPtr conn,
-                            char **const names,
-                            int nnames) {
-    testConnPtr privconn = conn->privateData;
-    int n = 0, i;
-
-    testDriverLock(privconn);
-    memset(names, 0, sizeof(*names)*nnames);
-    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
-        virStoragePoolObjLock(privconn->pools.objs[i]);
-        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
-            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
-            virStoragePoolObjUnlock(privconn->pools.objs[i]);
-            goto no_memory;
-        }
-        virStoragePoolObjUnlock(privconn->pools.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    return n;
-
-no_memory:
-    virReportOOMError(conn);
-    for (n = 0 ; n < nnames ; n++)
-        VIR_FREE(names[n]);
-    testDriverUnlock(privconn);
-    return -1;
-}
-
-
-static int
-testStoragePoolStart(virStoragePoolPtr pool,
-                     unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is already active"), pool->name);
-        goto cleanup;
-    }
-
-    privpool->active = 1;
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static char *
-testStorageFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
-                           const char *type ATTRIBUTE_UNUSED,
-                           const char *srcSpec ATTRIBUTE_UNUSED,
-                           unsigned int flags ATTRIBUTE_UNUSED)
-{
-    return NULL;
-}
-
-
-static virStoragePoolPtr
-testStoragePoolCreate(virConnectPtr conn,
-                      const char *xml,
-                      unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = conn->privateData;
-    virStoragePoolDefPtr def;
-    virStoragePoolObjPtr pool = NULL;
-    virStoragePoolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    if (!(def = virStoragePoolDefParseString(conn, xml)))
-        goto cleanup;
-
-    pool = virStoragePoolObjFindByUUID(&privconn->pools, def->uuid);
-    if (!pool)
-        pool = virStoragePoolObjFindByName(&privconn->pools, def->name);
-    if (pool) {
-        testError(conn, VIR_ERR_INTERNAL_ERROR,
-                  "%s", _("storage pool already exists"));
-        goto cleanup;
-    }
-
-    if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools, def)))
-        goto cleanup;
-    def = NULL;
-
-    if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
-        virStoragePoolObjRemove(&privconn->pools, pool);
-        pool = NULL;
-        goto cleanup;
-    }
-    pool->active = 1;
-
-    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
-
-cleanup:
-    virStoragePoolDefFree(def);
-    if (pool)
-        virStoragePoolObjUnlock(pool);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static virStoragePoolPtr
-testStoragePoolDefine(virConnectPtr conn,
-                      const char *xml,
-                      unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = conn->privateData;
-    virStoragePoolDefPtr def;
-    virStoragePoolObjPtr pool = NULL;
-    virStoragePoolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    if (!(def = virStoragePoolDefParseString(conn, xml)))
-        goto cleanup;
-
-    def->capacity = defaultPoolCap;
-    def->allocation = defaultPoolAlloc;
-    def->available = defaultPoolCap - defaultPoolAlloc;
-
-    if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools, def)))
-        goto cleanup;
-    def = NULL;
-
-    if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
-        virStoragePoolObjRemove(&privconn->pools, pool);
-        pool = NULL;
-        goto cleanup;
-    }
-
-    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
-
-cleanup:
-    virStoragePoolDefFree(def);
-    if (pool)
-        virStoragePoolObjUnlock(pool);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int
-testStoragePoolUndefine(virStoragePoolPtr pool) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is already active"), pool->name);
-        goto cleanup;
-    }
-
-    virStoragePoolObjRemove(&privconn->pools, privpool);
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-static int
-testStoragePoolBuild(virStoragePoolPtr pool,
-                     unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is already active"), pool->name);
-        goto cleanup;
-    }
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static int
-testStoragePoolDestroy(virStoragePoolPtr pool) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-
-    privpool->active = 0;
-
-    if (privpool->configFile == NULL) {
-        virStoragePoolObjRemove(&privconn->pools, privpool);
-        privpool = NULL;
-    }
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    testDriverUnlock(privconn);
-    return ret;
-}
-
-
-static int
-testStoragePoolDelete(virStoragePoolPtr pool,
-                      unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is already active"), pool->name);
-        goto cleanup;
-    }
-
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static int
-testStoragePoolRefresh(virStoragePoolPtr pool,
-                       unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static int
-testStoragePoolGetInfo(virStoragePoolPtr pool,
-                       virStoragePoolInfoPtr info) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    memset(info, 0, sizeof(virStoragePoolInfo));
-    if (privpool->active)
-        info->state = VIR_STORAGE_POOL_RUNNING;
-    else
-        info->state = VIR_STORAGE_POOL_INACTIVE;
-    info->capacity = privpool->def->capacity;
-    info->allocation = privpool->def->allocation;
-    info->available = privpool->def->available;
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static char *
-testStoragePoolDumpXML(virStoragePoolPtr pool,
-                       unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    char *ret = NULL;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    ret = virStoragePoolDefFormat(pool->conn, privpool->def);
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static int
-testStoragePoolGetAutostart(virStoragePoolPtr pool,
-                            int *autostart) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!privpool->configFile) {
-        *autostart = 0;
-    } else {
-        *autostart = privpool->autostart;
-    }
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static int
-testStoragePoolSetAutostart(virStoragePoolPtr pool,
-                            int autostart) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!privpool->configFile) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG,
-                  "%s", _("pool has no config file"));
-        goto cleanup;
-    }
-
-    autostart = (autostart != 0);
-    privpool->autostart = autostart;
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static int
-testStoragePoolNumVolumes(virStoragePoolPtr pool) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-
-    ret = privpool->volumes.count;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static int
-testStoragePoolListVolumes(virStoragePoolPtr pool,
-                           char **const names,
-                           int maxnames) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    int i = 0, n = 0;
-
-    memset(names, 0, maxnames * sizeof(*names));
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-
-    for (i = 0 ; i < privpool->volumes.count && n < maxnames ; i++) {
-        if ((names[n++] = strdup(privpool->volumes.objs[i]->name)) == NULL) {
-            virReportOOMError(pool->conn);
-            goto cleanup;
-        }
-    }
-
-    virStoragePoolObjUnlock(privpool);
-    return n;
-
- cleanup:
-    for (n = 0 ; n < maxnames ; n++)
-        VIR_FREE(names[i]);
-
-    memset(names, 0, maxnames * sizeof(*names));
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return -1;
-}
-
-
-static virStorageVolPtr
-testStorageVolumeLookupByName(virStoragePoolPtr pool,
-                              const char *name ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol;
-    virStorageVolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-
-    privvol = virStorageVolDefFindByName(privpool, name);
-
-    if (!privvol) {
-        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching name '%s'"), name);
-        goto cleanup;
-    }
-
-    ret = virGetStorageVol(pool->conn, privpool->def->name,
-                           privvol->name, privvol->key);
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static virStorageVolPtr
-testStorageVolumeLookupByKey(virConnectPtr conn,
-                             const char *key) {
-    testConnPtr privconn = conn->privateData;
-    unsigned int i;
-    virStorageVolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->pools.count ; i++) {
-        virStoragePoolObjLock(privconn->pools.objs[i]);
-        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
-            virStorageVolDefPtr privvol =
-                virStorageVolDefFindByKey(privconn->pools.objs[i], key);
-
-            if (privvol) {
-                ret = virGetStorageVol(conn,
-                                       privconn->pools.objs[i]->def->name,
-                                       privvol->name,
-                                       privvol->key);
-                virStoragePoolObjUnlock(privconn->pools.objs[i]);
-                break;
-            }
-        }
-        virStoragePoolObjUnlock(privconn->pools.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    if (!ret)
-        testError(conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching key '%s'"), key);
-
-    return ret;
-}
-
-static virStorageVolPtr
-testStorageVolumeLookupByPath(virConnectPtr conn,
-                              const char *path) {
-    testConnPtr privconn = conn->privateData;
-    unsigned int i;
-    virStorageVolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    for (i = 0 ; i < privconn->pools.count ; i++) {
-        virStoragePoolObjLock(privconn->pools.objs[i]);
-        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
-            virStorageVolDefPtr privvol =
-                virStorageVolDefFindByPath(privconn->pools.objs[i], path);
-
-            if (privvol) {
-                ret = virGetStorageVol(conn,
-                                       privconn->pools.objs[i]->def->name,
-                                       privvol->name,
-                                       privvol->key);
-                virStoragePoolObjUnlock(privconn->pools.objs[i]);
-                break;
-            }
-        }
-        virStoragePoolObjUnlock(privconn->pools.objs[i]);
-    }
-    testDriverUnlock(privconn);
-
-    if (!ret)
-        testError(conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching path '%s'"), path);
-
-    return ret;
-}
-
-static virStorageVolPtr
-testStorageVolumeCreateXML(virStoragePoolPtr pool,
-                           const char *xmldesc,
-                           unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol = NULL;
-    virStorageVolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-
-    privvol = virStorageVolDefParseString(pool->conn, privpool->def, xmldesc);
-    if (privvol == NULL)
-        goto cleanup;
-
-    if (virStorageVolDefFindByName(privpool, privvol->name)) {
-        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  "%s", _("storage vol already exists"));
-        goto cleanup;
-    }
-
-    /* Make sure enough space */
-    if ((privpool->def->allocation + privvol->allocation) >
-         privpool->def->capacity) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Not enough free space in pool for volume '%s'"),
-                  privvol->name);
-        goto cleanup;
-    }
-
-    if (VIR_REALLOC_N(privpool->volumes.objs,
-                      privpool->volumes.count+1) < 0) {
-        virReportOOMError(pool->conn);
-        goto cleanup;
-    }
-
-    if (virAsprintf(&privvol->target.path, "%s/%s",
-                    privpool->def->target.path,
-                    privvol->name) == -1) {
-        virReportOOMError(pool->conn);
-        goto cleanup;
-    }
-
-    privvol->key = strdup(privvol->target.path);
-    if (privvol->key == NULL) {
-        virReportOOMError(pool->conn);
-        goto cleanup;
-    }
-
-    privpool->def->allocation += privvol->allocation;
-    privpool->def->available = (privpool->def->capacity -
-                                privpool->def->allocation);
-
-    privpool->volumes.objs[privpool->volumes.count++] = privvol;
-
-    ret = virGetStorageVol(pool->conn, privpool->def->name,
-                           privvol->name, privvol->key);
-    privvol = NULL;
-
-cleanup:
-    virStorageVolDefFree(privvol);
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static virStorageVolPtr
-testStorageVolumeCreateXMLFrom(virStoragePoolPtr pool,
-                               const char *xmldesc,
-                               virStorageVolPtr clonevol,
-                               unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = pool->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol = NULL, origvol = NULL;
-    virStorageVolPtr ret = NULL;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           pool->name);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), pool->name);
-        goto cleanup;
-    }
-
-    privvol = virStorageVolDefParseString(pool->conn, privpool->def, xmldesc);
-    if (privvol == NULL)
-        goto cleanup;
-
-    if (virStorageVolDefFindByName(privpool, privvol->name)) {
-        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  "%s", _("storage vol already exists"));
-        goto cleanup;
-    }
-
-    origvol = virStorageVolDefFindByName(privpool, clonevol->name);
-    if (!origvol) {
-        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching name '%s'"),
-                  clonevol->name);
-        goto cleanup;
-    }
-
-    /* Make sure enough space */
-    if ((privpool->def->allocation + privvol->allocation) >
-         privpool->def->capacity) {
-        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Not enough free space in pool for volume '%s'"),
-                  privvol->name);
-        goto cleanup;
-    }
-    privpool->def->available = (privpool->def->capacity -
-                                privpool->def->allocation);
-
-    if (VIR_REALLOC_N(privpool->volumes.objs,
-                      privpool->volumes.count+1) < 0) {
-        virReportOOMError(pool->conn);
-        goto cleanup;
-    }
-
-    if (virAsprintf(&privvol->target.path, "%s/%s",
-                    privpool->def->target.path,
-                    privvol->name) == -1) {
-        virReportOOMError(pool->conn);
-        goto cleanup;
-    }
-
-    privvol->key = strdup(privvol->target.path);
-    if (privvol->key == NULL) {
-        virReportOOMError(pool->conn);
-        goto cleanup;
-    }
-
-    privpool->def->allocation += privvol->allocation;
-    privpool->def->available = (privpool->def->capacity -
-                                privpool->def->allocation);
-
-    privpool->volumes.objs[privpool->volumes.count++] = privvol;
-
-    ret = virGetStorageVol(pool->conn, privpool->def->name,
-                           privvol->name, privvol->key);
-    privvol = NULL;
-
-cleanup:
-    virStorageVolDefFree(privvol);
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static int
-testStorageVolumeDelete(virStorageVolPtr vol,
-                        unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = vol->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol;
-    int i;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           vol->pool);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-
-    privvol = virStorageVolDefFindByName(privpool, vol->name);
-
-    if (privvol == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching name '%s'"),
-                  vol->name);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), vol->pool);
-        goto cleanup;
-    }
-
-
-    privpool->def->allocation -= privvol->allocation;
-    privpool->def->available = (privpool->def->capacity -
-                                privpool->def->allocation);
-
-    for (i = 0 ; i < privpool->volumes.count ; i++) {
-        if (privpool->volumes.objs[i] == privvol) {
-            virStorageVolDefFree(privvol);
-
-            if (i < (privpool->volumes.count - 1))
-                memmove(privpool->volumes.objs + i,
-                        privpool->volumes.objs + i + 1,
-                        sizeof(*(privpool->volumes.objs)) *
-                                (privpool->volumes.count - (i + 1)));
-
-            if (VIR_REALLOC_N(privpool->volumes.objs,
-                              privpool->volumes.count - 1) < 0) {
-                ; /* Failure to reduce memory allocation isn't fatal */
-            }
-            privpool->volumes.count--;
-
-            break;
-        }
-    }
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static int testStorageVolumeTypeForPool(int pooltype) {
-
-    switch(pooltype) {
-        case VIR_STORAGE_POOL_DIR:
-        case VIR_STORAGE_POOL_FS:
-        case VIR_STORAGE_POOL_NETFS:
-            return VIR_STORAGE_VOL_FILE;
-        default:
-            return VIR_STORAGE_VOL_BLOCK;
-    }
-}
-
-static int
-testStorageVolumeGetInfo(virStorageVolPtr vol,
-                         virStorageVolInfoPtr info) {
-    testConnPtr privconn = vol->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol;
-    int ret = -1;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           vol->pool);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privvol = virStorageVolDefFindByName(privpool, vol->name);
-
-    if (privvol == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching name '%s'"),
-                  vol->name);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), vol->pool);
-        goto cleanup;
-    }
-
-    memset(info, 0, sizeof(*info));
-    info->type = testStorageVolumeTypeForPool(privpool->def->type);
-    info->capacity = privvol->capacity;
-    info->allocation = privvol->allocation;
-    ret = 0;
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static char *
-testStorageVolumeGetXMLDesc(virStorageVolPtr vol,
-                            unsigned int flags ATTRIBUTE_UNUSED) {
-    testConnPtr privconn = vol->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol;
-    char *ret = NULL;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           vol->pool);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privvol = virStorageVolDefFindByName(privpool, vol->name);
-
-    if (privvol == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching name '%s'"),
-                  vol->name);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), vol->pool);
-        goto cleanup;
-    }
-
-    ret = virStorageVolDefFormat(vol->conn, privpool->def, privvol);
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-static char *
-testStorageVolumeGetPath(virStorageVolPtr vol) {
-    testConnPtr privconn = vol->conn->privateData;
-    virStoragePoolObjPtr privpool;
-    virStorageVolDefPtr privvol;
-    char *ret = NULL;
-
-    testDriverLock(privconn);
-    privpool = virStoragePoolObjFindByName(&privconn->pools,
-                                           vol->pool);
-    testDriverUnlock(privconn);
-
-    if (privpool == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-        goto cleanup;
-    }
-
-    privvol = virStorageVolDefFindByName(privpool, vol->name);
-
-    if (privvol == NULL) {
-        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
-                  _("no storage vol with matching name '%s'"),
-                  vol->name);
-        goto cleanup;
-    }
-
-    if (!virStoragePoolObjIsActive(privpool)) {
-        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
-                  _("storage pool '%s' is not active"), vol->pool);
-        goto cleanup;
-    }
-
-    ret = strdup(privvol->target.path);
-    if (ret == NULL)
-        virReportOOMError(vol->conn);
-
-cleanup:
-    if (privpool)
-        virStoragePoolObjUnlock(privpool);
-    return ret;
-}
-
-
-static virDrvOpenStatus testDevMonOpen(virConnectPtr conn,
-                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                                       int flags ATTRIBUTE_UNUSED) {
-    if (STRNEQ(conn->driver->name, "Test"))
-        return VIR_DRV_OPEN_DECLINED;
-
-    conn->devMonPrivateData = conn->privateData;
-    return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int testDevMonClose(virConnectPtr conn) {
-    conn->devMonPrivateData = NULL;
-    return 0;
-}
-
-
-static int
-testDomainEventRegister (virConnectPtr conn,
-                         virConnectDomainEventCallback callback,
-                         void *opaque,
-                         virFreeCallback freecb)
-{
-    testConnPtr driver = conn->privateData;
-    int ret;
-
-    testDriverLock(driver);
-    ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
-                                        callback, opaque, freecb);
-    testDriverUnlock(driver);
-
-    return ret;
-}
-
-static int
-testDomainEventDeregister (virConnectPtr conn,
-                           virConnectDomainEventCallback callback)
-{
-    testConnPtr driver = conn->privateData;
-    int ret;
-
-    testDriverLock(driver);
-    if (driver->domainEventDispatching)
-        ret = virDomainEventCallbackListMarkDelete(conn, driver->domainEventCallbacks,
-                                                   callback);
-    else
-        ret = virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
-                                               callback);
-    testDriverUnlock(driver);
-
-    return ret;
-}
-
-static void testDomainEventDispatchFunc(virConnectPtr conn,
-                                        virDomainEventPtr event,
-                                        virConnectDomainEventCallback cb,
-                                        void *cbopaque,
-                                        void *opaque)
-{
-    testConnPtr driver = opaque;
-
-    /* Drop the lock whle dispatching, for sake of re-entrancy */
-    testDriverUnlock(driver);
-    virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
-    testDriverLock(driver);
-}
-
-static void testDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
-{
-    testConnPtr driver = opaque;
-    virDomainEventQueue tempQueue;
-
-    testDriverLock(driver);
-
-    driver->domainEventDispatching = 1;
-
-    /* Copy the queue, so we're reentrant safe */
-    tempQueue.count = driver->domainEventQueue->count;
-    tempQueue.events = driver->domainEventQueue->events;
-    driver->domainEventQueue->count = 0;
-    driver->domainEventQueue->events = NULL;
-
-    virEventUpdateTimeout(driver->domainEventTimer, -1);
-    virDomainEventQueueDispatch(&tempQueue,
-                                driver->domainEventCallbacks,
-                                testDomainEventDispatchFunc,
-                                driver);
-
-    /* Purge any deleted callbacks */
-    virDomainEventCallbackListPurgeMarked(driver->domainEventCallbacks);
-
-    driver->domainEventDispatching = 0;
-    testDriverUnlock(driver);
-}
-
-
-/* driver must be locked before calling */
-static void testDomainEventQueue(testConnPtr driver,
-                                 virDomainEventPtr event)
-{
-    if (driver->domainEventTimer < 0) {
-        virDomainEventFree(event);
-        return;
-    }
-
-    if (virDomainEventQueuePush(driver->domainEventQueue,
-                                event) < 0)
-        virDomainEventFree(event);
-
-    if (driver->domainEventQueue->count == 1)
-        virEventUpdateTimeout(driver->domainEventTimer, 0);
-}
-
-static virDrvOpenStatus testSecretOpen(virConnectPtr conn,
-                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                                       int flags ATTRIBUTE_UNUSED) {
-    if (STRNEQ(conn->driver->name, "Test"))
-        return VIR_DRV_OPEN_DECLINED;
-
-    conn->secretPrivateData = conn->privateData;
-    return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int testSecretClose(virConnectPtr conn) {
-    conn->secretPrivateData = NULL;
-    return 0;
-}
-
-static virDriver testDriver = {
-    VIR_DRV_TEST,
-    "Test",
-    testOpen, /* open */
-    testClose, /* close */
-    NULL, /* supports_feature */
-    NULL, /* type */
-    testGetVersion, /* version */
-    testGetHostname, /* getHostname */
-    testGetMaxVCPUs, /* getMaxVcpus */
-    testNodeGetInfo, /* nodeGetInfo */
-    testGetCapabilities, /* getCapabilities */
-    testListDomains, /* listDomains */
-    testNumOfDomains, /* numOfDomains */
-    testDomainCreateXML, /* domainCreateXML */
-    testLookupDomainByID, /* domainLookupByID */
-    testLookupDomainByUUID, /* domainLookupByUUID */
-    testLookupDomainByName, /* domainLookupByName */
-    testPauseDomain, /* domainSuspend */
-    testResumeDomain, /* domainResume */
-    testShutdownDomain, /* domainShutdown */
-    testRebootDomain, /* domainReboot */
-    testDestroyDomain, /* domainDestroy */
-    testGetOSType, /* domainGetOSType */
-    testGetMaxMemory, /* domainGetMaxMemory */
-    testSetMaxMemory, /* domainSetMaxMemory */
-    testSetMemory, /* domainSetMemory */
-    testGetDomainInfo, /* domainGetInfo */
-    testDomainSave, /* domainSave */
-    testDomainRestore, /* domainRestore */
-    testDomainCoreDump, /* domainCoreDump */
-    testSetVcpus, /* domainSetVcpus */
-    NULL, /* domainPinVcpu */
-    NULL, /* domainGetVcpus */
-    NULL, /* domainGetMaxVcpus */
-    NULL, /* domainGetSecurityLabel */
-    NULL, /* nodeGetSecurityModel */
-    testDomainDumpXML, /* domainDumpXML */
-    NULL, /* domainXmlFromNative */
-    NULL, /* domainXmlToNative */
-    testListDefinedDomains, /* listDefinedDomains */
-    testNumOfDefinedDomains, /* numOfDefinedDomains */
-    testDomainCreate, /* domainCreate */
-    testDomainDefineXML, /* domainDefineXML */
-    testDomainUndefine, /* domainUndefine */
-    NULL, /* domainAttachDevice */
-    NULL, /* domainDetachDevice */
-    testDomainGetAutostart, /* domainGetAutostart */
-    testDomainSetAutostart, /* domainSetAutostart */
-    testDomainGetSchedulerType, /* domainGetSchedulerType */
-    testDomainGetSchedulerParams, /* domainGetSchedulerParameters */
-    testDomainSetSchedulerParams, /* domainSetSchedulerParameters */
-    NULL, /* domainMigratePrepare */
-    NULL, /* domainMigratePerform */
-    NULL, /* domainMigrateFinish */
-    testDomainBlockStats, /* domainBlockStats */
-    testDomainInterfaceStats, /* domainInterfaceStats */
-    NULL, /* domainBlockPeek */
-    NULL, /* domainMemoryPeek */
-    testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
-    NULL, /* getFreeMemory */
-    testDomainEventRegister, /* domainEventRegister */
-    testDomainEventDeregister, /* domainEventDeregister */
-    NULL, /* domainMigratePrepare2 */
-    NULL, /* domainMigrateFinish2 */
-    NULL, /* nodeDeviceDettach */
-    NULL, /* nodeDeviceReAttach */
-    NULL, /* nodeDeviceReset */
-};
-
-static virNetworkDriver testNetworkDriver = {
-    "Test",
-    testOpenNetwork, /* open */
-    testCloseNetwork, /* close */
-    testNumNetworks, /* numOfNetworks */
-    testListNetworks, /* listNetworks */
-    testNumDefinedNetworks, /* numOfDefinedNetworks */
-    testListDefinedNetworks, /* listDefinedNetworks */
-    testLookupNetworkByUUID, /* networkLookupByUUID */
-    testLookupNetworkByName, /* networkLookupByName */
-    testNetworkCreate, /* networkCreateXML */
-    testNetworkDefine, /* networkDefineXML */
-    testNetworkUndefine, /* networkUndefine */
-    testNetworkStart, /* networkCreate */
-    testNetworkDestroy, /* networkDestroy */
-    testNetworkDumpXML, /* networkDumpXML */
-    testNetworkGetBridgeName, /* networkGetBridgeName */
-    testNetworkGetAutostart, /* networkGetAutostart */
-    testNetworkSetAutostart, /* networkSetAutostart */
-};
-
-static virInterfaceDriver testInterfaceDriver = {
-    "Test",                     /* name */
-    testOpenInterface,          /* open */
-    testCloseInterface,         /* close */
-    testNumOfInterfaces,        /* numOfInterfaces */
-    testListInterfaces,         /* listInterfaces */
-    testNumOfDefinedInterfaces, /* numOfDefinedInterfaces */
-    testListDefinedInterfaces,  /* listDefinedInterfaces */
-    testLookupInterfaceByName,  /* interfaceLookupByName */
-    testLookupInterfaceByMACString, /* interfaceLookupByMACString */
-    testInterfaceGetXMLDesc,    /* interfaceGetXMLDesc */
-    testInterfaceDefineXML,     /* interfaceDefineXML */
-    testInterfaceUndefine,      /* interfaceUndefine */
-    testInterfaceCreate,        /* interfaceCreate */
-    testInterfaceDestroy,       /* interfaceDestroy */
-};
-
-
-static virStorageDriver testStorageDriver = {
-    .name = "Test",
-    .open = testStorageOpen,
-    .close = testStorageClose,
-
-    .numOfPools = testStorageNumPools,
-    .listPools = testStorageListPools,
-    .numOfDefinedPools = testStorageNumDefinedPools,
-    .listDefinedPools = testStorageListDefinedPools,
-    .findPoolSources = testStorageFindPoolSources,
-    .poolLookupByName = testStoragePoolLookupByName,
-    .poolLookupByUUID = testStoragePoolLookupByUUID,
-    .poolLookupByVolume = testStoragePoolLookupByVolume,
-    .poolCreateXML = testStoragePoolCreate,
-    .poolDefineXML = testStoragePoolDefine,
-    .poolBuild = testStoragePoolBuild,
-    .poolUndefine = testStoragePoolUndefine,
-    .poolCreate = testStoragePoolStart,
-    .poolDestroy = testStoragePoolDestroy,
-    .poolDelete = testStoragePoolDelete,
-    .poolRefresh = testStoragePoolRefresh,
-    .poolGetInfo = testStoragePoolGetInfo,
-    .poolGetXMLDesc = testStoragePoolDumpXML,
-    .poolGetAutostart = testStoragePoolGetAutostart,
-    .poolSetAutostart = testStoragePoolSetAutostart,
-    .poolNumOfVolumes = testStoragePoolNumVolumes,
-    .poolListVolumes = testStoragePoolListVolumes,
-
-    .volLookupByName = testStorageVolumeLookupByName,
-    .volLookupByKey = testStorageVolumeLookupByKey,
-    .volLookupByPath = testStorageVolumeLookupByPath,
-    .volCreateXML = testStorageVolumeCreateXML,
-    .volCreateXMLFrom = testStorageVolumeCreateXMLFrom,
-    .volDelete = testStorageVolumeDelete,
-    .volGetInfo = testStorageVolumeGetInfo,
-    .volGetXMLDesc = testStorageVolumeGetXMLDesc,
-    .volGetPath = testStorageVolumeGetPath,
-};
-
-static virDeviceMonitor testDevMonitor = {
-    .name = "Test",
-    .open = testDevMonOpen,
-    .close = testDevMonClose,
-};
-
-static virSecretDriver testSecretDriver = {
-    .name = "Test",
-    .open = testSecretOpen,
-    .close = testSecretClose,
-};
-
-
-/**
- * testRegister:
- *
- * Registers the test driver
- */
-int
-testRegister(void)
-{
-    if (virRegisterDriver(&testDriver) < 0)
-        return -1;
-    if (virRegisterNetworkDriver(&testNetworkDriver) < 0)
-        return -1;
-    if (virRegisterInterfaceDriver(&testInterfaceDriver) < 0)
-        return -1;
-    if (virRegisterStorageDriver(&testStorageDriver) < 0)
-        return -1;
-    if (virRegisterDeviceMonitor(&testDevMonitor) < 0)
-        return -1;
-    if (virRegisterSecretDriver(&testSecretDriver) < 0)
-        return -1;
-
-    return 0;
-}
diff --git a/src/test.h b/src/test.h
deleted file mode 100644 (file)
index c6bdbd0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * test.h: A "mock" hypervisor for use by application unit tests
- *
- * Copyright (C) 2006-2006 Red Hat, Inc.
- * Copyright (C) 2006  Daniel P. Berrange
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- *
- * Daniel Berrange <berrange@redhat.com>
- */
-
-#ifndef __VIR_TEST_INTERNAL_H__
-#define __VIR_TEST_INTERNAL_H__
-
-#include "internal.h"
-
-int testRegister(void);
-
-#endif /* __VIR_TEST_INTERNAL_H__ */
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
new file mode 100644 (file)
index 0000000..778992c
--- /dev/null
@@ -0,0 +1,4375 @@
+/*
+ * test.c: A "mock" hypervisor for use by application unit tests
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Daniel Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <libxml/xmlsave.h>
+
+
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "test_driver.h"
+#include "buf.h"
+#include "util.h"
+#include "uuid.h"
+#include "capabilities.h"
+#include "memory.h"
+#include "network_conf.h"
+#include "interface_conf.h"
+#include "domain_conf.h"
+#include "domain_event.h"
+#include "event.h"
+#include "storage_conf.h"
+#include "xml.h"
+#include "threads.h"
+#include "logging.h"
+
+#define VIR_FROM_THIS VIR_FROM_TEST
+
+#define MAX_CPUS 128
+
+struct _testCell {
+    unsigned long mem;
+    int numCpus;
+    int cpus[MAX_CPUS];
+};
+typedef struct _testCell testCell;
+typedef struct _testCell *testCellPtr;
+
+#define MAX_CELLS 128
+
+struct _testConn {
+    virMutex lock;
+
+    char path[PATH_MAX];
+    int nextDomID;
+    virCapsPtr caps;
+    virNodeInfo nodeInfo;
+    virDomainObjList domains;
+    virNetworkObjList networks;
+    virInterfaceObjList ifaces;
+    virStoragePoolObjList pools;
+    int numCells;
+    testCell cells[MAX_CELLS];
+
+
+    /* An array of callbacks */
+    virDomainEventCallbackListPtr domainEventCallbacks;
+    virDomainEventQueuePtr domainEventQueue;
+    int domainEventTimer;
+    int domainEventDispatching;
+};
+typedef struct _testConn testConn;
+typedef struct _testConn *testConnPtr;
+
+#define TEST_MODEL "i686"
+#define TEST_MODEL_WORDSIZE 32
+#define TEST_EMULATOR "/usr/bin/test-hv"
+
+static const virNodeInfo defaultNodeInfo = {
+    TEST_MODEL,
+    1024*1024*3, /* 3 GB */
+    16,
+    1400,
+    2,
+    2,
+    2,
+    2,
+};
+
+
+#define testError(conn, code, fmt...)                               \
+        virReportErrorHelper(conn, VIR_FROM_TEST, code, __FILE__, \
+                               __FUNCTION__, __LINE__, fmt)
+
+static int testClose(virConnectPtr conn);
+static void testDomainEventFlush(int timer, void *opaque);
+static void testDomainEventQueue(testConnPtr driver,
+                                 virDomainEventPtr event);
+
+
+static void testDriverLock(testConnPtr driver)
+{
+    virMutexLock(&driver->lock);
+}
+
+static void testDriverUnlock(testConnPtr driver)
+{
+    virMutexUnlock(&driver->lock);
+}
+
+static virCapsPtr
+testBuildCapabilities(virConnectPtr conn) {
+    testConnPtr privconn = conn->privateData;
+    virCapsPtr caps;
+    virCapsGuestPtr guest;
+    const char *const guest_types[] = { "hvm", "xen" };
+    int i;
+
+    if ((caps = virCapabilitiesNew(TEST_MODEL, 0, 0)) == NULL)
+        goto no_memory;
+
+    if (virCapabilitiesAddHostFeature(caps, "pae") < 0)
+        goto no_memory;
+    if (virCapabilitiesAddHostFeature(caps ,"nonpae") < 0)
+        goto no_memory;
+
+    for (i = 0; i < privconn->numCells; i++) {
+        if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].numCpus,
+                                           privconn->cells[i].cpus) < 0)
+            goto no_memory;
+    }
+
+    for (i = 0; i < ARRAY_CARDINALITY(guest_types) ; i++) {
+        if ((guest = virCapabilitiesAddGuest(caps,
+                                             guest_types[i],
+                                             TEST_MODEL,
+                                             TEST_MODEL_WORDSIZE,
+                                             TEST_EMULATOR,
+                                             NULL,
+                                             0,
+                                             NULL)) == NULL)
+            goto no_memory;
+
+        if (virCapabilitiesAddGuestDomain(guest,
+                                          "test",
+                                          NULL,
+                                          NULL,
+                                          0,
+                                          NULL) == NULL)
+            goto no_memory;
+
+        if (virCapabilitiesAddGuestFeature(guest, "pae", 1, 1) == NULL)
+            goto no_memory;
+        if (virCapabilitiesAddGuestFeature(guest ,"nonpae", 1, 1) == NULL)
+            goto no_memory;
+    }
+
+    return caps;
+
+no_memory:
+    virReportOOMError(conn);
+    virCapabilitiesFree(caps);
+    return NULL;
+}
+
+
+static const char *defaultDomainXML =
+"<domain type='test'>"
+"  <name>test</name>"
+"  <memory>8388608</memory>"
+"  <currentMemory>2097152</currentMemory>"
+"  <vcpu>2</vcpu>"
+"  <os>"
+"    <type>hvm</type>"
+"  </os>"
+"</domain>";
+
+
+static const char *defaultNetworkXML =
+"<network>"
+"  <name>default</name>"
+"  <bridge name='virbr0' />"
+"  <forward/>"
+"  <ip address='192.168.122.1' netmask='255.255.255.0'>"
+"    <dhcp>"
+"      <range start='192.168.122.2' end='192.168.122.254' />"
+"    </dhcp>"
+"  </ip>"
+"</network>";
+
+static const char *defaultInterfaceXML =
+"<interface type=\"ethernet\" name=\"eth1\">"
+"  <start mode=\"onboot\"/>"
+"  <mac address=\"aa:bb:cc:dd:ee:ff\"/>"
+"  <mtu size=\"1492\"/>"
+"  <protocol family=\"ipv4\">"
+"    <ip address=\"192.168.0.5\" prefix=\"24\"/>"
+"    <route gateway=\"192.168.0.1\"/>"
+"  </protocol>"
+"</interface>";
+
+static const char *defaultPoolXML =
+"<pool type='dir'>"
+"  <name>default-pool</name>"
+"  <target>"
+"    <path>/default-pool</path>"
+"  </target>"
+"</pool>";
+
+static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull);
+static const unsigned long long defaultPoolAlloc = 0;
+
+static int testStoragePoolObjSetDefaults(virConnectPtr conn, virStoragePoolObjPtr pool);
+
+static char *
+testDomainGenerateIfname(virConnectPtr conn,
+                         virDomainDefPtr domdef) {
+    int maxif = 1024;
+    int ifctr, i;
+
+    for (ifctr = 0; ifctr < maxif; ++ifctr) {
+        char *ifname;
+        int found = 0;
+
+        if (virAsprintf(&ifname, "testnet%d", ifctr) < 0) {
+            virReportOOMError(conn);
+            return NULL;
+        }
+
+        /* Generate network interface names */
+        for (i = 0 ; i < domdef->nnets ; i++) {
+            if (domdef->nets[i]->ifname &&
+                STREQ (domdef->nets[i]->ifname, ifname)) {
+                found = 1;
+                break;
+            }
+        }
+
+        if (!found)
+            return ifname;
+    }
+
+    testError(conn, VIR_ERR_INTERNAL_ERROR,
+              _("Exceeded max iface limit %d"), maxif);
+    return NULL;
+}
+
+static int
+testDomainGenerateIfnames(virConnectPtr conn,
+                          virDomainDefPtr domdef)
+{
+    int i = 0;
+
+    for (i = 0; i < domdef->nnets; i++) {
+        char *ifname;
+        if (domdef->nets[i]->ifname)
+            continue;
+
+        ifname = testDomainGenerateIfname(conn, domdef);
+        if (!ifname)
+            return -1;
+
+        domdef->nets[i]->ifname = ifname;
+    }
+
+    return 0;
+}
+
+
+static int testOpenDefault(virConnectPtr conn) {
+    int u;
+    struct timeval tv;
+    testConnPtr privconn;
+    virDomainDefPtr domdef = NULL;
+    virDomainObjPtr domobj = NULL;
+    virNetworkDefPtr netdef = NULL;
+    virNetworkObjPtr netobj = NULL;
+    virInterfaceDefPtr interfacedef = NULL;
+    virInterfaceObjPtr interfaceobj = NULL;
+    virStoragePoolDefPtr pooldef = NULL;
+    virStoragePoolObjPtr poolobj = NULL;
+
+    if (VIR_ALLOC(privconn) < 0) {
+        virReportOOMError(conn);
+        return VIR_DRV_OPEN_ERROR;
+    }
+    if (virMutexInit(&privconn->lock) < 0) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("cannot initialize mutex"));
+        VIR_FREE(privconn);
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    testDriverLock(privconn);
+    conn->privateData = privconn;
+
+    if (gettimeofday(&tv, NULL) < 0) {
+        virReportSystemError(conn, errno,
+                             "%s", _("getting time of day"));
+        goto error;
+    }
+
+    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
+
+    // Numa setup
+    privconn->numCells = 2;
+    for (u = 0; u < 2; ++u) {
+        privconn->cells[u].numCpus = 8;
+        privconn->cells[u].mem = (u + 1) * 2048 * 1024;
+    }
+    for (u = 0 ; u < 16 ; u++) {
+        privconn->cells[u % 2].cpus[(u / 2)] = u;
+    }
+
+    if (!(privconn->caps = testBuildCapabilities(conn)))
+        goto error;
+
+    privconn->nextDomID = 1;
+
+    if (!(domdef = virDomainDefParseString(conn, privconn->caps,
+                                           defaultDomainXML,
+                                           VIR_DOMAIN_XML_INACTIVE)))
+        goto error;
+    if (testDomainGenerateIfnames(conn, domdef) < 0)
+        goto error;
+    if (!(domobj = virDomainAssignDef(conn, &privconn->domains, domdef)))
+        goto error;
+    domdef = NULL;
+    domobj->def->id = privconn->nextDomID++;
+    domobj->state = VIR_DOMAIN_RUNNING;
+    domobj->persistent = 1;
+    virDomainObjUnlock(domobj);
+
+    if (!(netdef = virNetworkDefParseString(conn, defaultNetworkXML)))
+        goto error;
+    if (!(netobj = virNetworkAssignDef(conn, &privconn->networks, netdef))) {
+        virNetworkDefFree(netdef);
+        goto error;
+    }
+    netobj->active = 1;
+    netobj->persistent = 1;
+    virNetworkObjUnlock(netobj);
+
+    if (!(interfacedef = virInterfaceDefParseString(conn, defaultInterfaceXML)))
+        goto error;
+    if (!(interfaceobj = virInterfaceAssignDef(conn, &privconn->ifaces, interfacedef))) {
+        virInterfaceDefFree(interfacedef);
+        goto error;
+    }
+    interfaceobj->active = 1;
+    virInterfaceObjUnlock(interfaceobj);
+
+    if (!(pooldef = virStoragePoolDefParseString(conn, defaultPoolXML)))
+        goto error;
+
+    if (!(poolobj = virStoragePoolObjAssignDef(conn, &privconn->pools,
+                                               pooldef))) {
+        virStoragePoolDefFree(pooldef);
+        goto error;
+    }
+
+    if (testStoragePoolObjSetDefaults(conn, poolobj) == -1) {
+        virStoragePoolObjUnlock(poolobj);
+        goto error;
+    }
+    poolobj->active = 1;
+    virStoragePoolObjUnlock(poolobj);
+
+    testDriverUnlock(privconn);
+
+    return VIR_DRV_OPEN_SUCCESS;
+
+error:
+    virDomainObjListFree(&privconn->domains);
+    virNetworkObjListFree(&privconn->networks);
+    virInterfaceObjListFree(&privconn->ifaces);
+    virStoragePoolObjListFree(&privconn->pools);
+    virCapabilitiesFree(privconn->caps);
+    testDriverUnlock(privconn);
+    conn->privateData = NULL;
+    VIR_FREE(privconn);
+    virDomainDefFree(domdef);
+    return VIR_DRV_OPEN_ERROR;
+}
+
+
+static char *testBuildFilename(const char *relativeTo,
+                               const char *filename) {
+    char *offset;
+    int baseLen;
+    if (!filename || filename[0] == '\0')
+        return (NULL);
+    if (filename[0] == '/')
+        return strdup(filename);
+
+    offset = strrchr(relativeTo, '/');
+    if ((baseLen = (offset-relativeTo+1))) {
+        char *absFile;
+        if (VIR_ALLOC_N(absFile, baseLen + strlen(filename) + 1) < 0)
+            return NULL;
+        strncpy(absFile, relativeTo, baseLen);
+        absFile[baseLen] = '\0';
+        strcat(absFile, filename);
+        return absFile;
+    } else {
+        return strdup(filename);
+    }
+}
+
+static int testOpenVolumesForPool(virConnectPtr conn,
+                                  xmlDocPtr xml,
+                                  xmlXPathContextPtr ctxt,
+                                  const char *file,
+                                  virStoragePoolObjPtr pool,
+                                  int poolidx) {
+    char *vol_xpath;
+    int i, ret, func_ret = -1;
+    xmlNodePtr *vols = NULL;
+    virStorageVolDefPtr def = NULL;
+
+    /* Find storage volumes */
+    if (virAsprintf(&vol_xpath, "/node/pool[%d]/volume", poolidx) < 0) {
+        virReportOOMError(NULL);
+        goto error;
+    }
+
+    ret = virXPathNodeSet(conn, vol_xpath, ctxt, &vols);
+    VIR_FREE(vol_xpath);
+    if (ret < 0) {
+        testError(NULL, VIR_ERR_XML_ERROR,
+                  _("node vol list for pool '%s'"), pool->def->name);
+        goto error;
+    }
+
+    for (i = 0 ; i < ret ; i++) {
+        char *relFile = virXMLPropString(vols[i], "file");
+        if (relFile != NULL) {
+            char *absFile = testBuildFilename(file, relFile);
+            VIR_FREE(relFile);
+            if (!absFile) {
+                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                          _("resolving volume filename"));
+                goto error;
+            }
+
+            def = virStorageVolDefParseFile(conn, pool->def, absFile);
+            VIR_FREE(absFile);
+            if (!def)
+                goto error;
+        } else {
+            if ((def = virStorageVolDefParseNode(conn, pool->def, xml,
+                                                 vols[i])) == NULL) {
+                goto error;
+            }
+        }
+
+        if (VIR_REALLOC_N(pool->volumes.objs,
+                          pool->volumes.count+1) < 0) {
+            virReportOOMError(conn);
+            goto error;
+        }
+
+        if (virAsprintf(&def->target.path, "%s/%s",
+                        pool->def->target.path,
+                        def->name) == -1) {
+            virReportOOMError(conn);
+            goto error;
+        }
+
+        def->key = strdup(def->target.path);
+        if (def->key == NULL) {
+            virReportOOMError(conn);
+            goto error;
+        }
+
+        pool->def->allocation += def->allocation;
+        pool->def->available = (pool->def->capacity -
+                                pool->def->allocation);
+
+        pool->volumes.objs[pool->volumes.count++] = def;
+        def = NULL;
+    }
+
+    func_ret = 0;
+error:
+    virStorageVolDefFree(def);
+    VIR_FREE(vols);
+    return func_ret;
+}
+
+static int testOpenFromFile(virConnectPtr conn,
+                            const char *file) {
+    int fd = -1, i, ret;
+    long l;
+    char *str;
+    xmlDocPtr xml = NULL;
+    xmlNodePtr root = NULL;
+    xmlNodePtr *domains = NULL, *networks = NULL, *ifaces = NULL, *pools = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    virNodeInfoPtr nodeInfo;
+    virNetworkObjPtr net;
+    virInterfaceObjPtr iface;
+    virDomainObjPtr dom;
+    testConnPtr privconn;
+    if (VIR_ALLOC(privconn) < 0) {
+        virReportOOMError(conn);
+        return VIR_DRV_OPEN_ERROR;
+    }
+    if (virMutexInit(&privconn->lock) < 0) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("cannot initialize mutex"));
+        VIR_FREE(privconn);
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    testDriverLock(privconn);
+    conn->privateData = privconn;
+
+    if (!(privconn->caps = testBuildCapabilities(conn)))
+        goto error;
+
+    if ((fd = open(file, O_RDONLY)) < 0) {
+        virReportSystemError(NULL, errno,
+                             _("loading host definition file '%s'"),
+                             file);
+        goto error;
+    }
+
+    if (!(xml = xmlReadFd(fd, file, NULL,
+                          XML_PARSE_NOENT | XML_PARSE_NONET |
+                          XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
+        testError(NULL, VIR_ERR_INTERNAL_ERROR,
+                  _("Invalid XML in file '%s'"), file);
+        goto error;
+    }
+    close(fd);
+    fd = -1;
+
+    root = xmlDocGetRootElement(xml);
+    if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s",
+                  _("Root element is not 'node'"));
+        goto error;
+    }
+
+    ctxt = xmlXPathNewContext(xml);
+    if (ctxt == NULL) {
+        testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                  _("creating xpath context"));
+        goto error;
+    }
+
+    privconn->nextDomID = 1;
+    privconn->numCells = 0;
+    strncpy(privconn->path, file, PATH_MAX-1);
+    privconn->path[PATH_MAX-1] = '\0';
+    memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
+
+    nodeInfo = &privconn->nodeInfo;
+    ret = virXPathLong(conn, "string(/node/cpu/nodes[1])", ctxt, &l);
+    if (ret == 0) {
+        nodeInfo->nodes = l;
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu numa nodes"));
+        goto error;
+    }
+
+    ret = virXPathLong(conn, "string(/node/cpu/sockets[1])", ctxt, &l);
+    if (ret == 0) {
+        nodeInfo->sockets = l;
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu sockets"));
+        goto error;
+    }
+
+    ret = virXPathLong(conn, "string(/node/cpu/cores[1])", ctxt, &l);
+    if (ret == 0) {
+        nodeInfo->cores = l;
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu cores"));
+        goto error;
+    }
+
+    ret = virXPathLong(conn, "string(/node/cpu/threads[1])", ctxt, &l);
+    if (ret == 0) {
+        nodeInfo->threads = l;
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu threads"));
+        goto error;
+    }
+
+    nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
+    ret = virXPathLong(conn, "string(/node/cpu/active[1])", ctxt, &l);
+    if (ret == 0) {
+        if (l < nodeInfo->cpus) {
+            nodeInfo->cpus = l;
+        }
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node active cpu"));
+        goto error;
+    }
+    ret = virXPathLong(conn, "string(/node/cpu/mhz[1])", ctxt, &l);
+    if (ret == 0) {
+        nodeInfo->mhz = l;
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node cpu mhz"));
+        goto error;
+    }
+
+    str = virXPathString(conn, "string(/node/cpu/model[1])", ctxt);
+    if (str != NULL) {
+        strncpy(nodeInfo->model, str, sizeof(nodeInfo->model)-1);
+        nodeInfo->model[sizeof(nodeInfo->model)-1] = '\0';
+        VIR_FREE(str);
+    }
+
+    ret = virXPathLong(conn, "string(/node/memory[1])", ctxt, &l);
+    if (ret == 0) {
+        nodeInfo->memory = l;
+    } else if (ret == -2) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node memory"));
+        goto error;
+    }
+
+    ret = virXPathNodeSet(conn, "/node/domain", ctxt, &domains);
+    if (ret < 0) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node domain list"));
+        goto error;
+    }
+
+    for (i = 0 ; i < ret ; i++) {
+        virDomainDefPtr def;
+        char *relFile = virXMLPropString(domains[i], "file");
+        if (relFile != NULL) {
+            char *absFile = testBuildFilename(file, relFile);
+            VIR_FREE(relFile);
+            if (!absFile) {
+                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving domain filename"));
+                goto error;
+            }
+            def = virDomainDefParseFile(conn, privconn->caps, absFile,
+                                        VIR_DOMAIN_XML_INACTIVE);
+            VIR_FREE(absFile);
+            if (!def)
+                goto error;
+        } else {
+            if ((def = virDomainDefParseNode(conn, privconn->caps, xml, domains[i],
+                                   VIR_DOMAIN_XML_INACTIVE)) == NULL)
+                goto error;
+        }
+
+        if (testDomainGenerateIfnames(conn, def) < 0 ||
+            !(dom = virDomainAssignDef(conn, &privconn->domains, def))) {
+            virDomainDefFree(def);
+            goto error;
+        }
+
+        dom->state = VIR_DOMAIN_RUNNING;
+        dom->def->id = privconn->nextDomID++;
+        dom->persistent = 1;
+        virDomainObjUnlock(dom);
+    }
+    VIR_FREE(domains);
+
+    ret = virXPathNodeSet(conn, "/node/network", ctxt, &networks);
+    if (ret < 0) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node network list"));
+        goto error;
+    }
+    for (i = 0 ; i < ret ; i++) {
+        virNetworkDefPtr def;
+        char *relFile = virXMLPropString(networks[i], "file");
+        if (relFile != NULL) {
+            char *absFile = testBuildFilename(file, relFile);
+            VIR_FREE(relFile);
+            if (!absFile) {
+                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving network filename"));
+                goto error;
+            }
+
+            def = virNetworkDefParseFile(conn, absFile);
+            VIR_FREE(absFile);
+            if (!def)
+                goto error;
+        } else {
+            if ((def = virNetworkDefParseNode(conn, xml, networks[i])) == NULL)
+                goto error;
+        }
+        if (!(net = virNetworkAssignDef(conn, &privconn->networks,
+                                        def))) {
+            virNetworkDefFree(def);
+            goto error;
+        }
+        net->persistent = 1;
+        net->active = 1;
+        virNetworkObjUnlock(net);
+    }
+    VIR_FREE(networks);
+
+    /* Parse interface definitions */
+    ret = virXPathNodeSet(conn, "/node/interface", ctxt, &ifaces);
+    if (ret < 0) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node interface list"));
+        goto error;
+    }
+    for (i = 0 ; i < ret ; i++) {
+        virInterfaceDefPtr def;
+        char *relFile = virXMLPropString(ifaces[i], "file");
+        if (relFile != NULL) {
+            char *absFile = testBuildFilename(file, relFile);
+            VIR_FREE(relFile);
+            if (!absFile) {
+                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("resolving interface filename"));
+                goto error;
+            }
+
+            def = virInterfaceDefParseFile(conn, absFile);
+            VIR_FREE(absFile);
+            if (!def)
+                goto error;
+        } else {
+        if ((def = virInterfaceDefParseNode(conn, xml, ifaces[i])) == NULL)
+                goto error;
+        }
+        if (!(iface = virInterfaceAssignDef(conn, &privconn->ifaces, def))) {
+            virInterfaceDefFree(def);
+            goto error;
+        }
+        virInterfaceObjUnlock(iface);
+    }
+    VIR_FREE(ifaces);
+
+    /* Parse Storage Pool list */
+    ret = virXPathNodeSet(conn, "/node/pool", ctxt, &pools);
+    if (ret < 0) {
+        testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node pool list"));
+        goto error;
+    }
+    for (i = 0 ; i < ret ; i++) {
+        virStoragePoolDefPtr def;
+        virStoragePoolObjPtr pool;
+        char *relFile = virXMLPropString(pools[i], "file");
+        if (relFile != NULL) {
+            char *absFile = testBuildFilename(file, relFile);
+            VIR_FREE(relFile);
+            if (!absFile) {
+                testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                          _("resolving pool filename"));
+                goto error;
+            }
+
+            def = virStoragePoolDefParseFile(conn, absFile);
+            VIR_FREE(absFile);
+            if (!def)
+                goto error;
+        } else {
+            if ((def = virStoragePoolDefParseNode(conn, xml,
+                                                  pools[i])) == NULL) {
+                goto error;
+            }
+        }
+
+        if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools,
+                                                def))) {
+            virStoragePoolDefFree(def);
+            goto error;
+        }
+
+        if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
+            virStoragePoolObjUnlock(pool);
+            goto error;
+        }
+        pool->active = 1;
+
+        /* Find storage volumes */
+        if (testOpenVolumesForPool(conn, xml, ctxt, file, pool, i+1) < 0) {
+            virStoragePoolObjUnlock(pool);
+            goto error;
+        }
+
+        virStoragePoolObjUnlock(pool);
+    }
+    VIR_FREE(pools);
+
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xml);
+    testDriverUnlock(privconn);
+
+    return (0);
+
+ error:
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xml);
+    VIR_FREE(domains);
+    VIR_FREE(networks);
+    VIR_FREE(ifaces);
+    VIR_FREE(pools);
+    if (fd != -1)
+        close(fd);
+    virDomainObjListFree(&privconn->domains);
+    virNetworkObjListFree(&privconn->networks);
+    virInterfaceObjListFree(&privconn->ifaces);
+    virStoragePoolObjListFree(&privconn->pools);
+    testDriverUnlock(privconn);
+    VIR_FREE(privconn);
+    conn->privateData = NULL;
+    return VIR_DRV_OPEN_ERROR;
+}
+
+
+static virDrvOpenStatus testOpen(virConnectPtr conn,
+                    virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                    int flags ATTRIBUTE_UNUSED)
+{
+    int ret;
+
+    if (!conn->uri)
+        return VIR_DRV_OPEN_DECLINED;
+
+    if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "test"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    /* Remote driver should handle these. */
+    if (conn->uri->server)
+        return VIR_DRV_OPEN_DECLINED;
+
+    /* From this point on, the connection is for us. */
+    if (!conn->uri->path
+        || conn->uri->path[0] == '\0'
+        || (conn->uri->path[0] == '/' && conn->uri->path[1] == '\0')) {
+        testError (NULL, VIR_ERR_INVALID_ARG,
+                   "%s", _("testOpen: supply a path or use test:///default"));
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    if (STREQ(conn->uri->path, "/default"))
+        ret = testOpenDefault(conn);
+    else
+        ret = testOpenFromFile(conn,
+                               conn->uri->path);
+
+    if (ret == VIR_DRV_OPEN_SUCCESS) {
+        testConnPtr privconn = conn->privateData;
+        testDriverLock(privconn);
+        /* Init callback list */
+        if (VIR_ALLOC(privconn->domainEventCallbacks) < 0 ||
+            !(privconn->domainEventQueue = virDomainEventQueueNew())) {
+            virReportOOMError(NULL);
+            testDriverUnlock(privconn);
+            testClose(conn);
+            return VIR_DRV_OPEN_ERROR;
+        }
+
+        if ((privconn->domainEventTimer =
+             virEventAddTimeout(-1, testDomainEventFlush, privconn, NULL)) < 0)
+            DEBUG0("virEventAddTimeout failed: No addTimeoutImpl defined. "
+                   "continuing without events.");
+        testDriverUnlock(privconn);
+    }
+
+    return (ret);
+}
+
+static int testClose(virConnectPtr conn)
+{
+    testConnPtr privconn = conn->privateData;
+    testDriverLock(privconn);
+    virCapabilitiesFree(privconn->caps);
+    virDomainObjListFree(&privconn->domains);
+    virNetworkObjListFree(&privconn->networks);
+    virInterfaceObjListFree(&privconn->ifaces);
+    virStoragePoolObjListFree(&privconn->pools);
+
+    virDomainEventCallbackListFree(privconn->domainEventCallbacks);
+    virDomainEventQueueFree(privconn->domainEventQueue);
+
+    if (privconn->domainEventTimer != -1)
+        virEventRemoveTimeout(privconn->domainEventTimer);
+
+    testDriverUnlock(privconn);
+    virMutexDestroy(&privconn->lock);
+
+    VIR_FREE (privconn);
+    conn->privateData = NULL;
+    return 0;
+}
+
+static int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
+                          unsigned long *hvVer)
+{
+    *hvVer = 2;
+    return (0);
+}
+
+static char *testGetHostname (virConnectPtr conn)
+{
+    char *result;
+
+    result = virGetHostname();
+    if (result == NULL) {
+        virReportSystemError(conn, errno,
+                             "%s", _("cannot lookup hostname"));
+        return NULL;
+    }
+    /* Caller frees this string. */
+    return result;
+}
+
+static int testGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED,
+                           const char *type ATTRIBUTE_UNUSED)
+{
+    return 32;
+}
+
+static int testNodeGetInfo(virConnectPtr conn,
+                           virNodeInfoPtr info)
+{
+    testConnPtr privconn = conn->privateData;
+    testDriverLock(privconn);
+    memcpy(info, &privconn->nodeInfo, sizeof(virNodeInfo));
+    testDriverUnlock(privconn);
+    return (0);
+}
+
+static char *testGetCapabilities (virConnectPtr conn)
+{
+    testConnPtr privconn = conn->privateData;
+    char *xml;
+    testDriverLock(privconn);
+    if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
+        virReportOOMError(conn);
+    testDriverUnlock(privconn);
+    return xml;
+}
+
+static int testNumOfDomains(virConnectPtr conn)
+{
+    testConnPtr privconn = conn->privateData;
+    unsigned int numActive = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->domains.count ; i++)
+        if (virDomainIsActive(privconn->domains.objs[i]))
+            numActive++;
+    testDriverUnlock(privconn);
+
+    return numActive;
+}
+
+static virDomainPtr
+testDomainCreateXML(virConnectPtr conn, const char *xml,
+                      unsigned int flags ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = conn->privateData;
+    virDomainPtr ret = NULL;
+    virDomainDefPtr def;
+    virDomainObjPtr dom = NULL;
+    virDomainEventPtr event = NULL;
+
+    testDriverLock(privconn);
+    if ((def = virDomainDefParseString(conn, privconn->caps, xml,
+                                       VIR_DOMAIN_XML_INACTIVE)) == NULL)
+        goto cleanup;
+
+    if (testDomainGenerateIfnames(conn, def) < 0)
+        goto cleanup;
+    if (!(dom = virDomainAssignDef(conn, &privconn->domains, def)))
+        goto cleanup;
+    def = NULL;
+    dom->state = VIR_DOMAIN_RUNNING;
+    dom->def->id = privconn->nextDomID++;
+
+    event = virDomainEventNewFromObj(dom,
+                                     VIR_DOMAIN_EVENT_STARTED,
+                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);
+
+    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
+    if (ret)
+        ret->id = dom->def->id;
+
+cleanup:
+    if (dom)
+        virDomainObjUnlock(dom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    if (def)
+        virDomainDefFree(def);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+
+static virDomainPtr testLookupDomainByID(virConnectPtr conn,
+                                         int id)
+{
+    testConnPtr privconn = conn->privateData;
+    virDomainPtr ret = NULL;
+    virDomainObjPtr dom;
+
+    testDriverLock(privconn);
+    dom = virDomainFindByID(&privconn->domains, id);
+    testDriverUnlock(privconn);
+
+    if (dom == NULL) {
+        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
+    if (ret)
+        ret->id = dom->def->id;
+
+cleanup:
+    if (dom)
+        virDomainObjUnlock(dom);
+    return ret;
+}
+
+static virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
+                                           const unsigned char *uuid)
+{
+    testConnPtr privconn = conn->privateData;
+    virDomainPtr ret = NULL;
+    virDomainObjPtr dom ;
+
+    testDriverLock(privconn);
+    dom = virDomainFindByUUID(&privconn->domains, uuid);
+    testDriverUnlock(privconn);
+
+    if (dom == NULL) {
+        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
+    if (ret)
+        ret->id = dom->def->id;
+
+cleanup:
+    if (dom)
+        virDomainObjUnlock(dom);
+    return ret;
+}
+
+static virDomainPtr testLookupDomainByName(virConnectPtr conn,
+                                           const char *name)
+{
+    testConnPtr privconn = conn->privateData;
+    virDomainPtr ret = NULL;
+    virDomainObjPtr dom;
+
+    testDriverLock(privconn);
+    dom = virDomainFindByName(&privconn->domains, name);
+    testDriverUnlock(privconn);
+
+    if (dom == NULL) {
+        testError (conn, VIR_ERR_NO_DOMAIN, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
+    if (ret)
+        ret->id = dom->def->id;
+
+cleanup:
+    if (dom)
+        virDomainObjUnlock(dom);
+    return ret;
+}
+
+static int testListDomains (virConnectPtr conn,
+                            int *ids,
+                            int maxids)
+{
+    testConnPtr privconn = conn->privateData;
+    unsigned int n = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->domains.count && n < maxids ; i++) {
+        virDomainObjLock(privconn->domains.objs[i]);
+        if (virDomainIsActive(privconn->domains.objs[i]))
+            ids[n++] = privconn->domains.objs[i]->def->id;
+        virDomainObjUnlock(privconn->domains.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+}
+
+static int testDestroyDomain (virDomainPtr domain)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privdom->state = VIR_DOMAIN_SHUTOFF;
+    privdom->def->id = -1;
+    domain->id = -1;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
+    if (!privdom->persistent) {
+        virDomainRemoveInactive(&privconn->domains,
+                                privdom);
+        privdom = NULL;
+    }
+
+
+    ret = 0;
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testResumeDomain (virDomainPtr domain)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (privdom->state != VIR_DOMAIN_PAUSED) {
+        testError(domain->conn,
+                  VIR_ERR_INTERNAL_ERROR, _("domain '%s' not paused"),
+                  domain->name);
+        goto cleanup;
+    }
+
+    privdom->state = VIR_DOMAIN_RUNNING;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_RESUMED,
+                                     VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event) {
+        testDriverLock(privconn);
+        testDomainEventQueue(privconn, event);
+        testDriverUnlock(privconn);
+    }
+    return ret;
+}
+
+static int testPauseDomain (virDomainPtr domain)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (privdom->state == VIR_DOMAIN_SHUTOFF ||
+        privdom->state == VIR_DOMAIN_PAUSED) {
+        testError(domain->conn,
+                  VIR_ERR_INTERNAL_ERROR, _("domain '%s' not running"),
+                  domain->name);
+        goto cleanup;
+    }
+
+    privdom->state = VIR_DOMAIN_PAUSED;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_SUSPENDED,
+                                     VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+
+    if (event) {
+        testDriverLock(privconn);
+        testDomainEventQueue(privconn, event);
+        testDriverUnlock(privconn);
+    }
+    return ret;
+}
+
+static int testShutdownDomain (virDomainPtr domain)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (privdom->state == VIR_DOMAIN_SHUTOFF) {
+        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("domain '%s' not running"), domain->name);
+        goto cleanup;
+    }
+
+    privdom->state = VIR_DOMAIN_SHUTOFF;
+    domain->id = -1;
+    privdom->def->id = -1;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
+    if (!privdom->persistent) {
+        virDomainRemoveInactive(&privconn->domains,
+                                privdom);
+        privdom = NULL;
+    }
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+/* Similar behaviour as shutdown */
+static int testRebootDomain (virDomainPtr domain,
+                             unsigned int action ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privdom->state = VIR_DOMAIN_SHUTDOWN;
+    switch (privdom->def->onReboot) {
+    case VIR_DOMAIN_LIFECYCLE_DESTROY:
+        privdom->state = VIR_DOMAIN_SHUTOFF;
+        domain->id = -1;
+        privdom->def->id = -1;
+        break;
+
+    case VIR_DOMAIN_LIFECYCLE_RESTART:
+        privdom->state = VIR_DOMAIN_RUNNING;
+        break;
+
+    case VIR_DOMAIN_LIFECYCLE_PRESERVE:
+        privdom->state = VIR_DOMAIN_SHUTOFF;
+        domain->id = -1;
+        privdom->def->id = -1;
+        break;
+
+    case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME:
+        privdom->state = VIR_DOMAIN_RUNNING;
+        break;
+
+    default:
+        privdom->state = VIR_DOMAIN_SHUTOFF;
+        domain->id = -1;
+        privdom->def->id = -1;
+        break;
+    }
+
+    if (privdom->state == VIR_DOMAIN_SHUTOFF) {
+        event = virDomainEventNewFromObj(privdom,
+                                         VIR_DOMAIN_EVENT_STOPPED,
+                                         VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
+        if (!privdom->persistent) {
+            virDomainRemoveInactive(&privconn->domains,
+                                    privdom);
+            privdom = NULL;
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testGetDomainInfo (virDomainPtr domain,
+                              virDomainInfoPtr info)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    struct timeval tv;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (gettimeofday(&tv, NULL) < 0) {
+        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("getting time of day"));
+        goto cleanup;
+    }
+
+    info->state = privdom->state;
+    info->memory = privdom->def->memory;
+    info->maxMem = privdom->def->maxmem;
+    info->nrVirtCpu = privdom->def->vcpus;
+    info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll  * 1000ll) + (tv.tv_usec * 1000ll));
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+#define TEST_SAVE_MAGIC "TestGuestMagic"
+
+static int testDomainSave(virDomainPtr domain,
+                          const char *path)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    char *xml = NULL;
+    int fd = -1;
+    int len;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    xml = virDomainDefFormat(domain->conn,
+                             privdom->def,
+                             VIR_DOMAIN_XML_SECURE);
+
+    if (xml == NULL) {
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' failed to allocate space for metadata"),
+                             domain->name);
+        goto cleanup;
+    }
+
+    if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': open failed"),
+                             domain->name, path);
+        goto cleanup;
+    }
+    len = strlen(xml);
+    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
+        goto cleanup;
+    }
+    if (safewrite(fd, (char*)&len, sizeof(len)) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
+        goto cleanup;
+    }
+    if (safewrite(fd, xml, len) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
+        goto cleanup;
+    }
+
+    if (close(fd) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("saving domain '%s' to '%s': write failed"),
+                             domain->name, path);
+        goto cleanup;
+    }
+    fd = -1;
+
+    privdom->state = VIR_DOMAIN_SHUTOFF;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_SAVED);
+    if (!privdom->persistent) {
+        virDomainRemoveInactive(&privconn->domains,
+                                privdom);
+        privdom = NULL;
+    }
+    ret = 0;
+
+cleanup:
+    VIR_FREE(xml);
+
+    /* Don't report failure in close or unlink, because
+     * in either case we're already in a failure scenario
+     * and have reported a earlier error */
+    if (ret != 0) {
+        if (fd != -1)
+            close(fd);
+        unlink(path);
+    }
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testDomainRestore(virConnectPtr conn,
+                             const char *path)
+{
+    testConnPtr privconn = conn->privateData;
+    char *xml = NULL;
+    char magic[15];
+    int fd = -1;
+    int len;
+    virDomainDefPtr def = NULL;
+    virDomainObjPtr dom = NULL;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    if ((fd = open(path, O_RDONLY)) < 0) {
+        virReportSystemError(conn, errno,
+                             _("cannot read domain image '%s'"),
+                             path);
+        goto cleanup;
+    }
+    if (saferead(fd, magic, sizeof(magic)) != sizeof(magic)) {
+        virReportSystemError(conn, errno,
+                             _("incomplete save header in '%s'"),
+                             path);
+        goto cleanup;
+    }
+    if (memcmp(magic, TEST_SAVE_MAGIC, sizeof(magic))) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("mismatched header magic"));
+        goto cleanup;
+    }
+    if (saferead(fd, (char*)&len, sizeof(len)) != sizeof(len)) {
+        virReportSystemError(conn, errno,
+                             _("failed to read metadata length in '%s'"),
+                             path);
+        goto cleanup;
+    }
+    if (len < 1 || len > 8192) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("length of metadata out of range"));
+        goto cleanup;
+    }
+    if (VIR_ALLOC_N(xml, len+1) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+    if (saferead(fd, xml, len) != len) {
+        virReportSystemError(conn, errno,
+                             _("incomplete metdata in '%s'"), path);
+        goto cleanup;
+    }
+    xml[len] = '\0';
+
+    testDriverLock(privconn);
+    def = virDomainDefParseString(conn, privconn->caps, xml,
+                                  VIR_DOMAIN_XML_INACTIVE);
+    if (!def)
+        goto cleanup;
+
+    if (testDomainGenerateIfnames(conn, def) < 0)
+        goto cleanup;
+    if (!(dom = virDomainAssignDef(conn, &privconn->domains, def)))
+        goto cleanup;
+    def = NULL;
+
+    dom->state = VIR_DOMAIN_RUNNING;
+    dom->def->id = privconn->nextDomID++;
+    event = virDomainEventNewFromObj(dom,
+                                     VIR_DOMAIN_EVENT_STARTED,
+                                     VIR_DOMAIN_EVENT_STARTED_RESTORED);
+    ret = 0;
+
+cleanup:
+    virDomainDefFree(def);
+    VIR_FREE(xml);
+    if (fd != -1)
+        close(fd);
+    if (dom)
+        virDomainObjUnlock(dom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testDomainCoreDump(virDomainPtr domain,
+                              const char *to,
+                              int flags ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    int fd = -1;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if ((fd = open(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("domain '%s' coredump: failed to open %s"),
+                             domain->name, to);
+        goto cleanup;
+    }
+    if (safewrite(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("domain '%s' coredump: failed to write header to %s"),
+                             domain->name, to);
+        goto cleanup;
+    }
+    if (close(fd) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             _("domain '%s' coredump: write failed: %s"),
+                             domain->name, to);
+        goto cleanup;
+    }
+    privdom->state = VIR_DOMAIN_SHUTOFF;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_CRASHED);
+    if (!privdom->persistent) {
+        virDomainRemoveInactive(&privconn->domains,
+                                privdom);
+        privdom = NULL;
+    }
+    ret = 0;
+
+cleanup:
+    if (fd != -1)
+        close(fd);
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static char *testGetOSType(virDomainPtr dom) {
+    char *ret = strdup("linux");
+    if (!ret)
+        virReportOOMError(dom->conn);
+    return ret;
+}
+
+static unsigned long testGetMaxMemory(virDomainPtr domain) {
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    unsigned long ret = 0;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    ret = privdom->def->maxmem;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static int testSetMaxMemory(virDomainPtr domain,
+                            unsigned long memory)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    /* XXX validate not over host memory wrt to other domains */
+    privdom->def->maxmem = memory;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static int testSetMemory(virDomainPtr domain,
+                         unsigned long memory)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (memory > privdom->def->maxmem) {
+        testError(domain->conn,
+                  VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privdom->def->memory = memory;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static int testSetVcpus(virDomainPtr domain,
+                        unsigned int nrCpus) {
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    /* We allow more cpus in guest than host */
+    if (nrCpus > 32) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privdom->def->vcpus = nrCpus;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static char *testDomainDumpXML(virDomainPtr domain, int flags)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainDefPtr def;
+    virDomainObjPtr privdom;
+    char *ret = NULL;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
+        privdom->newDef ? privdom->newDef : privdom->def;
+
+    ret = virDomainDefFormat(domain->conn,
+                             def,
+                             flags);
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static int testNumOfDefinedDomains(virConnectPtr conn) {
+    testConnPtr privconn = conn->privateData;
+    unsigned int numInactive = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->domains.count ; i++) {
+        virDomainObjLock(privconn->domains.objs[i]);
+        if (!virDomainIsActive(privconn->domains.objs[i]))
+            numInactive++;
+        virDomainObjUnlock(privconn->domains.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return numInactive;
+}
+
+static int testListDefinedDomains(virConnectPtr conn,
+                                  char **const names,
+                                  int maxnames) {
+    testConnPtr privconn = conn->privateData;
+    unsigned int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*maxnames);
+    for (i = 0 ; i < privconn->domains.count && n < maxnames ; i++) {
+        virDomainObjLock(privconn->domains.objs[i]);
+        if (!virDomainIsActive(privconn->domains.objs[i]) &&
+            !(names[n++] = strdup(privconn->domains.objs[i]->def->name))) {
+            virDomainObjUnlock(privconn->domains.objs[i]);
+            goto no_memory;
+        }
+        virDomainObjUnlock(privconn->domains.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < maxnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+static virDomainPtr testDomainDefineXML(virConnectPtr conn,
+                                        const char *xml) {
+    testConnPtr privconn = conn->privateData;
+    virDomainPtr ret = NULL;
+    virDomainDefPtr def;
+    virDomainObjPtr dom = NULL;
+    virDomainEventPtr event = NULL;
+
+    testDriverLock(privconn);
+    if ((def = virDomainDefParseString(conn, privconn->caps, xml,
+                                       VIR_DOMAIN_XML_INACTIVE)) == NULL)
+        goto cleanup;
+
+    if (testDomainGenerateIfnames(conn, def) < 0)
+        goto cleanup;
+    if (!(dom = virDomainAssignDef(conn, &privconn->domains, def)))
+        goto cleanup;
+    def = NULL;
+    dom->persistent = 1;
+
+    event = virDomainEventNewFromObj(dom,
+                                     VIR_DOMAIN_EVENT_DEFINED,
+                                     VIR_DOMAIN_EVENT_DEFINED_ADDED);
+
+    ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
+    if (ret)
+        ret->id = dom->def->id;
+
+cleanup:
+    virDomainDefFree(def);
+    if (dom)
+        virDomainObjUnlock(dom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testNodeGetCellsFreeMemory(virConnectPtr conn,
+                                      unsigned long long *freemems,
+                                      int startCell, int maxCells) {
+    testConnPtr privconn = conn->privateData;
+    int i, j;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    if (startCell > privconn->numCells) {
+        testError(conn, VIR_ERR_INVALID_ARG,
+                  "%s", _("Range exceeds available cells"));
+        goto cleanup;
+    }
+
+    for (i = startCell, j = 0;
+         (i < privconn->numCells && j < maxCells) ;
+         ++i, ++j) {
+        freemems[j] = privconn->cells[i].mem;
+    }
+    ret = j;
+
+cleanup:
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+
+static int testDomainCreate(virDomainPtr domain) {
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (privdom->state != VIR_DOMAIN_SHUTOFF) {
+        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("Domain '%s' is already running"), domain->name);
+        goto cleanup;
+    }
+
+    domain->id = privdom->def->id = privconn->nextDomID++;
+    privdom->state = VIR_DOMAIN_RUNNING;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_STARTED,
+                                     VIR_DOMAIN_EVENT_STARTED_BOOTED);
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testDomainUndefine(virDomainPtr domain) {
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    virDomainEventPtr event = NULL;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (privdom->state != VIR_DOMAIN_SHUTOFF) {
+        testError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("Domain '%s' is still running"), domain->name);
+        goto cleanup;
+    }
+
+    privdom->state = VIR_DOMAIN_SHUTOFF;
+    event = virDomainEventNewFromObj(privdom,
+                                     VIR_DOMAIN_EVENT_UNDEFINED,
+                                     VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
+    virDomainRemoveInactive(&privconn->domains,
+                            privdom);
+    privdom = NULL;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    if (event)
+        testDomainEventQueue(privconn, event);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testDomainGetAutostart(virDomainPtr domain,
+                                  int *autostart)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    *autostart = privdom->autostart;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+
+static int testDomainSetAutostart(virDomainPtr domain,
+                                  int autostart)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privdom->autostart = autostart ? 1 : 0;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static char *testDomainGetSchedulerType(virDomainPtr domain,
+                                        int *nparams)
+{
+    char *type = NULL;
+
+    *nparams = 1;
+    type = strdup("fair");
+    if (!type)
+        virReportOOMError(domain->conn);
+
+    return type;
+}
+
+static int testDomainGetSchedulerParams(virDomainPtr domain,
+                                        virSchedParameterPtr params,
+                                        int *nparams)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (*nparams != 1) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, "nparams");
+        goto cleanup;
+    }
+    strcpy(params[0].field, "weight");
+    params[0].type = VIR_DOMAIN_SCHED_FIELD_UINT;
+    /* XXX */
+    /*params[0].value.ui = privdom->weight;*/
+    params[0].value.ui = 50;
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+
+static int testDomainSetSchedulerParams(virDomainPtr domain,
+                                        virSchedParameterPtr params,
+                                        int nparams)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (nparams != 1) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, "nparams");
+        goto cleanup;
+    }
+    if (STRNEQ(params[0].field, "weight")) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, "field");
+        goto cleanup;
+    }
+    if (params[0].type != VIR_DOMAIN_SCHED_FIELD_UINT) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, "type");
+        goto cleanup;
+    }
+    /* XXX */
+    /*privdom->weight = params[0].value.ui;*/
+    ret = 0;
+
+cleanup:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static int testDomainBlockStats(virDomainPtr domain,
+                                const char *path,
+                                struct _virDomainBlockStats *stats)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    struct timeval tv;
+    unsigned long long statbase;
+    int i, found = 0, ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    for (i = 0 ; i < privdom->def->ndisks ; i++) {
+        if (STREQ(path, privdom->def->disks[i]->dst)) {
+            found = 1;
+            break;
+        }
+    }
+
+    if (!found) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG,
+                  _("invalid path: %s"), path);
+        goto error;
+    }
+
+    if (gettimeofday(&tv, NULL) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             "%s", _("getting time of day"));
+        goto error;
+    }
+
+    /* No significance to these numbers, just enough to mix it up*/
+    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
+    stats->rd_req = statbase / 10;
+    stats->rd_bytes = statbase / 20;
+    stats->wr_req = statbase / 30;
+    stats->wr_bytes = statbase / 40;
+    stats->errs = tv.tv_sec / 2;
+
+    ret = 0;
+error:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static int testDomainInterfaceStats(virDomainPtr domain,
+                                    const char *path,
+                                    struct _virDomainInterfaceStats *stats)
+{
+    testConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr privdom;
+    struct timeval tv;
+    unsigned long long statbase;
+    int i, found = 0, ret = -1;
+
+    testDriverLock(privconn);
+    privdom = virDomainFindByName(&privconn->domains,
+                                  domain->name);
+    testDriverUnlock(privconn);
+
+    if (privdom == NULL) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    for (i = 0 ; i < privdom->def->nnets ; i++) {
+        if (privdom->def->nets[i]->ifname &&
+            STREQ (privdom->def->nets[i]->ifname, path)) {
+            found = 1;
+            break;
+        }
+    }
+
+    if (!found) {
+        testError(domain->conn, VIR_ERR_INVALID_ARG,
+                  _("invalid path, '%s' is not a known interface"), path);
+        goto error;
+    }
+
+    if (gettimeofday(&tv, NULL) < 0) {
+        virReportSystemError(domain->conn, errno,
+                             "%s", _("getting time of day"));
+        goto error;
+    }
+
+    /* No significance to these numbers, just enough to mix it up*/
+    statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
+    stats->rx_bytes = statbase / 10;
+    stats->rx_packets = statbase / 100;
+    stats->rx_errs = tv.tv_sec / 1;
+    stats->rx_drop = tv.tv_sec / 2;
+    stats->tx_bytes = statbase / 20;
+    stats->tx_packets = statbase / 110;
+    stats->tx_errs = tv.tv_sec / 3;
+    stats->tx_drop = tv.tv_sec / 4;
+
+    ret = 0;
+error:
+    if (privdom)
+        virDomainObjUnlock(privdom);
+    return ret;
+}
+
+static virDrvOpenStatus testOpenNetwork(virConnectPtr conn,
+                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                        int flags ATTRIBUTE_UNUSED) {
+    if (STRNEQ(conn->driver->name, "Test"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    conn->networkPrivateData = conn->privateData;
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int testCloseNetwork(virConnectPtr conn) {
+    conn->networkPrivateData = NULL;
+    return 0;
+}
+
+
+static virNetworkPtr testLookupNetworkByUUID(virConnectPtr conn,
+                                           const unsigned char *uuid)
+{
+    testConnPtr privconn = conn->privateData;
+    virNetworkObjPtr net;
+    virNetworkPtr ret = NULL;
+
+    testDriverLock(privconn);
+    net = virNetworkFindByUUID(&privconn->networks, uuid);
+    testDriverUnlock(privconn);
+
+    if (net == NULL) {
+        testError (conn, VIR_ERR_NO_NETWORK, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
+
+cleanup:
+    if (net)
+        virNetworkObjUnlock(net);
+    return ret;
+}
+
+static virNetworkPtr testLookupNetworkByName(virConnectPtr conn,
+                                             const char *name)
+{
+    testConnPtr privconn = conn->privateData;
+    virNetworkObjPtr net;
+    virNetworkPtr ret = NULL;
+
+    testDriverLock(privconn);
+    net = virNetworkFindByName(&privconn->networks, name);
+    testDriverUnlock(privconn);
+
+    if (net == NULL) {
+        testError (conn, VIR_ERR_NO_NETWORK, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
+
+cleanup:
+    if (net)
+        virNetworkObjUnlock(net);
+    return ret;
+}
+
+
+static int testNumNetworks(virConnectPtr conn) {
+    testConnPtr privconn = conn->privateData;
+    int numActive = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->networks.count ; i++) {
+        virNetworkObjLock(privconn->networks.objs[i]);
+        if (virNetworkIsActive(privconn->networks.objs[i]))
+            numActive++;
+        virNetworkObjUnlock(privconn->networks.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return numActive;
+}
+
+static int testListNetworks(virConnectPtr conn, char **const names, int nnames) {
+    testConnPtr privconn = conn->privateData;
+    int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*nnames);
+    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
+        virNetworkObjLock(privconn->networks.objs[i]);
+        if (virNetworkIsActive(privconn->networks.objs[i]) &&
+            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
+            virNetworkObjUnlock(privconn->networks.objs[i]);
+            goto no_memory;
+        }
+        virNetworkObjUnlock(privconn->networks.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < nnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+static int testNumDefinedNetworks(virConnectPtr conn) {
+    testConnPtr privconn = conn->privateData;
+    int numInactive = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->networks.count ; i++) {
+        virNetworkObjLock(privconn->networks.objs[i]);
+        if (!virNetworkIsActive(privconn->networks.objs[i]))
+            numInactive++;
+        virNetworkObjUnlock(privconn->networks.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return numInactive;
+}
+
+static int testListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
+    testConnPtr privconn = conn->privateData;
+    int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*nnames);
+    for (i = 0 ; i < privconn->networks.count && n < nnames ; i++) {
+        virNetworkObjLock(privconn->networks.objs[i]);
+        if (!virNetworkIsActive(privconn->networks.objs[i]) &&
+            !(names[n++] = strdup(privconn->networks.objs[i]->def->name))) {
+            virNetworkObjUnlock(privconn->networks.objs[i]);
+            goto no_memory;
+        }
+        virNetworkObjUnlock(privconn->networks.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < nnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+static virNetworkPtr testNetworkCreate(virConnectPtr conn, const char *xml) {
+    testConnPtr privconn = conn->privateData;
+    virNetworkDefPtr def;
+    virNetworkObjPtr net = NULL;
+    virNetworkPtr ret = NULL;
+
+    testDriverLock(privconn);
+    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
+        goto cleanup;
+
+    if ((net = virNetworkAssignDef(conn, &privconn->networks, def)) == NULL)
+        goto cleanup;
+    def = NULL;
+    net->active = 1;
+
+    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
+
+cleanup:
+    virNetworkDefFree(def);
+    if (net)
+        virNetworkObjUnlock(net);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static virNetworkPtr testNetworkDefine(virConnectPtr conn, const char *xml) {
+    testConnPtr privconn = conn->privateData;
+    virNetworkDefPtr def;
+    virNetworkObjPtr net = NULL;
+    virNetworkPtr ret = NULL;
+
+    testDriverLock(privconn);
+    if ((def = virNetworkDefParseString(conn, xml)) == NULL)
+        goto cleanup;
+
+    if ((net = virNetworkAssignDef(conn, &privconn->networks, def)) == NULL)
+        goto cleanup;
+    def = NULL;
+    net->persistent = 1;
+
+    ret = virGetNetwork(conn, net->def->name, net->def->uuid);
+
+cleanup:
+    virNetworkDefFree(def);
+    if (net)
+        virNetworkObjUnlock(net);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testNetworkUndefine(virNetworkPtr network) {
+    testConnPtr privconn = network->conn->privateData;
+    virNetworkObjPtr privnet;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (virNetworkIsActive(privnet)) {
+        testError(network->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("Network '%s' is still running"), network->name);
+        goto cleanup;
+    }
+
+    virNetworkRemoveInactive(&privconn->networks,
+                             privnet);
+    privnet = NULL;
+    ret = 0;
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testNetworkStart(virNetworkPtr network) {
+    testConnPtr privconn = network->conn->privateData;
+    virNetworkObjPtr privnet;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+    testDriverUnlock(privconn);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (virNetworkIsActive(privnet)) {
+        testError(network->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("Network '%s' is already running"), network->name);
+        goto cleanup;
+    }
+
+    privnet->active = 1;
+    ret = 0;
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    return ret;
+}
+
+static int testNetworkDestroy(virNetworkPtr network) {
+    testConnPtr privconn = network->conn->privateData;
+    virNetworkObjPtr privnet;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privnet->active = 0;
+    if (!privnet->persistent) {
+        virNetworkRemoveInactive(&privconn->networks,
+                                 privnet);
+        privnet = NULL;
+    }
+    ret = 0;
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static char *testNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = network->conn->privateData;
+    virNetworkObjPtr privnet;
+    char *ret = NULL;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+    testDriverUnlock(privconn);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    ret = virNetworkDefFormat(network->conn, privnet->def);
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    return ret;
+}
+
+static char *testNetworkGetBridgeName(virNetworkPtr network) {
+    testConnPtr privconn = network->conn->privateData;
+    char *bridge = NULL;
+    virNetworkObjPtr privnet;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+    testDriverUnlock(privconn);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (privnet->def->bridge &&
+        !(bridge = strdup(privnet->def->bridge))) {
+        virReportOOMError(network->conn);
+        goto cleanup;
+    }
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    return bridge;
+}
+
+static int testNetworkGetAutostart(virNetworkPtr network,
+                                   int *autostart) {
+    testConnPtr privconn = network->conn->privateData;
+    virNetworkObjPtr privnet;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+    testDriverUnlock(privconn);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    *autostart = privnet->autostart;
+    ret = 0;
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    return ret;
+}
+
+static int testNetworkSetAutostart(virNetworkPtr network,
+                                   int autostart) {
+    testConnPtr privconn = network->conn->privateData;
+    virNetworkObjPtr privnet;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privnet = virNetworkFindByName(&privconn->networks,
+                                   network->name);
+    testDriverUnlock(privconn);
+
+    if (privnet == NULL) {
+        testError(network->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privnet->autostart = autostart ? 1 : 0;
+    ret = 0;
+
+cleanup:
+    if (privnet)
+        virNetworkObjUnlock(privnet);
+    return ret;
+}
+
+
+/*
+ * Physical host interface routines
+ */
+
+static virDrvOpenStatus testOpenInterface(virConnectPtr conn,
+                                          virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                          int flags ATTRIBUTE_UNUSED)
+{
+    if (STRNEQ(conn->driver->name, "Test"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    conn->interfacePrivateData = conn->privateData;
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int testCloseInterface(virConnectPtr conn)
+{
+    conn->interfacePrivateData = NULL;
+    return 0;
+}
+
+
+static int testNumOfInterfaces(virConnectPtr conn)
+{
+    testConnPtr privconn = conn->privateData;
+    int i, count = 0;
+
+    testDriverLock(privconn);
+    for (i = 0 ; (i < privconn->ifaces.count); i++) {
+        virInterfaceObjLock(privconn->ifaces.objs[i]);
+        if (virInterfaceIsActive(privconn->ifaces.objs[i])) {
+            count++;
+        }
+        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
+    }
+    testDriverUnlock(privconn);
+    return count;
+}
+
+static int testListInterfaces(virConnectPtr conn, char **const names, int nnames)
+{
+    testConnPtr privconn = conn->privateData;
+    int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*nnames);
+    for (i = 0 ; (i < privconn->ifaces.count) && (n < nnames); i++) {
+        virInterfaceObjLock(privconn->ifaces.objs[i]);
+        if (virInterfaceIsActive(privconn->ifaces.objs[i])) {
+            if (!(names[n++] = strdup(privconn->ifaces.objs[i]->def->name))) {
+                virInterfaceObjUnlock(privconn->ifaces.objs[i]);
+                goto no_memory;
+            }
+        }
+        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < nnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+static int testNumOfDefinedInterfaces(virConnectPtr conn)
+{
+    testConnPtr privconn = conn->privateData;
+    int i, count = 0;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->ifaces.count; i++) {
+        virInterfaceObjLock(privconn->ifaces.objs[i]);
+        if (!virInterfaceIsActive(privconn->ifaces.objs[i])) {
+            count++;
+        }
+        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
+    }
+    testDriverUnlock(privconn);
+    return count;
+}
+
+static int testListDefinedInterfaces(virConnectPtr conn, char **const names, int nnames)
+{
+    testConnPtr privconn = conn->privateData;
+    int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*nnames);
+    for (i = 0 ; (i < privconn->ifaces.count) && (n < nnames); i++) {
+        virInterfaceObjLock(privconn->ifaces.objs[i]);
+        if (!virInterfaceIsActive(privconn->ifaces.objs[i])) {
+            if (!(names[n++] = strdup(privconn->ifaces.objs[i]->def->name))) {
+                virInterfaceObjUnlock(privconn->ifaces.objs[i]);
+                goto no_memory;
+            }
+        }
+        virInterfaceObjUnlock(privconn->ifaces.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < nnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+static virInterfacePtr testLookupInterfaceByName(virConnectPtr conn,
+                                                 const char *name)
+{
+    testConnPtr privconn = conn->privateData;
+    virInterfaceObjPtr iface;
+    virInterfacePtr ret = NULL;
+
+    testDriverLock(privconn);
+    iface = virInterfaceFindByName(&privconn->ifaces, name);
+    testDriverUnlock(privconn);
+
+    if (iface == NULL) {
+        testError (conn, VIR_ERR_NO_INTERFACE, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetInterface(conn, iface->def->name, iface->def->mac);
+
+cleanup:
+    if (iface)
+        virInterfaceObjUnlock(iface);
+    return ret;
+}
+
+static virInterfacePtr testLookupInterfaceByMACString(virConnectPtr conn,
+                                                      const char *mac)
+{
+    testConnPtr privconn = conn->privateData;
+    virInterfaceObjPtr iface;
+    int ifacect;
+    virInterfacePtr ret = NULL;
+
+    testDriverLock(privconn);
+    ifacect = virInterfaceFindByMACString(&privconn->ifaces, mac, &iface, 1);
+    testDriverUnlock(privconn);
+
+    if (ifacect == 0) {
+        testError (conn, VIR_ERR_NO_INTERFACE, NULL);
+        goto cleanup;
+    }
+
+    if (ifacect > 1) {
+        testError (conn, VIR_ERR_MULTIPLE_INTERFACES, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetInterface(conn, iface->def->name, iface->def->mac);
+
+cleanup:
+    if (iface)
+        virInterfaceObjUnlock(iface);
+    return ret;
+}
+
+static char *testInterfaceGetXMLDesc(virInterfacePtr iface,
+                                     unsigned int flags ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = iface->conn->privateData;
+    virInterfaceObjPtr privinterface;
+    char *ret = NULL;
+
+    testDriverLock(privconn);
+    privinterface = virInterfaceFindByName(&privconn->ifaces,
+                                           iface->name);
+    testDriverUnlock(privconn);
+
+    if (privinterface == NULL) {
+        testError(iface->conn, VIR_ERR_NO_INTERFACE, __FUNCTION__);
+        goto cleanup;
+    }
+
+    ret = virInterfaceDefFormat(iface->conn, privinterface->def);
+
+cleanup:
+    if (privinterface)
+        virInterfaceObjUnlock(privinterface);
+    return ret;
+}
+
+
+static virInterfacePtr testInterfaceDefineXML(virConnectPtr conn, const char *xmlStr,
+                                              unsigned int flags ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = conn->privateData;
+    virInterfaceDefPtr def;
+    virInterfaceObjPtr iface = NULL;
+    virInterfacePtr ret = NULL;
+
+    testDriverLock(privconn);
+    if ((def = virInterfaceDefParseString(conn, xmlStr)) == NULL)
+        goto cleanup;
+
+    if ((iface = virInterfaceAssignDef(conn, &privconn->ifaces, def)) == NULL)
+        goto cleanup;
+    def = NULL;
+
+    ret = virGetInterface(conn, iface->def->name, iface->def->mac);
+
+cleanup:
+    virInterfaceDefFree(def);
+    if (iface)
+        virInterfaceObjUnlock(iface);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testInterfaceUndefine(virInterfacePtr iface)
+{
+    testConnPtr privconn = iface->conn->privateData;
+    virInterfaceObjPtr privinterface;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privinterface = virInterfaceFindByName(&privconn->ifaces,
+                                           iface->name);
+
+    if (privinterface == NULL) {
+        testError (iface->conn, VIR_ERR_NO_INTERFACE, NULL);
+        goto cleanup;
+    }
+
+    virInterfaceRemove(&privconn->ifaces,
+                       privinterface);
+    ret = 0;
+
+cleanup:
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testInterfaceCreate(virInterfacePtr iface,
+                               unsigned int flags ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = iface->conn->privateData;
+    virInterfaceObjPtr privinterface;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privinterface = virInterfaceFindByName(&privconn->ifaces,
+                                           iface->name);
+
+    if (privinterface == NULL) {
+        testError (iface->conn, VIR_ERR_NO_INTERFACE, NULL);
+        goto cleanup;
+    }
+
+    if (privinterface->active != 0) {
+        testError (iface->conn, VIR_ERR_OPERATION_INVALID, NULL);
+        goto cleanup;
+    }
+
+    privinterface->active = 1;
+    ret = 0;
+
+cleanup:
+    if (privinterface)
+        virInterfaceObjUnlock(privinterface);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int testInterfaceDestroy(virInterfacePtr iface,
+                                unsigned int flags ATTRIBUTE_UNUSED)
+{
+    testConnPtr privconn = iface->conn->privateData;
+    virInterfaceObjPtr privinterface;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privinterface = virInterfaceFindByName(&privconn->ifaces,
+                                           iface->name);
+
+    if (privinterface == NULL) {
+        testError (iface->conn, VIR_ERR_NO_INTERFACE, NULL);
+        goto cleanup;
+    }
+
+    if (privinterface->active == 0) {
+        testError (iface->conn, VIR_ERR_OPERATION_INVALID, NULL);
+        goto cleanup;
+    }
+
+    privinterface->active = 0;
+    ret = 0;
+
+cleanup:
+    if (privinterface)
+        virInterfaceObjUnlock(privinterface);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+
+
+/*
+ * Storage Driver routines
+ */
+
+static int testStoragePoolObjSetDefaults(virConnectPtr conn,
+                                         virStoragePoolObjPtr pool) {
+
+    pool->def->capacity = defaultPoolCap;
+    pool->def->allocation = defaultPoolAlloc;
+    pool->def->available = defaultPoolCap - defaultPoolAlloc;
+
+    pool->configFile = strdup("\0");
+    if (!pool->configFile) {
+        virReportOOMError(conn);
+        return -1;
+    }
+
+    return 0;
+}
+
+static virDrvOpenStatus testStorageOpen(virConnectPtr conn,
+                                        virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                        int flags ATTRIBUTE_UNUSED) {
+    if (STRNEQ(conn->driver->name, "Test"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    conn->storagePrivateData = conn->privateData;
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int testStorageClose(virConnectPtr conn) {
+    conn->storagePrivateData = NULL;
+    return 0;
+}
+
+static virStoragePoolPtr
+testStoragePoolLookupByUUID(virConnectPtr conn,
+                            const unsigned char *uuid) {
+    testConnPtr privconn = conn->privateData;
+    virStoragePoolObjPtr pool;
+    virStoragePoolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    pool = virStoragePoolObjFindByUUID(&privconn->pools, uuid);
+    testDriverUnlock(privconn);
+
+    if (pool == NULL) {
+        testError (conn, VIR_ERR_NO_STORAGE_POOL, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
+
+cleanup:
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    return ret;
+}
+
+static virStoragePoolPtr
+testStoragePoolLookupByName(virConnectPtr conn,
+                            const char *name) {
+    testConnPtr privconn = conn->privateData;
+    virStoragePoolObjPtr pool;
+    virStoragePoolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    pool = virStoragePoolObjFindByName(&privconn->pools, name);
+    testDriverUnlock(privconn);
+
+    if (pool == NULL) {
+        testError (conn, VIR_ERR_NO_STORAGE_POOL, NULL);
+        goto cleanup;
+    }
+
+    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
+
+cleanup:
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    return ret;
+}
+
+static virStoragePoolPtr
+testStoragePoolLookupByVolume(virStorageVolPtr vol) {
+    return testStoragePoolLookupByName(vol->conn, vol->pool);
+}
+
+static int
+testStorageNumPools(virConnectPtr conn) {
+    testConnPtr privconn = conn->privateData;
+    int numActive = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->pools.count ; i++)
+        if (virStoragePoolObjIsActive(privconn->pools.objs[i]))
+            numActive++;
+    testDriverUnlock(privconn);
+
+    return numActive;
+}
+
+static int
+testStorageListPools(virConnectPtr conn,
+                     char **const names,
+                     int nnames) {
+    testConnPtr privconn = conn->privateData;
+    int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*nnames);
+    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
+        virStoragePoolObjLock(privconn->pools.objs[i]);
+        if (virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
+            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
+            virStoragePoolObjUnlock(privconn->pools.objs[i]);
+            goto no_memory;
+        }
+        virStoragePoolObjUnlock(privconn->pools.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < nnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+static int
+testStorageNumDefinedPools(virConnectPtr conn) {
+    testConnPtr privconn = conn->privateData;
+    int numInactive = 0, i;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->pools.count ; i++) {
+        virStoragePoolObjLock(privconn->pools.objs[i]);
+        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]))
+            numInactive++;
+        virStoragePoolObjUnlock(privconn->pools.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return numInactive;
+}
+
+static int
+testStorageListDefinedPools(virConnectPtr conn,
+                            char **const names,
+                            int nnames) {
+    testConnPtr privconn = conn->privateData;
+    int n = 0, i;
+
+    testDriverLock(privconn);
+    memset(names, 0, sizeof(*names)*nnames);
+    for (i = 0 ; i < privconn->pools.count && n < nnames ; i++) {
+        virStoragePoolObjLock(privconn->pools.objs[i]);
+        if (!virStoragePoolObjIsActive(privconn->pools.objs[i]) &&
+            !(names[n++] = strdup(privconn->pools.objs[i]->def->name))) {
+            virStoragePoolObjUnlock(privconn->pools.objs[i]);
+            goto no_memory;
+        }
+        virStoragePoolObjUnlock(privconn->pools.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    return n;
+
+no_memory:
+    virReportOOMError(conn);
+    for (n = 0 ; n < nnames ; n++)
+        VIR_FREE(names[n]);
+    testDriverUnlock(privconn);
+    return -1;
+}
+
+
+static int
+testStoragePoolStart(virStoragePoolPtr pool,
+                     unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is already active"), pool->name);
+        goto cleanup;
+    }
+
+    privpool->active = 1;
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static char *
+testStorageFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
+                           const char *type ATTRIBUTE_UNUSED,
+                           const char *srcSpec ATTRIBUTE_UNUSED,
+                           unsigned int flags ATTRIBUTE_UNUSED)
+{
+    return NULL;
+}
+
+
+static virStoragePoolPtr
+testStoragePoolCreate(virConnectPtr conn,
+                      const char *xml,
+                      unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = conn->privateData;
+    virStoragePoolDefPtr def;
+    virStoragePoolObjPtr pool = NULL;
+    virStoragePoolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    if (!(def = virStoragePoolDefParseString(conn, xml)))
+        goto cleanup;
+
+    pool = virStoragePoolObjFindByUUID(&privconn->pools, def->uuid);
+    if (!pool)
+        pool = virStoragePoolObjFindByName(&privconn->pools, def->name);
+    if (pool) {
+        testError(conn, VIR_ERR_INTERNAL_ERROR,
+                  "%s", _("storage pool already exists"));
+        goto cleanup;
+    }
+
+    if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools, def)))
+        goto cleanup;
+    def = NULL;
+
+    if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
+        virStoragePoolObjRemove(&privconn->pools, pool);
+        pool = NULL;
+        goto cleanup;
+    }
+    pool->active = 1;
+
+    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
+
+cleanup:
+    virStoragePoolDefFree(def);
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static virStoragePoolPtr
+testStoragePoolDefine(virConnectPtr conn,
+                      const char *xml,
+                      unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = conn->privateData;
+    virStoragePoolDefPtr def;
+    virStoragePoolObjPtr pool = NULL;
+    virStoragePoolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    if (!(def = virStoragePoolDefParseString(conn, xml)))
+        goto cleanup;
+
+    def->capacity = defaultPoolCap;
+    def->allocation = defaultPoolAlloc;
+    def->available = defaultPoolCap - defaultPoolAlloc;
+
+    if (!(pool = virStoragePoolObjAssignDef(conn, &privconn->pools, def)))
+        goto cleanup;
+    def = NULL;
+
+    if (testStoragePoolObjSetDefaults(conn, pool) == -1) {
+        virStoragePoolObjRemove(&privconn->pools, pool);
+        pool = NULL;
+        goto cleanup;
+    }
+
+    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid);
+
+cleanup:
+    virStoragePoolDefFree(def);
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int
+testStoragePoolUndefine(virStoragePoolPtr pool) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is already active"), pool->name);
+        goto cleanup;
+    }
+
+    virStoragePoolObjRemove(&privconn->pools, privpool);
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+static int
+testStoragePoolBuild(virStoragePoolPtr pool,
+                     unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is already active"), pool->name);
+        goto cleanup;
+    }
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static int
+testStoragePoolDestroy(virStoragePoolPtr pool) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+
+    privpool->active = 0;
+
+    if (privpool->configFile == NULL) {
+        virStoragePoolObjRemove(&privconn->pools, privpool);
+        privpool = NULL;
+    }
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    testDriverUnlock(privconn);
+    return ret;
+}
+
+
+static int
+testStoragePoolDelete(virStoragePoolPtr pool,
+                      unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is already active"), pool->name);
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static int
+testStoragePoolRefresh(virStoragePoolPtr pool,
+                       unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static int
+testStoragePoolGetInfo(virStoragePoolPtr pool,
+                       virStoragePoolInfoPtr info) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    memset(info, 0, sizeof(virStoragePoolInfo));
+    if (privpool->active)
+        info->state = VIR_STORAGE_POOL_RUNNING;
+    else
+        info->state = VIR_STORAGE_POOL_INACTIVE;
+    info->capacity = privpool->def->capacity;
+    info->allocation = privpool->def->allocation;
+    info->available = privpool->def->available;
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static char *
+testStoragePoolDumpXML(virStoragePoolPtr pool,
+                       unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    char *ret = NULL;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    ret = virStoragePoolDefFormat(pool->conn, privpool->def);
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static int
+testStoragePoolGetAutostart(virStoragePoolPtr pool,
+                            int *autostart) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!privpool->configFile) {
+        *autostart = 0;
+    } else {
+        *autostart = privpool->autostart;
+    }
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static int
+testStoragePoolSetAutostart(virStoragePoolPtr pool,
+                            int autostart) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!privpool->configFile) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG,
+                  "%s", _("pool has no config file"));
+        goto cleanup;
+    }
+
+    autostart = (autostart != 0);
+    privpool->autostart = autostart;
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static int
+testStoragePoolNumVolumes(virStoragePoolPtr pool) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+
+    ret = privpool->volumes.count;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static int
+testStoragePoolListVolumes(virStoragePoolPtr pool,
+                           char **const names,
+                           int maxnames) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    int i = 0, n = 0;
+
+    memset(names, 0, maxnames * sizeof(*names));
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+
+    for (i = 0 ; i < privpool->volumes.count && n < maxnames ; i++) {
+        if ((names[n++] = strdup(privpool->volumes.objs[i]->name)) == NULL) {
+            virReportOOMError(pool->conn);
+            goto cleanup;
+        }
+    }
+
+    virStoragePoolObjUnlock(privpool);
+    return n;
+
+ cleanup:
+    for (n = 0 ; n < maxnames ; n++)
+        VIR_FREE(names[i]);
+
+    memset(names, 0, maxnames * sizeof(*names));
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return -1;
+}
+
+
+static virStorageVolPtr
+testStorageVolumeLookupByName(virStoragePoolPtr pool,
+                              const char *name ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol;
+    virStorageVolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+
+    privvol = virStorageVolDefFindByName(privpool, name);
+
+    if (!privvol) {
+        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching name '%s'"), name);
+        goto cleanup;
+    }
+
+    ret = virGetStorageVol(pool->conn, privpool->def->name,
+                           privvol->name, privvol->key);
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static virStorageVolPtr
+testStorageVolumeLookupByKey(virConnectPtr conn,
+                             const char *key) {
+    testConnPtr privconn = conn->privateData;
+    unsigned int i;
+    virStorageVolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->pools.count ; i++) {
+        virStoragePoolObjLock(privconn->pools.objs[i]);
+        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
+            virStorageVolDefPtr privvol =
+                virStorageVolDefFindByKey(privconn->pools.objs[i], key);
+
+            if (privvol) {
+                ret = virGetStorageVol(conn,
+                                       privconn->pools.objs[i]->def->name,
+                                       privvol->name,
+                                       privvol->key);
+                virStoragePoolObjUnlock(privconn->pools.objs[i]);
+                break;
+            }
+        }
+        virStoragePoolObjUnlock(privconn->pools.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    if (!ret)
+        testError(conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching key '%s'"), key);
+
+    return ret;
+}
+
+static virStorageVolPtr
+testStorageVolumeLookupByPath(virConnectPtr conn,
+                              const char *path) {
+    testConnPtr privconn = conn->privateData;
+    unsigned int i;
+    virStorageVolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    for (i = 0 ; i < privconn->pools.count ; i++) {
+        virStoragePoolObjLock(privconn->pools.objs[i]);
+        if (virStoragePoolObjIsActive(privconn->pools.objs[i])) {
+            virStorageVolDefPtr privvol =
+                virStorageVolDefFindByPath(privconn->pools.objs[i], path);
+
+            if (privvol) {
+                ret = virGetStorageVol(conn,
+                                       privconn->pools.objs[i]->def->name,
+                                       privvol->name,
+                                       privvol->key);
+                virStoragePoolObjUnlock(privconn->pools.objs[i]);
+                break;
+            }
+        }
+        virStoragePoolObjUnlock(privconn->pools.objs[i]);
+    }
+    testDriverUnlock(privconn);
+
+    if (!ret)
+        testError(conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching path '%s'"), path);
+
+    return ret;
+}
+
+static virStorageVolPtr
+testStorageVolumeCreateXML(virStoragePoolPtr pool,
+                           const char *xmldesc,
+                           unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol = NULL;
+    virStorageVolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+
+    privvol = virStorageVolDefParseString(pool->conn, privpool->def, xmldesc);
+    if (privvol == NULL)
+        goto cleanup;
+
+    if (virStorageVolDefFindByName(privpool, privvol->name)) {
+        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  "%s", _("storage vol already exists"));
+        goto cleanup;
+    }
+
+    /* Make sure enough space */
+    if ((privpool->def->allocation + privvol->allocation) >
+         privpool->def->capacity) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("Not enough free space in pool for volume '%s'"),
+                  privvol->name);
+        goto cleanup;
+    }
+
+    if (VIR_REALLOC_N(privpool->volumes.objs,
+                      privpool->volumes.count+1) < 0) {
+        virReportOOMError(pool->conn);
+        goto cleanup;
+    }
+
+    if (virAsprintf(&privvol->target.path, "%s/%s",
+                    privpool->def->target.path,
+                    privvol->name) == -1) {
+        virReportOOMError(pool->conn);
+        goto cleanup;
+    }
+
+    privvol->key = strdup(privvol->target.path);
+    if (privvol->key == NULL) {
+        virReportOOMError(pool->conn);
+        goto cleanup;
+    }
+
+    privpool->def->allocation += privvol->allocation;
+    privpool->def->available = (privpool->def->capacity -
+                                privpool->def->allocation);
+
+    privpool->volumes.objs[privpool->volumes.count++] = privvol;
+
+    ret = virGetStorageVol(pool->conn, privpool->def->name,
+                           privvol->name, privvol->key);
+    privvol = NULL;
+
+cleanup:
+    virStorageVolDefFree(privvol);
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static virStorageVolPtr
+testStorageVolumeCreateXMLFrom(virStoragePoolPtr pool,
+                               const char *xmldesc,
+                               virStorageVolPtr clonevol,
+                               unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = pool->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol = NULL, origvol = NULL;
+    virStorageVolPtr ret = NULL;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           pool->name);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(pool->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), pool->name);
+        goto cleanup;
+    }
+
+    privvol = virStorageVolDefParseString(pool->conn, privpool->def, xmldesc);
+    if (privvol == NULL)
+        goto cleanup;
+
+    if (virStorageVolDefFindByName(privpool, privvol->name)) {
+        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  "%s", _("storage vol already exists"));
+        goto cleanup;
+    }
+
+    origvol = virStorageVolDefFindByName(privpool, clonevol->name);
+    if (!origvol) {
+        testError(pool->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching name '%s'"),
+                  clonevol->name);
+        goto cleanup;
+    }
+
+    /* Make sure enough space */
+    if ((privpool->def->allocation + privvol->allocation) >
+         privpool->def->capacity) {
+        testError(pool->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("Not enough free space in pool for volume '%s'"),
+                  privvol->name);
+        goto cleanup;
+    }
+    privpool->def->available = (privpool->def->capacity -
+                                privpool->def->allocation);
+
+    if (VIR_REALLOC_N(privpool->volumes.objs,
+                      privpool->volumes.count+1) < 0) {
+        virReportOOMError(pool->conn);
+        goto cleanup;
+    }
+
+    if (virAsprintf(&privvol->target.path, "%s/%s",
+                    privpool->def->target.path,
+                    privvol->name) == -1) {
+        virReportOOMError(pool->conn);
+        goto cleanup;
+    }
+
+    privvol->key = strdup(privvol->target.path);
+    if (privvol->key == NULL) {
+        virReportOOMError(pool->conn);
+        goto cleanup;
+    }
+
+    privpool->def->allocation += privvol->allocation;
+    privpool->def->available = (privpool->def->capacity -
+                                privpool->def->allocation);
+
+    privpool->volumes.objs[privpool->volumes.count++] = privvol;
+
+    ret = virGetStorageVol(pool->conn, privpool->def->name,
+                           privvol->name, privvol->key);
+    privvol = NULL;
+
+cleanup:
+    virStorageVolDefFree(privvol);
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static int
+testStorageVolumeDelete(virStorageVolPtr vol,
+                        unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = vol->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol;
+    int i;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           vol->pool);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+
+    privvol = virStorageVolDefFindByName(privpool, vol->name);
+
+    if (privvol == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching name '%s'"),
+                  vol->name);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), vol->pool);
+        goto cleanup;
+    }
+
+
+    privpool->def->allocation -= privvol->allocation;
+    privpool->def->available = (privpool->def->capacity -
+                                privpool->def->allocation);
+
+    for (i = 0 ; i < privpool->volumes.count ; i++) {
+        if (privpool->volumes.objs[i] == privvol) {
+            virStorageVolDefFree(privvol);
+
+            if (i < (privpool->volumes.count - 1))
+                memmove(privpool->volumes.objs + i,
+                        privpool->volumes.objs + i + 1,
+                        sizeof(*(privpool->volumes.objs)) *
+                                (privpool->volumes.count - (i + 1)));
+
+            if (VIR_REALLOC_N(privpool->volumes.objs,
+                              privpool->volumes.count - 1) < 0) {
+                ; /* Failure to reduce memory allocation isn't fatal */
+            }
+            privpool->volumes.count--;
+
+            break;
+        }
+    }
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static int testStorageVolumeTypeForPool(int pooltype) {
+
+    switch(pooltype) {
+        case VIR_STORAGE_POOL_DIR:
+        case VIR_STORAGE_POOL_FS:
+        case VIR_STORAGE_POOL_NETFS:
+            return VIR_STORAGE_VOL_FILE;
+        default:
+            return VIR_STORAGE_VOL_BLOCK;
+    }
+}
+
+static int
+testStorageVolumeGetInfo(virStorageVolPtr vol,
+                         virStorageVolInfoPtr info) {
+    testConnPtr privconn = vol->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol;
+    int ret = -1;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           vol->pool);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privvol = virStorageVolDefFindByName(privpool, vol->name);
+
+    if (privvol == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching name '%s'"),
+                  vol->name);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), vol->pool);
+        goto cleanup;
+    }
+
+    memset(info, 0, sizeof(*info));
+    info->type = testStorageVolumeTypeForPool(privpool->def->type);
+    info->capacity = privvol->capacity;
+    info->allocation = privvol->allocation;
+    ret = 0;
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static char *
+testStorageVolumeGetXMLDesc(virStorageVolPtr vol,
+                            unsigned int flags ATTRIBUTE_UNUSED) {
+    testConnPtr privconn = vol->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol;
+    char *ret = NULL;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           vol->pool);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privvol = virStorageVolDefFindByName(privpool, vol->name);
+
+    if (privvol == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching name '%s'"),
+                  vol->name);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), vol->pool);
+        goto cleanup;
+    }
+
+    ret = virStorageVolDefFormat(vol->conn, privpool->def, privvol);
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+static char *
+testStorageVolumeGetPath(virStorageVolPtr vol) {
+    testConnPtr privconn = vol->conn->privateData;
+    virStoragePoolObjPtr privpool;
+    virStorageVolDefPtr privvol;
+    char *ret = NULL;
+
+    testDriverLock(privconn);
+    privpool = virStoragePoolObjFindByName(&privconn->pools,
+                                           vol->pool);
+    testDriverUnlock(privconn);
+
+    if (privpool == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto cleanup;
+    }
+
+    privvol = virStorageVolDefFindByName(privpool, vol->name);
+
+    if (privvol == NULL) {
+        testError(vol->conn, VIR_ERR_INVALID_STORAGE_VOL,
+                  _("no storage vol with matching name '%s'"),
+                  vol->name);
+        goto cleanup;
+    }
+
+    if (!virStoragePoolObjIsActive(privpool)) {
+        testError(vol->conn, VIR_ERR_INTERNAL_ERROR,
+                  _("storage pool '%s' is not active"), vol->pool);
+        goto cleanup;
+    }
+
+    ret = strdup(privvol->target.path);
+    if (ret == NULL)
+        virReportOOMError(vol->conn);
+
+cleanup:
+    if (privpool)
+        virStoragePoolObjUnlock(privpool);
+    return ret;
+}
+
+
+static virDrvOpenStatus testDevMonOpen(virConnectPtr conn,
+                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                       int flags ATTRIBUTE_UNUSED) {
+    if (STRNEQ(conn->driver->name, "Test"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    conn->devMonPrivateData = conn->privateData;
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int testDevMonClose(virConnectPtr conn) {
+    conn->devMonPrivateData = NULL;
+    return 0;
+}
+
+
+static int
+testDomainEventRegister (virConnectPtr conn,
+                         virConnectDomainEventCallback callback,
+                         void *opaque,
+                         virFreeCallback freecb)
+{
+    testConnPtr driver = conn->privateData;
+    int ret;
+
+    testDriverLock(driver);
+    ret = virDomainEventCallbackListAdd(conn, driver->domainEventCallbacks,
+                                        callback, opaque, freecb);
+    testDriverUnlock(driver);
+
+    return ret;
+}
+
+static int
+testDomainEventDeregister (virConnectPtr conn,
+                           virConnectDomainEventCallback callback)
+{
+    testConnPtr driver = conn->privateData;
+    int ret;
+
+    testDriverLock(driver);
+    if (driver->domainEventDispatching)
+        ret = virDomainEventCallbackListMarkDelete(conn, driver->domainEventCallbacks,
+                                                   callback);
+    else
+        ret = virDomainEventCallbackListRemove(conn, driver->domainEventCallbacks,
+                                               callback);
+    testDriverUnlock(driver);
+
+    return ret;
+}
+
+static void testDomainEventDispatchFunc(virConnectPtr conn,
+                                        virDomainEventPtr event,
+                                        virConnectDomainEventCallback cb,
+                                        void *cbopaque,
+                                        void *opaque)
+{
+    testConnPtr driver = opaque;
+
+    /* Drop the lock whle dispatching, for sake of re-entrancy */
+    testDriverUnlock(driver);
+    virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
+    testDriverLock(driver);
+}
+
+static void testDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
+{
+    testConnPtr driver = opaque;
+    virDomainEventQueue tempQueue;
+
+    testDriverLock(driver);
+
+    driver->domainEventDispatching = 1;
+
+    /* Copy the queue, so we're reentrant safe */
+    tempQueue.count = driver->domainEventQueue->count;
+    tempQueue.events = driver->domainEventQueue->events;
+    driver->domainEventQueue->count = 0;
+    driver->domainEventQueue->events = NULL;
+
+    virEventUpdateTimeout(driver->domainEventTimer, -1);
+    virDomainEventQueueDispatch(&tempQueue,
+                                driver->domainEventCallbacks,
+                                testDomainEventDispatchFunc,
+                                driver);
+
+    /* Purge any deleted callbacks */
+    virDomainEventCallbackListPurgeMarked(driver->domainEventCallbacks);
+
+    driver->domainEventDispatching = 0;
+    testDriverUnlock(driver);
+}
+
+
+/* driver must be locked before calling */
+static void testDomainEventQueue(testConnPtr driver,
+                                 virDomainEventPtr event)
+{
+    if (driver->domainEventTimer < 0) {
+        virDomainEventFree(event);
+        return;
+    }
+
+    if (virDomainEventQueuePush(driver->domainEventQueue,
+                                event) < 0)
+        virDomainEventFree(event);
+
+    if (driver->domainEventQueue->count == 1)
+        virEventUpdateTimeout(driver->domainEventTimer, 0);
+}
+
+static virDrvOpenStatus testSecretOpen(virConnectPtr conn,
+                                       virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                       int flags ATTRIBUTE_UNUSED) {
+    if (STRNEQ(conn->driver->name, "Test"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    conn->secretPrivateData = conn->privateData;
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int testSecretClose(virConnectPtr conn) {
+    conn->secretPrivateData = NULL;
+    return 0;
+}
+
+static virDriver testDriver = {
+    VIR_DRV_TEST,
+    "Test",
+    testOpen, /* open */
+    testClose, /* close */
+    NULL, /* supports_feature */
+    NULL, /* type */
+    testGetVersion, /* version */
+    testGetHostname, /* getHostname */
+    testGetMaxVCPUs, /* getMaxVcpus */
+    testNodeGetInfo, /* nodeGetInfo */
+    testGetCapabilities, /* getCapabilities */
+    testListDomains, /* listDomains */
+    testNumOfDomains, /* numOfDomains */
+    testDomainCreateXML, /* domainCreateXML */
+    testLookupDomainByID, /* domainLookupByID */
+    testLookupDomainByUUID, /* domainLookupByUUID */
+    testLookupDomainByName, /* domainLookupByName */
+    testPauseDomain, /* domainSuspend */
+    testResumeDomain, /* domainResume */
+    testShutdownDomain, /* domainShutdown */
+    testRebootDomain, /* domainReboot */
+    testDestroyDomain, /* domainDestroy */
+    testGetOSType, /* domainGetOSType */
+    testGetMaxMemory, /* domainGetMaxMemory */
+    testSetMaxMemory, /* domainSetMaxMemory */
+    testSetMemory, /* domainSetMemory */
+    testGetDomainInfo, /* domainGetInfo */
+    testDomainSave, /* domainSave */
+    testDomainRestore, /* domainRestore */
+    testDomainCoreDump, /* domainCoreDump */
+    testSetVcpus, /* domainSetVcpus */
+    NULL, /* domainPinVcpu */
+    NULL, /* domainGetVcpus */
+    NULL, /* domainGetMaxVcpus */
+    NULL, /* domainGetSecurityLabel */
+    NULL, /* nodeGetSecurityModel */
+    testDomainDumpXML, /* domainDumpXML */
+    NULL, /* domainXmlFromNative */
+    NULL, /* domainXmlToNative */
+    testListDefinedDomains, /* listDefinedDomains */
+    testNumOfDefinedDomains, /* numOfDefinedDomains */
+    testDomainCreate, /* domainCreate */
+    testDomainDefineXML, /* domainDefineXML */
+    testDomainUndefine, /* domainUndefine */
+    NULL, /* domainAttachDevice */
+    NULL, /* domainDetachDevice */
+    testDomainGetAutostart, /* domainGetAutostart */
+    testDomainSetAutostart, /* domainSetAutostart */
+    testDomainGetSchedulerType, /* domainGetSchedulerType */
+    testDomainGetSchedulerParams, /* domainGetSchedulerParameters */
+    testDomainSetSchedulerParams, /* domainSetSchedulerParameters */
+    NULL, /* domainMigratePrepare */
+    NULL, /* domainMigratePerform */
+    NULL, /* domainMigrateFinish */
+    testDomainBlockStats, /* domainBlockStats */
+    testDomainInterfaceStats, /* domainInterfaceStats */
+    NULL, /* domainBlockPeek */
+    NULL, /* domainMemoryPeek */
+    testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
+    NULL, /* getFreeMemory */
+    testDomainEventRegister, /* domainEventRegister */
+    testDomainEventDeregister, /* domainEventDeregister */
+    NULL, /* domainMigratePrepare2 */
+    NULL, /* domainMigrateFinish2 */
+    NULL, /* nodeDeviceDettach */
+    NULL, /* nodeDeviceReAttach */
+    NULL, /* nodeDeviceReset */
+};
+
+static virNetworkDriver testNetworkDriver = {
+    "Test",
+    testOpenNetwork, /* open */
+    testCloseNetwork, /* close */
+    testNumNetworks, /* numOfNetworks */
+    testListNetworks, /* listNetworks */
+    testNumDefinedNetworks, /* numOfDefinedNetworks */
+    testListDefinedNetworks, /* listDefinedNetworks */
+    testLookupNetworkByUUID, /* networkLookupByUUID */
+    testLookupNetworkByName, /* networkLookupByName */
+    testNetworkCreate, /* networkCreateXML */
+    testNetworkDefine, /* networkDefineXML */
+    testNetworkUndefine, /* networkUndefine */
+    testNetworkStart, /* networkCreate */
+    testNetworkDestroy, /* networkDestroy */
+    testNetworkDumpXML, /* networkDumpXML */
+    testNetworkGetBridgeName, /* networkGetBridgeName */
+    testNetworkGetAutostart, /* networkGetAutostart */
+    testNetworkSetAutostart, /* networkSetAutostart */
+};
+
+static virInterfaceDriver testInterfaceDriver = {
+    "Test",                     /* name */
+    testOpenInterface,          /* open */
+    testCloseInterface,         /* close */
+    testNumOfInterfaces,        /* numOfInterfaces */
+    testListInterfaces,         /* listInterfaces */
+    testNumOfDefinedInterfaces, /* numOfDefinedInterfaces */
+    testListDefinedInterfaces,  /* listDefinedInterfaces */
+    testLookupInterfaceByName,  /* interfaceLookupByName */
+    testLookupInterfaceByMACString, /* interfaceLookupByMACString */
+    testInterfaceGetXMLDesc,    /* interfaceGetXMLDesc */
+    testInterfaceDefineXML,     /* interfaceDefineXML */
+    testInterfaceUndefine,      /* interfaceUndefine */
+    testInterfaceCreate,        /* interfaceCreate */
+    testInterfaceDestroy,       /* interfaceDestroy */
+};
+
+
+static virStorageDriver testStorageDriver = {
+    .name = "Test",
+    .open = testStorageOpen,
+    .close = testStorageClose,
+
+    .numOfPools = testStorageNumPools,
+    .listPools = testStorageListPools,
+    .numOfDefinedPools = testStorageNumDefinedPools,
+    .listDefinedPools = testStorageListDefinedPools,
+    .findPoolSources = testStorageFindPoolSources,
+    .poolLookupByName = testStoragePoolLookupByName,
+    .poolLookupByUUID = testStoragePoolLookupByUUID,
+    .poolLookupByVolume = testStoragePoolLookupByVolume,
+    .poolCreateXML = testStoragePoolCreate,
+    .poolDefineXML = testStoragePoolDefine,
+    .poolBuild = testStoragePoolBuild,
+    .poolUndefine = testStoragePoolUndefine,
+    .poolCreate = testStoragePoolStart,
+    .poolDestroy = testStoragePoolDestroy,
+    .poolDelete = testStoragePoolDelete,
+    .poolRefresh = testStoragePoolRefresh,
+    .poolGetInfo = testStoragePoolGetInfo,
+    .poolGetXMLDesc = testStoragePoolDumpXML,
+    .poolGetAutostart = testStoragePoolGetAutostart,
+    .poolSetAutostart = testStoragePoolSetAutostart,
+    .poolNumOfVolumes = testStoragePoolNumVolumes,
+    .poolListVolumes = testStoragePoolListVolumes,
+
+    .volLookupByName = testStorageVolumeLookupByName,
+    .volLookupByKey = testStorageVolumeLookupByKey,
+    .volLookupByPath = testStorageVolumeLookupByPath,
+    .volCreateXML = testStorageVolumeCreateXML,
+    .volCreateXMLFrom = testStorageVolumeCreateXMLFrom,
+    .volDelete = testStorageVolumeDelete,
+    .volGetInfo = testStorageVolumeGetInfo,
+    .volGetXMLDesc = testStorageVolumeGetXMLDesc,
+    .volGetPath = testStorageVolumeGetPath,
+};
+
+static virDeviceMonitor testDevMonitor = {
+    .name = "Test",
+    .open = testDevMonOpen,
+    .close = testDevMonClose,
+};
+
+static virSecretDriver testSecretDriver = {
+    .name = "Test",
+    .open = testSecretOpen,
+    .close = testSecretClose,
+};
+
+
+/**
+ * testRegister:
+ *
+ * Registers the test driver
+ */
+int
+testRegister(void)
+{
+    if (virRegisterDriver(&testDriver) < 0)
+        return -1;
+    if (virRegisterNetworkDriver(&testNetworkDriver) < 0)
+        return -1;
+    if (virRegisterInterfaceDriver(&testInterfaceDriver) < 0)
+        return -1;
+    if (virRegisterStorageDriver(&testStorageDriver) < 0)
+        return -1;
+    if (virRegisterDeviceMonitor(&testDevMonitor) < 0)
+        return -1;
+    if (virRegisterSecretDriver(&testSecretDriver) < 0)
+        return -1;
+
+    return 0;
+}
diff --git a/src/test/test_driver.h b/src/test/test_driver.h
new file mode 100644 (file)
index 0000000..c6bdbd0
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * test.h: A "mock" hypervisor for use by application unit tests
+ *
+ * Copyright (C) 2006-2006 Red Hat, Inc.
+ * Copyright (C) 2006  Daniel P. Berrange
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Daniel Berrange <berrange@redhat.com>
+ */
+
+#ifndef __VIR_TEST_INTERNAL_H__
+#define __VIR_TEST_INTERNAL_H__
+
+#include "internal.h"
+
+int testRegister(void);
+
+#endif /* __VIR_TEST_INTERNAL_H__ */