1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2008 Red Hat, Inc.
6 #include "test-utils.h"
8 #ifdef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
9 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
15 type_error (SoupMessage *msg, GType expected, GValueArray *params, int bad_value)
17 soup_xmlrpc_set_fault (msg,
18 SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS,
19 "Bad parameter #%d: expected %s, got %s",
20 bad_value + 1, g_type_name (expected),
21 g_type_name (G_VALUE_TYPE (¶ms->values[bad_value])));
25 args_error (SoupMessage *msg, GValueArray *params, int expected)
27 soup_xmlrpc_set_fault (msg,
28 SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS,
29 "Wrong number of parameters: expected %d, got %d",
30 expected, params->n_values);
34 do_sum (SoupMessage *msg, GValueArray *params)
39 if (params->n_values != 1) {
40 args_error (msg, params, 1);
43 if (!soup_value_array_get_nth (params, 0, G_TYPE_VALUE_ARRAY, &nums)) {
44 type_error (msg, G_TYPE_VALUE_ARRAY, params, 0);
48 for (i = 0; i < nums->n_values; i++) {
49 if (!soup_value_array_get_nth (nums, i, G_TYPE_INT, &val)) {
50 type_error (msg, G_TYPE_INT, nums, i);
56 soup_xmlrpc_set_response (msg, G_TYPE_INT, sum);
61 do_countBools (SoupMessage *msg, GValueArray *params)
63 int i, trues = 0, falses = 0;
65 GHashTable *ret = soup_value_hash_new ();
68 if (params->n_values != 1) {
69 args_error (msg, params, 1);
72 if (!soup_value_array_get_nth (params, 0, G_TYPE_VALUE_ARRAY, &bools)) {
73 type_error (msg, G_TYPE_VALUE_ARRAY, params, 0);
77 for (i = 0; i < bools->n_values; i++) {
78 if (!soup_value_array_get_nth (bools, i, G_TYPE_BOOLEAN, &val)) {
79 type_error (msg, G_TYPE_BOOLEAN, params, i);
88 soup_value_hash_insert (ret, "true", G_TYPE_INT, trues);
89 soup_value_hash_insert (ret, "false", G_TYPE_INT, falses);
90 soup_xmlrpc_set_response (msg, G_TYPE_HASH_TABLE, ret);
91 g_hash_table_destroy (ret);
96 do_md5sum (SoupMessage *msg, GValueArray *params)
99 GByteArray *data, *digest;
100 gsize digest_len = 16;
102 if (params->n_values != 1) {
103 args_error (msg, params, 1);
107 if (!soup_value_array_get_nth (params, 0, SOUP_TYPE_BYTE_ARRAY, &data)) {
108 type_error (msg, SOUP_TYPE_BYTE_ARRAY, params, 0);
111 checksum = g_checksum_new (G_CHECKSUM_MD5);
112 g_checksum_update (checksum, data->data, data->len);
113 digest = g_byte_array_new ();
114 g_byte_array_set_size (digest, digest_len);
115 g_checksum_get_digest (checksum, digest->data, &digest_len);
116 g_checksum_free (checksum);
118 soup_xmlrpc_set_response (msg, SOUP_TYPE_BYTE_ARRAY, digest);
119 g_byte_array_free (digest, TRUE);
124 do_dateChange (SoupMessage *msg, GValueArray *params)
130 if (params->n_values != 2) {
131 args_error (msg, params, 2);
135 if (!soup_value_array_get_nth (params, 0, SOUP_TYPE_DATE, &date)) {
136 type_error (msg, SOUP_TYPE_DATE, params, 0);
139 if (!soup_value_array_get_nth (params, 1, G_TYPE_HASH_TABLE, &arg)) {
140 type_error (msg, G_TYPE_HASH_TABLE, params, 1);
144 if (soup_value_hash_lookup (arg, "tm_year", G_TYPE_INT, &val))
145 date->year = val + 1900;
146 if (soup_value_hash_lookup (arg, "tm_mon", G_TYPE_INT, &val))
147 date->month = val + 1;
148 if (soup_value_hash_lookup (arg, "tm_mday", G_TYPE_INT, &val))
150 if (soup_value_hash_lookup (arg, "tm_hour", G_TYPE_INT, &val))
152 if (soup_value_hash_lookup (arg, "tm_min", G_TYPE_INT, &val))
154 if (soup_value_hash_lookup (arg, "tm_sec", G_TYPE_INT, &val))
157 soup_xmlrpc_set_response (msg, SOUP_TYPE_DATE, date);
161 do_echo (SoupMessage *msg, GValueArray *params)
165 GValueArray *in, *out;
167 if (!soup_value_array_get_nth (params, 0, G_TYPE_VALUE_ARRAY, &in)) {
168 type_error (msg, G_TYPE_VALUE_ARRAY, params, 0);
172 out = g_value_array_new (in->n_values);
173 for (i = 0; i < in->n_values; i++) {
174 if (!soup_value_array_get_nth (in, i, G_TYPE_STRING, &val)) {
175 type_error (msg, G_TYPE_STRING, in, i);
178 soup_value_array_append (out, G_TYPE_STRING, val);
181 soup_xmlrpc_set_response (msg, G_TYPE_VALUE_ARRAY, out);
182 g_value_array_free (out);
186 do_ping (SoupMessage *msg, GValueArray *params)
188 if (params->n_values) {
189 args_error (msg, params, 0);
193 soup_xmlrpc_set_response (msg, G_TYPE_STRING, "pong");
197 server_callback (SoupServer *server, SoupMessage *msg,
198 const char *path, GHashTable *query,
199 SoupClientContext *context, gpointer data)
204 if (msg->method != SOUP_METHOD_POST) {
205 soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
209 soup_message_set_status (msg, SOUP_STATUS_OK);
211 if (!soup_xmlrpc_parse_method_call (msg->request_body->data,
212 msg->request_body->length,
213 &method_name, ¶ms)) {
214 soup_xmlrpc_set_fault (msg, SOUP_XMLRPC_FAULT_PARSE_ERROR_NOT_WELL_FORMED,
215 "Could not parse method call");
219 if (!strcmp (method_name, "sum"))
220 do_sum (msg, params);
221 else if (!strcmp (method_name, "countBools"))
222 do_countBools (msg, params);
223 else if (!strcmp (method_name, "md5sum"))
224 do_md5sum (msg, params);
225 else if (!strcmp (method_name, "dateChange"))
226 do_dateChange (msg, params);
227 else if (!strcmp (method_name, "echo"))
228 do_echo (msg, params);
229 else if (!strcmp (method_name, "ping"))
230 do_ping (msg, params);
232 soup_xmlrpc_set_fault (msg, SOUP_XMLRPC_FAULT_SERVER_ERROR_REQUESTED_METHOD_NOT_FOUND,
233 "Unknown method %s", method_name);
236 g_free (method_name);
237 g_value_array_free (params);
241 xmlrpc_test_exited (GPid pid, int status, gpointer data)
243 errors = WIFEXITED (status) ? WEXITSTATUS (status) : 1;
244 g_main_loop_quit (loop);
248 xmlrpc_test_print (GIOChannel *io, GIOCondition cond, gpointer data)
254 if (!(cond & G_IO_IN))
257 status = g_io_channel_read_line (io, &line, &len, NULL, NULL);
258 if (status == G_IO_STATUS_NORMAL) {
259 /* Don't print the exit status, just the debug stuff */
260 if (strncmp (line, "xmlrpc-test:", strlen ("xmlrpc-test:")) != 0)
261 g_print ("%s", line);
264 } else if (status == G_IO_STATUS_AGAIN)
271 do_xmlrpc_tests (SoupURI *uri)
277 GError *error = NULL;
278 GIOChannel *child_out;
280 argv[0] = "./xmlrpc-test";
283 argv[3] = soup_uri_to_string (uri, FALSE);
285 for (arg = 0; arg < debug_level && arg < 3; arg++)
286 argv[arg + 4] = "-d";
287 argv[arg + 4] = NULL;
289 ok = g_spawn_async_with_pipes (NULL, argv, NULL,
290 G_SPAWN_DO_NOT_REAP_CHILD,
297 g_print ("Could not run xmlrpc-test: %s\n", error->message);
302 g_child_watch_add (pid, xmlrpc_test_exited, NULL);
303 child_out = g_io_channel_unix_new (out);
304 g_io_add_watch (child_out, G_IO_IN | G_IO_ERR | G_IO_HUP,
305 xmlrpc_test_print, NULL);
306 g_io_channel_unref (child_out);
309 gboolean run_tests = TRUE;
311 static GOptionEntry no_test_entry[] = {
312 { "no-tests", 'n', G_OPTION_FLAG_REVERSE,
313 G_OPTION_ARG_NONE, &run_tests,
314 "Don't run tests, just run the test server", NULL },
319 main (int argc, char **argv)
324 test_init (argc, argv, no_test_entry);
326 server = soup_test_server_new (FALSE);
327 soup_server_add_handler (server, "/xmlrpc-server.php",
328 server_callback, NULL, NULL);
330 loop = g_main_loop_new (NULL, TRUE);
333 uri = soup_uri_new ("http://127.0.0.1/xmlrpc-server.php");
334 soup_uri_set_port (uri, soup_server_get_port (server));
335 do_xmlrpc_tests (uri);
338 g_print ("Listening on port %d\n", soup_server_get_port (server));
340 g_main_loop_run (loop);
341 g_main_loop_unref (loop);
343 soup_test_server_quit_unref (server);