2006-05-09 15:35:46 +00:00
|
|
|
/*
|
|
|
|
* xmlrpctest.c: simple client for XML-RPC tests
|
|
|
|
*
|
2008-02-07 16:49:29 +00:00
|
|
|
* Copyright (C) 2005, 2008 Red Hat, Inc.
|
2006-05-09 15:35:46 +00:00
|
|
|
*
|
|
|
|
* See COPYING.LIB for the License of this software
|
|
|
|
*
|
|
|
|
* Karel Zak <kzak@redhat.com>
|
|
|
|
*
|
|
|
|
* $Id$
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-12-05 21:40:15 +00:00
|
|
|
|
2006-05-09 15:35:46 +00:00
|
|
|
#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>
|
|
|
|
|
Standardize use of header files, making internal.h primary.
* qemud/internal.h, qemud/qemud.h: Rename this file so it
doesn't conflict with src/internal.h.
* HACKING: Document how header files should be used.
* qemud/Makefile.am: Add src/ directory to includes.
* qemud/event.c, qemud/mdns.c, qemud/qemud.c, qemud/remote.c,
qemud/remote_protocol.c, qemud/remote_protocol.h,
qemud/remote_protocol.x, src/buf.c, src/libvirt.c,
src/nodeinfo.c, src/qemu_conf.c, src/qemu_driver.c,
src/stats_linux.c, src/storage_backend.c, src/storage_backend_fs.c,
src/storage_backend_iscsi.c, src/storage_backend_logical.c,
src/storage_conf.c, src/storage_driver.c, src/util.c,
src/util.h, src/virsh.c, src/virterror.c, src/xend_internal.c,
src/xml.c, tests/reconnect.c, tests/xmlrpctest.c,
tests/qparamtest.c: Standardize use of header files.
* docs/*, po/*: Rebuild docs.
2008-05-23 08:24:41 +00:00
|
|
|
#include "internal.h"
|
2007-06-26 22:33:22 +00:00
|
|
|
#include "buf.h"
|
2006-05-09 15:35:46 +00:00
|
|
|
#include "xmlrpc.h"
|
|
|
|
|
|
|
|
#include "testutils.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define NLOOPS 100 /* default number of loops per test */
|
|
|
|
|
|
|
|
static char *progname;
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2007-07-18 21:13:26 +00:00
|
|
|
testMethodPlusINT(const void *data)
|
2006-05-09 15:35:46 +00:00
|
|
|
{
|
|
|
|
int retval = 0;
|
|
|
|
xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
if (xmlRpcCall(cxt, "plus", "i", "ii",
|
2006-05-09 15:35:46 +00:00
|
|
|
(const char *) &retval, 10, 10) < 0)
|
|
|
|
return -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
return retval==(10+10) ? 0 : -1;
|
2006-05-09 15:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2007-07-18 21:13:26 +00:00
|
|
|
testMethodPlusDOUBLE(const void *data)
|
2006-05-09 15:35:46 +00:00
|
|
|
{
|
|
|
|
double retval = 0;
|
|
|
|
xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
if (xmlRpcCall(cxt, "plus", "f", "ff",
|
2006-05-09 15:35:46 +00:00
|
|
|
(const char *) &retval, 10.1234, 10.1234) < 0)
|
|
|
|
return -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
return retval==(10.1234+10.1234) ? 0 : -1;
|
2006-05-09 15:35:46 +00:00
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
static void
|
|
|
|
marshalRequest(virBufferPtr buf, const char *fmt, ...)
|
2006-05-09 15:35:46 +00:00
|
|
|
{
|
|
|
|
int argc;
|
|
|
|
xmlRpcValuePtr *argv;
|
|
|
|
va_list ap;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2006-05-09 15:35:46 +00:00
|
|
|
va_start(ap, fmt);
|
|
|
|
argv = xmlRpcArgvNew(fmt, ap, &argc);
|
|
|
|
va_end(ap);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
xmlRpcMarshalRequest("test", buf, argc, argv);
|
2006-05-09 15:35:46 +00:00
|
|
|
|
|
|
|
xmlRpcArgvFree(argc, argv);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2006-05-09 15:35:46 +00:00
|
|
|
xml = xmlReadDoc((const xmlChar *) xmlstr, "xmlrpctest.xml", NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
|
|
|
if (!xml)
|
|
|
|
goto error;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2006-05-09 15:35:46 +00:00
|
|
|
if (!(ctxt = xmlXPathNewContext(xml)))
|
|
|
|
goto error;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2006-05-09 15:35:46 +00:00
|
|
|
if (!(obj = xmlXPathEval(BAD_CAST xpath, ctxt)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
switch(type) {
|
|
|
|
case XML_RPC_INTEGER:
|
2008-02-05 19:27:37 +00:00
|
|
|
if ((obj->type != XPATH_NUMBER) ||
|
2006-05-09 15:35:46 +00:00
|
|
|
((int) obj->floatval != *((int *)expected)))
|
|
|
|
goto error;
|
|
|
|
break;
|
|
|
|
case XML_RPC_DOUBLE:
|
2008-02-05 19:27:37 +00:00
|
|
|
if ((obj->type != XPATH_NUMBER) ||
|
2006-05-09 15:35:46 +00:00
|
|
|
((double) obj->floatval != *((double *)expected)))
|
|
|
|
goto error;
|
|
|
|
break;
|
|
|
|
case XML_RPC_STRING:
|
2008-02-05 19:27:37 +00:00
|
|
|
if ((obj->type != XPATH_STRING) ||
|
2008-05-14 19:51:24 +00:00
|
|
|
(STRNEQ((const char *)obj->stringval, (const char *)expected)))
|
2006-05-09 15:35:46 +00:00
|
|
|
goto error;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
|
2008-02-05 19:27:37 +00:00
|
|
|
error:
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2008-01-29 18:23:43 +00:00
|
|
|
xmlXPathFreeContext(ctxt);
|
2006-05-09 15:35:46 +00:00
|
|
|
if (xml)
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2007-07-18 21:13:26 +00:00
|
|
|
testMarshalRequestINT(const void *data)
|
2006-05-09 15:35:46 +00:00
|
|
|
{
|
|
|
|
int num = INT_MAX;
|
|
|
|
int ret = 0;
|
|
|
|
int check = data ? *((int *)data) : 0;
|
2008-04-28 15:14:59 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
marshalRequest(&buf, "i", num);
|
|
|
|
char *content;
|
|
|
|
|
|
|
|
if (virBufferError(&buf))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
content = virBufferContentAndReset(&buf);
|
2006-05-09 15:35:46 +00:00
|
|
|
|
|
|
|
if (check)
|
2008-04-28 15:14:59 +00:00
|
|
|
ret = checkRequestValue(content,
|
2006-05-09 15:35:46 +00:00
|
|
|
"number(/methodCall/params/param[1]/value/int)",
|
|
|
|
XML_RPC_INTEGER, (void *) &num);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
free(content);
|
2006-05-09 15:35:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2007-07-18 21:13:26 +00:00
|
|
|
testMarshalRequestSTRING(const void *data ATTRIBUTE_UNUSED)
|
2006-05-09 15:35:46 +00:00
|
|
|
{
|
|
|
|
const char *str = "This library will be really sexy.";
|
|
|
|
int ret = 0;
|
|
|
|
int check = data ? *((int *)data) : 0;
|
2008-04-28 15:14:59 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
char *content;
|
|
|
|
|
|
|
|
marshalRequest(&buf, "s", str);
|
2006-05-09 15:35:46 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferError(&buf))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
content = virBufferContentAndReset(&buf);
|
2008-02-05 19:27:37 +00:00
|
|
|
if (check)
|
2008-04-28 15:14:59 +00:00
|
|
|
ret = checkRequestValue(content,
|
2006-05-09 15:35:46 +00:00
|
|
|
"string(/methodCall/params/param[1]/value/string)",
|
|
|
|
XML_RPC_STRING, (void *) str);
|
2008-04-28 15:14:59 +00:00
|
|
|
|
|
|
|
free(content);
|
2006-05-09 15:35:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2007-07-18 21:13:26 +00:00
|
|
|
testMarshalRequestDOUBLE(const void *data)
|
2006-05-09 15:35:46 +00:00
|
|
|
{
|
|
|
|
double num = 123456789.123;
|
|
|
|
int ret = 0;
|
|
|
|
int check = data ? *((int *)data) : 0;
|
2008-04-28 15:14:59 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
char *content;
|
2006-05-09 15:35:46 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
marshalRequest(&buf, "f", num);
|
|
|
|
|
|
|
|
if (virBufferError(&buf))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
content = virBufferContentAndReset(&buf);
|
2006-05-09 15:35:46 +00:00
|
|
|
if (check)
|
2008-04-28 15:14:59 +00:00
|
|
|
ret = checkRequestValue(content,
|
2006-05-09 15:35:46 +00:00
|
|
|
"number(/methodCall/params/param[1]/value/double)",
|
|
|
|
XML_RPC_DOUBLE, (void *) &num);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
free(content);
|
2006-05-09 15:35:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-05-10 12:15:49 +00:00
|
|
|
|
2006-05-09 15:35:46 +00:00
|
|
|
int
|
|
|
|
main(int argc, char **argv)
|
|
|
|
{
|
2008-04-10 16:54:54 +00:00
|
|
|
xmlRpcContextPtr cxt = NULL;
|
2006-05-09 15:35:46 +00:00
|
|
|
int check = 1;
|
2008-04-10 16:54:54 +00:00
|
|
|
int ret = 0;
|
2006-05-09 15:35:46 +00:00
|
|
|
const char *url = "http://localhost:8000";
|
|
|
|
|
2008-04-10 16:54:54 +00:00
|
|
|
progname = argv[0];
|
2006-05-09 15:35:46 +00:00
|
|
|
|
2008-04-10 16:54:54 +00:00
|
|
|
if (argc > 2)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Usage: %s [url]\n", progname);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2006-05-09 15:35:46 +00:00
|
|
|
if (argc == 2)
|
|
|
|
url = argv[1];
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* client-server tests
|
2006-05-10 12:15:49 +00:00
|
|
|
*/
|
2008-04-10 16:54:54 +00:00
|
|
|
if (!(cxt = xmlRpcContextNew(url)))
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s: failed create new RPC context\n", progname);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2006-05-09 15:35:46 +00:00
|
|
|
|
2008-02-05 19:27:37 +00:00
|
|
|
if (virtTestRun("XML-RPC methodCall INT+INT",
|
2007-07-18 21:13:26 +00:00
|
|
|
NLOOPS, testMethodPlusINT, (const void *) cxt) != 0)
|
2006-05-09 15:35:46 +00:00
|
|
|
ret = -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
if (virtTestRun("XML-RPC methodCall DOUBLE+DOUBLE",
|
2007-07-18 21:13:26 +00:00
|
|
|
NLOOPS, testMethodPlusDOUBLE, (const void *) cxt) != 0)
|
2006-05-09 15:35:46 +00:00
|
|
|
ret = -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-04-10 16:54:54 +00:00
|
|
|
xmlRpcContextFree(cxt);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* regression / performance tests
|
2006-05-10 12:15:49 +00:00
|
|
|
*/
|
2008-02-05 19:27:37 +00:00
|
|
|
if (virtTestRun("XML-RPC request marshalling: INT (check)",
|
2007-07-18 21:13:26 +00:00
|
|
|
1, testMarshalRequestINT, (const void *) &check) != 0)
|
2006-05-09 15:35:46 +00:00
|
|
|
ret = -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
if (virtTestRun("XML-RPC request marshalling: INT",
|
2006-05-09 15:35:46 +00:00
|
|
|
NLOOPS, testMarshalRequestINT, NULL) != 0)
|
|
|
|
ret = -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
|
|
|
|
if (virtTestRun("XML-RPC request marshalling: DOUBLE (check)",
|
2007-07-18 21:13:26 +00:00
|
|
|
1, testMarshalRequestDOUBLE, (const void *) &check) != 0)
|
2006-05-09 15:35:46 +00:00
|
|
|
ret = -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
if (virtTestRun("XML-RPC request marshalling: DOUBLE",
|
2006-05-09 15:35:46 +00:00
|
|
|
NLOOPS, testMarshalRequestDOUBLE, NULL) != 0)
|
|
|
|
ret = -1;
|
|
|
|
|
2008-02-05 19:27:37 +00:00
|
|
|
if (virtTestRun("XML-RPC request marshalling: STRING (check)",
|
2006-05-09 15:35:46 +00:00
|
|
|
1, testMarshalRequestSTRING, (void *) &check) != 0)
|
|
|
|
ret = -1;
|
2008-02-05 19:27:37 +00:00
|
|
|
if (virtTestRun("XML-RPC request marshalling: STRING",
|
2006-05-09 15:35:46 +00:00
|
|
|
NLOOPS, testMarshalRequestSTRING, NULL) != 0)
|
|
|
|
ret = -1;
|
2006-05-10 12:15:49 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
2006-05-09 15:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vim: set tabstop=4:
|
|
|
|
* vim: set shiftwidth=4:
|
|
|
|
* vim: set expandtab:
|
|
|
|
*/
|