nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* This file is part of GLib |
2 | * |
||
3 | * Copyright (C) 2010 Sven Herzberg |
||
4 | * |
||
5 | * This work is provided "as is"; redistribution and modification |
||
6 | * in whole or in part, in any medium, physical or electronic is |
||
7 | * permitted without restriction. |
||
8 | * |
||
9 | * This work is distributed in the hope that it will be useful, |
||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
12 | * |
||
13 | * In no event shall the authors or contributors be liable for any |
||
14 | * direct, indirect, incidental, special, exemplary, or consequential |
||
15 | * damages (including, but not limited to, procurement of substitute |
||
16 | * goods or services; loss of use, data, or profits; or business |
||
17 | * interruption) however caused and on any theory of liability, whether |
||
18 | * in contract, strict liability, or tort (including negligence or |
||
19 | * otherwise) arising in any way out of the use of this software, even |
||
20 | * if advised of the possibility of such damage. |
||
21 | */ |
||
22 | |||
23 | #include <errno.h> /* errno */ |
||
24 | #include <glib.h> |
||
25 | #ifdef G_OS_UNIX |
||
26 | #include <unistd.h> /* pipe() */ |
||
27 | #endif |
||
28 | #ifdef G_OS_WIN32 |
||
29 | #include <io.h> |
||
30 | #include <fcntl.h> |
||
31 | #define pipe(fds) _pipe(fds, 4096, _O_BINARY) |
||
32 | #endif |
||
33 | |||
34 | static const char *argv0; |
||
35 | |||
36 | static void |
||
37 | debug (void) |
||
38 | { |
||
39 | if (g_test_subprocess ()) |
||
40 | g_debug ("this is a regular g_debug() from the test suite"); |
||
41 | } |
||
42 | |||
43 | static void |
||
44 | info (void) |
||
45 | { |
||
46 | if (g_test_subprocess ()) |
||
47 | g_info ("this is a regular g_info from the test suite"); |
||
48 | } |
||
49 | |||
50 | static void |
||
51 | message (void) |
||
52 | { |
||
53 | if (g_test_subprocess ()) |
||
54 | g_message ("this is a regular g_message() from the test suite"); |
||
55 | } |
||
56 | |||
57 | static void |
||
58 | warning (void) |
||
59 | { |
||
60 | if (g_test_subprocess ()) |
||
61 | g_warning ("this is a regular g_warning() from the test suite"); |
||
62 | } |
||
63 | |||
64 | static void |
||
65 | critical (void) |
||
66 | { |
||
67 | if (g_test_subprocess ()) |
||
68 | g_critical ("this is a regular g_critical() from the test suite"); |
||
69 | } |
||
70 | |||
71 | static void |
||
72 | error (void) |
||
73 | { |
||
74 | if (g_test_subprocess ()) |
||
75 | g_error ("this is a regular g_error() from the test suite"); |
||
76 | } |
||
77 | |||
78 | static void |
||
79 | gtest_message (void) |
||
80 | { |
||
81 | if (g_test_subprocess ()) |
||
82 | g_test_message ("this is a regular g_test_message() from the test suite"); |
||
83 | } |
||
84 | |||
85 | static gboolean |
||
86 | test_message_cb1 (GIOChannel * channel, |
||
87 | GIOCondition condition, |
||
88 | gpointer user_data) |
||
89 | { |
||
90 | GIOStatus status; |
||
91 | guchar buf[512]; |
||
92 | gsize read_bytes = 0; |
||
93 | |||
94 | g_assert_cmpuint (condition, ==, G_IO_IN); |
||
95 | |||
96 | for (status = g_io_channel_read_chars (channel, (gchar*)buf, sizeof (buf), &read_bytes, NULL); |
||
97 | status == G_IO_STATUS_NORMAL; |
||
98 | status = g_io_channel_read_chars (channel, (gchar*)buf, sizeof (buf), &read_bytes, NULL)) |
||
99 | { |
||
100 | g_test_log_buffer_push (user_data, read_bytes, buf); |
||
101 | } |
||
102 | |||
103 | g_assert_cmpuint (status, ==, G_IO_STATUS_AGAIN); |
||
104 | |||
105 | return TRUE; |
||
106 | } |
||
107 | |||
108 | static void |
||
109 | test_message_cb2 (GPid pid, |
||
110 | gint status, |
||
111 | gpointer user_data) |
||
112 | { |
||
113 | g_spawn_close_pid (pid); |
||
114 | |||
115 | g_main_loop_quit (user_data); |
||
116 | } |
||
117 | |||
118 | static void |
||
119 | test_message (void) |
||
120 | { |
||
121 | gchar* argv[] = { |
||
122 | (gchar*)argv0, |
||
123 | NULL, |
||
124 | "--GTestSubprocess", |
||
125 | "-p", "/glib/testing/protocol/debug", |
||
126 | "-p", "/glib/testing/protocol/message", |
||
127 | "-p", "/glib/testing/protocol/gtest-message", |
||
128 | NULL |
||
129 | }; |
||
130 | GTestLogBuffer* tlb; |
||
131 | GTestLogMsg * msg; |
||
132 | GIOChannel * channel; |
||
133 | GMainLoop * loop; |
||
134 | GError * error = NULL; |
||
135 | gulong child_source; |
||
136 | gulong io_source; |
||
137 | GPid pid = 0; |
||
138 | int pipes[2]; |
||
139 | int passed = 0; |
||
140 | int messages = 0; |
||
141 | const char * line_term; |
||
142 | int line_term_len; |
||
143 | |||
144 | if (0 > pipe (pipes)) |
||
145 | { |
||
146 | g_error ("error creating pipe: %s", g_strerror (errno)); |
||
147 | } |
||
148 | |||
149 | argv[1] = g_strdup_printf ("--GTestLogFD=%u", pipes[1]); |
||
150 | |||
151 | if (!g_spawn_async (NULL, |
||
152 | argv, NULL, |
||
153 | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_LEAVE_DESCRIPTORS_OPEN | |
||
154 | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, |
||
155 | NULL, NULL, &pid, |
||
156 | &error)) |
||
157 | { |
||
158 | g_error ("error spawning the test: %s", error->message); |
||
159 | } |
||
160 | |||
161 | tlb = g_test_log_buffer_new (); |
||
162 | loop = g_main_loop_new (NULL, FALSE); |
||
163 | |||
164 | channel = g_io_channel_unix_new (pipes[0]); |
||
165 | g_io_channel_set_close_on_unref (channel, TRUE); |
||
166 | g_io_channel_set_encoding (channel, NULL, NULL); |
||
167 | g_io_channel_set_buffered (channel, FALSE); |
||
168 | g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); |
||
169 | g_assert (g_io_channel_get_line_term (channel, NULL) == NULL); |
||
170 | g_io_channel_set_line_term (channel, "\n", 1); |
||
171 | line_term = g_io_channel_get_line_term (channel, &line_term_len); |
||
172 | g_assert_cmpint (*line_term, ==, '\n'); |
||
173 | g_assert_cmpint (line_term_len, ==, 1); |
||
174 | |||
175 | g_assert (g_io_channel_get_close_on_unref (channel)); |
||
176 | g_assert (g_io_channel_get_encoding (channel) == NULL); |
||
177 | g_assert (!g_io_channel_get_buffered (channel)); |
||
178 | |||
179 | io_source = g_io_add_watch (channel, G_IO_IN, test_message_cb1, tlb); |
||
180 | child_source = g_child_watch_add (pid, test_message_cb2, loop); |
||
181 | |||
182 | g_main_loop_run (loop); |
||
183 | |||
184 | test_message_cb1 (channel, G_IO_IN, tlb); |
||
185 | |||
186 | g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "Source ID*"); |
||
187 | g_assert (!g_source_remove (child_source)); |
||
188 | g_test_assert_expected_messages (); |
||
189 | g_assert (g_source_remove (io_source)); |
||
190 | g_io_channel_unref (channel); |
||
191 | |||
192 | for (msg = g_test_log_buffer_pop (tlb); |
||
193 | msg; |
||
194 | msg = g_test_log_buffer_pop (tlb)) |
||
195 | { |
||
196 | switch (msg->log_type) |
||
197 | { |
||
198 | case G_TEST_LOG_START_BINARY: |
||
199 | case G_TEST_LOG_START_CASE: |
||
200 | case G_TEST_LOG_START_SUITE: |
||
201 | case G_TEST_LOG_STOP_SUITE: |
||
202 | /* ignore */ |
||
203 | break; |
||
204 | case G_TEST_LOG_STOP_CASE: |
||
205 | passed++; |
||
206 | break; |
||
207 | case G_TEST_LOG_MESSAGE: |
||
208 | { |
||
209 | gchar const* known_messages[] = { |
||
210 | "this is a regular g_test_message() from the test suite", |
||
211 | "GLib-MESSAGE: this is a regular g_message() from the test suite", |
||
212 | "GLib-DEBUG: this is a regular g_debug() from the test suite" |
||
213 | }; |
||
214 | g_assert_cmpint (messages, <, G_N_ELEMENTS (known_messages)); |
||
215 | g_assert_cmpstr (msg->strings[0], ==, known_messages[messages]); |
||
216 | messages++; |
||
217 | } |
||
218 | break; |
||
219 | case G_TEST_LOG_ERROR: |
||
220 | g_assert_not_reached (); |
||
221 | break; |
||
222 | default: |
||
223 | g_error ("unexpected log message type: %s", g_test_log_type_name (msg->log_type)); |
||
224 | } |
||
225 | g_test_log_msg_free (msg); |
||
226 | } |
||
227 | |||
228 | g_assert_cmpint (passed, ==, 3); |
||
229 | g_assert_cmpint (messages, ==, 3); |
||
230 | |||
231 | g_free (argv[1]); |
||
232 | g_main_loop_unref (loop); |
||
233 | g_test_log_buffer_free (tlb); |
||
234 | } |
||
235 | |||
236 | static void |
||
237 | test_error (void) |
||
238 | { |
||
239 | gchar* tests[] = { |
||
240 | "/glib/testing/protocol/warning", |
||
241 | "/glib/testing/protocol/critical", |
||
242 | "/glib/testing/protocol/error" |
||
243 | }; |
||
244 | gint i; |
||
245 | int messages = 0; |
||
246 | |||
247 | for (i = 0; i < G_N_ELEMENTS (tests); i++) |
||
248 | { |
||
249 | gchar* argv[] = { |
||
250 | (gchar*)argv0, |
||
251 | NULL, |
||
252 | "--GTestSubprocess", |
||
253 | "-p", tests[i], |
||
254 | NULL |
||
255 | }; |
||
256 | GTestLogBuffer* tlb; |
||
257 | GTestLogMsg * msg; |
||
258 | GIOChannel * channel; |
||
259 | GMainLoop * loop; |
||
260 | GError * error = NULL; |
||
261 | gulong child_source; |
||
262 | gulong io_source; |
||
263 | GPid pid = 0; |
||
264 | int pipes[2]; |
||
265 | |||
266 | if (0 > pipe (pipes)) |
||
267 | { |
||
268 | g_error ("error creating pipe: %s", g_strerror (errno)); |
||
269 | } |
||
270 | |||
271 | argv[1] = g_strdup_printf ("--GTestLogFD=%u", pipes[1]); |
||
272 | |||
273 | if (!g_spawn_async (NULL, |
||
274 | argv, NULL, |
||
275 | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_LEAVE_DESCRIPTORS_OPEN | |
||
276 | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, |
||
277 | NULL, NULL, &pid, |
||
278 | &error)) |
||
279 | { |
||
280 | g_error ("error spawning the test: %s", error->message); |
||
281 | } |
||
282 | |||
283 | tlb = g_test_log_buffer_new (); |
||
284 | loop = g_main_loop_new (NULL, FALSE); |
||
285 | |||
286 | channel = g_io_channel_unix_new (pipes[0]); |
||
287 | g_io_channel_set_close_on_unref (channel, TRUE); |
||
288 | g_io_channel_set_encoding (channel, NULL, NULL); |
||
289 | g_io_channel_set_buffered (channel, FALSE); |
||
290 | g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); |
||
291 | |||
292 | io_source = g_io_add_watch (channel, G_IO_IN, test_message_cb1, tlb); |
||
293 | child_source = g_child_watch_add (pid, test_message_cb2, loop); |
||
294 | |||
295 | g_main_loop_run (loop); |
||
296 | |||
297 | test_message_cb1 (channel, G_IO_IN, tlb); |
||
298 | |||
299 | g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "Source ID*"); |
||
300 | g_assert (!g_source_remove (child_source)); |
||
301 | g_test_assert_expected_messages (); |
||
302 | g_assert (g_source_remove (io_source)); |
||
303 | g_io_channel_unref (channel); |
||
304 | |||
305 | for (msg = g_test_log_buffer_pop (tlb); |
||
306 | msg; |
||
307 | msg = g_test_log_buffer_pop (tlb)) |
||
308 | { |
||
309 | switch (msg->log_type) |
||
310 | { |
||
311 | case G_TEST_LOG_START_BINARY: |
||
312 | case G_TEST_LOG_START_CASE: |
||
313 | case G_TEST_LOG_START_SUITE: |
||
314 | case G_TEST_LOG_STOP_SUITE: |
||
315 | /* ignore */ |
||
316 | break; |
||
317 | case G_TEST_LOG_STOP_CASE: |
||
318 | case G_TEST_LOG_MESSAGE: |
||
319 | g_assert_not_reached (); |
||
320 | break; |
||
321 | case G_TEST_LOG_ERROR: |
||
322 | { |
||
323 | gchar const* known_messages[] = { |
||
324 | "GLib-FATAL-WARNING: this is a regular g_warning() from the test suite", |
||
325 | "GLib-FATAL-CRITICAL: this is a regular g_critical() from the test suite", |
||
326 | "GLib-FATAL-ERROR: this is a regular g_error() from the test suite" |
||
327 | }; |
||
328 | g_assert_cmpint (messages, <, G_N_ELEMENTS (known_messages)); |
||
329 | g_assert_cmpstr (msg->strings[0], ==, known_messages[messages]); |
||
330 | messages++; |
||
331 | } |
||
332 | break; |
||
333 | default: |
||
334 | g_error ("unexpected log message type: %s", g_test_log_type_name (msg->log_type)); |
||
335 | } |
||
336 | g_test_log_msg_free (msg); |
||
337 | } |
||
338 | |||
339 | g_free (argv[1]); |
||
340 | g_main_loop_unref (loop); |
||
341 | g_test_log_buffer_free (tlb); |
||
342 | } |
||
343 | |||
344 | g_assert_cmpint (messages, ==, 3); |
||
345 | } |
||
346 | |||
347 | int |
||
348 | main (int argc, |
||
349 | char**argv) |
||
350 | { |
||
351 | argv0 = argv[0]; |
||
352 | |||
353 | g_test_init (&argc, &argv, NULL); |
||
354 | |||
355 | /* we use ourself as the testcase, these are the ones we need internally */ |
||
356 | g_test_add_func ("/glib/testing/protocol/debug", debug); |
||
357 | g_test_add_func ("/glib/testing/protocol/info", info); |
||
358 | g_test_add_func ("/glib/testing/protocol/message", message); |
||
359 | g_test_add_func ("/glib/testing/protocol/warning", warning); |
||
360 | g_test_add_func ("/glib/testing/protocol/critical", critical); |
||
361 | g_test_add_func ("/glib/testing/protocol/error", error); |
||
362 | g_test_add_func ("/glib/testing/protocol/gtest-message", gtest_message); |
||
363 | |||
364 | /* these are the real tests */ |
||
365 | g_test_add_func ("/glib/testing/protocol/test-message", test_message); |
||
366 | g_test_add_func ("/glib/testing/protocol/test-error", test_error); |
||
367 | |||
368 | return g_test_run (); |
||
369 | } |
||
370 | |||
371 | /* vim:set et sw=2 cino=t0,f0,(0,{s,>2s,n-1s,^-1s,e2s: */ |