? src/test.core ? src/test.save Index: docs/testnetdef.xml =================================================================== RCS file: docs/testnetdef.xml diff -N docs/testnetdef.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ docs/testnetdef.xml 25 Jul 2007 14:47:32 -0000 @@ -0,0 +1,12 @@ + + default + 004b96e12d78c30f5aa5f03c87d21e69 + + + + + + + + + Index: docs/testnetpriv.xml =================================================================== RCS file: docs/testnetpriv.xml diff -N docs/testnetpriv.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ docs/testnetpriv.xml 25 Jul 2007 14:47:32 -0000 @@ -0,0 +1,11 @@ + + private + 004b22212d78c30f5aa5f03c87d21e69 + + + + + + + + Index: docs/testnode.xml =================================================================== RCS file: /data/cvs/libvirt/docs/testnode.xml,v retrieving revision 1.3 diff -u -p -r1.3 testnode.xml --- docs/testnode.xml 18 Jan 2007 21:13:15 -0000 1.3 +++ docs/testnode.xml 25 Jul 2007 14:47:32 -0000 @@ -9,6 +9,8 @@ --> + + 6000 Index: src/driver.h =================================================================== RCS file: /data/cvs/libvirt/src/driver.h,v retrieving revision 1.31 diff -u -p -r1.31 driver.h --- src/driver.h 17 Jul 2007 13:27:26 -0000 1.31 +++ src/driver.h 25 Jul 2007 14:47:33 -0000 @@ -304,6 +304,7 @@ typedef virNetworkDriver *virNetworkDriv * - close */ struct _virNetworkDriver { + const char * name; /* the name of the driver */ virDrvOpen open; virDrvClose close; virDrvNumOfNetworks numOfNetworks; Index: src/libvirt.c =================================================================== RCS file: /data/cvs/libvirt/src/libvirt.c,v retrieving revision 1.91 diff -u -p -r1.91 libvirt.c --- src/libvirt.c 24 Jul 2007 15:32:56 -0000 1.91 +++ src/libvirt.c 25 Jul 2007 14:47:33 -0000 @@ -423,8 +423,8 @@ do_open (const char *name, int flags) #endif res = virDriverTab[i]->open (ret, name, flags); #ifdef ENABLE_DEBUG - fprintf (stderr, "libvirt: do_open: driver %d returned %s\n", - i, + fprintf (stderr, "libvirt: do_open: driver %d %s returned %s\n", + i, virDriverTab[i]->name, res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" : (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" : (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status"))); @@ -444,9 +444,18 @@ do_open (const char *name, int flags) for (i = 0; i < virNetworkDriverTabCount; i++) { res = virNetworkDriverTab[i]->open (ret, name, flags); +#ifdef ENABLE_DEBUG + fprintf (stderr, "libvirt: do_open: network driver %d %s returned %s\n", + i, virNetworkDriverTab[i]->name, + res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" : + (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" : + (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status"))); +#endif if (res == VIR_DRV_OPEN_ERROR) { - virLibConnWarning (NULL, VIR_WAR_NO_NETWORK, - "Is the daemon running ?"); + if (STREQ(virNetworkDriverTab[i]->name, "remote")) { + virLibConnWarning (NULL, VIR_WAR_NO_NETWORK, + "Is the daemon running ?"); + } break; } else if (res == VIR_DRV_OPEN_SUCCESS) { ret->networkDriver = virNetworkDriverTab[i]; Index: src/qemu_driver.c =================================================================== RCS file: /data/cvs/libvirt/src/qemu_driver.c,v retrieving revision 1.11 diff -u -p -r1.11 qemu_driver.c --- src/qemu_driver.c 24 Jul 2007 14:24:52 -0000 1.11 +++ src/qemu_driver.c 25 Jul 2007 14:47:33 -0000 @@ -2440,6 +2440,7 @@ static virDriver qemuDriver = { }; static virNetworkDriver qemuNetworkDriver = { + "QEMU", qemudOpenNetwork, /* open */ qemudCloseNetwork, /* close */ qemudNumNetworks, /* numOfNetworks */ Index: src/remote_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/remote_internal.c,v retrieving revision 1.15 diff -u -p -r1.15 remote_internal.c --- src/remote_internal.c 12 Jul 2007 15:17:08 -0000 1.15 +++ src/remote_internal.c 25 Jul 2007 14:47:34 -0000 @@ -2950,6 +2950,7 @@ static virDriver driver = { }; static virNetworkDriver network_driver = { + .name = "remote", .open = remoteNetworkOpen, .close = remoteNetworkClose, .numOfNetworks = remoteNumOfNetworks, Index: src/test.c =================================================================== RCS file: /data/cvs/libvirt/src/test.c,v retrieving revision 1.42 diff -u -p -r1.42 test.c --- src/test.c 18 Jul 2007 10:11:09 -0000 1.42 +++ src/test.c 25 Jul 2007 14:47:34 -0000 @@ -35,133 +35,27 @@ #include #include #include +#include +#include #include "internal.h" #include "test.h" #include "xml.h" #include "buf.h" -int testOpen(virConnectPtr conn, - const char *name, - int flags); -int testClose (virConnectPtr conn); -int testGetVersion(virConnectPtr conn, - unsigned long *hvVer); -char *testGetHostname (virConnectPtr conn); -char *testGetURI (virConnectPtr conn); -int testNodeGetInfo(virConnectPtr conn, - virNodeInfoPtr info); -char *testGetCapabilities (virConnectPtr conn); -int testNumOfDomains(virConnectPtr conn); -int testListDomains(virConnectPtr conn, - int *ids, - int maxids); -char *testGetOSType(virDomainPtr dom); -virDomainPtr -testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc, - unsigned int flags ATTRIBUTE_UNUSED); -virDomainPtr testLookupDomainByID(virConnectPtr conn, - int id); -virDomainPtr testLookupDomainByUUID(virConnectPtr conn, - const unsigned char *uuid); -virDomainPtr testLookupDomainByName(virConnectPtr conn, - const char *name); -int testDestroyDomain(virDomainPtr domain); -int testResumeDomain(virDomainPtr domain); -int testPauseDomain(virDomainPtr domain); -int testShutdownDomain (virDomainPtr domain); -int testRebootDomain (virDomainPtr domain, - virDomainRestart action); -int testGetDomainInfo(virDomainPtr domain, - virDomainInfoPtr info); -unsigned long testGetMaxMemory(virDomainPtr domain); -int testSetMaxMemory(virDomainPtr domain, - unsigned long memory); -int testSetMemory(virDomainPtr domain, - unsigned long memory); -int testSetVcpus(virDomainPtr domain, - unsigned int nrCpus); -char * testDomainDumpXML(virDomainPtr domain, int flags); - -int testNumOfDefinedDomains(virConnectPtr conn); -int testListDefinedDomains(virConnectPtr conn, - char **const names, - int maxnames); - -virDomainPtr testDomainDefineXML(virConnectPtr conn, - const char *xml); - -int testDomainCreate(virDomainPtr dom); - -int testDomainUndefine(virDomainPtr dom); - -static virDriver testDriver = { - VIR_DRV_TEST, - "Test", - LIBVIR_VERSION_NUMBER, - testOpen, /* open */ - testClose, /* close */ - NULL, /* type */ - testGetVersion, /* version */ - testGetHostname, /* hostname */ - testGetURI, /* URI */ - NULL, /* getMaxVcpus */ - testNodeGetInfo, /* nodeGetInfo */ - testGetCapabilities, /* getCapabilities */ - testListDomains, /* listDomains */ - testNumOfDomains, /* numOfDomains */ - testDomainCreateLinux, /* domainCreateLinux */ - 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 */ - NULL, /* domainSave */ - NULL, /* domainRestore */ - NULL, /* domainCoreDump */ - testSetVcpus, /* domainSetVcpus */ - NULL, /* domainPinVcpu */ - NULL, /* domainGetVcpus */ - NULL, /* domainGetMaxVcpus */ - testDomainDumpXML, /* domainDumpXML */ - testListDefinedDomains, /* listDefinedDomains */ - testNumOfDefinedDomains, /* numOfDefinedDomains */ - testDomainCreate, /* domainCreate */ - testDomainDefineXML, /* domainDefineXML */ - testDomainUndefine, /* domainUndefine */ - NULL, /* domainAttachDevice */ - NULL, /* domainDetachDevice */ - NULL, /* domainGetAutostart */ - NULL, /* domainSetAutostart */ - NULL, /* domainGetSchedulerType */ - NULL, /* domainGetSchedulerParameters */ - NULL, /* domainSetSchedulerParameters */ -}; - -/* Per-connection private data. */ -struct _testPrivate { - int handle; - char *path; -}; -typedef struct _testPrivate *testPrivatePtr; -typedef struct _testDev { +struct _testDev { char name[20]; int mode; -} testDev; +}; +typedef struct _testDev testDev; +typedef struct _testDev *testDevPtr; #define MAX_DEVICES 10 -typedef struct _testDom { +struct _testDom { int active; + int config; int id; char name[20]; unsigned char uuid[VIR_UUID_BUFLEN]; @@ -173,31 +67,46 @@ typedef struct _testDom { virDomainRestart onCrash; int numDevices; testDev devices[MAX_DEVICES]; -} testDom; + int autostart; + unsigned int weight; +}; +typedef struct _testDom testDom; +typedef struct _testDom *testDomPtr; + +struct _testNet { + int active; + int config; + int running; + char name[20]; + char bridge[20]; + unsigned char uuid[VIR_UUID_BUFLEN]; + int forward; + char forwardDev[IF_NAMESIZE]; + char ipAddress[INET_ADDRSTRLEN]; + char ipNetmask[INET_ADDRSTRLEN]; + + char dhcpStart[INET_ADDRSTRLEN]; + char dhcpEnd[INET_ADDRSTRLEN]; + + int autostart; +}; +typedef struct _testNet testNet; +typedef struct _testNet *testNetPtr; #define MAX_DOMAINS 20 +#define MAX_NETWORKS 20 -typedef struct _testCon { - int active; +struct _testConn { + char path[PATH_MAX]; + int nextDomID; virNodeInfo nodeInfo; int numDomains; testDom domains[MAX_DOMAINS]; -} testCon; - -#define MAX_CONNECTIONS 5 - -typedef struct _testNode { - int numConnections; - testCon connections[MAX_CONNECTIONS]; -} testNode; - -/* XXX, how about we stuff this in a SHM - segment so multiple apps can run tests - against the mock hypervisor concurrently. - Would need a pthread process shared mutex - too probably */ -static testNode *node = NULL; -static int nextDomID = 1; + int numNetworks; + testNet networks[MAX_NETWORKS]; +}; +typedef struct _testConn testConn; +typedef struct _testConn *testConnPtr; #define TEST_MODEL "i686" #define TEST_MODEL_WORDSIZE "32" @@ -213,9 +122,42 @@ static const virNodeInfo defaultNodeInfo 2, }; +#define GET_DOMAIN(dom, ret) \ + int domidx; \ + testConnPtr privconn; \ + testDomPtr privdom; \ + \ + privconn = (testConnPtr)dom->conn->privateData; \ + if ((domidx = getDomainIndex(dom)) < 0) { \ + testError((dom)->conn, (dom), NULL, VIR_ERR_INVALID_ARG, \ + __FUNCTION__); \ + return (ret); \ + } \ + privdom = &privconn->domains[domidx]; + +#define GET_NETWORK(net, ret) \ + int netidx; \ + testConnPtr privconn; \ + testNetPtr privnet; \ + \ + privconn = (testConnPtr)net->conn->privateData; \ + if ((netidx = getNetworkIndex(net)) < 0) { \ + testError((net)->conn, NULL, (net), VIR_ERR_INVALID_ARG, \ + __FUNCTION__); \ + return (ret); \ + } \ + privnet = &privconn->networks[netidx]; + +#define GET_CONNECTION(conn, ret) \ + testConnPtr privconn; \ + \ + privconn = (testConnPtr)conn->privateData; + + static void testError(virConnectPtr con, virDomainPtr dom, + virNetworkPtr net, virErrorNumber error, const char *info) { @@ -225,7 +167,7 @@ testError(virConnectPtr con, return; errmsg = __virErrorMsg(error, info); - __virRaiseError(con, dom, NULL, VIR_FROM_TEST, error, VIR_ERR_ERROR, + __virRaiseError(con, dom, net, VIR_FROM_TEST, error, VIR_ERR_ERROR, errmsg, info, NULL, 0, 0, errmsg, info, 0); } @@ -257,16 +199,6 @@ static const char *testRestartFlagToStri return (NULL); } -/** - * testRegister: - * - * Registers the test driver - */ -int -testRegister(void) -{ - return virRegisterDriver(&testDriver); -} static int testLoadDomain(virConnectPtr conn, int domid, @@ -276,7 +208,6 @@ static int testLoadDomain(virConnectPtr char *name = NULL; unsigned char rawuuid[VIR_UUID_BUFLEN]; char *dst_uuid; - testCon *con; struct timeval tv; unsigned long memory = 0; unsigned long maxMem = 0; @@ -287,39 +218,39 @@ static int testLoadDomain(virConnectPtr virDomainRestart onReboot = VIR_DOMAIN_RESTART; virDomainRestart onPoweroff = VIR_DOMAIN_DESTROY; virDomainRestart onCrash = VIR_DOMAIN_RENAME_RESTART; - testPrivatePtr priv; + GET_CONNECTION(conn, -1); if (gettimeofday(&tv, NULL) < 0) { - testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); return (-1); } root = xmlDocGetRootElement(xml); if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain")); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); goto error; } ctxt = xmlXPathNewContext(xml); if (ctxt == NULL) { - testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context")); + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context")); goto error; } name = virXPathString("string(/domain/name[1])", ctxt); if (name == NULL) { - testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("domain name")); + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("domain name")); goto error; } str = virXPathString("string(/domain/uuid[1])", ctxt); if (str == NULL) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid")); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain uuid")); goto error; } dst_uuid = (char *) &rawuuid[0]; if (!(virParseUUID((char **)&dst_uuid, str))) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid")); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain uuid")); goto error; } free(str); @@ -327,7 +258,7 @@ static int testLoadDomain(virConnectPtr ret = virXPathLong("string(/domain/memory[1])", ctxt, &l); if (ret != 0) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory")); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain memory")); goto error; } maxMem = l; @@ -336,8 +267,8 @@ static int testLoadDomain(virConnectPtr if (ret == -1) { memory = maxMem; } else if (ret == -2) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain current memory")); - goto error; + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain current memory")); + goto error; } else { memory = l; } @@ -346,8 +277,8 @@ static int testLoadDomain(virConnectPtr if (ret == -1) { nrVirtCpu = 1; } else if (ret == -2) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain vcpus")); - goto error; + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain vcpus")); + goto error; } else { nrVirtCpu = l; } @@ -355,38 +286,35 @@ static int testLoadDomain(virConnectPtr str = virXPathString("string(/domain/on_reboot[1])", ctxt); if (str != NULL) { if (!(onReboot = testRestartStringToFlag(str))) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain reboot behaviour")); - free(str); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain reboot behaviour")); + free(str); goto error; } - free(str); + free(str); } str = virXPathString("string(/domain/on_poweroff[1])", ctxt); if (str != NULL) { - if (!(onReboot = testRestartStringToFlag(str))) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain poweroff behaviour")); - free(str); + if (!(onPoweroff = testRestartStringToFlag(str))) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain poweroff behaviour")); + free(str); goto error; } - free(str); + free(str); } str = virXPathString("string(/domain/on_crash[1])", ctxt); if (str != NULL) { - if (!(onReboot = testRestartStringToFlag(str))) { - testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain crash behaviour")); - free(str); + if (!(onCrash = testRestartStringToFlag(str))) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain crash behaviour")); + free(str); goto error; } - free(str); + free(str); } - priv = (testPrivatePtr) conn->privateData; - con = &node->connections[priv->handle]; - for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (!con->domains[i].active) { + if (!privconn->domains[i].active) { handle = i; break; } @@ -394,28 +322,29 @@ static int testLoadDomain(virConnectPtr if (handle < 0) return (-1); - con->domains[handle].active = 1; - con->domains[handle].id = domid; - strncpy(con->domains[handle].name, name, sizeof(con->domains[handle].name)); + privconn->domains[handle].active = 1; + privconn->domains[handle].id = domid; + strncpy(privconn->domains[handle].name, name, sizeof(privconn->domains[handle].name)-1); + privconn->domains[handle].name[sizeof(privconn->domains[handle].name)-1] = '\0'; free(name); name = NULL; if (memory > maxMem) memory = maxMem; - memmove(con->domains[handle].uuid, rawuuid, VIR_UUID_BUFLEN); - con->domains[handle].info.maxMem = maxMem; - con->domains[handle].info.memory = memory; - con->domains[handle].info.state = domid < 0 ? VIR_DOMAIN_SHUTOFF : VIR_DOMAIN_RUNNING; - con->domains[handle].info.nrVirtCpu = nrVirtCpu; - con->domains[handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); - con->domains[handle].maxVCPUs = nrVirtCpu; - - con->domains[handle].onReboot = onReboot; - con->domains[handle].onPoweroff = onPoweroff; - con->domains[handle].onCrash = onCrash; + memmove(privconn->domains[handle].uuid, rawuuid, VIR_UUID_BUFLEN); + privconn->domains[handle].info.maxMem = maxMem; + privconn->domains[handle].info.memory = memory; + privconn->domains[handle].info.state = domid < 0 ? VIR_DOMAIN_SHUTOFF : VIR_DOMAIN_RUNNING; + privconn->domains[handle].info.nrVirtCpu = nrVirtCpu; + privconn->domains[handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); + privconn->domains[handle].maxVCPUs = nrVirtCpu; + + privconn->domains[handle].onReboot = onReboot; + privconn->domains[handle].onPoweroff = onPoweroff; + privconn->domains[handle].onCrash = onCrash; - return (0); + return (handle); error: if (name) @@ -431,7 +360,7 @@ static int testLoadDomainFromDoc(virConn if (!(xml = xmlReadDoc(BAD_CAST doc, "domain.xml", NULL, XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); return (-1); } @@ -442,65 +371,268 @@ static int testLoadDomainFromDoc(virConn return (ret); } + static int testLoadDomainFromFile(virConnectPtr conn, int domid, - const char *file) { + const char *filename) { int ret, fd; xmlDocPtr xml; - if ((fd = open(file, O_RDONLY)) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load domain definition file")); + if ((fd = open(filename, O_RDONLY)) < 0) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load domain definition file")); return (-1); } - if (!(xml = xmlReadFd(fd, file, NULL, + if (!(xml = xmlReadFd(fd, filename, NULL, XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); - close(fd); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); return (-1); } - close(fd); ret = testLoadDomain(conn, domid, xml); xmlFreeDoc(xml); + close(fd); + + return (ret); +} + + +static int testLoadNetwork(virConnectPtr conn, + xmlDocPtr xml) { + xmlNodePtr root = NULL; + xmlXPathContextPtr ctxt = NULL; + char *name = NULL, *bridge = NULL; + unsigned char rawuuid[VIR_UUID_BUFLEN]; + char *dst_uuid; + char *str; + char *ipaddress = NULL, *ipnetmask = NULL, *dhcpstart = NULL, *dhcpend = NULL; + int forward; + char *forwardDev = NULL; + int handle = -1, i; + GET_CONNECTION(conn, -1); + + root = xmlDocGetRootElement(xml); + if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "network"))) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("network")); + goto error; + } + + ctxt = xmlXPathNewContext(xml); + if (ctxt == NULL) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context")); + goto error; + } + + name = virXPathString("string(/network/name[1])", ctxt); + if (name == NULL) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("network name")); + goto error; + } + + bridge = virXPathString("string(/network/bridge[1]/@name)", ctxt); + + str = virXPathString("string(/network/uuid[1])", ctxt); + if (str == NULL) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("network uuid")); + goto error; + } + dst_uuid = (char *) &rawuuid[0]; + if (!(virParseUUID((char **)&dst_uuid, str))) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("network uuid")); + goto error; + } + free(str); + + + forward = virXPathBoolean("count(/network/forward) != 0", ctxt); + if (forward < 0) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("network forward")); + goto error; + } + + forwardDev = virXPathString("string(/network/forward/@dev)", ctxt); + + + ipaddress = virXPathString("string(/network/ip/@address)", ctxt); + if (ipaddress == NULL) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("ip address")); + goto error; + } + ipnetmask = virXPathString("string(/network/ip/@netmask)", ctxt); + if (ipnetmask == NULL) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("ip netmask")); + goto error; + } + dhcpstart = virXPathString("string(/network/ip/dhcp/range[1]/@start)", ctxt); + if (dhcpstart == NULL) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("ip address")); + goto error; + } + dhcpend = virXPathString("string(/network/ip/dhcp/range[1]/@end)", ctxt); + if (dhcpend == NULL) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("ip address")); + goto error; + } + + for (i = 0 ; i < MAX_NETWORKS ; i++) { + if (!privconn->networks[i].active) { + handle = i; + break; + } + } + if (handle < 0) + return (-1); + + privconn->networks[handle].active = 1; + privconn->networks[handle].running = 1; + strncpy(privconn->networks[handle].name, name, sizeof(privconn->networks[handle].name)-1); + privconn->networks[handle].name[sizeof(privconn->networks[handle].name)-1] = '\0'; + strncpy(privconn->networks[handle].bridge, bridge ? bridge : name, sizeof(privconn->networks[handle].bridge)-1); + privconn->networks[handle].bridge[sizeof(privconn->networks[handle].bridge)-1] = '\0'; + free(name); + name = NULL; + if (bridge) { + free(bridge); + bridge = NULL; + } + + memmove(privconn->networks[handle].uuid, rawuuid, VIR_UUID_BUFLEN); + privconn->networks[handle].forward = forward; + if (forwardDev) { + strncpy(privconn->networks[handle].forwardDev, forwardDev, sizeof(privconn->networks[handle].forwardDev)-1); + privconn->networks[handle].forwardDev[sizeof(privconn->networks[handle].forwardDev)-1] = '\0'; + } + + strncpy(privconn->networks[handle].ipAddress, ipaddress, sizeof(privconn->networks[handle].ipAddress)-1); + privconn->networks[handle].ipAddress[sizeof(privconn->networks[handle].ipAddress)-1] = '\0'; + free(ipaddress); + strncpy(privconn->networks[handle].ipNetmask, ipnetmask, sizeof(privconn->networks[handle].ipNetmask)-1); + privconn->networks[handle].ipNetmask[sizeof(privconn->networks[handle].ipNetmask)-1] = '\0'; + free(ipnetmask); + strncpy(privconn->networks[handle].dhcpStart, dhcpstart, sizeof(privconn->networks[handle].dhcpStart)-1); + privconn->networks[handle].dhcpStart[sizeof(privconn->networks[handle].dhcpStart)-1] = '\0'; + free(dhcpstart); + strncpy(privconn->networks[handle].dhcpEnd, dhcpend, sizeof(privconn->networks[handle].dhcpEnd)-1); + privconn->networks[handle].dhcpEnd[sizeof(privconn->networks[handle].dhcpEnd)-1] = '\0'; + free(dhcpend); + return (handle); + + error: + if (ipaddress) + free(ipaddress); + if (ipnetmask) + free(ipnetmask); + if (dhcpstart) + free(dhcpstart); + if (dhcpend) + free(dhcpend); + if (name) + free(name); + return (-1); +} + +static int testLoadNetworkFromDoc(virConnectPtr conn, + const char *doc) { + int ret; + xmlDocPtr xml; + if (!(xml = xmlReadDoc(BAD_CAST doc, "network.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("network")); + return (-1); + } + + ret = testLoadNetwork(conn, xml); + + xmlFreeDoc(xml); + + return (ret); +} + + +static int testLoadNetworkFromFile(virConnectPtr conn, + const char *filename) { + int ret, fd; + xmlDocPtr xml; + + if ((fd = open(filename, O_RDONLY)) < 0) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load network definition file")); + return (-1); + } + + if (!(xml = xmlReadFd(fd, filename, NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("network")); + return (-1); + } + + ret = testLoadNetwork(conn, xml); + + xmlFreeDoc(xml); + close(fd); return (ret); } -static int testOpenDefault(virConnectPtr conn, - int connid) { +static int testOpenDefault(virConnectPtr conn) { int u; struct timeval tv; - testPrivatePtr priv = (testPrivatePtr) conn->privateData; + testConnPtr privconn = malloc(sizeof(testConn)); + if (!privconn) { + testError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "testConn"); + return VIR_DRV_OPEN_ERROR; + } + memset(privconn, 0, sizeof(testConn)); if (gettimeofday(&tv, NULL) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); return VIR_DRV_OPEN_ERROR; } - priv->handle = connid; - node->connections[connid].active = 1; - memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo)); - - node->connections[connid].numDomains = 1; - node->connections[connid].domains[0].active = 1; - node->connections[connid].domains[0].id = nextDomID++; - node->connections[connid].domains[0].onReboot = VIR_DOMAIN_RESTART; - node->connections[connid].domains[0].onCrash = VIR_DOMAIN_RESTART; - node->connections[connid].domains[0].onPoweroff = VIR_DOMAIN_DESTROY; - strcpy(node->connections[connid].domains[0].name, "test"); + memmove(&privconn->nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo)); + + strcpy(privconn->path, "/default"); + privconn->nextDomID = 1; + privconn->numDomains = 1; + privconn->domains[0].active = 1; + privconn->domains[0].config = 1; + privconn->domains[0].id = privconn->nextDomID++; + privconn->domains[0].onReboot = VIR_DOMAIN_RESTART; + privconn->domains[0].onCrash = VIR_DOMAIN_RESTART; + privconn->domains[0].onPoweroff = VIR_DOMAIN_DESTROY; + strcpy(privconn->domains[0].name, "test"); for (u = 0 ; u < VIR_UUID_BUFLEN ; u++) { - node->connections[connid].domains[0].uuid[u] = (u * 75)%255; + privconn->domains[0].uuid[u] = (u * 75)%255; } - node->connections[connid].domains[0].info.maxMem = 8192 * 1024; - node->connections[connid].domains[0].info.memory = 2048 * 1024; - node->connections[connid].domains[0].info.state = VIR_DOMAIN_RUNNING; - node->connections[connid].domains[0].info.nrVirtCpu = 2; - node->connections[connid].domains[0].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); - return (0); + privconn->domains[0].info.maxMem = 8192 * 1024; + privconn->domains[0].info.memory = 2048 * 1024; + privconn->domains[0].info.state = VIR_DOMAIN_RUNNING; + privconn->domains[0].info.nrVirtCpu = 2; + privconn->domains[0].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); + + + privconn->numNetworks = 1; + privconn->networks[0].active = 1; + privconn->networks[0].config = 1; + privconn->networks[0].running = 1; + strcpy(privconn->networks[0].name, "default"); + strcpy(privconn->networks[0].bridge, "default"); + for (u = 0 ; u < VIR_UUID_BUFLEN ; u++) { + privconn->networks[0].uuid[u] = (u * 75)%255; + } + privconn->networks[0].forward = 1; + strcpy(privconn->networks[0].forwardDev, "eth0"); + strcpy(privconn->networks[0].ipAddress, "192.168.122.1"); + strcpy(privconn->networks[0].ipNetmask, "255.255.255.0"); + strcpy(privconn->networks[0].dhcpStart, "192.168.122.128"); + strcpy(privconn->networks[0].dhcpEnd, "192.168.122.253"); + + conn->privateData = privconn; + return (VIR_DRV_OPEN_SUCCESS); } @@ -526,27 +658,30 @@ static char *testBuildFilename(const cha } static int testOpenFromFile(virConnectPtr conn, - int connid, const char *file) { - int fd, i, ret; + int fd = -1, i, ret; long l; char *str; - xmlDocPtr xml; + xmlDocPtr xml = NULL; xmlNodePtr root = NULL; - xmlNodePtr *domains; + xmlNodePtr *domains, *networks; xmlXPathContextPtr ctxt = NULL; virNodeInfoPtr nodeInfo; - testPrivatePtr priv = (testPrivatePtr) conn->privateData; + testConnPtr privconn = malloc(sizeof(testConn)); + if (!privconn) { + testError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY, "testConn"); + return VIR_DRV_OPEN_ERROR; + } if ((fd = open(file, O_RDONLY)) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file")); - return VIR_DRV_OPEN_ERROR; + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file")); + goto error; } if (!(xml = xmlReadFd(fd, file, NULL, XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("host")); + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("host")); goto error; } close(fd); @@ -554,70 +689,74 @@ static int testOpenFromFile(virConnectPt root = xmlDocGetRootElement(xml); if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node")); + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node")); goto error; } ctxt = xmlXPathNewContext(xml); if (ctxt == NULL) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context")); + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context")); goto error; } - priv->handle = connid; - node->connections[connid].active = 1; - node->connections[connid].numDomains = 0; - memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo)); - nodeInfo = &node->connections[connid].nodeInfo; + conn->privateData = privconn; + privconn->nextDomID = 1; + privconn->numDomains = 0; + privconn->numNetworks = 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("string(/node/cpu/nodes[1])", ctxt, &l); if (ret == 0) { nodeInfo->nodes = l; } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu numa nodes")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu numa nodes")); + goto error; } ret = virXPathLong("string(/node/cpu/sockets[1])", ctxt, &l); if (ret == 0) { nodeInfo->sockets = l; } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu sockets")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu sockets")); + goto error; } ret = virXPathLong("string(/node/cpu/cores[1])", ctxt, &l); if (ret == 0) { nodeInfo->cores = l; } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu cores")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu cores")); + goto error; } ret = virXPathLong("string(/node/cpu/threads[1])", ctxt, &l); if (ret == 0) { nodeInfo->threads = l; } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu threads")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu threads")); + goto error; } nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes; ret = virXPathLong("string(/node/cpu/active[1])", ctxt, &l); if (ret == 0) { if (l < nodeInfo->cpus) { - nodeInfo->cpus = l; - } + nodeInfo->cpus = l; + } } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node active cpu")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node active cpu")); + goto error; } ret = virXPathLong("string(/node/cpu/mhz[1])", ctxt, &l); if (ret == 0) { nodeInfo->mhz = l; } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu mhz")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node cpu mhz")); + goto error; } str = virXPathString("string(/node/cpu/model[1])", ctxt); @@ -631,98 +770,115 @@ static int testOpenFromFile(virConnectPt if (ret == 0) { nodeInfo->memory = l; } else if (ret == -2) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node memory")); - goto error; + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node memory")); + goto error; } ret = virXPathNodeSet("/node/domain", ctxt, &domains); if (ret < 0) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node domain list")); + testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node domain list")); goto error; } for (i = 0 ; i < ret ; i++) { xmlChar *domFile = xmlGetProp(domains[i], BAD_CAST "file"); char *absFile = testBuildFilename(file, (const char *)domFile); - int domid = nextDomID++; + int domid = privconn->nextDomID++, handle; free(domFile); if (!absFile) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename")); + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename")); goto error; } - if (testLoadDomainFromFile(conn, domid, absFile) != 0) { + if ((handle = testLoadDomainFromFile(conn, domid, absFile)) < 0) { free(absFile); goto error; } + privconn->domains[handle].config = 1; free(absFile); - node->connections[connid].numDomains++; + privconn->numDomains++; } - if (domains != NULL) + if (domains != NULL) { free(domains); + domains = NULL; + } + + + ret = virXPathNodeSet("/node/network", ctxt, &networks); + if (ret > 0) { + for (i = 0 ; i < ret ; i++) { + xmlChar *netFile = xmlGetProp(networks[i], BAD_CAST "file"); + char *absFile = testBuildFilename(file, (const char *)netFile); + int handle; + free(netFile); + if (!absFile) { + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving network filename")); + goto error; + } + if ((handle = testLoadNetworkFromFile(conn, absFile)) < 0) { + free(absFile); + goto error; + } + privconn->networks[handle].config = 1; + free(absFile); + privconn->numNetworks++; + } + if (networks != NULL) { + free(networks); + networks = NULL; + } + } xmlFreeDoc(xml); return (0); error: - if (node->connections[connid].active) { - for (i = 0 ; i connections[connid].numDomains ; i++) { - node->connections[connid].domains[i].active = 0; - } - node->connections[connid].numDomains = 0; - node->connections[connid].active = 0; - } + if (domains != NULL) + free(domains); + if (networks != NULL) + free(networks); if (xml) xmlFreeDoc(xml); if (fd != -1) close(fd); + free(privconn); + conn->privateData = NULL; return VIR_DRV_OPEN_ERROR; } -static int getNextConnection(void) { - int i; - if (node == NULL) { - node = calloc(1, sizeof(testNode)); - nextDomID = 1; - if (!node) { - testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating node")); - return (-1); - } - } - - for (i = 0 ; i < MAX_CONNECTIONS ; i++) { - if (!node->connections[i].active) { - return (i); - } - } - return (-1); -} - static int getDomainIndex(virDomainPtr domain) { int i; - testCon *con; - testPrivatePtr priv = (testPrivatePtr) domain->conn->privateData; + GET_CONNECTION(domain->conn, -1); - con = &node->connections[priv->handle]; for (i = 0 ; i < MAX_DOMAINS ; i++) { if (domain->id >= 0) { - if (domain->id == con->domains[i].id) + if (domain->id == privconn->domains[i].id) return (i); } else { - if (!strcmp(domain->name, con->domains[i].name)) + if (STREQ(domain->name, privconn->domains[i].name)) return (i); } } return (-1); } -int testOpen(virConnectPtr conn, - const char *name, - int flags ATTRIBUTE_UNUSED) +static int getNetworkIndex(virNetworkPtr network) { + int i; + GET_CONNECTION(network->conn, -1); + + for (i = 0 ; i < MAX_NETWORKS ; i++) { + if (STREQ(network->name, privconn->networks[i].name)) + return (i); + } + return (-1); +} + +static int testOpen(virConnectPtr conn, + const char *name, + int flags ATTRIBUTE_UNUSED) { xmlURIPtr uri; - int ret, connid; - testPrivatePtr priv; + int ret; if (!name) return VIR_DRV_OPEN_DECLINED; @@ -752,121 +908,82 @@ int testOpen(virConnectPtr conn, if (!uri->path || uri->path[0] == '\0' || (uri->path[0] == '/' && uri->path[1] == '\0')) { - testError (NULL, NULL, VIR_ERR_INVALID_ARG, + testError (NULL, NULL, NULL, VIR_ERR_INVALID_ARG, _("testOpen: supply a path or use test:///default")); return VIR_DRV_OPEN_ERROR; } - if ((connid = getNextConnection()) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many connections")); - return VIR_DRV_OPEN_ERROR; - } - - /* Allocate per-connection private data. */ - priv = conn->privateData = calloc (1, sizeof (struct _testPrivate)); - if (!priv) { - testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating private data")); - return VIR_DRV_OPEN_ERROR; - } - priv->handle = -1; - priv->path = strdup (uri->path); - if (!priv->path) { - testError (NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating path")); - return VIR_DRV_OPEN_ERROR; - } - - if (strcmp(uri->path, "/default") == 0) { - ret = testOpenDefault(conn, - connid); - } else { + if (STREQ(uri->path, "/default")) + ret = testOpenDefault(conn); + else ret = testOpenFromFile(conn, - connid, uri->path); - } xmlFreeURI(uri); - if (ret < 0) free (conn->privateData); - return (ret); } -int testClose(virConnectPtr conn) +static int testClose(virConnectPtr conn) { - testPrivatePtr priv; - - if (!conn) { - testError (NULL, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); - return -1; - } - - priv = (testPrivatePtr) conn->privateData; - if (!priv) { - testError (NULL, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); - return -1; - } - - if (priv->handle >= 0) { - testCon *con = &node->connections[priv->handle]; - con->active = 0; - memset (con, 0, sizeof *con); // RWMJ - why? - } - - free (priv->path); - free (priv); + GET_CONNECTION(conn, -1); + free (privconn); + conn->privateData = conn; return 0; } -int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, - unsigned long *hvVer) +static int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, + unsigned long *hvVer) { *hvVer = 2; return (0); } -char * -testGetHostname (virConnectPtr conn) +static char *testGetHostname (virConnectPtr conn) { int r; char hostname [HOST_NAME_MAX+1], *str; r = gethostname (hostname, HOST_NAME_MAX+1); if (r == -1) { - testError (conn, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno)); + testError (conn, NULL, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno)); return NULL; } str = strdup (hostname); if (str == NULL) { - testError (conn, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno)); + testError (conn, NULL, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno)); return NULL; } return str; } -char * -testGetURI (virConnectPtr conn) +static char * testGetURI (virConnectPtr conn) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; char *uri; + GET_CONNECTION(conn, NULL); - if (asprintf (&uri, "test://%s", priv->path) == -1) { - testError (conn, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno)); + if (asprintf (&uri, "test://%s", privconn->path) == -1) { + testError (conn, NULL, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno)); return NULL; } return uri; } -int testNodeGetInfo(virConnectPtr conn, - virNodeInfoPtr info) +static int testGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *type ATTRIBUTE_UNUSED) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; - memcpy(info, &con->nodeInfo, sizeof(virNodeInfo)); - return (0); + return 32; } -char * -testGetCapabilities (virConnectPtr conn) +static int testNodeGetInfo(virConnectPtr conn, + virNodeInfoPtr info) +{ + GET_CONNECTION(conn, -1); + memcpy(info, &privconn->nodeInfo, sizeof(virNodeInfo)); + return (0); +} + +static char *testGetCapabilities (virConnectPtr conn) { static char caps[] = "\ \n\ @@ -896,501 +1013,471 @@ testGetCapabilities (virConnectPtr conn) char *caps_copy = strdup (caps); if (!caps_copy) { - testError(conn, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__); + testError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__); return NULL; } return caps_copy; } -int testNumOfDomains(virConnectPtr conn) +static int testNumOfDomains(virConnectPtr conn) { int numActive = 0, i; - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; + GET_CONNECTION(conn, -1); + for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (!con->domains[i].active || - con->domains[i].info.state == VIR_DOMAIN_SHUTOFF) + if (!privconn->domains[i].active || + privconn->domains[i].info.state == VIR_DOMAIN_SHUTOFF) continue; numActive++; } return (numActive); } -virDomainPtr +static virDomainPtr testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc, unsigned int flags ATTRIBUTE_UNUSED) { - testCon *con; - int domid, handle = -1, i; + int domid, handle = -1; virDomainPtr dom; - testPrivatePtr priv; + GET_CONNECTION(conn, NULL); - if (!VIR_IS_CONNECT(conn)) { - testError(conn, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); - return (NULL); - } if (xmlDesc == NULL) { - testError(conn, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); - return (NULL); - } - if (conn->flags & VIR_CONNECT_RO) { - testError(conn, NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + testError(conn, NULL, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); return (NULL); } - priv = (testPrivatePtr) conn->privateData; - - con = &node->connections[priv->handle]; - - if (con->numDomains == MAX_DOMAINS) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many domains")); + if (privconn->numDomains == MAX_DOMAINS) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many domains")); return (NULL); } - domid = nextDomID++; - if (testLoadDomainFromDoc(conn, domid, xmlDesc) < 0) + domid = privconn->nextDomID++; + if ((handle = testLoadDomainFromDoc(conn, domid, xmlDesc)) < 0) return (NULL); - for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (con->domains[i].id == domid) { - handle = i; - break; - } - } - dom = virGetDomain(conn, con->domains[handle].name, con->domains[handle].uuid); + privconn->domains[handle].config = 0; + + dom = virGetDomain(conn, privconn->domains[handle].name, privconn->domains[handle].uuid); if (dom == NULL) return NULL; - con->numDomains++; + privconn->numDomains++; return (dom); } -virDomainPtr testLookupDomainByID(virConnectPtr conn, - int id) +static virDomainPtr testLookupDomainByID(virConnectPtr conn, + int id) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; virDomainPtr dom; int i, idx = -1; + GET_CONNECTION(conn, NULL); for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (con->domains[i].active && - con->domains[i].id == id) { + if (privconn->domains[i].active && + privconn->domains[i].id == id) { idx = i; break; } } if (idx < 0) { - testError (conn, NULL, VIR_ERR_NO_DOMAIN, NULL); + testError (conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL); return(NULL); } - dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid); + dom = virGetDomain(conn, privconn->domains[idx].name, privconn->domains[idx].uuid); if (dom == NULL) return NULL; dom->id = id; return (dom); } -virDomainPtr testLookupDomainByUUID(virConnectPtr conn, - const unsigned char *uuid) +static virDomainPtr testLookupDomainByUUID(virConnectPtr conn, + const unsigned char *uuid) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; virDomainPtr dom; int i, idx = -1; + GET_CONNECTION(conn, NULL); for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (con->domains[i].active && - memcmp(uuid, con->domains[i].uuid, VIR_UUID_BUFLEN) == 0) { + if (privconn->domains[i].active && + memcmp(uuid, privconn->domains[i].uuid, VIR_UUID_BUFLEN) == 0) { idx = i; break; } } if (idx < 0) { - testError (conn, NULL, VIR_ERR_NO_DOMAIN, NULL); + testError (conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL); return NULL; } - dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid); + dom = virGetDomain(conn, privconn->domains[idx].name, privconn->domains[idx].uuid); if (dom == NULL) return NULL; - dom->id = con->domains[idx].id; + dom->id = privconn->domains[idx].id; return dom; } -virDomainPtr testLookupDomainByName(virConnectPtr conn, - const char *name) +static virDomainPtr testLookupDomainByName(virConnectPtr conn, + const char *name) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; virDomainPtr dom; int i, idx = -1; + GET_CONNECTION(conn, NULL); for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (con->domains[i].active && - strcmp(name, con->domains[i].name) == 0) { + if (privconn->domains[i].active && + strcmp(name, privconn->domains[i].name) == 0) { idx = i; break; } } if (idx < 0) { - testError (conn, NULL, VIR_ERR_NO_DOMAIN, NULL); + testError (conn, NULL, NULL, VIR_ERR_NO_DOMAIN, NULL); return NULL; } - dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid); + dom = virGetDomain(conn, privconn->domains[idx].name, privconn->domains[idx].uuid); if (dom == NULL) return NULL; - dom->id = con->domains[idx].id; + dom->id = privconn->domains[idx].id; return dom; } -int testListDomains (virConnectPtr conn, - int *ids, - int maxids) +static int testListDomains (virConnectPtr conn, + int *ids, + int maxids) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; int n, i; + GET_CONNECTION(conn, -1); for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) { - if (con->domains[i].active && - con->domains[i].info.state != VIR_DOMAIN_SHUTOFF) { - ids[n++] = con->domains[i].id; + if (privconn->domains[i].active && + privconn->domains[i].info.state != VIR_DOMAIN_SHUTOFF) { + ids[n++] = privconn->domains[i].id; } } return (n); } -int testDestroyDomain (virDomainPtr domain) +static int testDestroyDomain (virDomainPtr domain) { - testCon *con; - int domidx; - testPrivatePtr priv; + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); - return (-1); + if (privdom->config) { + privdom->info.state = VIR_DOMAIN_SHUTOFF; + privdom->id = -1; + domain->id = -1; + } else { + privdom->active = 0; } - - priv = (testPrivatePtr) domain->conn->privateData; - - con = &node->connections[priv->handle]; - con->domains[domidx].active = 0; return (0); } -int testResumeDomain (virDomainPtr domain) +static int testResumeDomain (virDomainPtr domain) { - testCon *con; - int domidx; - testPrivatePtr priv; + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); - return (-1); + if (privdom->info.state != VIR_DOMAIN_PAUSED) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, "domain not paused"); + return -1; } - priv = (testPrivatePtr) domain->conn->privateData; - - con = &node->connections[priv->handle]; - con->domains[domidx].info.state = VIR_DOMAIN_RUNNING; + privdom->info.state = VIR_DOMAIN_RUNNING; return (0); } -int testPauseDomain (virDomainPtr domain) +static int testPauseDomain (virDomainPtr domain) { - testCon *con;\ - int domidx; - testPrivatePtr priv; + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); - return (-1); + if (privdom->info.state == VIR_DOMAIN_SHUTOFF || + privdom->info.state == VIR_DOMAIN_PAUSED) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, "domain not running"); + return -1; } - priv = (testPrivatePtr) domain->conn->privateData; - - con = &node->connections[priv->handle]; - con->domains[domidx].info.state = VIR_DOMAIN_PAUSED; + privdom->info.state = VIR_DOMAIN_PAUSED; return (0); } -/* We don't do an immediate shutdown. We basically pretend that - out shutdown sequence takes 'n' seconds to complete. SO, here - we just set state to shutdown, and subsquent calls to getDomainInfo - will check to see if shutdown ought to be marked complete. */ -int testShutdownDomain (virDomainPtr domain) +static int testShutdownDomain (virDomainPtr domain) { - testCon *con; - int domidx; - struct timeval tv; - testPrivatePtr priv; + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); - return (-1); - } - - priv = (testPrivatePtr) domain->conn->privateData; - - con = &node->connections[priv->handle]; - - if (gettimeofday(&tv, NULL) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); - return (-1); + if (privdom->info.state == VIR_DOMAIN_SHUTOFF) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, "domain not running"); + return -1; } - con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF; + privdom->info.state = VIR_DOMAIN_SHUTOFF; domain->id = -1; - con->domains[domidx].id = -1; + privdom->id = -1; return (0); } /* Similar behaviour as shutdown */ -int testRebootDomain (virDomainPtr domain, virDomainRestart action) +static int testRebootDomain (virDomainPtr domain, virDomainRestart action) { - testCon *con; - int domidx; - struct timeval tv; - testPrivatePtr priv; - - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); - return (-1); - } - - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; - - if (gettimeofday(&tv, NULL) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); - return (-1); - } + GET_DOMAIN(domain, -1); if (!action) action = VIR_DOMAIN_RESTART; - con->domains[domidx].info.state = VIR_DOMAIN_SHUTDOWN; + privdom->info.state = VIR_DOMAIN_SHUTDOWN; switch (action) { case VIR_DOMAIN_DESTROY: - con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF; + privdom->info.state = VIR_DOMAIN_SHUTOFF; + domain->id = -1; + privdom->id = -1; break; case VIR_DOMAIN_RESTART: - con->domains[domidx].info.state = VIR_DOMAIN_RUNNING; + privdom->info.state = VIR_DOMAIN_RUNNING; break; case VIR_DOMAIN_PRESERVE: - con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF; + privdom->info.state = VIR_DOMAIN_SHUTOFF; + domain->id = -1; + privdom->id = -1; break; case VIR_DOMAIN_RENAME_RESTART: - con->domains[domidx].info.state = VIR_DOMAIN_RUNNING; + privdom->info.state = VIR_DOMAIN_RUNNING; break; default: - con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF; + privdom->info.state = VIR_DOMAIN_SHUTOFF; + domain->id = -1; + privdom->id = -1; break; } - domain->id = -1; - con->domains[domidx].id = -1; return (0); } -int testGetDomainInfo (virDomainPtr domain, - virDomainInfoPtr info) +static int testGetDomainInfo (virDomainPtr domain, + virDomainInfoPtr info) { struct timeval tv; - testCon *con; - int domidx; - testPrivatePtr priv; - - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; + GET_DOMAIN(domain, -1); if (gettimeofday(&tv, NULL) < 0) { - testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day")); return (-1); } - if (con->domains[domidx].info.state == VIR_DOMAIN_SHUTOFF) { - con->domains[domidx].info.cpuTime = 0; - con->domains[domidx].info.memory = 0; + if (privdom->info.state == VIR_DOMAIN_SHUTOFF) { + privdom->info.cpuTime = 0; + privdom->info.memory = 0; } else { - con->domains[domidx].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); + privdom->info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); } - memcpy(info, &con->domains[domidx].info, sizeof(virDomainInfo)); + memcpy(info, &privdom->info, sizeof(virDomainInfo)); return (0); } -char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) { - return strdup("linux"); -} +static char *testDomainDumpXML(virDomainPtr domain, int flags); -unsigned long testGetMaxMemory(virDomainPtr domain) { - testCon *con; - int domidx; - testPrivatePtr priv; +#define TEST_SAVE_MAGIC "TestGuestMagic" + +static int testDomainSave(virDomainPtr domain, + const char *path) +{ + char *xml; + int fd, len; + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); + xml = testDomainDumpXML(domain, 0); + + if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot save domain"); return (-1); } - - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; - return con->domains[domidx].info.maxMem; + len = strlen(xml); + if (write(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) != sizeof(TEST_SAVE_MAGIC)) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot write header"); + close(fd); + return (-1); + } + if (write(fd, (char*)&len, sizeof(len)) != sizeof(len)) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot write metadata length"); + close(fd); + return (-1); + } + if (write(fd, xml, len) != len) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot write metadata"); + close(fd); + return (-1); + } + if (close(fd) < 0) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot save domain data"); + close(fd); + return (-1); + } + if (privdom->config) { + privdom->info.state = VIR_DOMAIN_SHUTOFF; + privdom->id = -1; + domain->id = -1; + } else { + privdom->active = 0; + } + return 0; } -int testSetMaxMemory(virDomainPtr domain, - unsigned long memory) +static int testDomainRestore(virConnectPtr conn, + const char *path) { - testCon *con; - int domidx; - testPrivatePtr priv; - - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); + char *xml; + char magic[15]; + int fd, len, ret, domid; + GET_CONNECTION(conn, -1); + + if ((fd = open(path, O_RDONLY)) < 0) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot read domain image"); return (-1); } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + if (read(fd, magic, sizeof(magic)) != sizeof(magic)) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "incomplete save header"); + close(fd); return (-1); } - - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; - /* XXX validate not over host memory wrt to other domains */ - con->domains[domidx].info.maxMem = memory; - return (0); + if (memcmp(magic, TEST_SAVE_MAGIC, sizeof(magic))) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "mismatched header magic"); + close(fd); + return (-1); + } + if (read(fd, (char*)&len, sizeof(len)) != sizeof(len)) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "failed to read metadata length"); + close(fd); + return (-1); + } + if (len < 1 || len > 8192) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "length of metadata out of range"); + close(fd); + return (-1); + } + xml = malloc(len+1); + if (!xml) { + testError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "xml"); + close(fd); + return (-1); + } + if (read(fd, xml, len) != len) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "incomplete metdata"); + close(fd); + return (-1); + } + xml[len] = '\0'; + close(fd); + domid = privconn->nextDomID++; + ret = testLoadDomainFromDoc(conn, domid, xml); + free(xml); + return ret < 0 ? -1 : 0; } -int testSetMemory(virDomainPtr domain, - unsigned long memory) +static int testDomainCoreDump(virDomainPtr domain, + const char *to, + int flags ATTRIBUTE_UNUSED) { - testCon *con; - int domidx; - testPrivatePtr priv; + int fd; + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); + if ((fd = open(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot save domain core"); return (-1); } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + if (write(fd, TEST_SAVE_MAGIC, sizeof(TEST_SAVE_MAGIC)) != sizeof(TEST_SAVE_MAGIC)) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot write header"); + close(fd); return (-1); } - - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; - - if (memory > con->domains[domidx].info.maxMem) { - testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__); + if (close(fd) < 0) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + "cannot save domain data"); + close(fd); return (-1); } + if (privdom->config) { + privdom->info.state = VIR_DOMAIN_SHUTOFF; + privdom->id = -1; + domain->id = -1; + } else { + privdom->active = 0; + } + return 0; +} + +static char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) { + return strdup("linux"); +} + +static unsigned long testGetMaxMemory(virDomainPtr domain) { + GET_DOMAIN(domain, -1); - con->domains[domidx].info.memory = memory; + return privdom->info.maxMem; +} + +static int testSetMaxMemory(virDomainPtr domain, + unsigned long memory) +{ + GET_DOMAIN(domain, -1); + + /* XXX validate not over host memory wrt to other domains */ + privdom->info.maxMem = memory; return (0); } -int testSetVcpus(virDomainPtr domain, - unsigned int nrCpus) { - testCon *con; - int domidx; - testPrivatePtr priv; +static int testSetMemory(virDomainPtr domain, + unsigned long memory) +{ + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (-1); - } - if (domain->conn->flags & VIR_CONNECT_RO) { - testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + if (memory > privdom->info.maxMem) { + testError(domain->conn, domain, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); return (-1); } - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; + privdom->info.memory = memory; + return (0); +} + +static int testSetVcpus(virDomainPtr domain, + unsigned int nrCpus) { + GET_DOMAIN(domain, -1); /* We allow more cpus in guest than host */ if (nrCpus > 32) { - testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__); + testError(domain->conn, domain, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); return (-1); } - con->domains[domidx].info.nrVirtCpu = nrCpus; + privdom->info.nrVirtCpu = nrCpus; return (0); } -char * testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) +static char *testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) { virBufferPtr buf; char *xml; unsigned char *uuid; - testCon *con; - int domidx; - testPrivatePtr priv; - - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); - return (NULL); - } - - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; + GET_DOMAIN(domain, NULL); if (!(buf = virBufferNew(4000))) { - testError(domain->conn, domain, VIR_ERR_NO_MEMORY, __FUNCTION__); + testError(domain->conn, domain, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__); return (NULL); } @@ -1404,11 +1491,11 @@ char * testDomainDumpXML(virDomainPtr do uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); - virBufferVSprintf(buf, " %lu\n", con->domains[domidx].info.maxMem); - virBufferVSprintf(buf, " %d\n", con->domains[domidx].info.nrVirtCpu); - virBufferVSprintf(buf, " %s\n", testRestartFlagToString(con->domains[domidx].onReboot)); - virBufferVSprintf(buf, " %s\n", testRestartFlagToString(con->domains[domidx].onPoweroff)); - virBufferVSprintf(buf, " %s\n", testRestartFlagToString(con->domains[domidx].onCrash)); + virBufferVSprintf(buf, " %lu\n", privdom->info.maxMem); + virBufferVSprintf(buf, " %d\n", privdom->info.nrVirtCpu); + virBufferVSprintf(buf, " %s\n", testRestartFlagToString(privdom->onReboot)); + virBufferVSprintf(buf, " %s\n", testRestartFlagToString(privdom->onPoweroff)); + virBufferVSprintf(buf, " %s\n", testRestartFlagToString(privdom->onCrash)); virBufferAdd(buf, "\n", -1); @@ -1418,112 +1505,515 @@ char * testDomainDumpXML(virDomainPtr do return (xml); } - -int testNumOfDefinedDomains(virConnectPtr conn) { +static int testNumOfDefinedDomains(virConnectPtr conn) { int numInactive = 0, i; - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; + GET_CONNECTION(conn, -1); + for (i = 0 ; i < MAX_DOMAINS ; i++) { - if (!con->domains[i].active || - con->domains[i].info.state != VIR_DOMAIN_SHUTOFF) + if (!privconn->domains[i].active || + privconn->domains[i].info.state != VIR_DOMAIN_SHUTOFF) continue; numInactive++; } return (numInactive); } -int testListDefinedDomains(virConnectPtr conn, - char **const names, - int maxnames) { - testPrivatePtr priv = (testPrivatePtr) conn->privateData; - testCon *con = &node->connections[priv->handle]; +static int testListDefinedDomains(virConnectPtr conn, + char **const names, + int maxnames) { int n = 0, i; + GET_CONNECTION(conn, -1); for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxnames ; i++) { - if (con->domains[i].active && - con->domains[i].info.state == VIR_DOMAIN_SHUTOFF) { - names[n++] = strdup(con->domains[i].name); + if (privconn->domains[i].active && + privconn->domains[i].info.state == VIR_DOMAIN_SHUTOFF) { + names[n++] = strdup(privconn->domains[i].name); } } return (n); } -virDomainPtr testDomainDefineXML(virConnectPtr conn, - const char *doc) { - int ret; +static virDomainPtr testDomainDefineXML(virConnectPtr conn, + const char *doc) { + int handle; xmlDocPtr xml; - int domid; + GET_CONNECTION(conn, NULL); if (!(xml = xmlReadDoc(BAD_CAST doc, "domain.xml", NULL, XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); + testError(conn, NULL, NULL, VIR_ERR_XML_ERROR, _("domain")); return (NULL); } - domid = nextDomID++; - ret = testLoadDomain(conn, domid, xml); + handle = testLoadDomain(conn, -1, xml); + privconn->domains[handle].config = 1; xmlFreeDoc(xml); - if (ret < 0) + if (handle < 0) return (NULL); - return testLookupDomainByID(conn, domid); + return virGetDomain(conn, privconn->domains[handle].name, privconn->domains[handle].uuid); } -int testDomainCreate(virDomainPtr domain) { - testCon *con; - int domidx; - testPrivatePtr priv; +static int testDomainCreate(virDomainPtr domain) { + GET_DOMAIN(domain, -1); - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); + if (privdom->info.state != VIR_DOMAIN_SHUTOFF) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + _("Domain is already running")); return (-1); } - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; + domain->id = privdom->id = privconn->nextDomID++; + privdom->info.state = VIR_DOMAIN_RUNNING; - if (con->domains[domidx].info.state != VIR_DOMAIN_SHUTOFF) { - testError(domain->conn, domain, VIR_ERR_INTERNAL_ERROR, - _("Domain is already running")); + return (0); +} + +static int testDomainUndefine(virDomainPtr domain) { + GET_DOMAIN(domain, -1); + + if (privdom->info.state != VIR_DOMAIN_SHUTOFF) { + testError(domain->conn, domain, NULL, VIR_ERR_INTERNAL_ERROR, + _("Domain is still running")); return (-1); } - domain->id = con->domains[domidx].id = nextDomID++; - con->domains[domidx].info.state = VIR_DOMAIN_RUNNING; + privdom->active = 0; + + return (0); +} +static int testDomainGetAutostart(virDomainPtr domain, + int *autostart) +{ + GET_DOMAIN(domain, -1); + *autostart = privdom->autostart; return (0); } -int testDomainUndefine(virDomainPtr domain) { - testCon *con; - int domidx; - testPrivatePtr priv; - if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) || - ((domidx = getDomainIndex(domain)) < 0)) { - testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG, - __FUNCTION__); +static int testDomainSetAutostart(virDomainPtr domain, + int autostart) +{ + GET_DOMAIN(domain, -1); + privdom->autostart = autostart ? 1 : 0; + return (0); +} + +static char *testDomainGetSchedulerType(virDomainPtr domain, + int *nparams) +{ + char *type; + *nparams = 1; + type = strdup("fair"); + if (!type) { + testError(domain->conn, domain, NULL, VIR_ERR_NO_MEMORY, "schedular"); + return (NULL); + } + return type; +} + +static int testDomainGetSchedulerParams(virDomainPtr domain, + virSchedParameterPtr params, + int *nparams) +{ + GET_DOMAIN(domain, -1); + if (*nparams != 1) { + testError(domain->conn, domain, NULL, VIR_ERR_INVALID_ARG, "nparams"); return (-1); } + strcpy(params[0].field, "weight"); + params[0].type = VIR_DOMAIN_SCHED_FIELD_UINT; + params[0].value.ui = privdom->weight; + return 0; +} - priv = (testPrivatePtr) domain->conn->privateData; - con = &node->connections[priv->handle]; - if (con->domains[domidx].info.state != VIR_DOMAIN_SHUTOFF) { - testError(domain->conn, domain, VIR_ERR_INTERNAL_ERROR, - _("Domain is still running")); +static int testDomainSetSchedulerParams(virDomainPtr domain, + virSchedParameterPtr params, + int nparams) +{ + GET_DOMAIN(domain, -1); + if (nparams != 1) { + testError(domain->conn, domain, NULL, VIR_ERR_INVALID_ARG, "nparams"); + return (-1); + } + if (STRNEQ(params[0].field, "weight")) { + testError(domain->conn, domain, NULL, VIR_ERR_INVALID_ARG, "field"); + return (-1); + } + if (params[0].type != VIR_DOMAIN_SCHED_FIELD_UINT) { + testError(domain->conn, domain, NULL, VIR_ERR_INVALID_ARG, "type"); + return (-1); + } + privdom->weight = params[0].value.ui; + return 0; +} + +static virDrvOpenStatus testOpenNetwork(virConnectPtr conn, + const char *name 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) +{ + int i, idx = -1; + GET_CONNECTION(conn, NULL); + + for (i = 0 ; i < MAX_NETWORKS ; i++) { + if (privconn->networks[i].active && + memcmp(uuid, privconn->networks[i].uuid, VIR_UUID_BUFLEN) == 0) { + idx = i; + break; + } + } + + if (idx < 0) { + testError (conn, NULL, NULL, VIR_ERR_NO_NETWORK, NULL); + return NULL; + } + + return virGetNetwork(conn, privconn->networks[idx].name, privconn->networks[idx].uuid); +} + +static virNetworkPtr testLookupNetworkByName(virConnectPtr conn, + const char *name) +{ + int i, idx = -1; + GET_CONNECTION(conn, NULL); + + for (i = 0 ; i < MAX_NETWORKS ; i++) { + if (privconn->networks[i].active && + strcmp(name, privconn->networks[i].name) == 0) { + idx = i; + break; + } + } + + if (idx < 0) { + testError (conn, NULL, NULL, VIR_ERR_NO_NETWORK, NULL); + return NULL; + } + + return virGetNetwork(conn, privconn->networks[idx].name, privconn->networks[idx].uuid); +} + + +static int testNumNetworks(virConnectPtr conn) { + int numInactive = 0, i; + GET_CONNECTION(conn, -1); + + for (i = 0 ; i < MAX_NETWORKS ; i++) { + if (!privconn->networks[i].active || + !privconn->networks[i].running) + continue; + numInactive++; + } + return (numInactive); +} + +static int testListNetworks(virConnectPtr conn, char **const names, int nnames) { + int n = 0, i; + GET_CONNECTION(conn, -1); + + for (i = 0, n = 0 ; i < MAX_NETWORKS && n < nnames ; i++) { + if (privconn->networks[i].active && + privconn->networks[i].running) { + names[n++] = strdup(privconn->networks[i].name); + } + } + return (n); +} + +static int testNumDefinedNetworks(virConnectPtr conn) { + int numInactive = 0, i; + GET_CONNECTION(conn, -1); + + for (i = 0 ; i < MAX_NETWORKS ; i++) { + if (!privconn->networks[i].active || + privconn->networks[i].running) + continue; + numInactive++; + } + return (numInactive); +} + +static int testListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) { + int n = 0, i; + GET_CONNECTION(conn, -1); + + for (i = 0, n = 0 ; i < MAX_NETWORKS && n < nnames ; i++) { + if (privconn->networks[i].active && + !privconn->networks[i].running) { + names[n++] = strdup(privconn->networks[i].name); + } + } + return (n); +} + +static virNetworkPtr testNetworkCreate(virConnectPtr conn, const char *xml) { + int handle = -1; + virNetworkPtr net; + GET_CONNECTION(conn, NULL); + + if (xml == NULL) { + testError(conn, NULL, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (NULL); + } + + if (privconn->numNetworks == MAX_NETWORKS) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many networks")); + return (NULL); + } + + if ((handle = testLoadNetworkFromDoc(conn, xml)) < 0) + return (NULL); + privconn->networks[handle].config = 0; + + net = virGetNetwork(conn, privconn->networks[handle].name, privconn->networks[handle].uuid); + if (net == NULL) return NULL; + privconn->numNetworks++; + return (net); +} + +static virNetworkPtr testNetworkDefine(virConnectPtr conn, const char *xml) { + int handle = -1; + virNetworkPtr net; + GET_CONNECTION(conn, NULL); + + if (xml == NULL) { + testError(conn, NULL, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (NULL); + } + + if (privconn->numNetworks == MAX_NETWORKS) { + testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many networks")); + return (NULL); + } + + if ((handle = testLoadNetworkFromDoc(conn, xml)) < 0) + return (NULL); + + net = virGetNetwork(conn, privconn->networks[handle].name, privconn->networks[handle].uuid); + privconn->networks[handle].config = 1; + if (net == NULL) return NULL; + privconn->numNetworks++; + return (net); +} + +static int testNetworkUndefine(virNetworkPtr network) { + GET_NETWORK(network, -1); + + if (privnet->running) { + testError(network->conn, NULL, network, VIR_ERR_INTERNAL_ERROR, + _("Network is still running")); return (-1); } - con->domains[domidx].active = 0; + privnet->active = 0; + + return (0); +} + +static int testNetworkStart(virNetworkPtr network) { + GET_NETWORK(network, -1); + + if (privnet->running) { + testError(network->conn, NULL, network, VIR_ERR_INTERNAL_ERROR, + _("Network is already running")); + return (-1); + } + + privnet->running = 1; + + return (0); +} + +static int testNetworkDestroy(virNetworkPtr network) { + GET_NETWORK(network, -1); + + if (privnet->config) { + privnet->running = 0; + } else { + privnet->active = 0; + } + return (0); +} + +static char *testNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) { + virBufferPtr buf; + char *xml; + unsigned char *uuid; + GET_NETWORK(network, NULL); + + if (!(buf = virBufferNew(4000))) { + testError(network->conn, NULL, network, VIR_ERR_NO_MEMORY, __FUNCTION__); + return (NULL); + } + + virBufferAdd(buf, "\n", -1); + virBufferVSprintf(buf, " %s\n", network->name); + uuid = network->uuid; + virBufferVSprintf(buf, + " %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + + virBufferVSprintf(buf, " \n", privnet->bridge); + if (privnet->forward) { + if (privnet->forwardDev[0]) + virBufferVSprintf(buf, " \n", privnet->forwardDev); + else + virBufferAdd(buf, " \n", -1); + } + + virBufferVSprintf(buf, " \n", + privnet->ipAddress, privnet->ipNetmask); + virBufferAdd(buf, " \n", -1); + virBufferVSprintf(buf, " \n", + privnet->dhcpStart, privnet->dhcpEnd); + virBufferAdd(buf, " \n", -1); + virBufferAdd(buf, " \n", -1); + + virBufferAdd(buf, "\n", -1); + + xml = buf->content; + free(buf); + + return (xml); +} + +static char *testNetworkGetBridgeName(virNetworkPtr network) { + char *bridge; + GET_NETWORK(network, NULL); + bridge = strdup(privnet->bridge); + if (!bridge) { + testError(network->conn, NULL, network, VIR_ERR_NO_MEMORY, "network"); + return NULL; + } + return bridge; +} + +static int testNetworkGetAutostart(virNetworkPtr network, + int *autostart) { + GET_NETWORK(network, -1); + *autostart = privnet->autostart; + return (0); +} +static int testNetworkSetAutostart(virNetworkPtr network, + int autostart) { + GET_NETWORK(network, -1); + privnet->autostart = autostart ? 1 : 0; return (0); } + + +static virDriver testDriver = { + VIR_DRV_TEST, + "Test", + LIBVIR_VERSION_NUMBER, + testOpen, /* open */ + testClose, /* close */ + NULL, /* type */ + testGetVersion, /* version */ + testGetHostname, /* hostname */ + testGetURI, /* URI */ + testGetMaxVCPUs, /* getMaxVcpus */ + testNodeGetInfo, /* nodeGetInfo */ + testGetCapabilities, /* getCapabilities */ + testListDomains, /* listDomains */ + testNumOfDomains, /* numOfDomains */ + testDomainCreateLinux, /* domainCreateLinux */ + 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 */ + testDomainDumpXML, /* domainDumpXML */ + testListDefinedDomains, /* listDefinedDomains */ + testNumOfDefinedDomains, /* numOfDefinedDomains */ + testDomainCreate, /* domainCreate */ + testDomainDefineXML, /* domainDefineXML */ + testDomainUndefine, /* domainUndefine */ + NULL, /* domainAttachDevice */ + NULL, /* domainDetachDevice */ + testDomainGetAutostart, /* domainGetAutostart */ + testDomainSetAutostart, /* domainSetAutostart */ + testDomainGetSchedulerType, /* domainGetSchedulerType */ + testDomainGetSchedulerParams, /* domainGetSchedulerParameters */ + testDomainSetSchedulerParams, /* domainSetSchedulerParameters */ +}; + +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 */ +}; + + +/** + * testRegister: + * + * Registers the test driver + */ +int +testRegister(void) +{ + if (virRegisterDriver(&testDriver) < 0) + return -1; + if (virRegisterNetworkDriver(&testNetworkDriver) < 0) + return -1; + return 0; +} + #endif /* WITH_TEST */ /* Index: tests/virshtest.c =================================================================== RCS file: /data/cvs/libvirt/tests/virshtest.c,v retrieving revision 1.5 diff -u -p -r1.5 virshtest.c --- tests/virshtest.c 18 Jul 2007 21:08:22 -0000 1.5 +++ tests/virshtest.c 25 Jul 2007 14:47:34 -0000 @@ -12,341 +12,176 @@ static char *progname; #define MAX_FILE 4096 static int testFilterLine(char *buffer, - const char *toRemove) { - char *start; - char *end; - - if (!(start = strstr(buffer, toRemove))) - return -1; - - if (!(end = strstr(start+1, "\n"))) { - *start = '\0'; - } else { - memmove(start, end, strlen(end)+1); - } - return 0; -} - -static int testCompareOutput(const char *expect, const char *filter, const char *const argv[]) { - char expectData[MAX_FILE]; - char actualData[MAX_FILE]; - char *expectPtr = &(expectData[0]); - char *actualPtr = &(actualData[0]); - - if (virtTestLoadFile(expect, &expectPtr, MAX_FILE) < 0) - return -1; - - if (virtTestCaptureProgramOutput(argv, &actualPtr, MAX_FILE) < 0) - return -1; - - if (filter) - if (testFilterLine(actualData, filter) < 0) - return -1; - - if (getenv("DEBUG_TESTS")) { - printf("Expect %d '%s'\n", (int)strlen(expectData), expectData); - printf("Actual %d '%s'\n", (int)strlen(actualData), actualData); - } - if (strcmp(expectData, actualData)) - return -1; - - return 0; -} - - -#define VIRSH_DEFAULT "../src/virsh", \ - "--connect", \ - "test:///default" - -static char *custom_uri; - -#define VIRSH_CUSTOM "../src/virsh", \ - "--connect", \ - custom_uri - - - -static int testCompareListDefault(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_DEFAULT, - "list", - NULL - }; - return testCompareOutput("virshdata/list-default.txt", - NULL, - argv); -} - -static int testCompareListCustom(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "list", - NULL - }; - return testCompareOutput("virshdata/list-custom.txt", - NULL, - argv); -} - - -static int testCompareNodeinfoDefault(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_DEFAULT, - "nodeinfo", - NULL - }; - return testCompareOutput("virshdata/nodeinfo-default.txt", - NULL, - argv); -} - -static int testCompareNodeinfoCustom(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "nodeinfo", - NULL - }; - return testCompareOutput("virshdata/nodeinfo-custom.txt", - NULL, - argv); -} - -static int testCompareDominfoByID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "dominfo", - "2", - NULL - }; - return testCompareOutput("virshdata/dominfo-fc4.txt", - "\nCPU time:", - argv); -} - - -static int testCompareDominfoByUUID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "dominfo", - "ef861801-45b9-11cb-88e3-afbfe5370493", - NULL - }; - return testCompareOutput("virshdata/dominfo-fc4.txt", - "\nCPU time:", - argv); -} - - -static int testCompareDominfoByName(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "dominfo", - "fc4", - NULL - }; - return testCompareOutput("virshdata/dominfo-fc4.txt", - "\nCPU time:", - argv); -} - - -static int testCompareDomuuidByID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domuuid", - "2", - NULL - }; - return testCompareOutput("virshdata/domuuid-fc4.txt", - NULL, - argv); -} - -static int testCompareDomuuidByName(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domuuid", - "fc4", - NULL - }; - return testCompareOutput("virshdata/domuuid-fc4.txt", - NULL, - argv); -} - -static int testCompareDomidByName(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domid", - "fc4", - NULL - }; - return testCompareOutput("virshdata/domid-fc4.txt", - NULL, - argv); + const char *toRemove) { + char *start; + char *end; + + if (!(start = strstr(buffer, toRemove))) + return -1; + + if (!(end = strstr(start+1, "\n"))) { + *start = '\0'; + } else { + memmove(start, end, strlen(end)+1); + } + return 0; } +static int testCompareOutput(const char *expect, const char *filter, const char *uri, + const char *arg1, const char *arg2) { + char expectData[MAX_FILE]; + char actualData[MAX_FILE]; + char *expectPtr = &(expectData[0]); + char *actualPtr = &(actualData[0]); + char buffer[PATH_MAX]; + char cwd[PATH_MAX]; + const char *argv[] = { "../src/virsh", "--connect", buffer, arg1, arg2, NULL }; -static int testCompareDomidByUUID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domid", - "ef861801-45b9-11cb-88e3-afbfe5370493", - NULL - }; - return testCompareOutput("virshdata/domid-fc4.txt", - NULL, - argv); -} - + if (STRNEQ(uri, "/default")) { + if (!getcwd(cwd, PATH_MAX-1)) + return 1; + snprintf(buffer, PATH_MAX-1, "test://%s%s", cwd, uri); + } else { + snprintf(buffer, PATH_MAX-1, "test://%s", uri); + } + buffer[PATH_MAX-1] = '\0'; -static int testCompareDomnameByID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domname", - "2", - NULL - }; - return testCompareOutput("virshdata/domname-fc4.txt", - NULL, - argv); -} + if (virtTestLoadFile(expect, &expectPtr, MAX_FILE) < 0) + return -1; + if (virtTestCaptureProgramOutput(argv, &actualPtr, MAX_FILE) < 0) + return -1; -static int testCompareDomnameByUUID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domname", - "ef861801-45b9-11cb-88e3-afbfe5370493", - NULL - }; - return testCompareOutput("virshdata/domname-fc4.txt", - NULL, - argv); -} + if (filter) + if (testFilterLine(actualData, filter) < 0) + return -1; + + if (STRNEQ(expectData, actualData)) { + if (getenv("DEBUG_TESTS")) { + printf("Expect %d '%s'\n", (int)strlen(expectData), expectData); + printf("Actual %d '%s'\n", (int)strlen(actualData), actualData); + } + return -1; + } -static int testCompareDomstateByID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domstate", - "2", - NULL - }; - return testCompareOutput("virshdata/domstate-fc4.txt", - NULL, - argv); + return 0; } -static int testCompareDomstateByUUID(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domstate", - "ef861801-45b9-11cb-88e3-afbfe5370493", - NULL - }; - return testCompareOutput("virshdata/domstate-fc4.txt", - NULL, - argv); -} +#define VIRSH_DEFAULT "/default" +#define VIRSH_CUSTOM "/../docs/testnode.xml" -static int testCompareDomstateByName(const void *data ATTRIBUTE_UNUSED) { - const char *const argv[] = { - VIRSH_CUSTOM, - "domstate", - "fc4", - NULL - }; - return testCompareOutput("virshdata/domstate-fc4.txt", - NULL, - argv); +struct _testData { + const char *label; + const char *uri; + const char *arg1; + const char *arg2; + const char *filter; + const char *expect; +}; +typedef struct _testData testData; +typedef struct _testData *testDataPtr; + +testData testDataSets[] = { + { "list default", + VIRSH_DEFAULT, "list", NULL, + NULL, + "virshdata/list-default.txt" }, + { "list custom", + VIRSH_CUSTOM, "list", NULL, + NULL, + "virshdata/list-custom.txt" }, + { "nodeinfo default", + VIRSH_DEFAULT, "nodeinfo", NULL, + NULL, + "virshdata/nodeinfo-default.txt" }, + { "nodeinfo custom", + VIRSH_CUSTOM, "nodeinfo", NULL, + NULL, + "virshdata/nodeinfo-custom.txt" }, + { "dominfo by id", + VIRSH_CUSTOM, "dominfo", "2", + "\nCPU time:", + "virshdata/dominfo-fc4.txt" }, + { "dominfo by uuid", + VIRSH_CUSTOM, "dominfo", "ef861801-45b9-11cb-88e3-afbfe5370493", + "\nCPU time:", + "virshdata/dominfo-fc4.txt" }, + { "dominfo by name", + VIRSH_CUSTOM, "dominfo", "fc4", + "\nCPU time:", + "virshdata/dominfo-fc4.txt" }, + { "domuuid by id", + VIRSH_CUSTOM, "domuuid", "2", + NULL, + "virshdata/domuuid-fc4.txt" }, + { "domuuid by name", + VIRSH_CUSTOM, "domuuid", "fc4", + NULL, + "virshdata/domuuid-fc4.txt" }, + { "domid by name", + VIRSH_CUSTOM, "domid", "fc4", + NULL, + "virshdata/domid-fc4.txt" }, + { "domid by uuid", + VIRSH_CUSTOM, "domid", "ef861801-45b9-11cb-88e3-afbfe5370493", + NULL, + "virshdata/domid-fc4.txt" }, + { "domname by id", + VIRSH_CUSTOM, "domname", "2", + NULL, + "virshdata/domname-fc4.txt" }, + { "domname by uuid", + VIRSH_CUSTOM, "domname", "ef861801-45b9-11cb-88e3-afbfe5370493", + NULL, + "virshdata/domname-fc4.txt" }, + { "domstate by id", + VIRSH_CUSTOM, "domstate", "2", + NULL, + "virshdata/domstate-fc4.txt" }, + { "domstate by uuid", + VIRSH_CUSTOM, "domstate", "ef861801-45b9-11cb-88e3-afbfe5370493" , + NULL, + "virshdata/domstate-fc4.txt" }, + { "domstate by name", + VIRSH_CUSTOM, "domstate", "fc4", + NULL, + "virshdata/domstate-fc4.txt" }, +}; + +static int testCompare(const void *data) { + testDataPtr test = (testDataPtr)data; + return testCompareOutput(test->expect, + test->filter, + test->uri, + test->arg1, + test->arg2); } - - int main(int argc, char **argv) { - int ret = 0; - char cwd[PATH_MAX]; - char buffer[PATH_MAX]; - - if (!getcwd(cwd, PATH_MAX-1)) - return 1; - - snprintf(buffer, PATH_MAX-1, "test://%s/../docs/testnode.xml", cwd); - buffer[PATH_MAX-1] = '\0'; + int ret = 0, i; progname = argv[0]; - custom_uri = buffer; - + if (argc > 1) { - fprintf(stderr, "Usage: %s\n", progname); + fprintf(stderr, "Usage: %s\n", argv[0]); exit(EXIT_FAILURE); } - - if (virtTestRun("virsh list (default)", - 1, testCompareListDefault, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh list (custom)", - 1, testCompareListCustom, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh nodeinfo (default)", - 1, testCompareNodeinfoDefault, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh nodeinfo (custom)", - 1, testCompareNodeinfoCustom, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh dominfo (by id)", - 1, testCompareDominfoByID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh dominfo (by uuid)", - 1, testCompareDominfoByUUID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh dominfo (by name)", - 1, testCompareDominfoByName, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domid (by name)", - 1, testCompareDomidByName, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domid (by uuid)", - 1, testCompareDomidByUUID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domuuid (by id)", - 1, testCompareDomuuidByID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domuuid (by name)", - 1, testCompareDomuuidByName, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domname (by id)", - 1, testCompareDomnameByID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domname (by uuid)", - 1, testCompareDomnameByUUID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domstate (by id)", - 1, testCompareDomstateByID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domstate (by uuid)", - 1, testCompareDomstateByUUID, NULL) != 0) - ret = -1; - - if (virtTestRun("virsh domstate (by name)", - 1, testCompareDomstateByName, NULL) != 0) - ret = -1; + + for (i = 0 ; i < (sizeof(testDataSets)/sizeof(testDataSets[0])) ; i++) + if (virtTestRun(testDataSets[i].label, + 1, testCompare, &testDataSets[i]) != 0) + ret = -1; exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); } + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */