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 expect_warning, tls_available;
18 static int http_debug_level;
21 increment_debug_level (const char *option_name, const char *value,
22 gpointer data, GError **error)
29 increment_http_debug_level (const char *option_name, const char *value,
30 gpointer data, GError **error)
36 static GOptionEntry debug_entry[] = {
37 { "debug", 'd', G_OPTION_FLAG_NO_ARG,
38 G_OPTION_ARG_CALLBACK, increment_debug_level,
39 "Enable (or increase) test-specific debugging", NULL },
40 { "http-debug", 'h', G_OPTION_FLAG_NO_ARG,
41 G_OPTION_ARG_CALLBACK, increment_http_debug_level,
42 "Enable (or increase) HTTP-level debugging", NULL },
58 test_log_handler (const char *log_domain, GLogLevelFlags log_level,
59 const char *message, gpointer user_data)
61 if (log_level & (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL)) {
63 expect_warning = FALSE;
64 debug_printf (2, "Got expected warning: %s\n", message);
69 g_log_default_handler (log_domain, log_level, message, user_data);
73 test_init (int argc, char **argv, GOptionEntry *entries)
78 GTlsBackend *tls_backend;
80 setlocale (LC_ALL, "");
83 name = strrchr (argv[0], '/');
86 if (!strncmp (name, "lt-", 3))
90 opts = g_option_context_new (NULL);
91 g_option_context_add_main_entries (opts, debug_entry, NULL);
93 g_option_context_add_main_entries (opts, entries, NULL);
95 if (!g_option_context_parse (opts, &argc, &argv, &error)) {
96 g_printerr ("Could not parse arguments: %s\n",
99 g_option_context_get_help (opts, TRUE, NULL));
102 g_option_context_free (opts);
104 /* Exit cleanly on ^C in case we're valgrinding. */
105 signal (SIGINT, quit);
107 g_log_set_default_handler (test_log_handler, NULL);
109 tls_backend = g_tls_backend_get_default ();
110 tls_available = g_tls_backend_supports_tls (tls_backend);
122 g_object_unref (logger);
124 g_main_context_unref (g_main_context_default ());
126 debug_printf (1, "\n");
128 g_print ("%s: %d error(s).%s\n",
129 g_get_prgname (), errors,
130 debug_level == 0 ? " Run with '-d' for details" : "");
132 g_print ("%s: OK\n", g_get_prgname ());
136 debug_printf (int level, const char *format, ...)
140 if (debug_level < level)
143 va_start (args, format);
144 g_vprintf (format, args);
151 apache_cmd (const char *cmd)
158 cwd = g_get_current_dir ();
159 conf = g_build_filename (cwd, "httpd.conf", NULL);
161 argv[0] = APACHE_HTTPD;
170 ok = g_spawn_sync (cwd, (char **)argv, NULL, 0, NULL, NULL,
171 NULL, NULL, &status, NULL);
184 if (!apache_cmd ("start")) {
185 g_printerr ("Could not start apache\n");
188 apache_running = TRUE;
192 apache_cleanup (void)
197 if (g_file_get_contents ("httpd.pid", &contents, NULL, NULL)) {
198 pid = strtoul (contents, NULL, 10);
203 if (!apache_cmd ("graceful-stop"))
205 apache_running = FALSE;
208 while (kill (pid, 0) == 0)
213 #endif /* HAVE_APACHE */
216 soup_test_session_new (GType type, ...)
219 const char *propname;
220 SoupSession *session;
222 va_start (args, type);
223 propname = va_arg (args, const char *);
224 session = (SoupSession *)g_object_new_valist (type, propname, args);
227 g_object_set (G_OBJECT (session),
228 SOUP_SESSION_SSL_CA_FILE, SRCDIR "/test-cert.pem",
231 if (http_debug_level && !logger) {
232 SoupLoggerLogLevel level = MIN ((SoupLoggerLogLevel)http_debug_level, SOUP_LOGGER_LOG_BODY);
234 logger = soup_logger_new (level, -1);
238 soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
244 soup_test_session_abort_unref (SoupSession *session)
246 g_object_add_weak_pointer (G_OBJECT (session), (gpointer *)&session);
248 soup_session_abort (session);
249 g_object_unref (session);
253 debug_printf (1, "leaked SoupSession!\n");
254 g_object_remove_weak_pointer (G_OBJECT (session), (gpointer *)&session);
258 static gpointer run_server_thread (gpointer user_data);
261 test_server_new (gboolean in_own_thread, gboolean ssl)
264 GMainContext *async_context;
265 const char *ssl_cert_file, *ssl_key_file;
268 async_context = in_own_thread ? g_main_context_new () : NULL;
271 ssl_cert_file = SRCDIR "/test-cert.pem";
272 ssl_key_file = SRCDIR "/test-key.pem";
274 ssl_cert_file = ssl_key_file = NULL;
276 addr = soup_address_new ("127.0.0.1", SOUP_ADDRESS_ANY_PORT);
277 soup_address_resolve_sync (addr, NULL);
279 server = soup_server_new (SOUP_SERVER_INTERFACE, addr,
280 SOUP_SERVER_ASYNC_CONTEXT, async_context,
281 SOUP_SERVER_SSL_CERT_FILE, ssl_cert_file,
282 SOUP_SERVER_SSL_KEY_FILE, ssl_key_file,
284 g_object_unref (addr);
286 g_main_context_unref (async_context);
289 g_printerr ("Unable to create server\n");
296 thread = g_thread_new ("server_thread", run_server_thread, server);
297 g_object_set_data (G_OBJECT (server), "thread", thread);
299 soup_server_run_async (server);
305 soup_test_server_new (gboolean in_own_thread)
307 return test_server_new (in_own_thread, FALSE);
311 soup_test_server_new_ssl (gboolean in_own_thread)
313 return test_server_new (in_own_thread, TRUE);
317 run_server_thread (gpointer user_data)
319 SoupServer *server = user_data;
321 soup_server_run (server);
326 idle_quit_server (gpointer server)
328 soup_server_quit (server);
333 soup_test_server_quit_unref (SoupServer *server)
337 g_object_add_weak_pointer (G_OBJECT (server),
338 (gpointer *)&server);
340 thread = g_object_get_data (G_OBJECT (server), "thread");
342 soup_add_completion (soup_server_get_async_context (server),
343 idle_quit_server, server);
344 g_thread_join (thread);
346 soup_server_quit (server);
347 g_object_unref (server);
351 debug_printf (1, "leaked SoupServer!\n");
352 g_object_remove_weak_pointer (G_OBJECT (server),
353 (gpointer *)&server);
359 GAsyncResult *result;
363 async_as_sync_callback (GObject *object,
364 GAsyncResult *result,
367 AsyncAsSyncData *data = user_data;
369 data->result = g_object_ref (result);
370 g_main_loop_quit (data->loop);
374 soup_test_request_send_async_as_sync (SoupRequest *req,
375 GCancellable *cancellable,
378 AsyncAsSyncData data;
379 GInputStream *stream;
381 data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
383 soup_request_send_async (req, cancellable, async_as_sync_callback, &data);
384 g_main_loop_run (data.loop);
386 stream = soup_request_send_finish (req, data.result, error);
388 g_main_loop_unref (data.loop);
389 g_object_unref (data.result);
395 soup_test_stream_close_async_as_sync (GInputStream *stream,
396 GCancellable *cancellable,
399 AsyncAsSyncData data;
402 data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
404 g_input_stream_close_async (stream, G_PRIORITY_DEFAULT, cancellable,
405 async_as_sync_callback, &data);
406 g_main_loop_run (data.loop);
408 ok = g_input_stream_close_finish (stream, data.result, error);
410 g_main_loop_unref (data.loop);
411 g_object_unref (data.result);