• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright 2001-2003, Ximian, Inc.
4  * Copyright 2015, Collabora ltd.
5  */
6 
7 #include "test-utils.h"
8 
9 static SoupSession *session;
10 static const char *default_uri = "http://127.0.0.1:47524/xmlrpc-server.php";
11 static const char *uri = NULL;
12 static gboolean server_test = FALSE;
13 
14 #ifdef HAVE_PHP_XMLRPC
15 #define SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER
16 #else
17 #define SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER				\
18 	G_STMT_START {							\
19 		if (!server_test) {					\
20 			g_test_skip ("php-xmlrpc is not available");	\
21 			return;						\
22 		}							\
23 	} G_STMT_END
24 #endif
25 
26 static gboolean
send_xmlrpc(const char * body,const char * signature,GVariant ** retval)27 send_xmlrpc (const char *body, const char *signature, GVariant **retval)
28 {
29 	SoupMessage *msg;
30 	GError *err = NULL;
31 
32 	msg = soup_message_new ("POST", uri);
33 	soup_message_set_request (msg, "text/xml", SOUP_MEMORY_COPY,
34 				  body, strlen (body));
35 	soup_session_send_message (session, msg);
36 
37 	soup_test_assert_message_status (msg, SOUP_STATUS_OK);
38 
39 	*retval = soup_xmlrpc_parse_response (msg->response_body->data,
40 					      msg->response_body->length,
41 					      signature, &err);
42 	if (!*retval) {
43 		if (err->domain == SOUP_XMLRPC_FAULT)
44 			soup_test_assert (FALSE, "FAULT: %d %s\n", err->code, err->message);
45 		else
46 			soup_test_assert (FALSE, "ERROR: %s\n", err->message);
47 		g_error_free (err);
48 		g_object_unref (msg);
49 		return FALSE;
50 	}
51 
52 	return TRUE;
53 }
54 
55 static gboolean
do_xmlrpc(const char * method,GVariant * args,const char * signature,GVariant ** retval)56 do_xmlrpc (const char *method, GVariant *args, const char *signature, GVariant **retval)
57 {
58 	gboolean ret;
59 	char *body;
60 	GError *error = NULL;
61 
62 	body = soup_xmlrpc_build_request (method, args, &error);
63 	g_assert_no_error (error);
64 	if (!body)
65 		return FALSE;
66 
67 	ret = send_xmlrpc (body, signature, retval);
68 	g_free (body);
69 
70 	return ret;
71 }
72 
73 static void
test_sum(void)74 test_sum (void)
75 {
76 	GVariantBuilder builder;
77 	int i;
78 	double val, sum, result;
79 	GVariant *retval;
80 	gboolean ok;
81 
82 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
83 
84 	debug_printf (2, "sum (array of double -> double): ");
85 
86 	g_variant_builder_init (&builder, G_VARIANT_TYPE ("ad"));
87 	for (i = sum = 0; i < 10; i++) {
88 		val = g_random_int_range (0, 400) / 4.0;
89 		debug_printf (2, "%s%.2f", i == 0 ? "[" : ", ", val);
90 		g_variant_builder_add (&builder, "d", val);
91 		sum += val;
92 	}
93 	debug_printf (2, "] -> ");
94 
95 	ok = do_xmlrpc ("sum",
96 			g_variant_new ("(@ad)", g_variant_builder_end (&builder)),
97 			"d", &retval);
98 
99 	if (!ok)
100 		return;
101 
102 	result = g_variant_get_double (retval);
103 	debug_printf (2, "%.2f\n", result);
104 	g_assert_cmpfloat (result, ==, sum);
105 
106 	g_variant_unref (retval);
107 }
108 
109 static void
test_countBools(void)110 test_countBools (void)
111 {
112 	GVariantBuilder builder;
113 	int i, trues, falses;
114 	GVariant *retval;
115 	int ret_trues, ret_falses;
116 	gboolean val, ok;
117 
118 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
119 
120 	debug_printf (2, "countBools (array of boolean -> struct of ints): ");
121 
122 	g_variant_builder_init (&builder, G_VARIANT_TYPE ("ab"));
123 	for (i = trues = falses = 0; i < 10; i++) {
124 		val = g_random_boolean ();
125 		debug_printf (2, "%s%c", i == 0 ? "[" : ", ", val ? 'T' : 'F');
126 		g_variant_builder_add (&builder, "b", val);
127 		if (val)
128 			trues++;
129 		else
130 			falses++;
131 	}
132 	debug_printf (2, "] -> ");
133 
134 	ok = do_xmlrpc ("countBools",
135 			g_variant_new ("(@ab)", g_variant_builder_end (&builder)),
136 			"a{si}", &retval);
137 	if (!ok)
138 		return;
139 
140 	g_assert_true (g_variant_lookup (retval, "true", "i", &ret_trues));
141 	g_assert_true (g_variant_lookup (retval, "false", "i", &ret_falses));
142 	g_assert_cmpint (g_variant_n_children (retval), ==, 2);
143 	g_variant_unref (retval);
144 
145 	debug_printf (2, "{ true: %d, false: %d }\n", ret_trues, ret_falses);
146 	g_assert_cmpint (trues, ==, ret_trues);
147 	g_assert_cmpint (falses, ==, ret_falses);
148 }
149 
150 static void
test_md5sum(void)151 test_md5sum (void)
152 {
153 	GByteArray *data;
154 	int i;
155 	GChecksum *checksum;
156 	guchar digest[16];
157 	gsize digest_len = sizeof (digest);
158 	GVariant *retval;
159 	gboolean ok;
160 
161 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
162 
163 	debug_printf (2, "md5sum (base64 -> base64)\n");
164 
165 	data = g_byte_array_new ();
166 	g_byte_array_set_size (data, 256);
167 	for (i = 0; i < data->len; i++)
168 		data->data[i] = (char)(g_random_int_range (0, 256));
169 
170 	checksum = g_checksum_new (G_CHECKSUM_MD5);
171 	g_checksum_update (checksum, data->data, data->len);
172 	g_checksum_get_digest (checksum, digest, &digest_len);
173 	g_checksum_free (checksum);
174 
175 	ok = do_xmlrpc ("md5sum",
176 			g_variant_new ("(@ay)",
177 				       g_variant_new_from_data (G_VARIANT_TYPE_BYTESTRING,
178 								data->data, data->len,
179 								TRUE, NULL, NULL)),
180 			"ay", &retval);
181 	g_byte_array_free (data, TRUE);
182 	if (!ok)
183 		return;
184 
185 	soup_assert_cmpmem (g_variant_get_data (retval), g_variant_get_size (retval),
186 			    digest, digest_len);
187 	g_variant_unref (retval);
188 }
189 
190 static void
test_dateChange(void)191 test_dateChange (void)
192 {
193 	GVariantDict structval;
194 	SoupDate *date, *result;
195 	char *timestamp;
196 	GVariant *retval;
197 	gboolean ok;
198 	GError *error = NULL;
199 
200 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
201 
202 	debug_printf (2, "dateChange (date, struct of ints -> time)\n");
203 
204 	date = soup_date_new (1970 + (g_random_int_range (0, 50)),
205 			      1 + g_random_int_range (0, 12),
206 			      1 + g_random_int_range (0, 28),
207 			      g_random_int_range (0, 24),
208 			      g_random_int_range (0, 60),
209 			      g_random_int_range (0, 60));
210 	if (debug_level >= 2) {
211 		char *tmp;
212 
213 		tmp = soup_date_to_string (date, SOUP_DATE_ISO8601_XMLRPC);
214 		debug_printf (2, "date: %s, {", tmp);
215 		g_free (tmp);
216 	}
217 
218 	g_variant_dict_init (&structval, NULL);
219 
220 #define MAYBE (g_random_int_range (0, 3) != 0)
221 
222 	if (MAYBE) {
223 		date->year = 1970 + (g_random_int_range (0, 50));
224 		debug_printf (2, "tm_year: %d, ", date->year - 1900);
225 		g_variant_dict_insert (&structval, "tm_year",
226 					"i", date->year - 1900);
227 	}
228 	if (MAYBE) {
229 		date->month = 1 + g_random_int_range (0, 12);
230 		debug_printf (2, "tm_mon: %d, ", date->month - 1);
231 		g_variant_dict_insert (&structval, "tm_mon",
232 					"i", date->month - 1);
233 	}
234 	if (MAYBE) {
235 		date->day = 1 + g_random_int_range (0, 28);
236 		debug_printf (2, "tm_mday: %d, ", date->day);
237 		g_variant_dict_insert (&structval, "tm_mday",
238 					"i", date->day);
239 	}
240 	if (MAYBE) {
241 		date->hour = g_random_int_range (0, 24);
242 		debug_printf (2, "tm_hour: %d, ", date->hour);
243 		g_variant_dict_insert (&structval, "tm_hour",
244 					"i", date->hour);
245 	}
246 	if (MAYBE) {
247 		date->minute = g_random_int_range (0, 60);
248 		debug_printf (2, "tm_min: %d, ", date->minute);
249 		g_variant_dict_insert (&structval, "tm_min",
250 					"i", date->minute);
251 	}
252 	if (MAYBE) {
253 		date->second = g_random_int_range (0, 60);
254 		debug_printf (2, "tm_sec: %d, ", date->second);
255 		g_variant_dict_insert (&structval, "tm_sec",
256 					"i", date->second);
257 	}
258 
259 	debug_printf (2, "} -> ");
260 
261 	ok = do_xmlrpc ("dateChange",
262 			g_variant_new ("(vv)",
263 				       soup_xmlrpc_variant_new_datetime (date),
264 				       g_variant_dict_end (&structval)),
265 			NULL, &retval);
266 	if (!ok) {
267 		soup_date_free (date);
268 		return;
269 	}
270 
271 	result = soup_xmlrpc_variant_get_datetime (retval, &error);
272 	g_assert_no_error (error);
273 
274 	if (debug_level >= 2) {
275 		timestamp = soup_date_to_string (result, SOUP_DATE_ISO8601_XMLRPC);
276 		debug_printf (2, "%s\n", timestamp);
277 		g_free (timestamp);
278 	}
279 
280 	g_assert_cmpint (date->year,   ==, result->year);
281 	g_assert_cmpint (date->month,  ==, result->month);
282 	g_assert_cmpint (date->day,    ==, result->day);
283 	g_assert_cmpint (date->hour,   ==, result->hour);
284 	g_assert_cmpint (date->minute, ==, result->minute);
285 	g_assert_cmpint (date->second, ==, result->second);
286 
287 	soup_date_free (date);
288 	soup_date_free (result);
289 	g_variant_unref (retval);
290 }
291 
292 static const char *const echo_strings[] = {
293 	"This is a test",
294 	"& so is this",
295 	"and so is <this>",
296 	"&amp; so is &lt;this&gt;",
297 	NULL
298 };
299 
300 static void
test_echo(void)301 test_echo (void)
302 {
303 	GVariant *originals;
304 	GVariant *retval;
305 	char *str;
306 
307 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
308 
309 	debug_printf (2, "echo (array of string -> array of string):\n");
310 
311 	originals = g_variant_new ("^as", echo_strings);
312 	g_variant_ref_sink (originals);
313 	str = g_variant_print (originals, TRUE);
314 	debug_printf (2, "%s -> ", str);
315 	g_free (str);
316 
317 	if (!do_xmlrpc ("echo",
318 			g_variant_new ("(@as)", originals),
319 			"as", &retval)) {
320 		g_variant_unref (originals);
321 		return;
322 	}
323 
324 	str = g_variant_print (retval, TRUE);
325 	debug_printf (2, "%s\n", str);
326 	g_free (str);
327 
328 	g_assert_true (g_variant_equal (originals, retval));
329 
330 	g_variant_unref (originals);
331 	g_variant_unref (retval);
332 }
333 
334 static void
test_ping(gconstpointer include_params)335 test_ping (gconstpointer include_params)
336 {
337 	GVariant *retval;
338 	char *request;
339 	gboolean ret;
340 	GError *error = NULL;
341 
342 	g_test_bug ("671661");
343 
344 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
345 
346 	debug_printf (2, "ping (void (%s) -> string)\n",
347 		      include_params ? "empty <params>" : "no <params>");
348 
349 	request = soup_xmlrpc_build_request ("ping", g_variant_new ("()"), &error);
350 	g_assert_no_error (error);
351 	if (!request)
352 		return;
353 
354 	if (!include_params) {
355 		char *params, *end;
356 
357 		params = strstr (request, "<params/>");
358 		if (!params) {
359 			soup_test_assert (FALSE, "ERROR: XML did not contain <params/>!");
360 			return;
361 		}
362 		end = params + strlen ("<params/>");
363 		memmove (params, end, strlen (end) + 1);
364 	}
365 
366 	ret = send_xmlrpc (request, "s", &retval);
367 	g_free (request);
368 
369 	if (!ret)
370 		return;
371 
372 	g_assert_cmpstr (g_variant_get_string (retval, NULL), ==, "pong");
373 	g_variant_unref (retval);
374 }
375 
376 static void
do_bad_xmlrpc(const char * body)377 do_bad_xmlrpc (const char *body)
378 {
379 	SoupMessage *msg;
380 	GError *err = NULL;
381 
382 	msg = soup_message_new ("POST", uri);
383 	soup_message_set_request (msg, "text/xml", SOUP_MEMORY_COPY,
384 				  body, strlen (body));
385 	soup_session_send_message (session, msg);
386 
387 	soup_test_assert_message_status (msg, SOUP_STATUS_OK);
388 
389 	if (!soup_xmlrpc_parse_response (msg->response_body->data,
390 					 msg->response_body->length,
391 					 "()", &err)) {
392 		if (err->domain == SOUP_XMLRPC_FAULT) {
393 			debug_printf (1, "FAULT: %d %s (OK!)\n",
394 				      err->code, err->message);
395 			g_error_free (err);
396 			g_object_unref (msg);
397 			return;
398 		} else
399 			soup_test_assert (FALSE, "ERROR: could not parse response: %s\n", err->message);
400 	} else
401 		soup_test_assert (FALSE, "Unexpectedly got successful response!\n");
402 
403 	g_object_unref (msg);
404 }
405 
406 static void
test_fault_malformed(void)407 test_fault_malformed (void)
408 {
409 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
410 
411 	do_bad_xmlrpc ("<methodCall/>");
412 }
413 
414 static void
test_fault_method(void)415 test_fault_method (void)
416 {
417 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
418 
419 	do_bad_xmlrpc ("<methodCall><methodName>no_such_method</methodName><params><param><value><int>1</int></value></param></params></methodCall>");
420 }
421 
422 static void
test_fault_args(void)423 test_fault_args (void)
424 {
425 	SOUP_TEST_SKIP_IF_NO_XMLRPC_SERVER;
426 
427 	do_bad_xmlrpc ("<methodCall><methodName>sum</methodName><params><param><value><int>1</int></value></param></params></methodCall>");
428 }
429 
430 #define BODY_PREFIX \
431 	"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" \
432 	"<methodCall><methodName>MyMethod</methodName>"
433 #define BODY_SUFFIX \
434 	"</methodCall>\n"
435 
436 static void
verify_serialization(GVariant * value,const char * expected_params)437 verify_serialization (GVariant    *value,
438 		      const char *expected_params)
439 {
440 	char *debug;
441 	char *body;
442 	char *params;
443 	GError *error = NULL;
444 
445 	debug = g_variant_print (value, TRUE);
446 
447 	body = soup_xmlrpc_build_request ("MyMethod", value, &error);
448 	g_assert_no_error (error);
449 	g_assert (g_str_has_prefix (body, BODY_PREFIX));
450 	g_assert (g_str_has_suffix (body, BODY_SUFFIX));
451 
452 	params = g_strndup (body + strlen (BODY_PREFIX),
453 	                    strlen (body) - strlen (BODY_PREFIX)
454 	                                  - strlen (BODY_SUFFIX));
455 
456 	if (!g_str_equal (params, expected_params))
457 		g_error ("Failed to serialize '%s':\n"
458 		         "  expected: %s\n"
459 		         "  got:      %s\n",
460 		         debug, expected_params, params);
461 
462 	g_free (params);
463 	g_free (body);
464 	g_free (debug);
465 }
466 
467 static void
verify_serialization_fail(GVariant * value)468 verify_serialization_fail (GVariant *value)
469 {
470 	char *body;
471 	GError *error = NULL;
472 
473 	body = soup_xmlrpc_build_request ("MyMethod", value, &error);
474 	g_assert (body == NULL);
475 	g_assert (error != NULL);
476 	g_clear_error (&error);
477 }
478 
479 static void
test_serializer(void)480 test_serializer (void)
481 {
482 	SoupDate *date;
483 
484 	verify_serialization (g_variant_new_parsed ("()"),
485 		"<params/>");
486 	verify_serialization (g_variant_new_parsed ("(1, 2)"),
487 		"<params>"
488 		"<param><value><int>1</int></value></param>"
489 		"<param><value><int>2</int></value></param>"
490 		"</params>");
491 	verify_serialization (g_variant_new_parsed ("((1, 2),)"),
492 		"<params><param><value><array><data>"
493 		"<value><int>1</int></value>"
494 		"<value><int>2</int></value>"
495 		"</data></array></value></param></params>");
496 	verify_serialization (g_variant_new_parsed ("({'one', 1},)"),
497 		"<params><param><value><struct>"
498 		"<member><name>one</name><value><int>1</int></value></member>"
499 		"</struct></value></param></params>");
500 	verify_serialization (g_variant_new_parsed ("([{'one', 1},{'two', 2}],)"),
501 		"<params><param><value><struct>"
502 		"<member><name>one</name><value><int>1</int></value></member>"
503 		"<member><name>two</name><value><int>2</int></value></member>"
504 		"</struct></value></param></params>");
505 	verify_serialization (g_variant_new ("(^ay)", "bytestring"),
506 		"<params><param>"
507 		"<value><base64>Ynl0ZXN0cmluZwA=</base64></value>"
508 		"</param></params>");
509 	verify_serialization (g_variant_new ("(y)", 42),
510 		"<params>"
511 		"<param><value><int>42</int></value></param>"
512 		"</params>");
513 	date = soup_date_new_from_time_t (1434161309);
514 	verify_serialization (g_variant_new ("(v)", soup_xmlrpc_variant_new_datetime (date)),
515 		"<params>"
516 		"<param><value><dateTime.iso8601>20150613T02:08:29</dateTime.iso8601></value></param>"
517 		"</params>");
518 	soup_date_free (date);
519 	verify_serialization (g_variant_new ("(s)", "<>&"),
520 		"<params>"
521 		"<param><value><string>&lt;&gt;&amp;</string></value></param>"
522 		"</params>");
523 	verify_serialization (g_variant_new ("(u)", 0),
524 		"<params>"
525 		"<param><value><i8>0</i8></value></param>"
526 		"</params>");
527 
528 	verify_serialization_fail (g_variant_new_parsed ("({1, 2},)"));
529 	verify_serialization_fail (g_variant_new ("(mi)", NULL));
530 	verify_serialization_fail (g_variant_new ("(t)", 0));
531 }
532 
533 static void
verify_deserialization(GVariant * expected_variant,const char * signature,const char * params)534 verify_deserialization (GVariant *expected_variant,
535 			const char *signature,
536 			const char *params)
537 {
538 	char *body;
539 	char *method_name;
540 	SoupXMLRPCParams *out_params = NULL;
541 	GVariant *variant;
542 	GError *error = NULL;
543 
544 	body = g_strconcat (BODY_PREFIX, params, BODY_SUFFIX, NULL);
545 	method_name = soup_xmlrpc_parse_request (body, strlen (body),
546 						 &out_params,
547 						 &error);
548 	g_assert_no_error (error);
549 	g_assert_cmpstr (method_name, ==, "MyMethod");
550 
551 	variant = soup_xmlrpc_params_parse (out_params, signature, &error);
552 	g_assert_no_error (error);
553 
554 	if (!g_variant_equal (variant, expected_variant)) {
555 		char *str1, *str2;
556 
557 		str1 = g_variant_print (expected_variant, TRUE);
558 		str2 = g_variant_print (variant, TRUE);
559 		g_error ("Failed to deserialize '%s':\n"
560 		         "  expected: %s\n"
561 		         "  got:      %s\n",
562 		         params, str1, str2);
563 		g_free (str1);
564 		g_free (str2);
565 	}
566 
567 	soup_xmlrpc_params_free (out_params);
568 	g_variant_unref (variant);
569 	g_variant_unref (expected_variant);
570 	g_free (method_name);
571 	g_free (body);
572 }
573 
574 static void
verify_deserialization_fail(const char * signature,const char * params)575 verify_deserialization_fail (const char *signature,
576 			     const char *params)
577 {
578 	char *body;
579 	char *method_name;
580 	SoupXMLRPCParams *out_params = NULL;
581 	GVariant *variant;
582 	GError *error = NULL;
583 
584 	body = g_strconcat (BODY_PREFIX, params, BODY_SUFFIX, NULL);
585 	method_name = soup_xmlrpc_parse_request (body, strlen (body),
586 						 &out_params,
587 						 &error);
588 	g_assert_no_error (error);
589 	g_assert_cmpstr (method_name, ==, "MyMethod");
590 
591 	variant = soup_xmlrpc_params_parse (out_params, signature, &error);
592 	g_assert_error (error, SOUP_XMLRPC_ERROR, SOUP_XMLRPC_ERROR_ARGUMENTS);
593 	g_assert (variant == NULL);
594 
595 	g_free (body);
596 	g_free (method_name);
597 	g_clear_error (&error);
598 	soup_xmlrpc_params_free (out_params);
599 }
600 
601 static void
test_deserializer(void)602 test_deserializer (void)
603 {
604 	char *tmp;
605 	SoupDate *date;
606 
607 	verify_deserialization (g_variant_new_parsed ("@av []"),
608 		NULL,
609 		"<params/>");
610 	verify_deserialization (g_variant_new_parsed ("()"),
611 		"()",
612 		"<params/>");
613 	verify_deserialization (g_variant_new_parsed ("(@y 1,@n 2)"),
614 		"(yn)",
615 		"<params>"
616 		"<param><value><int>1</int></value></param>"
617 		"<param><value><int>2</int></value></param>"
618 		"</params>");
619 	verify_deserialization (g_variant_new_parsed ("[<[{'one', <1>},{'two', <2>}]>]"),
620 		NULL,
621 		"<params><param><value><struct>"
622 		"<member><name>one</name><value><int>1</int></value></member>"
623 		"<member><name>two</name><value><int>2</int></value></member>"
624 		"</struct></value></param></params>");
625 	verify_deserialization (g_variant_new_parsed ("([{'one', 1},{'two', 2}],)"),
626 		"(a{si})",
627 		"<params><param><value><struct>"
628 		"<member><name>one</name><value><int>1</int></value></member>"
629 		"<member><name>two</name><value><int>2</int></value></member>"
630 		"</struct></value></param></params>");
631 	date = soup_date_new_from_time_t (1434146909);
632 	verify_deserialization (g_variant_new_parsed ("[%v]", soup_xmlrpc_variant_new_datetime (date)),
633 		NULL,
634 		"<params>"
635 		"<param><value><dateTime.iso8601>20150612T22:08:29</dateTime.iso8601></value></param>"
636 		"</params>");
637 	soup_date_free (date);
638 	verify_deserialization (g_variant_new_parsed ("[<b'bytestring'>]"),
639 		NULL,
640 		"<params>"
641 		"<param><value><base64>Ynl0ZXN0cmluZwA=</base64></value></param>"
642 		"</params>");
643 	verify_deserialization (g_variant_new_parsed ("[<1>]"),
644 		"av",
645 		"<params><param><value><int>1</int></value></param></params>");
646 	verify_deserialization (g_variant_new_parsed ("[<%s>]", "<>&"),
647 		NULL,
648 		"<params>"
649 		"<param><value><string>&lt;&gt;&amp;</string></value></param>"
650 		"</params>");
651 	verify_deserialization (g_variant_new_parsed ("(@y 255,)"),
652 		"(y)",
653 		"<params>"
654 		"<param><value><int>255</int></value></param>"
655 		"</params>");
656 
657 	tmp = g_strdup_printf ("<params>"
658 		"<param><value><int>%"G_GUINT64_FORMAT"</int></value></param>"
659 		"</params>", G_MAXUINT64);
660 	verify_deserialization (g_variant_new ("(t)", G_MAXUINT64),
661 		"(t)", tmp);
662 	g_free (tmp);
663 
664 	verify_deserialization_fail (NULL,
665 		"<params>"
666 		"<param><value><boolean>2</boolean></value></param>"
667 		"</params>");
668 	verify_deserialization_fail ("(y)",
669 		"<params>"
670 		"<param><value><int>256</int></value></param>"
671 		"</params>");
672 	verify_deserialization_fail ("(ii)",
673 		"<params>"
674 		"<param><value><int>1</int></value></param>"
675 		"</params>");
676 	verify_deserialization_fail ("(i)",
677 		"<params>"
678 		"<param><value><int>1</int></value></param>"
679 		"<param><value><int>2</int></value></param>"
680 		"</params>");
681 }
682 
683 static void
test_fault(void)684 test_fault (void)
685 {
686 	char *body;
687 	GVariant *reply;
688 	GError *error = NULL;
689 
690 	body = soup_xmlrpc_build_fault (1, "error: %s", "failed");
691 	reply = soup_xmlrpc_parse_response (body, strlen (body), NULL, &error);
692 	g_assert_error (error, SOUP_XMLRPC_FAULT, 1);
693 	g_assert_cmpstr (error->message, ==, "error: failed");
694 	g_assert (reply == NULL);
695 
696 	g_free (body);
697 	g_clear_error (&error);
698 }
699 
700 static GOptionEntry xmlrpc_entries[] = {
701         { "uri", 'U', 0, G_OPTION_ARG_STRING, &uri,
702           "Alternate URI for server", NULL },
703         { "server-test", 'S', 0, G_OPTION_ARG_NONE, &server_test,
704           "If this is being run from xmlrpc-server-test", NULL },
705         { NULL }
706 };
707 
708 int
main(int argc,char ** argv)709 main (int argc, char **argv)
710 {
711 	int ret;
712 
713 	test_init (argc, argv, xmlrpc_entries);
714 
715 	if (!uri && !server_test) {
716 		apache_init ();
717 		uri = default_uri;
718 	}
719 
720 	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
721 
722 	g_test_add_func ("/xmlrpc/variant/serializer", test_serializer);
723 	g_test_add_func ("/xmlrpc/variant/deserializer", test_deserializer);
724 	g_test_add_func ("/xmlrpc/variant/fault", test_fault);
725 	g_test_add_func ("/xmlrpc/variant/sum", test_sum);
726 	g_test_add_func ("/xmlrpc/variant/countBools", test_countBools);
727 	g_test_add_func ("/xmlrpc/variant/md5sum", test_md5sum);
728 	g_test_add_func ("/xmlrpc/variant/dateChange", test_dateChange);
729 	g_test_add_func ("/xmlrpc/variant/echo", test_echo);
730 	g_test_add_data_func ("/xmlrpc/variant/ping/empty-params", GINT_TO_POINTER (TRUE), test_ping);
731 	g_test_add_data_func ("/xmlrpc/variant/ping/no-params", GINT_TO_POINTER (FALSE), test_ping);
732 	g_test_add_func ("/xmlrpc/variant/fault/malformed", test_fault_malformed);
733 	g_test_add_func ("/xmlrpc/variant/fault/method", test_fault_method);
734 	g_test_add_func ("/xmlrpc/variant/fault/args", test_fault_args);
735 
736 	ret = g_test_run ();
737 
738 	soup_test_session_abort_unref (session);
739 
740 	test_cleanup ();
741 	return ret;
742 }
743