mirror of
https://github.com/libvirt/libvirt.git
synced 2026-10-02 12:20:06 -05:00
XML-RPC tests
This commit is contained in:
1 parent
bfee5cd2cd
commit
0f579f785c
29 files changed
+770
-138
No files matched your search
@@ -0,0 +1,31 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
LIBVIRT = $(top_builddir)/src/.libs/libvirt.a
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_builddir)/src \
|
||||
-I@top_srcdir@/include \
|
||||
@LIBXML_CFLAGS@
|
||||
|
||||
LDADDS = \
|
||||
@STATIC_BINARIES@ \
|
||||
@LIBXML_LIBS@ \
|
||||
$(LIBVIRT)
|
||||
|
||||
EXTRA_DIST = xmlrpcserver.py
|
||||
|
||||
noinst_PROGRAMS = xmlrpctest
|
||||
|
||||
# Note: xmlrpc.[c|h] is not in libvirt yet
|
||||
xmlrpctest_SOURCES = \
|
||||
xmlrpctest.c \
|
||||
testutils.c testutils.h \
|
||||
$(top_builddir)/src/xmlrpc.c \
|
||||
$(top_builddir)/src/xmlrpc.h
|
||||
|
||||
xmlrpctest_LDFLAGS =
|
||||
xmlrpctest_LDADD = $(LDADDS)
|
||||
|
||||
$(LIBVIRT):
|
||||
-@(cd $(top_builddir)/src && $(MAKE) MAKEFLAGS+=--silent)
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
./xmlrpcserver.py >/dev/null 2>&1 &
|
||||
sleep 1
|
||||
./xmlrpctest
|
||||
pkill -f xmlrpcserver.py >/dev/null 2>&1 &
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* utils.c: basic test utils
|
||||
*
|
||||
* Copyright (C) 2005 Red Hat, Inc.
|
||||
*
|
||||
* See COPYING.LIB for the License of this software
|
||||
*
|
||||
* Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
#define GETTIMEOFDAY(T) gettimeofday(T, NULL)
|
||||
#define DIFF_MSEC(T, U) \
|
||||
((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
|
||||
((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
|
||||
|
||||
double
|
||||
virtTestCountAverage(double *items, int nitems)
|
||||
{
|
||||
long double sum = 0;
|
||||
int i;
|
||||
|
||||
for (i=1; i < nitems; i++)
|
||||
sum += items[i];
|
||||
|
||||
return (double) (sum / nitems);
|
||||
}
|
||||
|
||||
/*
|
||||
* Runs test anf count average time (if the nloops is grater than 1)
|
||||
*
|
||||
* returns: -1 = error, 0 = success
|
||||
*/
|
||||
int
|
||||
virtTestRun(const char *title, int nloops, int (*body)(void *data), void *data)
|
||||
{
|
||||
int i, ret = 0;
|
||||
double *ts = NULL;
|
||||
|
||||
if (nloops > 1 && (ts = calloc(nloops,
|
||||
sizeof(double)))==NULL)
|
||||
return -1;
|
||||
|
||||
for (i=0; i < nloops; i++) {
|
||||
struct timeval before, after;
|
||||
|
||||
if (ts)
|
||||
GETTIMEOFDAY(&before);
|
||||
if ((ret = body(data)) != 0)
|
||||
break;
|
||||
if (ts) {
|
||||
GETTIMEOFDAY(&after);
|
||||
ts[i] = DIFF_MSEC(&after, &before);
|
||||
}
|
||||
}
|
||||
if (ret == 0 && ts)
|
||||
fprintf(stderr, "%-50s ... OK [%.5f ms]\n", title,
|
||||
virtTestCountAverage(ts, nloops));
|
||||
else if (ret == 0)
|
||||
fprintf(stderr, "%-50s ... OK\n", title);
|
||||
else
|
||||
fprintf(stderr, "%-50s ... FAILED\n", title);
|
||||
|
||||
if (ts)
|
||||
free(ts);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* utils.c: test utils
|
||||
*
|
||||
* Copyright (C) 2005 Red Hat, Inc.
|
||||
*
|
||||
* See COPYING.LIB for the License of this software
|
||||
*
|
||||
* Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __VIT_TEST_UTILS_H__
|
||||
#define __VIT_TEST_UTILS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
double virtTestCountAverage (double *items,
|
||||
int nitems);
|
||||
|
||||
int virtTestRun (const char *title,
|
||||
int nloops,
|
||||
int (*body)(void *data),
|
||||
void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __VIT_TEST_UTILS_H__ */
|
||||
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# xmlrpcserver.py: simple server for XML-RPC tests
|
||||
#
|
||||
# Copyright (C) 2005 Red Hat, Inc.
|
||||
#
|
||||
# See COPYING.LIB for the License of this software
|
||||
#
|
||||
# Karel Zak <kzak@redhat.com>
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
#
|
||||
# simple client:
|
||||
#
|
||||
# >>> import xmlrpclib
|
||||
# >>> s=xmlrpclib.Server('http://localhost:8000')
|
||||
# >>> s.plus(10,10)
|
||||
# 20
|
||||
#
|
||||
|
||||
import sys
|
||||
from SimpleXMLRPCServer import SimpleXMLRPCServer
|
||||
|
||||
SERVER_PORT = 8000
|
||||
|
||||
|
||||
class VirtRPCServer(SimpleXMLRPCServer):
|
||||
def _dispatch(self, method, params):
|
||||
try:
|
||||
func = getattr(self, 'test_' + method)
|
||||
except AttributeError:
|
||||
raise Exception('method "%s" is not supported' % method)
|
||||
else:
|
||||
return func(*params)
|
||||
|
||||
def test_plus(self, x, y):
|
||||
return x + y
|
||||
|
||||
|
||||
server = VirtRPCServer(("localhost", SERVER_PORT))
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
|
||||
# vim: set tabstop=4:
|
||||
# vim: set shiftwidth=4:
|
||||
# vim: set expandtab:
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* xmlrpctest.c: simple client for XML-RPC tests
|
||||
*
|
||||
* Copyright (C) 2005 Red Hat, Inc.
|
||||
*
|
||||
* See COPYING.LIB for the License of this software
|
||||
*
|
||||
* Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xpath.h>
|
||||
|
||||
#include "libvirt.h"
|
||||
#include "xml.h"
|
||||
#include "xmlrpc.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
#define NLOOPS 100 /* default number of loops per test */
|
||||
|
||||
static char *progname;
|
||||
|
||||
|
||||
static int
|
||||
testMethodPlusINT(void *data)
|
||||
{
|
||||
int retval = 0;
|
||||
xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
|
||||
|
||||
if (xmlRpcCall(cxt, "plus", "i", "ii",
|
||||
(const char *) &retval, 10, 10) < 0)
|
||||
return -1;
|
||||
|
||||
return retval==(10+10) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
testMethodPlusDOUBLE(void *data)
|
||||
{
|
||||
double retval = 0;
|
||||
xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
|
||||
|
||||
if (xmlRpcCall(cxt, "plus", "f", "ff",
|
||||
(const char *) &retval, 10.1234, 10.1234) < 0)
|
||||
return -1;
|
||||
|
||||
return retval==(10.1234+10.1234) ? 0 : -1;
|
||||
}
|
||||
|
||||
static virBufferPtr
|
||||
marshalRequest(const char *fmt, ...)
|
||||
{
|
||||
int argc;
|
||||
xmlRpcValuePtr *argv;
|
||||
virBufferPtr buf;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
argv = xmlRpcArgvNew(fmt, ap, &argc);
|
||||
va_end(ap);
|
||||
|
||||
buf = xmlRpcMarshalRequest("test", argc, argv);
|
||||
|
||||
xmlRpcArgvFree(argc, argv);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int
|
||||
checkRequestValue(const char *xmlstr, const char *xpath, int type, void *expected)
|
||||
{
|
||||
xmlDocPtr xml = NULL;
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
xmlXPathObjectPtr obj = NULL;
|
||||
int ret = -1;
|
||||
|
||||
xml = xmlReadDoc((const xmlChar *) xmlstr, "xmlrpctest.xml", NULL,
|
||||
XML_PARSE_NOENT | XML_PARSE_NONET |
|
||||
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
||||
if (!xml)
|
||||
goto error;
|
||||
|
||||
if (!(ctxt = xmlXPathNewContext(xml)))
|
||||
goto error;
|
||||
|
||||
if (!(obj = xmlXPathEval(BAD_CAST xpath, ctxt)))
|
||||
goto error;
|
||||
|
||||
switch(type) {
|
||||
case XML_RPC_INTEGER:
|
||||
if ((obj->type != XPATH_NUMBER) ||
|
||||
((int) obj->floatval != *((int *)expected)))
|
||||
goto error;
|
||||
break;
|
||||
case XML_RPC_DOUBLE:
|
||||
if ((obj->type != XPATH_NUMBER) ||
|
||||
((double) obj->floatval != *((double *)expected)))
|
||||
goto error;
|
||||
break;
|
||||
case XML_RPC_STRING:
|
||||
if ((obj->type != XPATH_STRING) ||
|
||||
(strcmp((const char *)obj->stringval, (const char *)expected)))
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
error:
|
||||
if (obj)
|
||||
xmlXPathFreeObject(obj);
|
||||
if (ctxt)
|
||||
xmlXPathFreeContext(ctxt);
|
||||
if (xml)
|
||||
xmlFreeDoc(xml);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
testMarshalRequestINT(void *data)
|
||||
{
|
||||
int num = INT_MAX;
|
||||
int ret = 0;
|
||||
int check = data ? *((int *)data) : 0;
|
||||
virBufferPtr buf = marshalRequest("i", num);
|
||||
|
||||
if (check)
|
||||
ret = checkRequestValue(buf->content,
|
||||
"number(/methodCall/params/param[1]/value/int)",
|
||||
XML_RPC_INTEGER, (void *) &num);
|
||||
|
||||
virBufferFree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
testMarshalRequestSTRING(void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
const char *str = "This library will be really sexy.";
|
||||
int ret = 0;
|
||||
int check = data ? *((int *)data) : 0;
|
||||
virBufferPtr buf = marshalRequest("s", str);
|
||||
|
||||
if (check)
|
||||
ret = checkRequestValue(buf->content,
|
||||
"string(/methodCall/params/param[1]/value/string)",
|
||||
XML_RPC_STRING, (void *) str);
|
||||
|
||||
virBufferFree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
testMarshalRequestDOUBLE(void *data)
|
||||
{
|
||||
double num = 123456789.123;
|
||||
int ret = 0;
|
||||
int check = data ? *((int *)data) : 0;
|
||||
virBufferPtr buf = marshalRequest("f", num);
|
||||
|
||||
if (check)
|
||||
ret = checkRequestValue(buf->content,
|
||||
"number(/methodCall/params/param[1]/value/double)",
|
||||
XML_RPC_DOUBLE, (void *) &num);
|
||||
|
||||
virBufferFree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
xmlRpcContextPtr cxt = NULL;
|
||||
int check = 1;
|
||||
int ret = 0;
|
||||
const char *url = "http://localhost:8000";
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [url]\n", progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc == 2)
|
||||
url = argv[1];
|
||||
|
||||
if (!(cxt = xmlRpcContextNew(url)))
|
||||
{
|
||||
fprintf(stderr, "%s: failed create new RPC context\n", progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* client-server tests */
|
||||
if (virtTestRun("XML-RPC methodCall INT+INT",
|
||||
NLOOPS, testMethodPlusINT, (void *) cxt) != 0)
|
||||
ret = -1;
|
||||
|
||||
if (virtTestRun("XML-RPC methodCall DOUBLE+DOUBLE",
|
||||
NLOOPS, testMethodPlusDOUBLE, (void *) cxt) != 0)
|
||||
ret = -1;
|
||||
|
||||
/* regression / performance tests */
|
||||
if (virtTestRun("XML-RPC request marshalling: INT (check)",
|
||||
1, testMarshalRequestINT, (void *) &check) != 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("XML-RPC request marshalling: INT",
|
||||
NLOOPS, testMarshalRequestINT, NULL) != 0)
|
||||
ret = -1;
|
||||
|
||||
if (virtTestRun("XML-RPC request marshalling: DOUBLE (check)",
|
||||
1, testMarshalRequestDOUBLE, (void *) &check) != 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("XML-RPC request marshalling: DOUBLE",
|
||||
NLOOPS, testMarshalRequestDOUBLE, NULL) != 0)
|
||||
ret = -1;
|
||||
|
||||
if (virtTestRun("XML-RPC request marshalling: STRING (check)",
|
||||
1, testMarshalRequestSTRING, (void *) &check) != 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("XML-RPC request marshalling: STRING",
|
||||
NLOOPS, testMarshalRequestSTRING, NULL) != 0)
|
||||
ret = -1;
|
||||
|
||||
xmlRpcContextFree(cxt);
|
||||
|
||||
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* vim: set tabstop=4:
|
||||
* vim: set shiftwidth=4:
|
||||
* vim: set expandtab:
|
||||
*/
|
||||
Reference in new issue
Block a user