7 #include "xmlrpc_config.h"
9 #include "xmlrpc-c/base.h"
10 #include "xmlrpc-c/server.h"
14 #include "method_registry.h"
17 #define FOO_USER_DATA ((void*) 0xF00)
18 #define BAR_USER_DATA ((void*) 0xBAF)
23 test_foo(xmlrpc_env * const envP,
24 xmlrpc_value * const paramArrayP,
25 void * const userData) {
30 TEST(paramArrayP != NULL);
31 TEST(userData == FOO_USER_DATA);
33 xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
38 return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y);
44 test_bar(xmlrpc_env * const envP,
45 xmlrpc_value * const paramArrayP,
46 void * const userData) {
51 TEST(paramArrayP != NULL);
52 TEST(userData == BAR_USER_DATA);
54 xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
59 xmlrpc_env_set_fault(envP, 123, "Test fault");
67 test_default(xmlrpc_env * const envP,
68 const char * const host ATTR_UNUSED,
69 const char * const methodName ATTR_UNUSED,
70 xmlrpc_value * const paramArrayP,
71 void * const userData) {
76 TEST(paramArrayP != NULL);
77 TEST(userData == FOO_USER_DATA);
79 xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
84 return xmlrpc_build_value(envP, "i", 2 * (x + y));
90 doRpc(xmlrpc_env * const envP,
91 xmlrpc_registry * const registryP,
92 const char * const methodName,
93 xmlrpc_value * const argArrayP,
94 xmlrpc_value ** const resultPP) {
95 /*----------------------------------------------------------------------------
96 Do what an XML-RPC server would do -- pass an XML call to the registry
99 Actually to our caller, we look more like an Xmlrpc-c client. We're
100 both the client and the server all bound together.
101 -----------------------------------------------------------------------------*/
102 xmlrpc_mem_block * callP;
103 xmlrpc_mem_block * responseP;
105 /* Build a call, and tell the registry to handle it. */
106 callP = xmlrpc_mem_block_new(envP, 0);
108 xmlrpc_serialize_call(envP, callP, methodName, argArrayP);
110 responseP = xmlrpc_registry_process_call(envP, registryP, NULL,
111 xmlrpc_mem_block_contents(callP),
112 xmlrpc_mem_block_size(callP));
114 TEST(responseP != NULL);
116 /* Parse the response. */
117 *resultPP = xmlrpc_parse_response(envP,
118 xmlrpc_mem_block_contents(responseP),
119 xmlrpc_mem_block_size(responseP));
121 xmlrpc_mem_block_free(callP);
122 xmlrpc_mem_block_free(responseP);
127 static const char * const validSigString[] = {
139 static const char * const invalidSigString[] = {
156 test_signature_method(xmlrpc_registry * const registryP) {
157 /*----------------------------------------------------------------------------
158 Test system.methodSignature system method.
159 -----------------------------------------------------------------------------*/
161 xmlrpc_value * argArrayP;
162 xmlrpc_value * resultP;
171 const char * nosigstring;
173 xmlrpc_env_init(&env);
175 argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosuchmethod");
176 doRpc(&env, registryP, "system.methodSignature", argArrayP, &resultP);
177 TEST_FAULT(&env, XMLRPC_NO_SUCH_METHOD_ERROR);
178 xmlrpc_DECREF(argArrayP);
180 argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0");
182 doRpc(&env, registryP, "system.methodSignature", argArrayP, &resultP);
185 xmlrpc_read_string(&env, resultP, &nosigstring);
188 TEST(streq(nosigstring, "undef"));
189 strfree(nosigstring);
190 xmlrpc_DECREF(resultP);
191 xmlrpc_DECREF(argArrayP);
193 argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig0");
194 doRpc(&env, registryP, "system.methodSignature", argArrayP, &resultP);
197 xmlrpc_decompose_value(&env, resultP, "((s))", &type0);
199 TEST(streq(type0, "int"));
201 xmlrpc_DECREF(resultP);
202 xmlrpc_DECREF(argArrayP);
204 argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig2");
205 doRpc(&env, registryP, "system.methodSignature", argArrayP, &resultP);
207 xmlrpc_decompose_value(&env, resultP, "((ssssssss))",
208 &type0, &type1, &type2, &type3,
209 &type4, &type5, &type6, &type7);
211 TEST(streq(type0, "int"));
212 TEST(streq(type1, "boolean"));
213 TEST(streq(type2, "double"));
214 TEST(streq(type3, "string"));
215 TEST(streq(type4, "dateTime.iso8601"));
216 TEST(streq(type5, "base64"));
217 TEST(streq(type6, "struct"));
218 TEST(streq(type7, "array"));
219 strfree(type0); strfree(type1); strfree(type2); strfree(type3);
220 strfree(type4); strfree(type5); strfree(type6); strfree(type7);
221 xmlrpc_DECREF(resultP);
222 xmlrpc_DECREF(argArrayP);
224 argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig3");
225 doRpc(&env, registryP, "system.methodSignature", argArrayP, &resultP);
227 xmlrpc_decompose_value(&env, resultP, "((s)(s))", &type0, &type1);
230 TEST(streq(type0, "int"));
231 TEST(streq(type1, "int"));
232 xmlrpc_DECREF(resultP);
233 xmlrpc_DECREF(argArrayP);
235 xmlrpc_env_clean(&env);
241 test_signature(void) {
244 xmlrpc_registry * registryP;
247 xmlrpc_env_init(&env);
249 printf(" Running signature tests.");
251 registryP = xmlrpc_registry_new(&env);
254 xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.nosig0",
255 test_foo, FOO_USER_DATA,
259 xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.nosig1",
260 test_foo, FOO_USER_DATA,
264 for (i = 0; validSigString[i]; ++i) {
265 const char * methodName;
266 casprintf(&methodName, "test.validsig%u", i);
267 xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, methodName,
268 test_foo, FOO_USER_DATA,
269 validSigString[i], NULL);
274 for (i = 0; invalidSigString[i]; ++i) {
275 const char * methodName;
276 casprintf(&methodName, "test.invalidsig%u", i);
277 xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, methodName,
278 test_foo, FOO_USER_DATA,
279 invalidSigString[i], NULL);
280 TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
284 test_signature_method(registryP);
286 xmlrpc_registry_free(registryP);
288 xmlrpc_env_clean(&env);
296 test_system_multicall(xmlrpc_registry * const registryP) {
297 /*----------------------------------------------------------------------------
298 Test system.multicall
299 -----------------------------------------------------------------------------*/
301 xmlrpc_value * multiP;
302 xmlrpc_int32 foo1_result, foo2_result;
303 xmlrpc_int32 bar_code, nosuch_code, multi_code, bogus1_code, bogus2_code;
304 char *bar_string, *nosuch_string, *multi_string;
305 char *bogus1_string, *bogus2_string;
306 xmlrpc_value * valueP;
307 xmlrpc_value * argArrayP;
309 xmlrpc_env_init(&env);
311 printf(" Running multicall tests.");
313 /* Build an argument array for our calls. */
314 argArrayP = xmlrpc_build_value(&env, "(ii)",
315 (xmlrpc_int32) 25, (xmlrpc_int32) 17);
318 multiP = xmlrpc_build_value(&env,
319 "(({s:s,s:V}{s:s,s:V}{s:s,s:V}"
320 "{s:s,s:()}s{}{s:s,s:V}))",
321 "methodName", "test.foo",
323 "methodName", "test.bar",
325 "methodName", "test.nosuch",
327 "methodName", "system.multicall",
330 "methodName", "test.foo",
331 "params", argArrayP);
333 doRpc(&env, registryP, "system.multicall", multiP, &valueP);
335 xmlrpc_decompose_value(&env, valueP,
336 "((i){s:i,s:s,*}{s:i,s:s,*}"
337 "{s:i,s:s,*}{s:i,s:s,*}{s:i,s:s,*}(i))",
339 "faultCode", &bar_code,
340 "faultString", &bar_string,
341 "faultCode", &nosuch_code,
342 "faultString", &nosuch_string,
343 "faultCode", &multi_code,
344 "faultString", &multi_string,
345 "faultCode", &bogus1_code,
346 "faultString", &bogus1_string,
347 "faultCode", &bogus2_code,
348 "faultString", &bogus2_string,
350 xmlrpc_DECREF(valueP);
352 TEST(foo1_result == 42);
353 TEST(bar_code == 123);
354 TEST(strcmp(bar_string, "Test fault") == 0);
355 TEST(nosuch_code == XMLRPC_NO_SUCH_METHOD_ERROR);
356 TEST(multi_code == XMLRPC_REQUEST_REFUSED_ERROR);
357 TEST(foo2_result == 42);
358 xmlrpc_DECREF(multiP);
365 xmlrpc_DECREF(argArrayP);
367 xmlrpc_env_clean(&env);
375 testCall(xmlrpc_registry * const registryP) {
379 xmlrpc_value * argArrayP;
380 xmlrpc_value * valueP;
383 printf(" Running call tests.");
385 xmlrpc_env_init(&env);
387 /* Build an argument array for our calls. */
388 argArrayP = xmlrpc_build_value(&env, "(ii)",
389 (xmlrpc_int32) 25, (xmlrpc_int32) 17);
392 /* Call test.foo and check the result. */
393 doRpc(&env, registryP, "test.foo", argArrayP, &valueP);
395 TEST(valueP != NULL);
396 xmlrpc_decompose_value(&env, valueP, "i", &i);
397 xmlrpc_DECREF(valueP);
401 /* Call test.bar and check the result. */
402 xmlrpc_env_init(&env2);
403 doRpc(&env2, registryP, "test.bar", argArrayP, &valueP);
404 TEST(env2.fault_occurred);
405 TEST(env2.fault_code == 123);
406 TEST(env2.fault_string && strcmp(env2.fault_string, "Test fault") == 0);
407 xmlrpc_env_clean(&env2);
409 /* Call a non-existant method and check the result. */
410 xmlrpc_env_init(&env2);
411 doRpc(&env2, registryP, "test.nosuch", argArrayP, &valueP);
412 TEST(valueP == NULL);
413 TEST_FAULT(&env2, XMLRPC_NO_SUCH_METHOD_ERROR);
414 xmlrpc_env_clean(&env2);
416 xmlrpc_DECREF(argArrayP);
418 xmlrpc_env_clean(&env);
426 testDefaultMethod(xmlrpc_registry * const registryP) {
429 xmlrpc_value * argArrayP;
430 xmlrpc_value * valueP;
433 xmlrpc_env_init(&env);
435 printf(" Running default method tests.");
437 /* Build an argument array for our calls. */
438 argArrayP = xmlrpc_build_value(&env, "(ii)",
439 (xmlrpc_int32) 25, (xmlrpc_int32) 17);
441 xmlrpc_registry_set_default_method(&env, registryP, &test_default,
444 doRpc(&env, registryP, "test.nosuch", argArrayP, &valueP);
446 TEST(valueP != NULL);
447 xmlrpc_decompose_value(&env, valueP, "i", &i);
448 xmlrpc_DECREF(valueP);
452 /* Change the default method. */
453 xmlrpc_registry_set_default_method(&env, registryP, &test_default,
457 xmlrpc_DECREF(argArrayP);
459 xmlrpc_env_clean(&env);
467 test_method_registry(void) {
469 xmlrpc_env env, env2;
470 xmlrpc_value * valueP;
471 xmlrpc_registry *registryP;
472 xmlrpc_mem_block *response;
474 xmlrpc_env_init(&env);
476 printf("Running method registry tests.");
478 /* Create a new registry. */
479 registryP = xmlrpc_registry_new(&env);
481 TEST(registryP != NULL);
483 /* Add some test methods. */
484 xmlrpc_registry_add_method(&env, registryP, NULL, "test.foo",
485 test_foo, FOO_USER_DATA);
487 xmlrpc_registry_add_method(&env, registryP, NULL, "test.bar",
488 test_bar, BAR_USER_DATA);
494 test_system_multicall(registryP);
496 /* PASS bogus XML data and make sure our parser pukes gracefully.
497 ** (Because of the way the code is laid out, and the presence of other
498 ** test suites, this lets us skip tests for invalid XML-RPC data.) */
499 xmlrpc_env_init(&env2);
500 response = xmlrpc_registry_process_call(&env, registryP, NULL,
502 strlen(expat_error_data));
504 TEST(response != NULL);
505 valueP = xmlrpc_parse_response(&env2, xmlrpc_mem_block_contents(response),
506 xmlrpc_mem_block_size(response));
507 TEST(valueP == NULL);
508 TEST_FAULT(&env2, XMLRPC_PARSE_ERROR);
509 xmlrpc_mem_block_free(response);
510 xmlrpc_env_clean(&env2);
513 testDefaultMethod(registryP);
517 /* Test cleanup code (w/memprof). */
518 xmlrpc_registry_free(registryP);
522 xmlrpc_env_clean(&env);