1 /* GLib testing framework examples
2 * Copyright (C) 2007 Tim Janik
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library 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. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gtestframework.h"
21 #include <sys/types.h>
29 #ifdef HAVE_SYS_SELECT_H
30 #include <sys/select.h>
31 #endif /* HAVE_SYS_SELECT_H */
33 /* --- structures --- */
38 void (*fixture_setup) (void*);
39 void (*fixture_test) (void*);
40 void (*fixture_teardown) (void*);
49 /* --- prototypes --- */
50 static void test_run_seed (const gchar *rseed);
51 static void test_trap_clear (void);
53 /* --- variables --- */
54 static int test_stdmsg = 1;
55 static gboolean test_mode_quick = TRUE;
56 static gboolean test_mode_perf = FALSE;
57 static gboolean test_mode_fatal = TRUE;
58 static gboolean g_test_initialized = FALSE;
59 static gboolean g_test_run_once = TRUE;
60 static gboolean test_run_quiet = FALSE;
61 static gboolean test_run_list = FALSE;
62 static gchar *test_run_output = NULL;
63 static gchar *test_run_seedstr = NULL;
64 static GRand *test_run_rand = NULL;
65 static gchar *test_run_name = "";
66 static GTimer *test_run_timer = NULL;
67 static GTimer *test_user_timer = NULL;
68 static double test_user_stamp = 0;
69 static GSList *test_paths = NULL;
70 static GTestSuite *test_suite_root = NULL;
71 static GSList *test_run_free_queue = NULL;
72 static int test_trap_last_status = 0;
73 static int test_trap_last_pid = 0;
74 static char *test_trap_last_stdout = NULL;
75 static char *test_trap_last_stderr = NULL;
77 /* --- functions --- */
79 parse_args (gint *argc_p,
83 gchar **argv = *argv_p;
85 /* parse known args */
86 for (i = 1; i < argc; i++)
88 if (strcmp (argv[i], "--g-fatal-warnings") == 0)
90 GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
91 fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
92 g_log_set_always_fatal (fatal_mask);
95 else if (strcmp (argv[i], "--keep-going") == 0 ||
96 strcmp (argv[i], "-k") == 0)
98 test_mode_fatal = FALSE;
101 else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0)
103 gchar *equal = argv[i] + 2;
105 test_paths = g_slist_prepend (test_paths, equal + 1);
106 else if (i + 1 < argc)
109 test_paths = g_slist_prepend (test_paths, argv[i]);
113 else if (strcmp ("-o", argv[i]) == 0 || strncmp ("-o=", argv[i], 3) == 0)
115 gchar *equal = argv[i] + 2;
117 test_run_output = equal + 1;
118 else if (i + 1 < argc)
121 test_run_output = argv[i];
125 else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
127 gchar *equal = argv[i] + 2;
128 const gchar *mode = "";
131 else if (i + 1 < argc)
136 if (strcmp (mode, "perf") == 0)
137 test_mode_perf = TRUE;
138 else if (strcmp (mode, "slow") == 0)
139 test_mode_quick = FALSE;
140 else if (strcmp (mode, "quick") == 0)
142 test_mode_quick = TRUE;
143 test_mode_perf = FALSE;
146 g_error ("unknown test mode: -m %s", mode);
149 else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0)
151 test_run_quiet = TRUE;
154 else if (strcmp ("-l", argv[i]) == 0)
156 test_run_list = TRUE;
159 else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0)
161 gchar *equal = argv[i] + 6;
163 test_run_seedstr = equal + 1;
164 else if (i + 1 < argc)
167 test_run_seedstr = argv[i];
174 for (i = 1; i < argc; i++)
185 g_test_init (int *argc,
189 static char seedstr[4 + 4 * 8 + 1];
192 g_return_if_fail (argc != NULL);
193 g_return_if_fail (argv != NULL);
194 g_return_if_fail (g_test_initialized == FALSE);
195 g_test_initialized = TRUE;
197 va_start (args, argv);
198 vararg1 = va_arg (args, gpointer); /* reserved for future extensions */
200 g_return_if_fail (vararg1 == NULL);
202 /* setup random seed string */
203 g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x", g_random_int(), g_random_int(), g_random_int(), g_random_int());
204 test_run_seedstr = seedstr;
206 /* parse args, sets up mode, changes seed, etc. */
207 parse_args (argc, argv);
209 /* verify GRand reliability, needed for reliable seeds */
212 GRand *rg = g_rand_new_with_seed (0xc8c49fb6);
213 guint32 t1 = g_rand_int (rg), t2 = g_rand_int (rg), t3 = g_rand_int (rg), t4 = g_rand_int (rg);
214 // g_print ("GRand-current: 0x%x 0x%x 0x%x 0x%x\n", t1, t2, t3, t4);
215 if (t1 != 0xfab39f9b || t2 != 0xb948fb0e || t3 != 0x3d31be26 || t4 != 0x43a19d66)
216 g_warning ("random numbers are not GRand-2.2 compatible, seeds may be broken (check $G_RANDOM_VERSION)");
220 /* check rand seed */
221 test_run_seed (test_run_seedstr);
222 if (test_run_seedstr == seedstr)
223 g_printerr ("NOTE: random-seed: %s\n", test_run_seedstr);
226 test_run_timer = g_timer_new();
230 test_run_seed (const gchar *rseed)
232 guint seed_failed = 0;
234 g_rand_free (test_run_rand);
235 test_run_rand = NULL;
236 while (strchr (" \t\v\r\n\f", *rseed))
238 if (strncmp (rseed, "R02S", 4) == 0) // seed for random generator 02 (GRand-2.2)
240 const char *s = rseed + 4;
241 if (strlen (s) >= 32) // require 4 * 8 chars
243 guint32 seedarray[4];
244 gchar *p, hexbuf[9] = { 0, };
245 memcpy (hexbuf, s + 0, 8);
246 seedarray[0] = g_ascii_strtoull (hexbuf, &p, 16);
247 seed_failed += p != NULL && *p != 0;
248 memcpy (hexbuf, s + 8, 8);
249 seedarray[1] = g_ascii_strtoull (hexbuf, &p, 16);
250 seed_failed += p != NULL && *p != 0;
251 memcpy (hexbuf, s + 16, 8);
252 seedarray[2] = g_ascii_strtoull (hexbuf, &p, 16);
253 seed_failed += p != NULL && *p != 0;
254 memcpy (hexbuf, s + 24, 8);
255 seedarray[3] = g_ascii_strtoull (hexbuf, &p, 16);
256 seed_failed += p != NULL && *p != 0;
259 test_run_rand = g_rand_new_with_seed_array (seedarray, 4);
264 g_error ("Unknown or invalid random seed: %s", rseed);
268 g_test_rand_int (void)
270 return g_rand_int (test_run_rand);
274 g_test_rand_int_range (gint32 begin,
277 return g_rand_int_range (test_run_rand, begin, end);
281 g_test_rand_double (void)
283 return g_rand_double (test_run_rand);
287 g_test_rand_double_range (double range_start,
290 return g_rand_double_range (test_run_rand, range_start, range_end);
294 g_test_timer_start (void)
296 if (!test_user_timer)
297 test_user_timer = g_timer_new();
299 g_timer_start (test_user_timer);
303 g_test_timer_elapsed (void)
305 test_user_stamp = test_user_timer ? g_timer_elapsed (test_user_timer, NULL) : 0;
306 return test_user_stamp;
310 g_test_timer_last (void)
312 return test_user_stamp;
316 g_test_get_root (void)
318 if (!test_suite_root)
320 test_suite_root = g_test_create_suite ("root");
321 g_free (test_suite_root->name);
322 test_suite_root->name = g_strdup ("");
324 return test_suite_root;
330 return g_test_run_suite (g_test_get_root());
334 g_test_create_case (const char *test_name,
336 void (*data_setup) (void),
337 void (*data_test) (void),
338 void (*data_teardown) (void))
340 g_return_val_if_fail (test_name != NULL, NULL);
341 g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL);
342 g_return_val_if_fail (test_name[0] != 0, NULL);
343 g_return_val_if_fail (data_test != NULL, NULL);
344 GTestCase *tc = g_slice_new0 (GTestCase);
345 tc->name = g_strdup (test_name);
346 tc->fixture_size = data_size;
347 tc->fixture_setup = (void*) data_setup;
348 tc->fixture_test = (void*) data_test;
349 tc->fixture_teardown = (void*) data_teardown;
354 g_test_add_vtable (const char *testpath,
356 void (*data_setup) (void),
357 void (*fixture_test_func) (void),
358 void (*data_teardown) (void))
364 g_return_if_fail (testpath != NULL);
365 g_return_if_fail (testpath[0] == '/');
366 g_return_if_fail (fixture_test_func != NULL);
368 suite = g_test_get_root();
369 segments = g_strsplit (testpath, "/", -1);
370 for (ui = 0; segments[ui] != NULL; ui++)
372 const char *seg = segments[ui];
373 gboolean islast = segments[ui + 1] == NULL;
374 if (islast && !seg[0])
375 g_error ("invalid test case path: %s", testpath);
377 continue; // initial or duplicate slash
380 GTestSuite *csuite = g_test_create_suite (seg);
381 g_test_suite_add_suite (suite, csuite);
386 GTestCase *tc = g_test_create_case (seg, data_size, data_setup, fixture_test_func, data_teardown);
387 g_test_suite_add (suite, tc);
390 g_strfreev (segments);
394 g_test_add_func (const char *testpath,
395 void (*test_func) (void))
397 g_return_if_fail (testpath != NULL);
398 g_return_if_fail (testpath[0] == '/');
399 g_return_if_fail (test_func != NULL);
400 g_test_add_vtable (testpath, 0, NULL, test_func, NULL);
404 g_test_create_suite (const char *suite_name)
406 g_return_val_if_fail (suite_name != NULL, NULL);
407 g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL);
408 g_return_val_if_fail (suite_name[0] != 0, NULL);
409 GTestSuite *ts = g_slice_new0 (GTestSuite);
410 ts->name = g_strdup (suite_name);
415 g_test_suite_add (GTestSuite *suite,
416 GTestCase *test_case)
418 g_return_if_fail (suite != NULL);
419 g_return_if_fail (test_case != NULL);
420 suite->cases = g_slist_prepend (suite->cases, test_case);
424 g_test_suite_add_suite (GTestSuite *suite,
425 GTestSuite *nestedsuite)
427 g_return_if_fail (suite != NULL);
428 g_return_if_fail (nestedsuite != NULL);
429 suite->suites = g_slist_prepend (suite->suites, nestedsuite);
433 g_test_queue_free (gpointer gfree_pointer)
436 test_run_free_queue = g_slist_prepend (test_run_free_queue, gfree_pointer);
440 test_case_run (GTestCase *tc)
443 g_timer_start (test_run_timer);
444 old_name = test_run_name;
445 test_run_name = g_strconcat (old_name, "/", tc->name, NULL);
447 g_print ("%s\n", test_run_name);
451 g_print ("%s: ", test_run_name);
452 void *fixture = g_malloc0 (tc->fixture_size);
453 test_run_seed (test_run_seedstr);
454 if (tc->fixture_setup)
455 tc->fixture_setup (fixture);
456 tc->fixture_test (fixture);
458 while (test_run_free_queue)
460 gpointer freeme = test_run_free_queue->data;
461 test_run_free_queue = g_slist_delete_link (test_run_free_queue, test_run_free_queue);
464 if (tc->fixture_teardown)
465 tc->fixture_teardown (fixture);
470 g_free (test_run_name);
471 test_run_name = old_name;
472 g_timer_stop (test_run_timer);
473 /* FIXME: need reporting here */
478 g_test_run_suite_internal (GTestSuite *suite,
481 guint n_bad = 0, n_good = 0, bad_suite = 0, l;
482 gchar *rest, *old_name = test_run_name;
483 GSList *slist, *reversed;
484 g_return_val_if_fail (suite != NULL, -1);
485 while (path[0] == '/')
488 rest = strchr (path, '/');
489 l = rest ? MIN (l, rest - path) : l;
490 test_run_name = suite->name[0] == 0 ? g_strdup (test_run_name) : g_strconcat (old_name, "/", suite->name, NULL);
491 reversed = g_slist_reverse (g_slist_copy (suite->cases));
492 for (slist = reversed; slist; slist = slist->next)
494 GTestCase *tc = slist->data;
495 guint n = l ? strlen (tc->name) : 0;
496 if (l == n && strncmp (path, tc->name, n) == 0)
499 n_bad += test_case_run (tc) != 0;
502 g_slist_free (reversed);
503 reversed = g_slist_reverse (g_slist_copy (suite->suites));
504 for (slist = reversed; slist; slist = slist->next)
506 GTestSuite *ts = slist->data;
507 guint n = l ? strlen (ts->name) : 0;
508 if (l == n && strncmp (path, ts->name, n) == 0)
509 bad_suite += g_test_run_suite_internal (ts, rest ? rest : "") != 0;
511 g_slist_free (reversed);
512 g_free (test_run_name);
513 test_run_name = old_name;
514 return n_bad || bad_suite;
518 g_test_run_suite (GTestSuite *suite)
521 g_return_val_if_fail (g_test_initialized == TRUE, -1);
522 g_return_val_if_fail (g_test_run_once == TRUE, -1);
523 g_test_run_once = FALSE;
525 test_paths = g_slist_prepend (test_paths, "");
528 const char *rest, *path = test_paths->data;
530 test_paths = g_slist_delete_link (test_paths, test_paths);
531 while (path[0] == '/')
533 rest = strchr (path, '/');
535 l = rest ? MIN (l, rest - path) : l;
536 n = l ? strlen (suite->name) : 0;
537 if (l == n && strncmp (path, suite->name, n) == 0)
538 n_bad += 0 != g_test_run_suite_internal (suite, rest ? rest : "");
544 g_assertion_message (const char *domain,
551 g_snprintf (lstr, 32, "%d", line);
552 char *s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "",
553 file, ":", lstr, ":",
554 func, func[0] ? ":" : "",
556 g_printerr ("**\n** %s\n", s);
562 g_assertion_message_expr (const char *domain,
568 char *s = g_strconcat ("assertion failed: (", expr, ")", NULL);
569 g_assertion_message (domain, file, line, func, s);
574 g_assertion_message_cmpnum (const char *domain,
587 case 'i': s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break;
588 case 'x': s = g_strdup_printf ("assertion failed (%s): (0x%08Lx %s 0x%08Lx)", expr, (guint64) arg1, cmp, (guint64) arg2); break;
589 case 'f': s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break;
590 /* ideally use: floats=%.7g double=%.17g */
592 g_assertion_message (domain, file, line, func, s);
597 g_assertion_message_cmpstr (const char *domain,
606 char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
607 a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL");
608 a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL");
611 s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
614 g_assertion_message (domain, file, line, func, s);
619 g_strcmp0 (const char *str1,
623 return -(str1 != str2);
626 return strcmp (str1, str2);
629 static int /* 0 on success */
635 if (patience >= 3) /* try graceful reap */
637 if (waitpid (pid, status, WNOHANG) > 0)
640 if (patience >= 2) /* try SIGHUP */
643 if (waitpid (pid, status, WNOHANG) > 0)
645 g_usleep (20 * 1000); /* give it some scheduling/shutdown time */
646 if (waitpid (pid, status, WNOHANG) > 0)
648 g_usleep (50 * 1000); /* give it some scheduling/shutdown time */
649 if (waitpid (pid, status, WNOHANG) > 0)
651 g_usleep (100 * 1000); /* give it some scheduling/shutdown time */
652 if (waitpid (pid, status, WNOHANG) > 0)
655 if (patience >= 1) /* try SIGTERM */
658 if (waitpid (pid, status, WNOHANG) > 0)
660 g_usleep (200 * 1000); /* give it some scheduling/shutdown time */
661 if (waitpid (pid, status, WNOHANG) > 0)
663 g_usleep (400 * 1000); /* give it some scheduling/shutdown time */
664 if (waitpid (pid, status, WNOHANG) > 0)
670 wr = waitpid (pid, status, 0);
671 while (wr < 0 && errno == EINTR);
676 g_string_must_read (GString *gstring,
679 #define STRING_BUFFER_SIZE 4096
680 char buf[STRING_BUFFER_SIZE];
683 bytes = read (fd, buf, sizeof (buf));
685 return 0; /* EOF, calling this function assumes data is available */
688 g_string_append_len (gstring, buf, bytes);
691 else if (bytes < 0 && errno == EINTR)
695 g_warning ("failed to read() from child process (%d): %s", test_trap_last_pid, g_strerror (errno));
696 return 1; /* ignore error after warning */
701 g_string_write_out (GString *gstring,
705 if (*stringpos < gstring->len)
709 r = write (outfd, gstring->str + *stringpos, gstring->len - *stringpos);
710 while (r < 0 && errno == EINTR);
711 *stringpos += MAX (r, 0);
721 ret = dup2 (fd1, fd2);
722 while (ret < 0 && errno == EINTR);
727 test_trap_clear (void)
729 test_trap_last_status = 0;
730 test_trap_last_pid = 0;
731 g_free (test_trap_last_stdout);
732 test_trap_last_stdout = NULL;
733 g_free (test_trap_last_stderr);
734 test_trap_last_stderr = NULL;
738 test_time_stamp (void)
742 g_get_current_time (&tv);
744 stamp = stamp * 1000000 + tv.tv_usec;
749 g_test_trap_fork (guint64 usec_timeout,
750 GTestTrapFlags test_trap_flags)
752 int stdout_pipe[2] = { -1, -1 };
753 int stderr_pipe[2] = { -1, -1 };
754 int stdtst_pipe[2] = { -1, -1 };
756 if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0 || pipe (stdtst_pipe) < 0)
757 g_error ("failed to create pipes to fork test program: %s", g_strerror (errno));
758 signal (SIGCHLD, SIG_DFL);
759 test_trap_last_pid = fork ();
760 if (test_trap_last_pid < 0)
761 g_error ("failed to fork test program: %s", g_strerror (errno));
762 if (test_trap_last_pid == 0) /* child */
765 close (stdout_pipe[0]);
766 close (stderr_pipe[0]);
767 close (stdtst_pipe[0]);
768 if (!(test_trap_flags & G_TEST_TRAP_INHERIT_STDIN))
769 fd0 = open ("/dev/null", O_RDONLY);
770 if (sane_dup2 (stdout_pipe[1], 1) < 0 || sane_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && sane_dup2 (fd0, 0) < 0))
771 g_error ("failed to dup2() in forked test program: %s", g_strerror (errno));
774 if (stdout_pipe[1] >= 3)
775 close (stdout_pipe[1]);
776 if (stderr_pipe[1] >= 3)
777 close (stderr_pipe[1]);
778 test_stdmsg = stdtst_pipe[1];
783 GString *sout = g_string_new (NULL);
784 GString *serr = g_string_new (NULL);
785 GString *stst = g_string_new (NULL);
787 int soutpos = 0, serrpos = 0, ststpos = 0, wr, need_wait = TRUE;
788 close (stdout_pipe[1]);
789 close (stderr_pipe[1]);
790 close (stdtst_pipe[1]);
791 sstamp = test_time_stamp();
792 /* read data until we get EOF on all pipes */
793 while (stdout_pipe[0] >= 0 || stderr_pipe[0] >= 0 || stdtst_pipe[0] > 0)
798 if (stdout_pipe[0] >= 0)
799 FD_SET (stdout_pipe[0], &fds);
800 if (stderr_pipe[0] >= 0)
801 FD_SET (stderr_pipe[0], &fds);
802 if (stdtst_pipe[0] >= 0)
803 FD_SET (stdtst_pipe[0], &fds);
805 tv.tv_usec = MIN (usec_timeout ? usec_timeout : 1000000, 100 * 1000); // sleep at most 0.5 seconds to catch clock skews, etc.
806 int ret = select (MAX (MAX (stdout_pipe[0], stderr_pipe[0]), stdtst_pipe[0]) + 1, &fds, NULL, NULL, &tv);
807 if (ret < 0 && errno != EINTR)
809 g_warning ("Unexpected error in select() while reading from child process (%d): %s", test_trap_last_pid, g_strerror (errno));
812 if (stdout_pipe[0] >= 0 && FD_ISSET (stdout_pipe[0], &fds) &&
813 g_string_must_read (sout, stdout_pipe[0]) == 0)
815 close (stdout_pipe[0]);
818 if (stderr_pipe[0] >= 0 && FD_ISSET (stderr_pipe[0], &fds) &&
819 g_string_must_read (serr, stderr_pipe[0]) == 0)
821 close (stderr_pipe[0]);
824 if (stdtst_pipe[0] >= 0 && FD_ISSET (stdtst_pipe[0], &fds) &&
825 g_string_must_read (stst, stdtst_pipe[0]) == 0)
827 close (stdtst_pipe[0]);
830 if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDOUT))
831 g_string_write_out (sout, 1, &soutpos);
832 if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDERR))
833 g_string_write_out (serr, 2, &serrpos);
834 if (TRUE) // FIXME: needs capturing into log file
835 g_string_write_out (stst, 1, &ststpos);
838 guint64 nstamp = test_time_stamp();
840 sstamp = MIN (sstamp, nstamp); // guard against backwards clock skews
841 if (usec_timeout < nstamp - sstamp)
843 /* timeout reached, need to abort the child now */
844 kill_child (test_trap_last_pid, &status, 3);
845 test_trap_last_status = 1024; /* timeout */
846 if (0 && WIFSIGNALED (status))
847 g_printerr ("%s: child timed out and received: %s\n", G_STRFUNC, g_strsignal (WTERMSIG (status)));
853 close (stdout_pipe[0]);
854 close (stderr_pipe[0]);
855 close (stdtst_pipe[0]);
860 wr = waitpid (test_trap_last_pid, &status, 0);
861 while (wr < 0 && errno == EINTR);
862 if (WIFEXITED (status)) /* normal exit */
863 test_trap_last_status = WEXITSTATUS (status); /* 0..255 */
864 else if (WIFSIGNALED (status))
865 test_trap_last_status = (WTERMSIG (status) << 12); /* signalled */
866 else /* WCOREDUMP (status) */
867 test_trap_last_status = 512; /* coredump */
869 test_trap_last_stdout = g_string_free (sout, FALSE);
870 test_trap_last_stderr = g_string_free (serr, FALSE);
871 g_string_free (stst, TRUE);
877 g_test_trap_has_passed (void)
879 return test_trap_last_status == 0; /* exit_status == 0 && !signal && !coredump */
883 g_test_trap_reached_timeout (void)
885 return 0 != (test_trap_last_status & 1024); /* timeout flag */
889 g_test_trap_assertions (const char *domain,
895 const char *stdout_pattern,
896 const char *stderr_pattern)
898 if (test_trap_last_pid == 0)
899 g_error ("child process failed to exit after g_test_trap_fork() and before g_test_trap_assert*()");
900 if (must_pass && !g_test_trap_has_passed())
902 char *msg = g_strdup_printf ("child process (%d) of test trap failed unexpectedly", test_trap_last_pid);
903 g_assertion_message (domain, file, line, func, msg);
906 if (must_fail && g_test_trap_has_passed())
908 char *msg = g_strdup_printf ("child process (%d) did not fail as expected", test_trap_last_pid);
909 g_assertion_message (domain, file, line, func, msg);
912 if (stdout_pattern && !g_pattern_match_simple (stdout_pattern, test_trap_last_stdout))
914 char *msg = g_strdup_printf ("stdout of child process (%d) failed to match: %s", test_trap_last_pid, stdout_pattern);
915 g_assertion_message (domain, file, line, func, msg);
918 if (stderr_pattern && !g_pattern_match_simple (stderr_pattern, test_trap_last_stderr))
920 char *msg = g_strdup_printf ("stderr of child process (%d) failed to match: %s", test_trap_last_pid, stderr_pattern);
921 g_assertion_message (domain, file, line, func, msg);