1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 #include "test-utils.h"
5 #include <glib/gprintf.h>
11 static gboolean apache_running;
14 static SoupLogger *logger;
16 int debug_level, errors;
17 gboolean parallelize = TRUE;
18 gboolean expect_warning, tls_available;
19 static int http_debug_level;
22 increment_debug_level (const char *option_name, const char *value,
23 gpointer data, GError **error)
30 increment_http_debug_level (const char *option_name, const char *value,
31 gpointer data, GError **error)
37 static GOptionEntry debug_entry[] = {
38 { "debug", 'd', G_OPTION_FLAG_NO_ARG,
39 G_OPTION_ARG_CALLBACK, increment_debug_level,
40 "Enable (or increase) test-specific debugging", NULL },
41 { "parallel", 'p', G_OPTION_FLAG_REVERSE,
42 G_OPTION_ARG_NONE, ¶llelize,
43 "Toggle parallelization (default is on, unless -d or -h)", NULL },
44 { "http-debug", 'h', G_OPTION_FLAG_NO_ARG,
45 G_OPTION_ARG_CALLBACK, increment_http_debug_level,
46 "Enable (or increase) HTTP-level debugging", NULL },
62 test_log_handler (const char *log_domain, GLogLevelFlags log_level,
63 const char *message, gpointer user_data)
65 if (log_level & (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL)) {
67 expect_warning = FALSE;
68 debug_printf (2, "Got expected warning: %s\n", message);
73 g_log_default_handler (log_domain, log_level, message, user_data);
77 test_init (int argc, char **argv, GOptionEntry *entries)
82 GTlsBackend *tls_backend;
84 setlocale (LC_ALL, "");
86 name = strrchr (argv[0], '/');
89 if (!strncmp (name, "lt-", 3))
93 opts = g_option_context_new (NULL);
94 g_option_context_add_main_entries (opts, debug_entry, NULL);
96 g_option_context_add_main_entries (opts, entries, NULL);
98 if (!g_option_context_parse (opts, &argc, &argv, &error)) {
99 g_printerr ("Could not parse arguments: %s\n",
102 g_option_context_get_help (opts, TRUE, NULL));
105 g_option_context_free (opts);
107 if (debug_level > 0 || http_debug_level > 0)
108 parallelize = !parallelize;
110 /* Exit cleanly on ^C in case we're valgrinding. */
111 signal (SIGINT, quit);
113 g_log_set_default_handler (test_log_handler, NULL);
115 tls_backend = g_tls_backend_get_default ();
116 tls_available = g_tls_backend_supports_tls (tls_backend);
128 g_object_unref (logger);
130 g_main_context_unref (g_main_context_default ());
132 debug_printf (1, "\n");
134 g_print ("%s: %d error(s).%s\n",
135 g_get_prgname (), errors,
136 debug_level == 0 ? " Run with '-d' for details" : "");
138 g_print ("%s: OK\n", g_get_prgname ());
142 debug_printf (int level, const char *format, ...)
146 if (debug_level < level)
149 va_start (args, format);
150 g_vprintf (format, args);
157 apache_cmd (const char *cmd)
164 cwd = g_get_current_dir ();
165 conf = g_build_filename (cwd, "httpd.conf", NULL);
167 argv[0] = APACHE_HTTPD;
176 ok = g_spawn_sync (cwd, (char **)argv, NULL, 0, NULL, NULL,
177 NULL, NULL, &status, NULL);
190 if (!apache_cmd ("start")) {
191 g_printerr ("Could not start apache\n");
194 apache_running = TRUE;
198 apache_cleanup (void)
203 if (g_file_get_contents ("httpd.pid", &contents, NULL, NULL)) {
204 pid = strtoul (contents, NULL, 10);
209 if (!apache_cmd ("graceful-stop"))
211 apache_running = FALSE;
214 while (kill (pid, 0) == 0)
219 #endif /* HAVE_APACHE */
222 soup_test_session_new (GType type, ...)
225 const char *propname;
226 SoupSession *session;
228 va_start (args, type);
229 propname = va_arg (args, const char *);
230 session = (SoupSession *)g_object_new_valist (type, propname, args);
233 g_object_set (G_OBJECT (session),
234 SOUP_SESSION_SSL_CA_FILE, SRCDIR "/test-cert.pem",
237 if (http_debug_level && !logger) {
238 SoupLoggerLogLevel level = MIN ((SoupLoggerLogLevel)http_debug_level, SOUP_LOGGER_LOG_BODY);
240 logger = soup_logger_new (level, -1);
244 soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
250 soup_test_session_abort_unref (SoupSession *session)
252 g_object_add_weak_pointer (G_OBJECT (session), (gpointer *)&session);
254 soup_session_abort (session);
255 g_object_unref (session);
259 debug_printf (1, "leaked SoupSession!\n");
260 g_object_remove_weak_pointer (G_OBJECT (session), (gpointer *)&session);
264 static gpointer run_server_thread (gpointer user_data);
267 test_server_new (gboolean in_own_thread, gboolean ssl)
270 GMainContext *async_context;
271 const char *ssl_cert_file, *ssl_key_file;
274 async_context = in_own_thread ? g_main_context_new () : NULL;
277 ssl_cert_file = SRCDIR "/test-cert.pem";
278 ssl_key_file = SRCDIR "/test-key.pem";
280 ssl_cert_file = ssl_key_file = NULL;
282 addr = soup_address_new ("127.0.0.1", SOUP_ADDRESS_ANY_PORT);
283 soup_address_resolve_sync (addr, NULL);
285 server = soup_server_new (SOUP_SERVER_INTERFACE, addr,
286 SOUP_SERVER_ASYNC_CONTEXT, async_context,
287 SOUP_SERVER_SSL_CERT_FILE, ssl_cert_file,
288 SOUP_SERVER_SSL_KEY_FILE, ssl_key_file,
290 g_object_unref (addr);
292 g_main_context_unref (async_context);
295 g_printerr ("Unable to create server\n");
302 thread = g_thread_new ("server_thread", run_server_thread, server);
303 g_object_set_data (G_OBJECT (server), "thread", thread);
305 soup_server_run_async (server);
311 soup_test_server_new (gboolean in_own_thread)
313 return test_server_new (in_own_thread, FALSE);
317 soup_test_server_new_ssl (gboolean in_own_thread)
319 return test_server_new (in_own_thread, TRUE);
323 run_server_thread (gpointer user_data)
325 SoupServer *server = user_data;
327 soup_server_run (server);
332 idle_quit_server (gpointer server)
334 soup_server_quit (server);
339 soup_test_server_quit_unref (SoupServer *server)
343 g_object_add_weak_pointer (G_OBJECT (server),
344 (gpointer *)&server);
346 thread = g_object_get_data (G_OBJECT (server), "thread");
348 soup_add_completion (soup_server_get_async_context (server),
349 idle_quit_server, server);
350 g_thread_join (thread);
352 soup_server_quit (server);
353 g_object_unref (server);
357 debug_printf (1, "leaked SoupServer!\n");
358 g_object_remove_weak_pointer (G_OBJECT (server),
359 (gpointer *)&server);
365 GAsyncResult *result;
369 async_as_sync_callback (GObject *object,
370 GAsyncResult *result,
373 AsyncAsSyncData *data = user_data;
375 data->result = g_object_ref (result);
376 g_main_loop_quit (data->loop);
380 soup_test_request_send (SoupRequest *req,
381 GCancellable *cancellable,
384 AsyncAsSyncData data;
385 GInputStream *stream;
387 if (SOUP_IS_SESSION_SYNC (soup_request_get_session (req)))
388 return soup_request_send (req, cancellable, error);
390 data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
392 soup_request_send_async (req, cancellable, async_as_sync_callback, &data);
393 g_main_loop_run (data.loop);
395 stream = soup_request_send_finish (req, data.result, error);
397 g_main_loop_unref (data.loop);
398 g_object_unref (data.result);
404 soup_test_request_close_stream (SoupRequest *req,
405 GInputStream *stream,
406 GCancellable *cancellable,
409 AsyncAsSyncData data;
412 if (SOUP_IS_SESSION_SYNC (soup_request_get_session (req)))
413 return g_input_stream_close (stream, cancellable, error);
415 data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
417 g_input_stream_close_async (stream, G_PRIORITY_DEFAULT, cancellable,
418 async_as_sync_callback, &data);
419 g_main_loop_run (data.loop);
421 ok = g_input_stream_close_finish (stream, data.result, error);
423 g_main_loop_unref (data.loop);
424 g_object_unref (data.result);