mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Added 'mock' hypervisor driver for use by unit tests
This commit is contained in:
parent
88e6f39ae6
commit
e5bb0cb052
@ -1,3 +1,9 @@
|
|||||||
|
Mon Jun 05 22:31:20 EDT 2006 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* src/test.c, src/test.h: New 'mock' hypervisor driver providing
|
||||||
|
a way to write predictable unit tests which exercise libvirt APIs.
|
||||||
|
* src/libvirt.c, src/Makefile.am: Integrate test hypervisor driver
|
||||||
|
|
||||||
Fri May 26 11:59:20 EDT 2006 Daniel P. Berrange <berrange@redhat.com>
|
Fri May 26 11:59:20 EDT 2006 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* src/hash.c, src/internal.h: Switch the uuid parameter in virGetDomain
|
* src/hash.c, src/internal.h: Switch the uuid parameter in virGetDomain
|
||||||
|
@ -16,6 +16,7 @@ libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
|
|||||||
libvirt_la_SOURCES = \
|
libvirt_la_SOURCES = \
|
||||||
libvirt.c internal.h \
|
libvirt.c internal.h \
|
||||||
hash.c hash.h \
|
hash.c hash.h \
|
||||||
|
test.c test.h \
|
||||||
xml.c xml.h \
|
xml.c xml.h \
|
||||||
xen_internal.c xen_internal.h \
|
xen_internal.c xen_internal.h \
|
||||||
xs_internal.c xs_internal.h \
|
xs_internal.c xs_internal.h \
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "xend_internal.h"
|
#include "xend_internal.h"
|
||||||
#include "xs_internal.h"
|
#include "xs_internal.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
@ -70,6 +71,7 @@ virInitialize(void)
|
|||||||
xenHypervisorRegister();
|
xenHypervisorRegister();
|
||||||
xenDaemonRegister();
|
xenDaemonRegister();
|
||||||
xenStoreRegister();
|
xenStoreRegister();
|
||||||
|
testRegister();
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
350
src/test.c
Normal file
350
src/test.c
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
/*
|
||||||
|
* test.c: A "mock" hypervisor for use by application unit tests
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* See COPYING.LIB for the License of this software
|
||||||
|
*
|
||||||
|
* Daniel Berrange <berrange@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <libxml/uri.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
static virDriver testDriver = {
|
||||||
|
"Test",
|
||||||
|
NULL, /* init */
|
||||||
|
testOpen, /* open */
|
||||||
|
testClose, /* close */
|
||||||
|
NULL, /* type */
|
||||||
|
testGetVersion, /* version */
|
||||||
|
testNodeGetInfo, /* nodeGetInfo */
|
||||||
|
testListDomains, /* listDomains */
|
||||||
|
testNumOfDomains, /* numOfDomains */
|
||||||
|
NULL, /* domainCreateLinux */
|
||||||
|
testLookupDomainByID, /* domainLookupByID */
|
||||||
|
testLookupDomainByUUID, /* domainLookupByUUID */
|
||||||
|
testLookupDomainByName, /* domainLookupByName */
|
||||||
|
testPauseDomain, /* domainSuspend */
|
||||||
|
testResumeDomain, /* domainResume */
|
||||||
|
NULL, /* domainShutdown */
|
||||||
|
NULL, /* domainReboot */
|
||||||
|
testDestroyDomain, /* domainDestroy */
|
||||||
|
NULL, /* domainFree */
|
||||||
|
NULL, /* domainGetName */
|
||||||
|
NULL, /* domainGetID */
|
||||||
|
NULL, /* domainGetUUID */
|
||||||
|
NULL, /* domainGetOSType */
|
||||||
|
NULL, /* domainGetMaxMemory */
|
||||||
|
testSetMaxMemory, /* domainSetMaxMemory */
|
||||||
|
NULL, /* domainSetMemory */
|
||||||
|
testGetDomainInfo, /* domainGetInfo */
|
||||||
|
NULL, /* domainSave */
|
||||||
|
NULL /* domainRestore */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _testDev {
|
||||||
|
char name[20];
|
||||||
|
virDeviceMode mode;
|
||||||
|
} testDev;
|
||||||
|
|
||||||
|
#define MAX_DEVICES 10
|
||||||
|
|
||||||
|
typedef struct _testDom {
|
||||||
|
int active;
|
||||||
|
char name[20];
|
||||||
|
unsigned char uuid[16];
|
||||||
|
virDomainKernel kernel;
|
||||||
|
virDomainInfo info;
|
||||||
|
virDomainRestart onRestart;
|
||||||
|
int numDevices;
|
||||||
|
testDev devices[MAX_DEVICES];
|
||||||
|
} testDom;
|
||||||
|
|
||||||
|
#define MAX_DOMAINS 20
|
||||||
|
|
||||||
|
typedef struct _testCon {
|
||||||
|
int active;
|
||||||
|
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 virNodeInfo nodeInfo = {
|
||||||
|
"i86",
|
||||||
|
1024*1024*3, /* 3 GB */
|
||||||
|
16,
|
||||||
|
1400,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
testError(virConnectPtr con,
|
||||||
|
virDomainPtr dom,
|
||||||
|
virErrorNumber error,
|
||||||
|
const char *info)
|
||||||
|
{
|
||||||
|
const char *errmsg;
|
||||||
|
|
||||||
|
if (error == VIR_ERR_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
errmsg = __virErrorMsg(error, info);
|
||||||
|
__virRaiseError(con, dom, VIR_FROM_XEN, error, VIR_ERR_ERROR,
|
||||||
|
errmsg, info, NULL, 0, 0, errmsg, info, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testRegister:
|
||||||
|
*
|
||||||
|
* Registers the test driver
|
||||||
|
*/
|
||||||
|
void testRegister(void)
|
||||||
|
{
|
||||||
|
virRegisterDriver(&testDriver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int testOpen(virConnectPtr conn,
|
||||||
|
const char *name,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
xmlURIPtr uri;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uri = xmlParseURI(name);
|
||||||
|
if (uri == NULL) {
|
||||||
|
if (!(flags & VIR_DRV_OPEN_QUIET))
|
||||||
|
testError(conn, NULL, VIR_ERR_NO_SUPPORT, name);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uri->scheme ||
|
||||||
|
strcmp(uri->scheme, "test") ||
|
||||||
|
!uri->path ||
|
||||||
|
strcmp(uri->path, "/default")) {
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
node = calloc(1, sizeof(testNode));
|
||||||
|
if (!node) {
|
||||||
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
|
||||||
|
if (!node->connections[i].active) {
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
if (gettimeofday(&tv, NULL) < 0) {
|
||||||
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->handle = i;
|
||||||
|
node->connections[i].active = 1;
|
||||||
|
|
||||||
|
node->connections[i].numDomains = 1;
|
||||||
|
node->connections[i].domains[0].active = 1;
|
||||||
|
strcpy(node->connections[i].domains[0].name, "Domain-0");
|
||||||
|
for (j = 0 ; j < 16 ; j++) {
|
||||||
|
node->connections[i].domains[0].uuid[j] = (j * 75)%255;
|
||||||
|
}
|
||||||
|
node->connections[i].domains[0].info.maxMem = 8192 * 1024;
|
||||||
|
node->connections[i].domains[0].info.memory = 2048 * 1024;
|
||||||
|
node->connections[i].domains[0].info.state = VIR_DOMAIN_RUNNING;
|
||||||
|
node->connections[i].domains[0].info.nrVirtCpu = 2;
|
||||||
|
node->connections[i].domains[0].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "too make connections");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testClose(virConnectPtr conn)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[conn->handle];
|
||||||
|
con->active = 0;
|
||||||
|
conn->handle = -1;
|
||||||
|
memset(con, 0, sizeof(testCon));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testGetVersion(virConnectPtr conn,
|
||||||
|
unsigned long *hvVer)
|
||||||
|
{
|
||||||
|
*hvVer = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testNodeGetInfo(virConnectPtr conn,
|
||||||
|
virNodeInfoPtr info)
|
||||||
|
{
|
||||||
|
memcpy(info, &nodeInfo, sizeof(nodeInfo));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testNumOfDomains(virConnectPtr conn)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[conn->handle];
|
||||||
|
return con->numDomains;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainPtr testLookupDomainByID(virConnectPtr conn,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[conn->handle];
|
||||||
|
virDomainPtr dom;
|
||||||
|
if (!con->domains[id].active) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
|
||||||
|
if (dom == NULL) {
|
||||||
|
testError(conn, NULL, VIR_ERR_NO_MEMORY, "Allocating domain");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
dom->handle = id;
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
|
||||||
|
const unsigned char *uuid)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[conn->handle];
|
||||||
|
virDomainPtr dom = NULL;
|
||||||
|
int i, id = -1;
|
||||||
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
||||||
|
if (con->domains[i].active &&
|
||||||
|
memcmp(uuid, con->domains[i].uuid, 16) == 0) {
|
||||||
|
id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id >= 0) {
|
||||||
|
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
|
||||||
|
if (dom == NULL) {
|
||||||
|
testError(conn, NULL, VIR_ERR_NO_MEMORY, "Allocating domain");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
dom->handle = id;
|
||||||
|
}
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainPtr testLookupDomainByName(virConnectPtr conn,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[conn->handle];
|
||||||
|
virDomainPtr dom = NULL;
|
||||||
|
int i, id = -1;
|
||||||
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
||||||
|
if (con->domains[i].active &&
|
||||||
|
strcmp(name, con->domains[i].name) == 0) {
|
||||||
|
id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id >= 0) {
|
||||||
|
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
|
||||||
|
if (dom == NULL) {
|
||||||
|
testError(conn, NULL, VIR_ERR_NO_MEMORY, "Allocating domain");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
dom->handle = id;
|
||||||
|
}
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testListDomains (virConnectPtr conn,
|
||||||
|
int *ids,
|
||||||
|
int maxids)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[conn->handle];
|
||||||
|
int n, i;
|
||||||
|
|
||||||
|
for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) {
|
||||||
|
if (con->domains[i].active) {
|
||||||
|
ids[n++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testDestroyDomain (virDomainPtr domain)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[domain->conn->handle];
|
||||||
|
con->domains[domain->handle].active = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testResumeDomain (virDomainPtr domain)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[domain->conn->handle];
|
||||||
|
con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testPauseDomain (virDomainPtr domain)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[domain->conn->handle];
|
||||||
|
con->domains[domain->handle].info.state = VIR_DOMAIN_PAUSED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testGetDomainInfo (virDomainPtr domain,
|
||||||
|
virDomainInfoPtr info)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[domain->conn->handle];
|
||||||
|
struct timeval tv;
|
||||||
|
if (gettimeofday(&tv, NULL) < 0) {
|
||||||
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
con->domains[domain->handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
|
||||||
|
memcpy(info, &con->domains[domain->handle].info, sizeof(virDomainInfo));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testSetMaxMemory (virDomainPtr domain,
|
||||||
|
unsigned long memory)
|
||||||
|
{
|
||||||
|
testCon *con = &node->connections[domain->conn->handle];
|
||||||
|
con->domains[domain->handle].info.maxMem = memory;
|
||||||
|
return 0;
|
||||||
|
}
|
52
src/test.h
Normal file
52
src/test.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* test.h: A "mock" hypervisor for use by application unit tests
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* See COPYING.LIB for the License of this software
|
||||||
|
*
|
||||||
|
* Daniel Berrange <berrange@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_TEST_SIMPLE_INTERNAL_H__
|
||||||
|
#define __VIR_TEST_SIMPLE_INTERNAL_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <virterror.h>
|
||||||
|
|
||||||
|
void testRegister(void);
|
||||||
|
int testOpen(virConnectPtr conn,
|
||||||
|
const char *name,
|
||||||
|
int flags);
|
||||||
|
int testClose (virConnectPtr conn);
|
||||||
|
int testGetVersion(virConnectPtr conn,
|
||||||
|
unsigned long *hvVer);
|
||||||
|
int testNodeGetInfo(virConnectPtr conn,
|
||||||
|
virNodeInfoPtr info);
|
||||||
|
int testNumOfDomains(virConnectPtr conn);
|
||||||
|
int testListDomains(virConnectPtr conn,
|
||||||
|
int *ids,
|
||||||
|
int maxids);
|
||||||
|
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 testGetDomainInfo(virDomainPtr domain,
|
||||||
|
virDomainInfoPtr info);
|
||||||
|
int testGetDomainID(virDomainPtr domain);
|
||||||
|
const char*testGetDomainName(virDomainPtr domain);
|
||||||
|
int testSetMaxMemory(virDomainPtr domain,
|
||||||
|
unsigned long memory);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* __VIR_TEST_INTERNAL_H__ */
|
Loading…
Reference in New Issue
Block a user