mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-06 19:58:34 +00:00
00654d880e
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8545 d0543943-73ff-0310-b7d9-9358b9ac24b2
952 lines
26 KiB
C
952 lines
26 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "int.h"
|
|
#include "casprintf.h"
|
|
#include "girstring.h"
|
|
|
|
#include "xmlrpc_config.h"
|
|
|
|
#include "xmlrpc-c/base.h"
|
|
#include "xmlrpc-c/server.h"
|
|
|
|
#include "test.h"
|
|
#include "xml_data.h"
|
|
#include "method_registry.h"
|
|
|
|
|
|
#define FOO_SERVERINFO ((void*) 0xF00)
|
|
#define FOO_CALLINFO ((void*) 0xFC0)
|
|
#define BAR_SERVERINFO ((void*) 0xBAF)
|
|
#define BAR_CALLINFO ((void*) 0xBAC)
|
|
#define MULTI_CALLINFO ((void*) 0xFFF)
|
|
#define DEFAULT_SERVERINFO ((void*) 0xD00)
|
|
#define DEFAULT_CALLINFO ((void*) 0xDC0)
|
|
|
|
static const char * const barHelp = "This is the help for Method test.bar.";
|
|
|
|
|
|
static xmlrpc_value *
|
|
test_foo(xmlrpc_env * const envP,
|
|
xmlrpc_value * const paramArrayP,
|
|
void * const serverInfo,
|
|
void * const callInfo) {
|
|
|
|
xmlrpc_int32 x, y;
|
|
|
|
TEST_NO_FAULT(envP);
|
|
TEST(paramArrayP != NULL);
|
|
TEST(serverInfo == FOO_SERVERINFO);
|
|
TEST(callInfo == FOO_CALLINFO || callInfo == MULTI_CALLINFO);
|
|
|
|
xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
|
|
TEST_NO_FAULT(envP);
|
|
TEST(x == 25);
|
|
TEST(y == 17);
|
|
|
|
return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y);
|
|
}
|
|
|
|
|
|
|
|
static xmlrpc_value *
|
|
test_foo_type1(xmlrpc_env * const envP,
|
|
xmlrpc_value * const paramArrayP,
|
|
void * const serverInfo) {
|
|
|
|
xmlrpc_int32 x, y;
|
|
|
|
TEST_NO_FAULT(envP);
|
|
TEST(paramArrayP != NULL);
|
|
TEST(serverInfo == FOO_SERVERINFO);
|
|
|
|
xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
|
|
TEST_NO_FAULT(envP);
|
|
TEST(x == 25);
|
|
TEST(y == 17);
|
|
|
|
return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y);
|
|
}
|
|
|
|
|
|
|
|
static xmlrpc_value *
|
|
test_bar(xmlrpc_env * const envP,
|
|
xmlrpc_value * const paramArrayP,
|
|
void * const serverInfo,
|
|
void * const callInfo) {
|
|
|
|
xmlrpc_int32 x, y;
|
|
|
|
TEST_NO_FAULT(envP);
|
|
TEST(paramArrayP != NULL);
|
|
TEST(serverInfo == BAR_SERVERINFO);
|
|
TEST(callInfo == BAR_CALLINFO || callInfo == MULTI_CALLINFO);
|
|
|
|
xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
|
|
TEST_NO_FAULT(envP);
|
|
TEST(x == 25);
|
|
TEST(y == 17);
|
|
|
|
xmlrpc_env_set_fault(envP, 123, "Test fault");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
static xmlrpc_value *
|
|
test_default(xmlrpc_env * const envP,
|
|
const char * const callInfo,
|
|
const char * const methodName,
|
|
xmlrpc_value * const paramArrayP,
|
|
void * const serverInfo) {
|
|
|
|
xmlrpc_int32 x, y;
|
|
|
|
TEST_NO_FAULT(envP);
|
|
TEST(paramArrayP != NULL);
|
|
TEST(serverInfo == DEFAULT_SERVERINFO);
|
|
|
|
TEST(streq(methodName, "test.nosuch") ||
|
|
streq(methodName, "test.nosuch.old"));
|
|
|
|
if (streq(methodName, "nosuch.method"))
|
|
TEST(callInfo == DEFAULT_CALLINFO);
|
|
else if (streq(methodName, "nosuch.method.old"))
|
|
TEST(callInfo == NULL);
|
|
|
|
xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
|
|
TEST_NO_FAULT(envP);
|
|
TEST(x == 25);
|
|
TEST(y == 17);
|
|
|
|
return xmlrpc_build_value(envP, "i", 2 * (x + y));
|
|
}
|
|
|
|
|
|
|
|
static xmlrpc_value *
|
|
test_exttype(xmlrpc_env * const envP,
|
|
xmlrpc_value * const paramArrayP ATTR_UNUSED,
|
|
void * const serverInfo ATTR_UNUSED,
|
|
void * const callInfo ATTR_UNUSED) {
|
|
|
|
return xmlrpc_build_value(envP, "(In)", (xmlrpc_int64)8);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
doRpc(xmlrpc_env * const envP,
|
|
xmlrpc_registry * const registryP,
|
|
const char * const methodName,
|
|
xmlrpc_value * const argArrayP,
|
|
void * const callInfo,
|
|
xmlrpc_value ** const resultPP) {
|
|
/*----------------------------------------------------------------------------
|
|
Do what an XML-RPC server would do -- pass an XML call to the registry
|
|
and get XML back.
|
|
|
|
Actually to our caller, we look more like an Xmlrpc-c client. We're
|
|
both the client and the server all bound together.
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_mem_block * callP;
|
|
xmlrpc_mem_block * responseP;
|
|
|
|
/* Build a call, and tell the registry to handle it. */
|
|
callP = xmlrpc_mem_block_new(envP, 0);
|
|
TEST_NO_FAULT(envP);
|
|
xmlrpc_serialize_call(envP, callP, methodName, argArrayP);
|
|
TEST_NO_FAULT(envP);
|
|
|
|
if (callInfo)
|
|
xmlrpc_registry_process_call2(
|
|
envP, registryP,
|
|
xmlrpc_mem_block_contents(callP),
|
|
xmlrpc_mem_block_size(callP),
|
|
callInfo, &responseP);
|
|
else
|
|
responseP = xmlrpc_registry_process_call(
|
|
envP, registryP, NULL,
|
|
xmlrpc_mem_block_contents(callP),
|
|
xmlrpc_mem_block_size(callP));
|
|
|
|
TEST_NO_FAULT(envP);
|
|
TEST(responseP != NULL);
|
|
|
|
/* Parse the response. */
|
|
*resultPP = xmlrpc_parse_response(envP,
|
|
xmlrpc_mem_block_contents(responseP),
|
|
xmlrpc_mem_block_size(responseP));
|
|
|
|
xmlrpc_mem_block_free(callP);
|
|
xmlrpc_mem_block_free(responseP);
|
|
}
|
|
|
|
|
|
|
|
static const char * const validSigString[] = {
|
|
"i:",
|
|
"s:d",
|
|
"i:bds86SA",
|
|
"i:,i:",
|
|
"i:dd,s:,A:A",
|
|
"i:,",
|
|
"b:i,",
|
|
"b:i,b:,",
|
|
NULL
|
|
};
|
|
|
|
static const char * const invalidSigString[] = {
|
|
"",
|
|
"i",
|
|
"q",
|
|
"i:q",
|
|
"i:ddq",
|
|
",",
|
|
",i:",
|
|
"i,",
|
|
"b:i,,b:i",
|
|
"ii:",
|
|
"ii:ii",
|
|
NULL
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
test_system_methodSignature(xmlrpc_registry * const registryP) {
|
|
/*----------------------------------------------------------------------------
|
|
Test system.methodSignature system method.
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_env env;
|
|
xmlrpc_value * argArrayP;
|
|
xmlrpc_value * resultP;
|
|
const char * type0;
|
|
const char * type1;
|
|
const char * type2;
|
|
const char * type3;
|
|
const char * type4;
|
|
const char * type5;
|
|
const char * type6;
|
|
const char * type7;
|
|
const char * nosigstring;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosuchmethod");
|
|
doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL,
|
|
&resultP);
|
|
TEST_FAULT(&env, XMLRPC_NO_SUCH_METHOD_ERROR);
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0");
|
|
|
|
doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL,
|
|
&resultP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_read_string(&env, resultP, &nosigstring);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(streq(nosigstring, "undef"));
|
|
strfree(nosigstring);
|
|
xmlrpc_DECREF(resultP);
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig0");
|
|
doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL,
|
|
&resultP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_decompose_value(&env, resultP, "((s))", &type0);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(streq(type0, "int"));
|
|
strfree(type0);
|
|
xmlrpc_DECREF(resultP);
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig2");
|
|
doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL,
|
|
&resultP);
|
|
TEST_NO_FAULT(&env);
|
|
xmlrpc_decompose_value(&env, resultP, "((ssssssss))",
|
|
&type0, &type1, &type2, &type3,
|
|
&type4, &type5, &type6, &type7);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(streq(type0, "int"));
|
|
TEST(streq(type1, "boolean"));
|
|
TEST(streq(type2, "double"));
|
|
TEST(streq(type3, "string"));
|
|
TEST(streq(type4, "dateTime.iso8601"));
|
|
TEST(streq(type5, "base64"));
|
|
TEST(streq(type6, "struct"));
|
|
TEST(streq(type7, "array"));
|
|
strfree(type0); strfree(type1); strfree(type2); strfree(type3);
|
|
strfree(type4); strfree(type5); strfree(type6); strfree(type7);
|
|
xmlrpc_DECREF(resultP);
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig3");
|
|
doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL,
|
|
&resultP);
|
|
TEST_NO_FAULT(&env);
|
|
xmlrpc_decompose_value(&env, resultP, "((s)(s))", &type0, &type1);
|
|
|
|
TEST_NO_FAULT(&env);
|
|
TEST(streq(type0, "int"));
|
|
TEST(streq(type1, "int"));
|
|
xmlrpc_DECREF(resultP);
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
test_signature(void) {
|
|
|
|
xmlrpc_env env;
|
|
xmlrpc_registry * registryP;
|
|
uint i;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running signature tests.");
|
|
|
|
registryP = xmlrpc_registry_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_add_method2(&env, registryP, "test.nosig0",
|
|
test_foo, NULL, NULL, FOO_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_add_method2(&env, registryP, "test.nosig1",
|
|
test_foo, "?", NULL, FOO_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
for (i = 0; validSigString[i]; ++i) {
|
|
const char * methodName;
|
|
casprintf(&methodName, "test.validsig%u", i);
|
|
xmlrpc_registry_add_method2(&env, registryP, methodName,
|
|
test_foo,
|
|
validSigString[i], NULL, FOO_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
strfree(methodName);
|
|
}
|
|
|
|
for (i = 0; invalidSigString[i]; ++i) {
|
|
const char * methodName;
|
|
casprintf(&methodName, "test.invalidsig%u", i);
|
|
xmlrpc_registry_add_method2(&env, registryP, methodName,
|
|
test_foo,
|
|
invalidSigString[i], NULL, FOO_SERVERINFO);
|
|
TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
|
|
strfree(methodName);
|
|
}
|
|
|
|
xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.old",
|
|
test_foo_type1, FOO_SERVERINFO,
|
|
NULL, NULL);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.old.invalid",
|
|
test_foo_type1, FOO_SERVERINFO,
|
|
invalidSigString[0], NULL);
|
|
TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
|
|
|
|
test_system_methodSignature(registryP);
|
|
|
|
xmlrpc_registry_free(registryP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
test_disable_introspection(void) {
|
|
|
|
xmlrpc_env env;
|
|
xmlrpc_registry * registryP;
|
|
xmlrpc_value * argArrayP;
|
|
xmlrpc_value * resultP;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running disable introspection tests.");
|
|
|
|
registryP = xmlrpc_registry_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_add_method2(&env, registryP, "test.nosig0",
|
|
test_foo, NULL, NULL, FOO_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_disable_introspection(registryP);
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0");
|
|
doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL,
|
|
&resultP);
|
|
TEST_FAULT(&env, XMLRPC_INTROSPECTION_DISABLED_ERROR);
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_registry_free(registryP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static const char * const expectedMethodName[] = {
|
|
/*----------------------------------------------------------------------------
|
|
The list we expect back from system.listMethods.
|
|
-----------------------------------------------------------------------------*/
|
|
"system.listMethods",
|
|
"system.methodSignature",
|
|
"system.methodHelp",
|
|
"system.multicall",
|
|
"system.shutdown",
|
|
"system.capabilities",
|
|
"test.foo",
|
|
"test.bar"
|
|
};
|
|
|
|
|
|
static void
|
|
test_system_listMethods(xmlrpc_registry * const registryP) {
|
|
/*----------------------------------------------------------------------------
|
|
Test system.listMethods
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_env env;
|
|
xmlrpc_value * resultP;
|
|
xmlrpc_value * argArrayP;
|
|
const char * methodName[8];
|
|
unsigned int size;
|
|
unsigned int i;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running system.listMethods tests.");
|
|
|
|
argArrayP = xmlrpc_array_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
doRpc(&env, registryP, "system.listMethods", argArrayP, NULL, &resultP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_ARRAY);
|
|
|
|
size = xmlrpc_array_size(&env, resultP);
|
|
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(size == ARRAY_SIZE(expectedMethodName));
|
|
|
|
xmlrpc_decompose_value(&env, resultP, "(ssssssss)",
|
|
&methodName[0], &methodName[1],
|
|
&methodName[2], &methodName[3],
|
|
&methodName[4], &methodName[5],
|
|
&methodName[6], &methodName[7]);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(methodName); ++i) {
|
|
TEST(streq(methodName[i], expectedMethodName[i]));
|
|
strfree(methodName[i]);
|
|
}
|
|
|
|
xmlrpc_DECREF(resultP);
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
test_system_methodHelp(xmlrpc_registry * const registryP) {
|
|
/*----------------------------------------------------------------------------
|
|
Test system.methodHelp
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_env env;
|
|
xmlrpc_value * resultP;
|
|
xmlrpc_value * argArrayP;
|
|
const char * helpString;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running system.methodHelp tests.");
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.foo");
|
|
TEST_NO_FAULT(&env);
|
|
|
|
doRpc(&env, registryP, "system.methodHelp", argArrayP, NULL, &resultP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_STRING);
|
|
|
|
xmlrpc_read_string(&env, resultP, &helpString);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(streq(helpString, "No help is available for this method."));
|
|
|
|
xmlrpc_DECREF(resultP);
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
|
|
argArrayP = xmlrpc_build_value(&env, "(s)", "test.bar");
|
|
TEST_NO_FAULT(&env);
|
|
|
|
doRpc(&env, registryP, "system.methodHelp", argArrayP, NULL, &resultP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_STRING);
|
|
|
|
xmlrpc_read_string(&env, resultP, &helpString);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(streq(helpString, barHelp));
|
|
|
|
xmlrpc_DECREF(resultP);
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
test_system_capabilities(xmlrpc_registry * const registryP) {
|
|
/*----------------------------------------------------------------------------
|
|
Test system.capabilities
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_env env;
|
|
xmlrpc_value * resultP;
|
|
xmlrpc_value * argArrayP;
|
|
const char * facility;
|
|
xmlrpc_int version_major, version_minor, version_point;
|
|
xmlrpc_int protocol_version;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running system.capabilities tests.");
|
|
|
|
argArrayP = xmlrpc_array_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
doRpc(&env, registryP, "system.capabilities", argArrayP, NULL, &resultP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_decompose_value(&env, resultP, "{s:s,s:i,s:i,s:i,s:i,*}",
|
|
"facility", &facility,
|
|
"version_major", &version_major,
|
|
"version_minor", &version_minor,
|
|
"version_point", &version_point,
|
|
"protocol_version", &protocol_version);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(streq(facility, "xmlrpc-c"));
|
|
TEST(protocol_version == 2);
|
|
|
|
xmlrpc_DECREF(resultP);
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
test_system_multicall(xmlrpc_registry * const registryP) {
|
|
/*----------------------------------------------------------------------------
|
|
Test system.multicall
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_env env;
|
|
xmlrpc_value * multiP;
|
|
xmlrpc_int32 foo1_result, foo2_result;
|
|
xmlrpc_int32 bar_code, nosuch_code;
|
|
char *bar_string, *nosuch_string;
|
|
xmlrpc_value * valueP;
|
|
xmlrpc_value * argArrayP;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running multicall tests.");
|
|
|
|
/* Build an argument array for our calls. */
|
|
argArrayP = xmlrpc_build_value(&env, "(ii)",
|
|
(xmlrpc_int32) 25, (xmlrpc_int32) 17);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
multiP = xmlrpc_build_value(&env,
|
|
"(("
|
|
"{s:s,s:A}" /* test.foo */
|
|
"{s:s,s:A}" /* test.bar */
|
|
"{s:s,s:A}" /* test.nosuch */
|
|
"{s:s,s:A}" /* test.foo */
|
|
"))",
|
|
"methodName", "test.foo",
|
|
"params", argArrayP,
|
|
"methodName", "test.bar",
|
|
"params", argArrayP,
|
|
"methodName", "test.nosuch",
|
|
"params", argArrayP,
|
|
"methodName", "test.foo",
|
|
"params", argArrayP);
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO,
|
|
&valueP);
|
|
TEST_NO_FAULT(&env);
|
|
xmlrpc_decompose_value(&env, valueP,
|
|
"("
|
|
"(i)" /* result of test.foo */
|
|
"{s:i,s:s,*}" /* result of test.bar */
|
|
"{s:i,s:s,*}" /* result of test.nosuch */
|
|
"(i)" /* result of test.foo #2 */
|
|
")",
|
|
&foo1_result,
|
|
"faultCode", &bar_code,
|
|
"faultString", &bar_string,
|
|
"faultCode", &nosuch_code,
|
|
"faultString", &nosuch_string,
|
|
&foo2_result);
|
|
xmlrpc_DECREF(valueP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(foo1_result == 42);
|
|
TEST(bar_code == 123);
|
|
TEST(strcmp(bar_string, "Test fault") == 0);
|
|
TEST(nosuch_code == XMLRPC_NO_SUCH_METHOD_ERROR);
|
|
TEST(foo2_result == 42);
|
|
xmlrpc_DECREF(multiP);
|
|
free(bar_string);
|
|
|
|
|
|
/* Now for some invalid multi calls */
|
|
|
|
multiP = xmlrpc_build_value(&env,
|
|
"(({s:s,s:V}{s:s,s:()}{s:s,s:V}))",
|
|
"methodName", "test.foo",
|
|
"params", argArrayP,
|
|
"methodName", "system.multicall",
|
|
"params",
|
|
"methodName", "test.foo",
|
|
"params", argArrayP);
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO,
|
|
&valueP);
|
|
TEST_FAULT(&env, XMLRPC_REQUEST_REFUSED_ERROR);
|
|
|
|
xmlrpc_DECREF(multiP);
|
|
|
|
multiP = xmlrpc_build_value(&env,
|
|
"(({s:s,s:V}d))",
|
|
"methodName", "test.foo",
|
|
"params", argArrayP,
|
|
5.0);
|
|
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO,
|
|
&valueP);
|
|
TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
|
|
|
|
xmlrpc_DECREF(multiP);
|
|
|
|
multiP = xmlrpc_build_value(&env,
|
|
"({s:s,s:V})",
|
|
"methodName", "test.foo",
|
|
"params", argArrayP);
|
|
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO,
|
|
&valueP);
|
|
TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
|
|
|
|
xmlrpc_DECREF(multiP);
|
|
|
|
multiP = xmlrpc_build_value(&env, "(({}))");
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO,
|
|
&valueP);
|
|
TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
|
|
|
|
xmlrpc_DECREF(multiP);
|
|
|
|
multiP = xmlrpc_build_value(&env, "(({s:s}))",
|
|
"methodName", "test.foo");
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO,
|
|
&valueP);
|
|
TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
|
|
|
|
xmlrpc_DECREF(multiP);
|
|
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
testCall(xmlrpc_registry * const registryP) {
|
|
|
|
xmlrpc_env env;
|
|
xmlrpc_env env2;
|
|
xmlrpc_value * argArrayP;
|
|
xmlrpc_value * valueP;
|
|
xmlrpc_int32 i;
|
|
|
|
printf(" Running call tests.");
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
/* Build an argument array for our calls. */
|
|
argArrayP = xmlrpc_build_value(&env, "(ii)",
|
|
(xmlrpc_int32) 25, (xmlrpc_int32) 17);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
/* Call test.foo and check the result. */
|
|
doRpc(&env, registryP, "test.foo", argArrayP, FOO_CALLINFO, &valueP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(valueP != NULL);
|
|
xmlrpc_decompose_value(&env, valueP, "i", &i);
|
|
xmlrpc_DECREF(valueP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(i == 42);
|
|
|
|
/* Call test.bar and check the result. */
|
|
xmlrpc_env_init(&env2);
|
|
doRpc(&env2, registryP, "test.bar", argArrayP, BAR_CALLINFO, &valueP);
|
|
TEST(env2.fault_occurred);
|
|
TEST(env2.fault_code == 123);
|
|
TEST(env2.fault_string && strcmp(env2.fault_string, "Test fault") == 0);
|
|
xmlrpc_env_clean(&env2);
|
|
|
|
/* Call a non-existant method and check the result. */
|
|
xmlrpc_env_init(&env2);
|
|
doRpc(&env2, registryP, "test.nosuch", argArrayP, FOO_CALLINFO, &valueP);
|
|
TEST(valueP == NULL);
|
|
TEST_FAULT(&env2, XMLRPC_NO_SUCH_METHOD_ERROR);
|
|
xmlrpc_env_clean(&env2);
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
testDefaultMethod(xmlrpc_registry * const registryP) {
|
|
|
|
xmlrpc_env env;
|
|
xmlrpc_value * argArrayP;
|
|
xmlrpc_value * valueP;
|
|
xmlrpc_int32 i;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running default method tests.");
|
|
|
|
/* Build an argument array for our calls. */
|
|
argArrayP = xmlrpc_build_value(&env, "(ii)",
|
|
(xmlrpc_int32) 25, (xmlrpc_int32) 17);
|
|
|
|
xmlrpc_registry_set_default_method(&env, registryP, &test_default,
|
|
DEFAULT_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
doRpc(&env, registryP, "test.nosuch", argArrayP, DEFAULT_CALLINFO,
|
|
&valueP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(valueP != NULL);
|
|
xmlrpc_decompose_value(&env, valueP, "i", &i);
|
|
xmlrpc_DECREF(valueP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(i == 84);
|
|
|
|
/* Now try it with old method interface */
|
|
|
|
doRpc(&env, registryP, "test.nosuch.old", argArrayP, NULL, &valueP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(valueP != NULL);
|
|
xmlrpc_read_int(&env, valueP, &i);
|
|
TEST_NO_FAULT(&env);
|
|
xmlrpc_DECREF(valueP);
|
|
TEST(i == 84);
|
|
|
|
/* Change the default method. */
|
|
xmlrpc_registry_set_default_method(&env, registryP, &test_default,
|
|
BAR_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
test_apache_dialect(void) {
|
|
|
|
char const expectedResp[] =
|
|
XML_PROLOGUE
|
|
"<methodResponse>\r\n"
|
|
"<params>\r\n"
|
|
"<param><value><array><data>\r\n"
|
|
"<value><ex.i8>8</ex.i8></value>\r\n"
|
|
"<value><ex.nil/></value>\r\n"
|
|
"</data></array></value></param>\r\n"
|
|
"</params>\r\n"
|
|
"</methodResponse>\r\n";
|
|
|
|
xmlrpc_env env;
|
|
xmlrpc_registry * registryP;
|
|
xmlrpc_value * argArrayP;
|
|
xmlrpc_mem_block * callP;
|
|
xmlrpc_mem_block * responseP;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf(" Running apache dialect tests.");
|
|
|
|
registryP = xmlrpc_registry_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_set_dialect(&env, registryP, xmlrpc_dialect_i8);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_set_dialect(&env, registryP, 100);
|
|
TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
|
|
|
|
xmlrpc_registry_set_dialect(&env, registryP, xmlrpc_dialect_apache);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_add_method2(&env, registryP, "test_exttype",
|
|
test_exttype, NULL, NULL, FOO_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
argArrayP = xmlrpc_array_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
callP = xmlrpc_mem_block_new(&env, 0);
|
|
TEST_NO_FAULT(&env);
|
|
xmlrpc_serialize_call(&env, callP, "test_exttype", argArrayP);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
xmlrpc_registry_process_call2(
|
|
&env, registryP,
|
|
xmlrpc_mem_block_contents(callP),
|
|
xmlrpc_mem_block_size(callP),
|
|
NULL, &responseP);
|
|
|
|
TEST_NO_FAULT(&env);
|
|
|
|
TEST(XMLRPC_MEMBLOCK_SIZE(char, responseP) == strlen(expectedResp));
|
|
TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, responseP),
|
|
expectedResp,
|
|
XMLRPC_MEMBLOCK_SIZE(char, responseP)));
|
|
|
|
xmlrpc_DECREF(argArrayP);
|
|
xmlrpc_mem_block_free(callP);
|
|
xmlrpc_mem_block_free(responseP);
|
|
xmlrpc_registry_free(registryP);
|
|
|
|
xmlrpc_env_clean(&env);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
void
|
|
test_method_registry(void) {
|
|
|
|
xmlrpc_env env, env2;
|
|
xmlrpc_value * valueP;
|
|
xmlrpc_registry * registryP;
|
|
xmlrpc_mem_block * responseP;
|
|
|
|
xmlrpc_env_init(&env);
|
|
|
|
printf("Running method registry tests.");
|
|
|
|
/* Create a new registry. */
|
|
registryP = xmlrpc_registry_new(&env);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(registryP != NULL);
|
|
|
|
/* Add some test methods. */
|
|
xmlrpc_registry_add_method(&env, registryP, NULL, "test.foo",
|
|
test_foo_type1, FOO_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
xmlrpc_registry_add_method2(&env, registryP, "test.bar",
|
|
test_bar, NULL, barHelp, BAR_SERVERINFO);
|
|
TEST_NO_FAULT(&env);
|
|
|
|
printf("\n");
|
|
testCall(registryP);
|
|
|
|
test_system_multicall(registryP);
|
|
|
|
xmlrpc_env_init(&env2);
|
|
xmlrpc_registry_process_call2(&env, registryP,
|
|
expat_error_data,
|
|
strlen(expat_error_data),
|
|
NULL,
|
|
&responseP);
|
|
TEST_NO_FAULT(&env);
|
|
TEST(responseP != NULL);
|
|
valueP = xmlrpc_parse_response(&env2, xmlrpc_mem_block_contents(responseP),
|
|
xmlrpc_mem_block_size(responseP));
|
|
TEST(valueP == NULL);
|
|
TEST_FAULT(&env2, XMLRPC_PARSE_ERROR);
|
|
xmlrpc_mem_block_free(responseP);
|
|
xmlrpc_env_clean(&env2);
|
|
|
|
printf("\n");
|
|
|
|
testDefaultMethod(registryP);
|
|
|
|
test_system_listMethods(registryP);
|
|
|
|
test_system_methodHelp(registryP);
|
|
|
|
test_system_capabilities(registryP);
|
|
|
|
test_signature();
|
|
|
|
test_disable_introspection();
|
|
|
|
test_apache_dialect();
|
|
|
|
/* Test cleanup code (w/memprof). */
|
|
xmlrpc_registry_free(registryP);
|
|
|
|
printf("\n");
|
|
|
|
xmlrpc_env_clean(&env);
|
|
}
|