More reliable means of checking if object was finalized
[platform/upstream/libsecret.git] / egg / egg-testing.c
1 /*
2  * gnome-keyring
3  *
4  * Copyright (C) 2011 Collabora Ltd.
5  * 
6  * This program is free software; you can redistribute it and/or modify 
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *  
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *  
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  *
21  * Author: Stef Walter <stefw@collabora.co.uk>
22  */
23
24 #include "config.h"
25
26 #include "egg-testing.h"
27
28 #include <glib-object.h>
29
30 #include <valgrind/valgrind.h>
31
32 #include <glib.h>
33 #include <glib/gstdio.h>
34
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38
39 static const char HEXC[] = "0123456789ABCDEF";
40
41 gchar *
42 egg_test_escape_data (const guchar *data,
43                       gsize n_data)
44 {
45         GString *result;
46         gchar c;
47         gsize i;
48         guchar j;
49
50         g_assert (data != NULL);
51
52         result = g_string_sized_new (n_data * 2 + 1);
53         for (i = 0; i < n_data; ++i) {
54                 c = data[i];
55                 if (g_ascii_isprint (c) && !strchr ("\n\r\v", c)) {
56                         g_string_append_c (result, c);
57                 } else {
58                         g_string_append (result, "\\x");
59                         j = c >> 4 & 0xf;
60                         g_string_append_c (result, HEXC[j]);
61                         j = c & 0xf;
62                         g_string_append_c (result, HEXC[j]);
63                 }
64         }
65
66         return g_string_free (result, FALSE);
67 }
68
69 void
70 egg_assertion_message_cmpmem (const char     *domain,
71                               const char     *file,
72                               int             line,
73                               const char     *func,
74                               const char     *expr,
75                               gconstpointer   arg1,
76                               gsize           n_arg1,
77                               const char     *cmp,
78                               gconstpointer   arg2,
79                               gsize           n_arg2)
80 {
81   char *a1, *a2, *s;
82   a1 = arg1 ? egg_test_escape_data (arg1, n_arg1) : g_strdup ("NULL");
83   a2 = arg2 ? egg_test_escape_data (arg2, n_arg2) : g_strdup ("NULL");
84   s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
85   g_free (a1);
86   g_free (a2);
87   g_assertion_message (domain, file, line, func, s);
88   g_free (s);
89 }
90
91 static void (*wait_stop_impl) (void);
92 static gboolean (*wait_until_impl) (int timeout);
93
94 void
95 egg_test_wait_stop (void)
96 {
97         g_assert (wait_stop_impl != NULL);
98         (wait_stop_impl) ();
99 }
100
101 gboolean
102 egg_test_wait_until (int timeout)
103 {
104         g_assert (wait_until_impl != NULL);
105         return (wait_until_impl) (timeout);
106 }
107
108 void
109 egg_test_wait_idle (void)
110 {
111         GMainContext *context;
112
113         g_assert (wait_until_impl != NULL);
114
115         context = g_main_context_get_thread_default ();
116         while (g_main_context_iteration (context, FALSE));
117 }
118
119 static GMainLoop *wait_loop = NULL;
120
121 static void
122 loop_wait_stop (void)
123 {
124         g_assert (wait_loop != NULL);
125         g_main_loop_quit (wait_loop);
126 }
127
128 static gboolean
129 on_loop_wait_timeout (gpointer data)
130 {
131         gboolean *timed_out = data;
132         *timed_out = TRUE;
133
134         g_assert (wait_loop != NULL);
135         g_main_loop_quit (wait_loop);
136
137         return TRUE; /* we remove this source later */
138 }
139
140 static gboolean
141 loop_wait_until (int timeout)
142 {
143         gboolean timed_out = FALSE;
144         guint source;
145
146         g_assert (wait_loop == NULL);
147         wait_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
148
149         source = g_timeout_add (timeout, on_loop_wait_timeout, &timed_out);
150
151         g_main_loop_run (wait_loop);
152
153         g_source_remove (source);
154         g_main_loop_unref (wait_loop);
155         wait_loop = NULL;
156         return !timed_out;
157 }
158
159 gint
160 egg_tests_run_with_loop (void)
161 {
162         gint ret;
163
164         wait_stop_impl = loop_wait_stop;
165         wait_until_impl = loop_wait_until;
166
167         ret = g_test_run ();
168
169         wait_stop_impl = NULL;
170         wait_until_impl = NULL;
171
172         while (g_main_context_iteration (NULL, FALSE));
173
174         return ret;
175 }