1 /* GLib testing utilities 2 * Copyright (C) 2007 Imendio AB 3 * Authors: Tim Janik, Sven Herzberg 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 * Boston, MA 02111-1307, USA. 19 */ 20 #include "config.h" 21 #include "gtestutils.h" 22 #include "galias.h" 23 #include <sys/types.h> 24 #ifdef G_OS_UNIX 25 #include <sys/wait.h> 26 #include <sys/time.h> 27 #include <fcntl.h> 28 #endif 29 #include <string.h> 30 #include <stdlib.h> 31 #include <stdio.h> 32 #ifdef HAVE_UNISTD_H 33 #include <unistd.h> 34 #endif 35 #ifdef G_OS_WIN32 36 #include <io.h> 37 #endif 38 #include <errno.h> 39 #include <signal.h> 40 #ifdef HAVE_SYS_SELECT_H 41 #include <sys/select.h> 42 #endif /* HAVE_SYS_SELECT_H */ 43 44 /* --- structures --- */ 45 struct GTestCase 46 { 47 gchar *name; 48 guint fixture_size; 49 void (*fixture_setup) (void*, gconstpointer); 50 void (*fixture_test) (void*, gconstpointer); 51 void (*fixture_teardown) (void*, gconstpointer); 52 gpointer test_data; 53 }; 54 struct GTestSuite 55 { 56 gchar *name; 57 GSList *suites; 58 GSList *cases; 59 }; 60 typedef struct DestroyEntry DestroyEntry; 61 struct DestroyEntry 62 { 63 DestroyEntry *next; 64 GDestroyNotify destroy_func; 65 gpointer destroy_data; 66 }; 67 68 /* --- prototypes --- */ 69 static void test_run_seed (const gchar *rseed); 70 static void test_trap_clear (void); 71 static guint8* g_test_log_dump (GTestLogMsg *msg, 72 guint *len); 73 static void gtest_default_log_handler (const gchar *log_domain, 74 GLogLevelFlags log_level, 75 const gchar *message, 76 gpointer unused_data); 77 78 79 /* --- variables --- */ 80 static int test_log_fd = -1; 81 static gboolean test_mode_fatal = TRUE; 82 static gboolean g_test_run_once = TRUE; 83 static gboolean test_run_list = FALSE; 84 static gchar *test_run_seedstr = NULL; 85 static GRand *test_run_rand = NULL; 86 static gchar *test_run_name = ""; 87 static guint test_run_forks = 0; 88 static guint test_run_count = 0; 89 static guint test_skip_count = 0; 90 static GTimer *test_user_timer = NULL; 91 static double test_user_stamp = 0; 92 static GSList *test_paths = NULL; 93 static GTestSuite *test_suite_root = NULL; 94 static int test_trap_last_status = 0; 95 static int test_trap_last_pid = 0; 96 static char *test_trap_last_stdout = NULL; 97 static char *test_trap_last_stderr = NULL; 98 static char *test_uri_base = NULL; 99 static gboolean test_debug_log = FALSE; 100 static DestroyEntry *test_destroy_queue = NULL; 101 static GTestConfig mutable_test_config_vars = { 102 FALSE, /* test_initialized */ 103 TRUE, /* test_quick */ 104 FALSE, /* test_perf */ 105 FALSE, /* test_verbose */ 106 FALSE, /* test_quiet */ 107 }; 108 const GTestConfig * const g_test_config_vars = &mutable_test_config_vars; 109 110 /* --- functions --- */ 111 const char* 112 g_test_log_type_name (GTestLogType log_type) 113 { 114 switch (log_type) 115 { 116 case G_TEST_LOG_NONE: return "none"; 117 case G_TEST_LOG_ERROR: return "error"; 118 case G_TEST_LOG_START_BINARY: return "binary"; 119 case G_TEST_LOG_LIST_CASE: return "list"; 120 case G_TEST_LOG_SKIP_CASE: return "skip"; 121 case G_TEST_LOG_START_CASE: return "start"; 122 case G_TEST_LOG_STOP_CASE: return "stop"; 123 case G_TEST_LOG_MIN_RESULT: return "minperf"; 124 case G_TEST_LOG_MAX_RESULT: return "maxperf"; 125 case G_TEST_LOG_MESSAGE: return "message"; 126 } 127 return "???"; 128 } 129 130 static void 131 g_test_log_send (guint n_bytes, 132 const guint8 *buffer) 133 { 134 if (test_log_fd >= 0) 135 { 136 int r; 137 do 138 r = write (test_log_fd, buffer, n_bytes); 139 while (r < 0 && errno == EINTR); 140 } 141 if (test_debug_log) 142 { 143 GTestLogBuffer *lbuffer = g_test_log_buffer_new (); 144 GTestLogMsg *msg; 145 guint ui; 146 g_test_log_buffer_push (lbuffer, n_bytes, buffer); 147 msg = g_test_log_buffer_pop (lbuffer); 148 g_warn_if_fail (msg != NULL); 149 g_warn_if_fail (lbuffer->data->len == 0); 150 g_test_log_buffer_free (lbuffer); 151 /* print message */ 152 g_printerr ("{*LOG(%s)", g_test_log_type_name (msg->log_type)); 153 for (ui = 0; ui < msg->n_strings; ui++) 154 g_printerr (":{%s}", msg->strings[ui]); 155 if (msg->n_nums) 156 { 157 g_printerr (":("); 158 for (ui = 0; ui < msg->n_nums; ui++) 159 g_printerr ("%s%.16Lg", ui ? ";" : "", msg->nums[ui]); 160 g_printerr (")"); 161 } 162 g_printerr (":LOG*}\n"); 163 g_test_log_msg_free (msg); 164 } 165 } 166 167 static void 168 g_test_log (GTestLogType lbit, 169 const gchar *string1, 170 const gchar *string2, 171 guint n_args, 172 long double *largs) 173 { 174 gboolean fail = lbit == G_TEST_LOG_STOP_CASE && largs[0] != 0; 175 GTestLogMsg msg; 176 gchar *astrings[3] = { NULL, NULL, NULL }; 177 guint8 *dbuffer; 178 guint32 dbufferlen; 179 180 switch (lbit) 181 { 182 case G_TEST_LOG_START_BINARY: 183 if (g_test_verbose()) 184 g_print ("GTest: random seed: %s\n", string2); 185 break; 186 case G_TEST_LOG_STOP_CASE: 187 if (g_test_verbose()) 188 g_print ("GTest: result: %s\n", fail ? "FAIL" : "OK"); 189 else if (!g_test_quiet()) 190 g_print ("%s\n", fail ? "FAIL" : "OK"); 191 if (fail && test_mode_fatal) 192 abort(); 193 break; 194 case G_TEST_LOG_MIN_RESULT: 195 if (g_test_verbose()) 196 g_print ("(MINPERF:%s)\n", string1); 197 break; 198 case G_TEST_LOG_MAX_RESULT: 199 if (g_test_verbose()) 200 g_print ("(MAXPERF:%s)\n", string1); 201 break; 202 case G_TEST_LOG_MESSAGE: 203 if (g_test_verbose()) 204 g_print ("(MSG: %s)\n", string1); 205 break; 206 default: ; 207 } 208 209 msg.log_type = lbit; 210 msg.n_strings = (string1 != NULL) + (string1 && string2); 211 msg.strings = astrings; 212 astrings[0] = (gchar*) string1; 213 astrings[1] = astrings[0] ? (gchar*) string2 : NULL; 214 msg.n_nums = n_args; 215 msg.nums = largs; 216 dbuffer = g_test_log_dump (&msg, &dbufferlen); 217 g_test_log_send (dbufferlen, dbuffer); 218 g_free (dbuffer); 219 220 switch (lbit) 221 { 222 case G_TEST_LOG_START_CASE: 223 if (g_test_verbose()) 224 g_print ("GTest: run: %s\n", string1); 225 else if (!g_test_quiet()) 226 g_print ("%s: ", string1); 227 break; 228 default: ; 229 } 230 } 231 232 /* We intentionally parse the command line without GOptionContext 233 * because otherwise you would never be able to test it. 234 */ 235 static void 236 parse_args (gint *argc_p, 237 gchar ***argv_p) 238 { 239 guint argc = *argc_p; 240 gchar **argv = *argv_p; 241 guint i, e; 242 /* parse known args */ 243 for (i = 1; i < argc; i++) 244 { 245 if (strcmp (argv[i], "--g-fatal-warnings") == 0) 246 { 247 GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK); 248 fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); 249 g_log_set_always_fatal (fatal_mask); 250 argv[i] = NULL; 251 } 252 else if (strcmp (argv[i], "--keep-going") == 0 || 253 strcmp (argv[i], "-k") == 0) 254 { 255 test_mode_fatal = FALSE; 256 argv[i] = NULL; 257 } 258 else if (strcmp (argv[i], "--debug-log") == 0) 259 { 260 test_debug_log = TRUE; 261 argv[i] = NULL; 262 } 263 else if (strcmp ("--GTestLogFD", argv[i]) == 0 || strncmp ("--GTestLogFD=", argv[i], 13) == 0) 264 { 265 gchar *equal = argv[i] + 12; 266 if (*equal == '=') 267 test_log_fd = g_ascii_strtoull (equal + 1, NULL, 0); 268 else if (i + 1 < argc) 269 { 270 argv[i++] = NULL; 271 test_log_fd = g_ascii_strtoull (argv[i], NULL, 0); 272 } 273 argv[i] = NULL; 274 } 275 else if (strcmp ("--GTestSkipCount", argv[i]) == 0 || strncmp ("--GTestSkipCount=", argv[i], 17) == 0) 276 { 277 gchar *equal = argv[i] + 16; 278 if (*equal == '=') 279 test_skip_count = g_ascii_strtoull (equal + 1, NULL, 0); 280 else if (i + 1 < argc) 281 { 282 argv[i++] = NULL; 283 test_skip_count = g_ascii_strtoull (argv[i], NULL, 0); 284 } 285 argv[i] = NULL; 286 } 287 else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0) 288 { 289 gchar *equal = argv[i] + 2; 290 if (*equal == '=') 291 test_paths = g_slist_prepend (test_paths, equal + 1); 292 else if (i + 1 < argc) 293 { 294 argv[i++] = NULL; 295 test_paths = g_slist_prepend (test_paths, argv[i]); 296 } 297 argv[i] = NULL; 298 } 299 else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0) 300 { 301 gchar *equal = argv[i] + 2; 302 const gchar *mode = ""; 303 if (*equal == '=') 304 mode = equal + 1; 305 else if (i + 1 < argc) 306 { 307 argv[i++] = NULL; 308 mode = argv[i]; 309 } 310 if (strcmp (mode, "perf") == 0) 311 mutable_test_config_vars.test_perf = TRUE; 312 else if (strcmp (mode, "slow") == 0) 313 mutable_test_config_vars.test_quick = FALSE; 314 else if (strcmp (mode, "thorough") == 0) 315 mutable_test_config_vars.test_quick = FALSE; 316 else if (strcmp (mode, "quick") == 0) 317 { 318 mutable_test_config_vars.test_quick = TRUE; 319 mutable_test_config_vars.test_perf = FALSE; 320 } 321 else 322 g_error ("unknown test mode: -m %s", mode); 323 argv[i] = NULL; 324 } 325 else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0) 326 { 327 mutable_test_config_vars.test_quiet = TRUE; 328 mutable_test_config_vars.test_verbose = FALSE; 329 argv[i] = NULL; 330 } 331 else if (strcmp ("--verbose", argv[i]) == 0) 332 { 333 mutable_test_config_vars.test_quiet = FALSE; 334 mutable_test_config_vars.test_verbose = TRUE; 335 argv[i] = NULL; 336 } 337 else if (strcmp ("-l", argv[i]) == 0) 338 { 339 test_run_list = TRUE; 340 argv[i] = NULL; 341 } 342 else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0) 343 { 344 gchar *equal = argv[i] + 6; 345 if (*equal == '=') 346 test_run_seedstr = equal + 1; 347 else if (i + 1 < argc) 348 { 349 argv[i++] = NULL; 350 test_run_seedstr = argv[i]; 351 } 352 argv[i] = NULL; 353 } 354 else if (strcmp ("-?", argv[i]) == 0 || strcmp ("--help", argv[i]) == 0) 355 { 356 printf ("Usage:\n" 357 " %s [OPTION...]\n\n" 358 "Help Options:\n" 359 " -?, --help Show help options\n" 360 "Test Options:\n" 361 " -l List test cases available in a test executable\n" 362 " -seed=RANDOMSEED Provide a random seed to reproduce test\n" 363 " runs using random numbers\n" 364 " --verbose Run tests verbosely\n" 365 " -q, --quiet Run tests quietly\n" 366 " -p TESTPATH execute all tests matching TESTPATH\n" 367 " -m {perf|slow|thorough|quick} Execute tests according modes\n" 368 " --debug-log debug test logging output\n" 369 " -k, --keep-going gtester-specific argument\n" 370 " --GTestLogFD=N gtester-specific argument\n" 371 " --GTestSkipCount=N gtester-specific argument\n", 372 argv[0]); 373 exit (0); 374 } 375 } 376 /* collapse argv */ 377 e = 1; 378 for (i = 1; i < argc; i++) 379 if (argv[i]) 380 { 381 argv[e++] = argv[i]; 382 if (i >= e) 383 argv[i] = NULL; 384 } 385 *argc_p = e; 386 } 387 388 /** 389 * g_test_init: 390 * @argc: Address of the @argc parameter of the main() function. 391 * Changed if any arguments were handled. 392 * @argv: Address of the @argv parameter of main(). 393 * Any parameters understood by g_test_init() stripped before return. 394 * @Varargs: Reserved for future extension. Currently, you must pass %NULL. 395 * 396 * Initialize the GLib testing framework, e.g. by seeding the 397 * test random number generator, the name for g_get_prgname() 398 * and parsing test related command line args. 399 * So far, the following arguments are understood: 400 * <variablelist> 401 * <varlistentry> 402 * <term><option>-l</option></term> 403 * <listitem><para> 404 * list test cases available in a test executable. 405 * </para></listitem> 406 * </varlistentry> 407 * <varlistentry> 408 * <term><option>--seed=<replaceable>RANDOMSEED</replaceable></option></term> 409 * <listitem><para> 410 * provide a random seed to reproduce test runs using random numbers. 411 * </para></listitem> 412 * </varlistentry> 413 * <varlistentry> 414 * <term><option>--verbose</option></term> 415 * <listitem><para>run tests verbosely.</para></listitem> 416 * </varlistentry> 417 * <varlistentry> 418 * <term><option>-q</option>, <option>--quiet</option></term> 419 * <listitem><para>run tests quietly.</para></listitem> 420 * </varlistentry> 421 * <varlistentry> 422 * <term><option>-p <replaceable>TESTPATH</replaceable></option></term> 423 * <listitem><para> 424 * execute all tests matching <replaceable>TESTPATH</replaceable>. 425 * </para></listitem> 426 * </varlistentry> 427 * <varlistentry> 428 * <term><option>-m {perf|slow|thorough|quick}</option></term> 429 * <listitem><para> 430 * execute tests according to these test modes: 431 * <variablelist> 432 * <varlistentry> 433 * <term>perf</term> 434 * <listitem><para> 435 * performance tests, may take long and report results. 436 * </para></listitem> 437 * </varlistentry> 438 * <varlistentry> 439 * <term>slow, thorough</term> 440 * <listitem><para> 441 * slow and thorough tests, may take quite long and 442 * maximize coverage. 443 * </para></listitem> 444 * </varlistentry> 445 * <varlistentry> 446 * <term>quick</term> 447 * <listitem><para> 448 * quick tests, should run really quickly and give good coverage. 449 * </para></listitem> 450 * </varlistentry> 451 * </variablelist> 452 * </para></listitem> 453 * </varlistentry> 454 * <varlistentry> 455 * <term><option>--debug-log</option></term> 456 * <listitem><para>debug test logging output.</para></listitem> 457 * </varlistentry> 458 * <varlistentry> 459 * <term><option>-k</option>, <option>--keep-going</option></term> 460 * <listitem><para>gtester-specific argument.</para></listitem> 461 * </varlistentry> 462 * <varlistentry> 463 * <term><option>--GTestLogFD <replaceable>N</replaceable></option></term> 464 * <listitem><para>gtester-specific argument.</para></listitem> 465 * </varlistentry> 466 * <varlistentry> 467 * <term><option>--GTestSkipCount <replaceable>N</replaceable></option></term> 468 * <listitem><para>gtester-specific argument.</para></listitem> 469 * </varlistentry> 470 * </variablelist> 471 * 472 * Since: 2.16 473 */ 474 void 475 g_test_init (int *argc, 476 char ***argv, 477 ...) 478 { 479 static char seedstr[4 + 4 * 8 + 1]; 480 va_list args; 481 gpointer vararg1; 482 /* make warnings and criticals fatal for all test programs */ 483 GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK); 484 fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); 485 g_log_set_always_fatal (fatal_mask); 486 /* check caller args */ 487 g_return_if_fail (argc != NULL); 488 g_return_if_fail (argv != NULL); 489 g_return_if_fail (g_test_config_vars->test_initialized == FALSE); 490 mutable_test_config_vars.test_initialized = TRUE; 491 492 va_start (args, argv); 493 vararg1 = va_arg (args, gpointer); /* reserved for future extensions */ 494 va_end (args); 495 g_return_if_fail (vararg1 == NULL); 496 497 /* setup random seed string */ 498 g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x", g_random_int(), g_random_int(), g_random_int(), g_random_int()); 499 test_run_seedstr = seedstr; 500 501 /* parse args, sets up mode, changes seed, etc. */ 502 parse_args (argc, argv); 503 if (!g_get_prgname()) 504 g_set_prgname ((*argv)[0]); 505 506 /* verify GRand reliability, needed for reliable seeds */ 507 if (1) 508 { 509 GRand *rg = g_rand_new_with_seed (0xc8c49fb6); 510 guint32 t1 = g_rand_int (rg), t2 = g_rand_int (rg), t3 = g_rand_int (rg), t4 = g_rand_int (rg); 511 /* g_print ("GRand-current: 0x%x 0x%x 0x%x 0x%x\n", t1, t2, t3, t4); */ 512 if (t1 != 0xfab39f9b || t2 != 0xb948fb0e || t3 != 0x3d31be26 || t4 != 0x43a19d66) 513 g_warning ("random numbers are not GRand-2.2 compatible, seeds may be broken (check $G_RANDOM_VERSION)"); 514 g_rand_free (rg); 515 } 516 517 /* check rand seed */ 518 test_run_seed (test_run_seedstr); 519 520 /* report program start */ 521 g_log_set_default_handler (gtest_default_log_handler, NULL); 522 g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL); 523 } 524 525 static void 526 test_run_seed (const gchar *rseed) 527 { 528 guint seed_failed = 0; 529 if (test_run_rand) 530 g_rand_free (test_run_rand); 531 test_run_rand = NULL; 532 while (strchr (" \t\v\r\n\f", *rseed)) 533 rseed++; 534 if (strncmp (rseed, "R02S", 4) == 0) /* seed for random generator 02 (GRand-2.2) */ 535 { 536 const char *s = rseed + 4; 537 if (strlen (s) >= 32) /* require 4 * 8 chars */ 538 { 539 guint32 seedarray[4]; 540 gchar *p, hexbuf[9] = { 0, }; 541 memcpy (hexbuf, s + 0, 8); 542 seedarray[0] = g_ascii_strtoull (hexbuf, &p, 16); 543 seed_failed += p != NULL && *p != 0; 544 memcpy (hexbuf, s + 8, 8); 545 seedarray[1] = g_ascii_strtoull (hexbuf, &p, 16); 546 seed_failed += p != NULL && *p != 0; 547 memcpy (hexbuf, s + 16, 8); 548 seedarray[2] = g_ascii_strtoull (hexbuf, &p, 16); 549 seed_failed += p != NULL && *p != 0; 550 memcpy (hexbuf, s + 24, 8); 551 seedarray[3] = g_ascii_strtoull (hexbuf, &p, 16); 552 seed_failed += p != NULL && *p != 0; 553 if (!seed_failed) 554 { 555 test_run_rand = g_rand_new_with_seed_array (seedarray, 4); 556 return; 557 } 558 } 559 } 560 g_error ("Unknown or invalid random seed: %s", rseed); 561 } 562 563 /** 564 * g_test_rand_int: 565 * 566 * Get a reproducible random integer number. 567 * 568 * The random numbers generated by the g_test_rand_*() family of functions 569 * change with every new test program start, unless the --seed option is 570 * given when starting test programs. 571 * 572 * For individual test cases however, the random number generator is 573 * reseeded, to avoid dependencies between tests and to make --seed 574 * effective for all test cases. 575 * 576 * Returns: a random number from the seeded random number generator. 577 * 578 * Since: 2.16 579 */ 580 gint32 581 g_test_rand_int (void) 582 { 583 return g_rand_int (test_run_rand); 584 } 585 586 /** 587 * g_test_rand_int_range: 588 * @begin: the minimum value returned by this function 589 * @end: the smallest value not to be returned by this function 590 * 591 * Get a reproducible random integer number out of a specified range, 592 * see g_test_rand_int() for details on test case random numbers. 593 * 594 * Returns: a number with @begin <= number < @end. 595 * 596 * Since: 2.16 597 */ 598 gint32 599 g_test_rand_int_range (gint32 begin, 600 gint32 end) 601 { 602 return g_rand_int_range (test_run_rand, begin, end); 603 } 604 605 /** 606 * g_test_rand_double: 607 * 608 * Get a reproducible random floating point number, 609 * see g_test_rand_int() for details on test case random numbers. 610 * 611 * Returns: a random number from the seeded random number generator. 612 * 613 * Since: 2.16 614 */ 615 double 616 g_test_rand_double (void) 617 { 618 return g_rand_double (test_run_rand); 619 } 620 621 /** 622 * g_test_rand_double_range: 623 * @range_start: the minimum value returned by this function 624 * @range_end: the minimum value not returned by this function 625 * 626 * Get a reproducible random floating pointer number out of a specified range, 627 * see g_test_rand_int() for details on test case random numbers. 628 * 629 * Returns: a number with @range_start <= number < @range_end. 630 * 631 * Since: 2.16 632 */ 633 double 634 g_test_rand_double_range (double range_start, 635 double range_end) 636 { 637 return g_rand_double_range (test_run_rand, range_start, range_end); 638 } 639 640 /** 641 * g_test_timer_start: 642 * 643 * Start a timing test. Call g_test_timer_elapsed() when the task is supposed 644 * to be done. Call this function again to restart the timer. 645 * 646 * Since: 2.16 647 */ 648 void 649 g_test_timer_start (void) 650 { 651 if (!test_user_timer) 652 test_user_timer = g_timer_new(); 653 test_user_stamp = 0; 654 g_timer_start (test_user_timer); 655 } 656 657 /** 658 * g_test_timer_elapsed: 659 * 660 * Get the time since the last start of the timer with g_test_timer_start(). 661 * 662 * Returns: the time since the last start of the timer, as a double 663 * 664 * Since: 2.16 665 */ 666 double 667 g_test_timer_elapsed (void) 668 { 669 test_user_stamp = test_user_timer ? g_timer_elapsed (test_user_timer, NULL) : 0; 670 return test_user_stamp; 671 } 672 673 /** 674 * g_test_timer_last: 675 * 676 * Report the last result of g_test_timer_elapsed(). 677 * 678 * Returns: the last result of g_test_timer_elapsed(), as a double 679 * 680 * Since: 2.16 681 */ 682 double 683 g_test_timer_last (void) 684 { 685 return test_user_stamp; 686 } 687 688 /** 689 * g_test_minimized_result: 690 * @minimized_quantity: the reported value 691 * @format: the format string of the report message 692 * @Varargs: arguments to pass to the printf() function 693 * 694 * Report the result of a performance or measurement test. 695 * The test should generally strive to minimize the reported 696 * quantities (smaller values are better than larger ones), 697 * this and @minimized_quantity can determine sorting 698 * order for test result reports. 699 * 700 * Since: 2.16 701 */ 702 void 703 g_test_minimized_result (double minimized_quantity, 704 const char *format, 705 ...) 706 { 707 long double largs = minimized_quantity; 708 gchar *buffer; 709 va_list args; 710 va_start (args, format); 711 buffer = g_strdup_vprintf (format, args); 712 va_end (args); 713 g_test_log (G_TEST_LOG_MIN_RESULT, buffer, NULL, 1, &largs); 714 g_free (buffer); 715 } 716 717 /** 718 * g_test_maximized_result: 719 * @maximized_quantity: the reported value 720 * @format: the format string of the report message 721 * @Varargs: arguments to pass to the printf() function 722 * 723 * Report the result of a performance or measurement test. 724 * The test should generally strive to maximize the reported 725 * quantities (larger values are better than smaller ones), 726 * this and @maximized_quantity can determine sorting 727 * order for test result reports. 728 * 729 * Since: 2.16 730 */ 731 void 732 g_test_maximized_result (double maximized_quantity, 733 const char *format, 734 ...) 735 { 736 long double largs = maximized_quantity; 737 gchar *buffer; 738 va_list args; 739 va_start (args, format); 740 buffer = g_strdup_vprintf (format, args); 741 va_end (args); 742 g_test_log (G_TEST_LOG_MAX_RESULT, buffer, NULL, 1, &largs); 743 g_free (buffer); 744 } 745 746 /** 747 * g_test_message: 748 * @format: the format string 749 * @...: printf-like arguments to @format 750 * 751 * Add a message to the test report. 752 * 753 * Since: 2.16 754 */ 755 void 756 g_test_message (const char *format, 757 ...) 758 { 759 gchar *buffer; 760 va_list args; 761 va_start (args, format); 762 buffer = g_strdup_vprintf (format, args); 763 va_end (args); 764 g_test_log (G_TEST_LOG_MESSAGE, buffer, NULL, 0, NULL); 765 g_free (buffer); 766 } 767 768 /** 769 * g_test_bug_base: 770 * @uri_pattern: the base pattern for bug URIs 771 * 772 * Specify the base URI for bug reports. 773 * 774 * The base URI is used to construct bug report messages for 775 * g_test_message() when g_test_bug() is called. 776 * Calling this function outside of a test case sets the 777 * default base URI for all test cases. Calling it from within 778 * a test case changes the base URI for the scope of the test 779 * case only. 780 * Bug URIs are constructed by appending a bug specific URI 781 * portion to @uri_pattern, or by replacing the special string 782 * '%s' within @uri_pattern if that is present. 783 * 784 * Since: 2.16 785 */ 786 void 787 g_test_bug_base (const char *uri_pattern) 788 { 789 g_free (test_uri_base); 790 test_uri_base = g_strdup (uri_pattern); 791 } 792 793 /** 794 * g_test_bug: 795 * @bug_uri_snippet: Bug specific bug tracker URI portion. 796 * 797 * This function adds a message to test reports that 798 * associates a bug URI with a test case. 799 * Bug URIs are constructed from a base URI set with g_test_bug_base() 800 * and @bug_uri_snippet. 801 * 802 * Since: 2.16 803 */ 804 void 805 g_test_bug (const char *bug_uri_snippet) 806 { 807 char *c; 808 g_return_if_fail (test_uri_base != NULL); 809 g_return_if_fail (bug_uri_snippet != NULL); 810 c = strstr (test_uri_base, "%s"); 811 if (c) 812 { 813 char *b = g_strndup (test_uri_base, c - test_uri_base); 814 char *s = g_strconcat (b, bug_uri_snippet, c + 2, NULL); 815 g_free (b); 816 g_test_message ("Bug Reference: %s", s); 817 g_free (s); 818 } 819 else 820 g_test_message ("Bug Reference: %s%s", test_uri_base, bug_uri_snippet); 821 } 822 823 /** 824 * g_test_get_root: 825 * 826 * Get the toplevel test suite for the test path API. 827 * 828 * Returns: the toplevel #GTestSuite 829 * 830 * Since: 2.16 831 */ 832 GTestSuite* 833 g_test_get_root (void) 834 { 835 if (!test_suite_root) 836 { 837 test_suite_root = g_test_create_suite ("root"); 838 g_free (test_suite_root->name); 839 test_suite_root->name = g_strdup (""); 840 } 841 return test_suite_root; 842 } 843 844 /** 845 * g_test_run: 846 * 847 * Runs all tests under the toplevel suite which can be retrieved 848 * with g_test_get_root(). Similar to g_test_run_suite(), the test 849 * cases to be run are filtered according to 850 * test path arguments (-p <replaceable>testpath</replaceable>) as 851 * parsed by g_test_init(). 852 * g_test_run_suite() or g_test_run() may only be called once 853 * in a program. 854 * 855 * Returns: 0 on success 856 * 857 * Since: 2.16 858 */ 859 int 860 g_test_run (void) 861 { 862 return g_test_run_suite (g_test_get_root()); 863 } 864 865 /** 866 * g_test_create_case: 867 * @test_name: the name for the test case 868 * @data_size: the size of the fixture data structure 869 * @test_data: test data argument for the test functions 870 * @data_setup: the function to set up the fixture data 871 * @data_test: the actual test function 872 * @data_teardown: the function to teardown the fixture data 873 * 874 * Create a new #GTestCase, named @test_name, this API is fairly 875 * low level, calling g_test_add() or g_test_add_func() is preferable. 876 * When this test is executed, a fixture structure of size @data_size 877 * will be allocated and filled with 0s. Then data_setup() is called 878 * to initialize the fixture. After fixture setup, the actual test 879 * function data_test() is called. Once the test run completed, the 880 * fixture structure is torn down by calling data_teardown() and 881 * after that the memory is released. 882 * 883 * Splitting up a test run into fixture setup, test function and 884 * fixture teardown is most usful if the same fixture is used for 885 * multiple tests. In this cases, g_test_create_case() will be 886 * called with the same fixture, but varying @test_name and 887 * @data_test arguments. 888 * 889 * Returns: a newly allocated #GTestCase. 890 * 891 * Since: 2.16 892 */ 893 GTestCase* 894 g_test_create_case (const char *test_name, 895 gsize data_size, 896 gconstpointer test_data, 897 void (*data_setup) (void), 898 void (*data_test) (void), 899 void (*data_teardown) (void)) 900 { 901 GTestCase *tc; 902 g_return_val_if_fail (test_name != NULL, NULL); 903 g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL); 904 g_return_val_if_fail (test_name[0] != 0, NULL); 905 g_return_val_if_fail (data_test != NULL, NULL); 906 tc = g_slice_new0 (GTestCase); 907 tc->name = g_strdup (test_name); 908 tc->test_data = (gpointer) test_data; 909 tc->fixture_size = data_size; 910 tc->fixture_setup = (void*) data_setup; 911 tc->fixture_test = (void*) data_test; 912 tc->fixture_teardown = (void*) data_teardown; 913 return tc; 914 } 915 916 void 917 g_test_add_vtable (const char *testpath, 918 gsize data_size, 919 gconstpointer test_data, 920 void (*data_setup) (void), 921 void (*fixture_test_func) (void), 922 void (*data_teardown) (void)) 923 { 924 gchar **segments; 925 guint ui; 926 GTestSuite *suite; 927 928 g_return_if_fail (testpath != NULL); 929 g_return_if_fail (testpath[0] == '/'); 930 g_return_if_fail (fixture_test_func != NULL); 931 932 suite = g_test_get_root(); 933 segments = g_strsplit (testpath, "/", -1); 934 for (ui = 0; segments[ui] != NULL; ui++) 935 { 936 const char *seg = segments[ui]; 937 gboolean islast = segments[ui + 1] == NULL; 938 if (islast && !seg[0]) 939 g_error ("invalid test case path: %s", testpath); 940 else if (!seg[0]) 941 continue; /* initial or duplicate slash */ 942 else if (!islast) 943 { 944 GTestSuite *csuite = g_test_create_suite (seg); 945 g_test_suite_add_suite (suite, csuite); 946 suite = csuite; 947 } 948 else /* islast */ 949 { 950 GTestCase *tc = g_test_create_case (seg, data_size, test_data, data_setup, fixture_test_func, data_teardown); 951 g_test_suite_add (suite, tc); 952 } 953 } 954 g_strfreev (segments); 955 } 956 957 /** 958 * g_test_add_func: 959 * @testpath: Slash-separated test case path name for the test. 960 * @test_func: The test function to invoke for this test. 961 * 962 * Create a new test case, similar to g_test_create_case(). However 963 * the test is assumed to use no fixture, and test suites are automatically 964 * created on the fly and added to the root fixture, based on the 965 * slash-separated portions of @testpath. 966 * 967 * Since: 2.16 968 */ 969 void 970 g_test_add_func (const char *testpath, 971 void (*test_func) (void)) 972 { 973 g_return_if_fail (testpath != NULL); 974 g_return_if_fail (testpath[0] == '/'); 975 g_return_if_fail (test_func != NULL); 976 g_test_add_vtable (testpath, 0, NULL, NULL, test_func, NULL); 977 } 978 979 /** 980 * g_test_add_data_func: 981 * @testpath: Slash-separated test case path name for the test. 982 * @test_data: Test data argument for the test function. 983 * @test_func: The test function to invoke for this test. 984 * 985 * Create a new test case, similar to g_test_create_case(). However 986 * the test is assumed to use no fixture, and test suites are automatically 987 * created on the fly and added to the root fixture, based on the 988 * slash-separated portions of @testpath. The @test_data argument 989 * will be passed as first argument to @test_func. 990 * 991 * Since: 2.16 992 */ 993 void 994 g_test_add_data_func (const char *testpath, 995 gconstpointer test_data, 996 void (*test_func) (gconstpointer)) 997 { 998 g_return_if_fail (testpath != NULL); 999 g_return_if_fail (testpath[0] == '/'); 1000 g_return_if_fail (test_func != NULL); 1001 g_test_add_vtable (testpath, 0, test_data, NULL, (void(*)(void)) test_func, NULL); 1002 } 1003 1004 /** 1005 * g_test_create_suite: 1006 * @suite_name: a name for the suite 1007 * 1008 * Create a new test suite with the name @suite_name. 1009 * 1010 * Returns: A newly allocated #GTestSuite instance. 1011 * 1012 * Since: 2.16 1013 */ 1014 GTestSuite* 1015 g_test_create_suite (const char *suite_name) 1016 { 1017 GTestSuite *ts; 1018 g_return_val_if_fail (suite_name != NULL, NULL); 1019 g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL); 1020 g_return_val_if_fail (suite_name[0] != 0, NULL); 1021 ts = g_slice_new0 (GTestSuite); 1022 ts->name = g_strdup (suite_name); 1023 return ts; 1024 } 1025 1026 /** 1027 * g_test_suite_add: 1028 * @suite: a #GTestSuite 1029 * @test_case: a #GTestCase 1030 * 1031 * Adds @test_case to @suite. 1032 * 1033 * Since: 2.16 1034 */ 1035 void 1036 g_test_suite_add (GTestSuite *suite, 1037 GTestCase *test_case) 1038 { 1039 g_return_if_fail (suite != NULL); 1040 g_return_if_fail (test_case != NULL); 1041 suite->cases = g_slist_prepend (suite->cases, test_case); 1042 } 1043 1044 /** 1045 * g_test_suite_add_suite: 1046 * @suite: a #GTestSuite 1047 * @nestedsuite: another #GTestSuite 1048 * 1049 * Adds @nestedsuite to @suite. 1050 * 1051 * Since: 2.16 1052 */ 1053 void 1054 g_test_suite_add_suite (GTestSuite *suite, 1055 GTestSuite *nestedsuite) 1056 { 1057 g_return_if_fail (suite != NULL); 1058 g_return_if_fail (nestedsuite != NULL); 1059 suite->suites = g_slist_prepend (suite->suites, nestedsuite); 1060 } 1061 1062 /** 1063 * g_test_queue_free: 1064 * @gfree_pointer: the pointer to be stored. 1065 * 1066 * Enqueue a pointer to be released with g_free() during the next 1067 * teardown phase. This is equivalent to calling g_test_queue_destroy() 1068 * with a destroy callback of g_free(). 1069 * 1070 * Since: 2.16 1071 */ 1072 void 1073 g_test_queue_free (gpointer gfree_pointer) 1074 { 1075 if (gfree_pointer) 1076 g_test_queue_destroy (g_free, gfree_pointer); 1077 } 1078 1079 /** 1080 * g_test_queue_destroy: 1081 * @destroy_func: Destroy callback for teardown phase. 1082 * @destroy_data: Destroy callback data. 1083 * 1084 * This function enqueus a callback @destroy_func() to be executed 1085 * during the next test case teardown phase. This is most useful 1086 * to auto destruct allocted test resources at the end of a test run. 1087 * Resources are released in reverse queue order, that means enqueueing 1088 * callback A before callback B will cause B() to be called before 1089 * A() during teardown. 1090 * 1091 * Since: 2.16 1092 */ 1093 void 1094 g_test_queue_destroy (GDestroyNotify destroy_func, 1095 gpointer destroy_data) 1096 { 1097 DestroyEntry *dentry; 1098 g_return_if_fail (destroy_func != NULL); 1099 dentry = g_slice_new0 (DestroyEntry); 1100 dentry->destroy_func = destroy_func; 1101 dentry->destroy_data = destroy_data; 1102 dentry->next = test_destroy_queue; 1103 test_destroy_queue = dentry; 1104 } 1105 1106 static int 1107 test_case_run (GTestCase *tc) 1108 { 1109 gchar *old_name = test_run_name, *old_base = g_strdup (test_uri_base); 1110 test_run_name = g_strconcat (old_name, "/", tc->name, NULL); 1111 if (++test_run_count <= test_skip_count) 1112 g_test_log (G_TEST_LOG_SKIP_CASE, test_run_name, NULL, 0, NULL); 1113 else if (test_run_list) 1114 { 1115 g_print ("%s\n", test_run_name); 1116 g_test_log (G_TEST_LOG_LIST_CASE, test_run_name, NULL, 0, NULL); 1117 } 1118 else 1119 { 1120 GTimer *test_run_timer = g_timer_new(); 1121 long double largs[3]; 1122 void *fixture; 1123 g_test_log (G_TEST_LOG_START_CASE, test_run_name, NULL, 0, NULL); 1124 test_run_forks = 0; 1125 g_timer_start (test_run_timer); 1126 fixture = tc->fixture_size ? g_malloc0 (tc->fixture_size) : tc->test_data; 1127 test_run_seed (test_run_seedstr); 1128 if (tc->fixture_setup) 1129 tc->fixture_setup (fixture, tc->test_data); 1130 tc->fixture_test (fixture, tc->test_data); 1131 test_trap_clear(); 1132 while (test_destroy_queue) 1133 { 1134 DestroyEntry *dentry = test_destroy_queue; 1135 test_destroy_queue = dentry->next; 1136 dentry->destroy_func (dentry->destroy_data); 1137 g_slice_free (DestroyEntry, dentry); 1138 } 1139 if (tc->fixture_teardown) 1140 tc->fixture_teardown (fixture, tc->test_data); 1141 if (tc->fixture_size) 1142 g_free (fixture); 1143 g_timer_stop (test_run_timer); 1144 largs[0] = 0; /* OK */ 1145 largs[1] = test_run_forks; 1146 largs[2] = g_timer_elapsed (test_run_timer, NULL); 1147 g_test_log (G_TEST_LOG_STOP_CASE, NULL, NULL, G_N_ELEMENTS (largs), largs); 1148 g_timer_destroy (test_run_timer); 1149 } 1150 g_free (test_run_name); 1151 test_run_name = old_name; 1152 g_free (test_uri_base); 1153 test_uri_base = old_base; 1154 return 0; 1155 } 1156 1157 static int 1158 g_test_run_suite_internal (GTestSuite *suite, 1159 const char *path) 1160 { 1161 guint n_bad = 0, n_good = 0, bad_suite = 0, l; 1162 gchar *rest, *old_name = test_run_name; 1163 GSList *slist, *reversed; 1164 g_return_val_if_fail (suite != NULL, -1); 1165 while (path[0] == '/') 1166 path++; 1167 l = strlen (path); 1168 rest = strchr (path, '/'); 1169 l = rest ? MIN (l, rest - path) : l; 1170 test_run_name = suite->name[0] == 0 ? g_strdup (test_run_name) : g_strconcat (old_name, "/", suite->name, NULL); 1171 reversed = g_slist_reverse (g_slist_copy (suite->cases)); 1172 for (slist = reversed; slist; slist = slist->next) 1173 { 1174 GTestCase *tc = slist->data; 1175 guint n = l ? strlen (tc->name) : 0; 1176 if (l == n && strncmp (path, tc->name, n) == 0) 1177 { 1178 n_good++; 1179 n_bad += test_case_run (tc) != 0; 1180 } 1181 } 1182 g_slist_free (reversed); 1183 reversed = g_slist_reverse (g_slist_copy (suite->suites)); 1184 for (slist = reversed; slist; slist = slist->next) 1185 { 1186 GTestSuite *ts = slist->data; 1187 guint n = l ? strlen (ts->name) : 0; 1188 if (l == n && strncmp (path, ts->name, n) == 0) 1189 bad_suite += g_test_run_suite_internal (ts, rest ? rest : "") != 0; 1190 } 1191 g_slist_free (reversed); 1192 g_free (test_run_name); 1193 test_run_name = old_name; 1194 return n_bad || bad_suite; 1195 } 1196 1197 /** 1198 * g_test_run_suite: 1199 * @suite: a #GTestSuite 1200 * 1201 * Execute the tests within @suite and all nested #GTestSuites. 1202 * The test suites to be executed are filtered according to 1203 * test path arguments (-p <replaceable>testpath</replaceable>) 1204 * as parsed by g_test_init(). 1205 * g_test_run_suite() or g_test_run() may only be called once 1206 * in a program. 1207 * 1208 * Returns: 0 on success 1209 * 1210 * Since: 2.16 1211 */ 1212 int 1213 g_test_run_suite (GTestSuite *suite) 1214 { 1215 guint n_bad = 0; 1216 g_return_val_if_fail (g_test_config_vars->test_initialized, -1); 1217 g_return_val_if_fail (g_test_run_once == TRUE, -1); 1218 g_test_run_once = FALSE; 1219 if (!test_paths) 1220 test_paths = g_slist_prepend (test_paths, ""); 1221 while (test_paths) 1222 { 1223 const char *rest, *path = test_paths->data; 1224 guint l, n = strlen (suite->name); 1225 test_paths = g_slist_delete_link (test_paths, test_paths); 1226 while (path[0] == '/') 1227 path++; 1228 if (!n) /* root suite, run unconditionally */ 1229 { 1230 n_bad += 0 != g_test_run_suite_internal (suite, path); 1231 continue; 1232 } 1233 /* regular suite, match path */ 1234 rest = strchr (path, '/'); 1235 l = strlen (path); 1236 l = rest ? MIN (l, rest - path) : l; 1237 if ((!l || l == n) && strncmp (path, suite->name, n) == 0) 1238 n_bad += 0 != g_test_run_suite_internal (suite, rest ? rest : ""); 1239 } 1240 return n_bad; 1241 } 1242 1243 static void 1244 gtest_default_log_handler (const gchar *log_domain, 1245 GLogLevelFlags log_level, 1246 const gchar *message, 1247 gpointer unused_data) 1248 { 1249 const gchar *strv[16]; 1250 gchar *msg; 1251 guint i = 0; 1252 if (log_domain) 1253 { 1254 strv[i++] = log_domain; 1255 strv[i++] = "-"; 1256 } 1257 if (log_level & G_LOG_FLAG_FATAL) 1258 strv[i++] = "FATAL-"; 1259 if (log_level & G_LOG_FLAG_RECURSION) 1260 strv[i++] = "RECURSIVE-"; 1261 if (log_level & G_LOG_LEVEL_ERROR) 1262 strv[i++] = "ERROR"; 1263 if (log_level & G_LOG_LEVEL_CRITICAL) 1264 strv[i++] = "CRITICAL"; 1265 if (log_level & G_LOG_LEVEL_WARNING) 1266 strv[i++] = "WARNING"; 1267 if (log_level & G_LOG_LEVEL_MESSAGE) 1268 strv[i++] = "MESSAGE"; 1269 if (log_level & G_LOG_LEVEL_INFO) 1270 strv[i++] = "INFO"; 1271 if (log_level & G_LOG_LEVEL_DEBUG) 1272 strv[i++] = "DEBUG"; 1273 strv[i++] = ": "; 1274 strv[i++] = message; 1275 strv[i++] = NULL; 1276 msg = g_strjoinv ("", (gchar**) strv); 1277 g_test_log (G_TEST_LOG_ERROR, msg, NULL, 0, NULL); 1278 g_log_default_handler (log_domain, log_level, message, unused_data); 1279 g_free (msg); 1280 } 1281 1282 void 1283 g_assertion_message (const char *domain, 1284 const char *file, 1285 int line, 1286 const char *func, 1287 const char *message) 1288 { 1289 char lstr[32]; 1290 char *s; 1291 if (!message) 1292 message = "code should not be reached"; 1293 g_snprintf (lstr, 32, "%d", line); 1294 s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "", 1295 "ERROR:", file, ":", lstr, ":", 1296 func, func[0] ? ":" : "", 1297 " ", message, NULL); 1298 g_printerr ("**\n%s\n", s); 1299 g_test_log (G_TEST_LOG_ERROR, s, NULL, 0, NULL); 1300 g_free (s); 1301 abort(); 1302 } 1303 1304 void 1305 g_assertion_message_expr (const char *domain, 1306 const char *file, 1307 int line, 1308 const char *func, 1309 const char *expr) 1310 { 1311 char *s = g_strconcat ("assertion failed: (", expr, ")", NULL); 1312 g_assertion_message (domain, file, line, func, s); 1313 g_free (s); 1314 } 1315 1316 void 1317 g_assertion_message_cmpnum (const char *domain, 1318 const char *file, 1319 int line, 1320 const char *func, 1321 const char *expr, 1322 long double arg1, 1323 const char *cmp, 1324 long double arg2, 1325 char numtype) 1326 { 1327 char *s = NULL; 1328 switch (numtype) 1329 { 1330 case 'i': s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break; 1331 case 'x': s = g_strdup_printf ("assertion failed (%s): (0x%08" G_GINT64_MODIFIER "x %s 0x%08" G_GINT64_MODIFIER "x)", expr, (guint64) arg1, cmp, (guint64) arg2); break; 1332 case 'f': s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break; 1333 /* ideally use: floats=%.7g double=%.17g */ 1334 } 1335 g_assertion_message (domain, file, line, func, s); 1336 g_free (s); 1337 } 1338 1339 void 1340 g_assertion_message_cmpstr (const char *domain, 1341 const char *file, 1342 int line, 1343 const char *func, 1344 const char *expr, 1345 const char *arg1, 1346 const char *cmp, 1347 const char *arg2) 1348 { 1349 char *a1, *a2, *s, *t1 = NULL, *t2 = NULL; 1350 a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL"); 1351 a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL"); 1352 g_free (t1); 1353 g_free (t2); 1354 s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2); 1355 g_free (a1); 1356 g_free (a2); 1357 g_assertion_message (domain, file, line, func, s); 1358 g_free (s); 1359 } 1360 1361 void 1362 g_assertion_message_error (const char *domain, 1363 const char *file, 1364 int line, 1365 const char *func, 1366 const char *expr, 1367 GError *error, 1368 GQuark error_domain, 1369 int error_code) 1370 { 1371 GString *gstring; 1372 1373 /* This is used by both g_assert_error() and g_assert_no_error(), so there 1374 * are three cases: expected an error but got the wrong error, expected 1375 * an error but got no error, and expected no error but got an error. 1376 */ 1377 1378 gstring = g_string_new ("assertion failed "); 1379 if (error_domain) 1380 g_string_append_printf (gstring, "(%s == (%s, %d)): ", expr, 1381 g_quark_to_string (error_domain), error_code); 1382 else 1383 g_string_append_printf (gstring, "(%s == NULL): ", expr); 1384 1385 if (error) 1386 g_string_append_printf (gstring, "%s (%s, %d)", error->message, 1387 g_quark_to_string (error->domain), error->code); 1388 else 1389 g_string_append_printf (gstring, "%s is NULL", expr); 1390 1391 g_assertion_message (domain, file, line, func, gstring->str); 1392 g_string_free (gstring, TRUE); 1393 } 1394 1395 /** 1396 * g_strcmp0: 1397 * @str1: a C string or %NULL 1398 * @str2: another C string or %NULL 1399 * 1400 * Compares @str1 and @str2 like strcmp(). Handles %NULL 1401 * gracefully by sorting it before non-%NULL strings. 1402 * 1403 * Returns: -1, 0 or 1, if @str1 is <, == or > than @str2. 1404 * 1405 * Since: 2.16 1406 */ 1407 int 1408 g_strcmp0 (const char *str1, 1409 const char *str2) 1410 { 1411 if (!str1) 1412 return -(str1 != str2); 1413 if (!str2) 1414 return str1 != str2; 1415 return strcmp (str1, str2); 1416 } 1417 1418 #ifdef G_OS_UNIX 1419 static int /* 0 on success */ 1420 kill_child (int pid, 1421 int *status, 1422 int patience) 1423 { 1424 int wr; 1425 if (patience >= 3) /* try graceful reap */ 1426 { 1427 if (waitpid (pid, status, WNOHANG) > 0) 1428 return 0; 1429 } 1430 if (patience >= 2) /* try SIGHUP */ 1431 { 1432 kill (pid, SIGHUP); 1433 if (waitpid (pid, status, WNOHANG) > 0) 1434 return 0; 1435 g_usleep (20 * 1000); /* give it some scheduling/shutdown time */ 1436 if (waitpid (pid, status, WNOHANG) > 0) 1437 return 0; 1438 g_usleep (50 * 1000); /* give it some scheduling/shutdown time */ 1439 if (waitpid (pid, status, WNOHANG) > 0) 1440 return 0; 1441 g_usleep (100 * 1000); /* give it some scheduling/shutdown time */ 1442 if (waitpid (pid, status, WNOHANG) > 0) 1443 return 0; 1444 } 1445 if (patience >= 1) /* try SIGTERM */ 1446 { 1447 kill (pid, SIGTERM); 1448 if (waitpid (pid, status, WNOHANG) > 0) 1449 return 0; 1450 g_usleep (200 * 1000); /* give it some scheduling/shutdown time */ 1451 if (waitpid (pid, status, WNOHANG) > 0) 1452 return 0; 1453 g_usleep (400 * 1000); /* give it some scheduling/shutdown time */ 1454 if (waitpid (pid, status, WNOHANG) > 0) 1455 return 0; 1456 } 1457 /* finish it off */ 1458 kill (pid, SIGKILL); 1459 do 1460 wr = waitpid (pid, status, 0); 1461 while (wr < 0 && errno == EINTR); 1462 return wr; 1463 } 1464 #endif 1465 1466 static inline int 1467 g_string_must_read (GString *gstring, 1468 int fd) 1469 { 1470 #define STRING_BUFFER_SIZE 4096 1471 char buf[STRING_BUFFER_SIZE]; 1472 gssize bytes; 1473 again: 1474 bytes = read (fd, buf, sizeof (buf)); 1475 if (bytes == 0) 1476 return 0; /* EOF, calling this function assumes data is available */ 1477 else if (bytes > 0) 1478 { 1479 g_string_append_len (gstring, buf, bytes); 1480 return 1; 1481 } 1482 else if (bytes < 0 && errno == EINTR) 1483 goto again; 1484 else /* bytes < 0 */ 1485 { 1486 g_warning ("failed to read() from child process (%d): %s", test_trap_last_pid, g_strerror (errno)); 1487 return 1; /* ignore error after warning */ 1488 } 1489 } 1490 1491 static inline void 1492 g_string_write_out (GString *gstring, 1493 int outfd, 1494 int *stringpos) 1495 { 1496 if (*stringpos < gstring->len) 1497 { 1498 int r; 1499 do 1500 r = write (outfd, gstring->str + *stringpos, gstring->len - *stringpos); 1501 while (r < 0 && errno == EINTR); 1502 *stringpos += MAX (r, 0); 1503 } 1504 } 1505 1506 static void 1507 test_trap_clear (void) 1508 { 1509 test_trap_last_status = 0; 1510 test_trap_last_pid = 0; 1511 g_free (test_trap_last_stdout); 1512 test_trap_last_stdout = NULL; 1513 g_free (test_trap_last_stderr); 1514 test_trap_last_stderr = NULL; 1515 } 1516 1517 #ifdef G_OS_UNIX 1518 1519 static int 1520 sane_dup2 (int fd1, 1521 int fd2) 1522 { 1523 int ret; 1524 do 1525 ret = dup2 (fd1, fd2); 1526 while (ret < 0 && errno == EINTR); 1527 return ret; 1528 } 1529 1530 static guint64 1531 test_time_stamp (void) 1532 { 1533 GTimeVal tv; 1534 guint64 stamp; 1535 g_get_current_time (&tv); 1536 stamp = tv.tv_sec; 1537 stamp = stamp * 1000000 + tv.tv_usec; 1538 return stamp; 1539 } 1540 1541 #endif 1542 1543 /** 1544 * g_test_trap_fork: 1545 * @usec_timeout: Timeout for the forked test in micro seconds. 1546 * @test_trap_flags: Flags to modify forking behaviour. 1547 * 1548 * Fork the current test program to execute a test case that might 1549 * not return or that might abort. The forked test case is aborted 1550 * and considered failing if its run time exceeds @usec_timeout. 1551 * 1552 * The forking behavior can be configured with the #GTestTrapFlags flags. 1553 * 1554 * In the following example, the test code forks, the forked child 1555 * process produces some sample output and exits successfully. 1556 * The forking parent process then asserts successful child program 1557 * termination and validates child program outputs. 1558 * 1559 * |[ 1560 * static void 1561 * test_fork_patterns (void) 1562 * { 1563 * if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) 1564 * { 1565 * g_print ("some stdout text: somagic17\n"); 1566 * g_printerr ("some stderr text: semagic43\n"); 1567 * exit (0); /* successful test run */ 1568 * } 1569 * g_test_trap_assert_passed(); 1570 * g_test_trap_assert_stdout ("*somagic17*"); 1571 * g_test_trap_assert_stderr ("*semagic43*"); 1572 * } 1573 * ]| 1574 * 1575 * This function is implemented only on Unix platforms. 1576 * 1577 * Returns: %TRUE for the forked child and %FALSE for the executing parent process. 1578 * 1579 * Since: 2.16 1580 */ 1581 gboolean 1582 g_test_trap_fork (guint64 usec_timeout, 1583 GTestTrapFlags test_trap_flags) 1584 { 1585 #ifdef G_OS_UNIX 1586 gboolean pass_on_forked_log = FALSE; 1587 int stdout_pipe[2] = { -1, -1 }; 1588 int stderr_pipe[2] = { -1, -1 }; 1589 int stdtst_pipe[2] = { -1, -1 }; 1590 test_trap_clear(); 1591 if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0 || pipe (stdtst_pipe) < 0) 1592 g_error ("failed to create pipes to fork test program: %s", g_strerror (errno)); 1593 signal (SIGCHLD, SIG_DFL); 1594 test_trap_last_pid = fork (); 1595 if (test_trap_last_pid < 0) 1596 g_error ("failed to fork test program: %s", g_strerror (errno)); 1597 if (test_trap_last_pid == 0) /* child */ 1598 { 1599 int fd0 = -1; 1600 close (stdout_pipe[0]); 1601 close (stderr_pipe[0]); 1602 close (stdtst_pipe[0]); 1603 if (!(test_trap_flags & G_TEST_TRAP_INHERIT_STDIN)) 1604 fd0 = open ("/dev/null", O_RDONLY); 1605 if (sane_dup2 (stdout_pipe[1], 1) < 0 || sane_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && sane_dup2 (fd0, 0) < 0)) 1606 g_error ("failed to dup2() in forked test program: %s", g_strerror (errno)); 1607 if (fd0 >= 3) 1608 close (fd0); 1609 if (stdout_pipe[1] >= 3) 1610 close (stdout_pipe[1]); 1611 if (stderr_pipe[1] >= 3) 1612 close (stderr_pipe[1]); 1613 test_log_fd = stdtst_pipe[1]; 1614 return TRUE; 1615 } 1616 else /* parent */ 1617 { 1618 GString *sout = g_string_new (NULL); 1619 GString *serr = g_string_new (NULL); 1620 guint64 sstamp; 1621 int soutpos = 0, serrpos = 0, wr, need_wait = TRUE; 1622 test_run_forks++; 1623 close (stdout_pipe[1]); 1624 close (stderr_pipe[1]); 1625 close (stdtst_pipe[1]); 1626 sstamp = test_time_stamp(); 1627 /* read data until we get EOF on all pipes */ 1628 while (stdout_pipe[0] >= 0 || stderr_pipe[0] >= 0 || stdtst_pipe[0] > 0) 1629 { 1630 fd_set fds; 1631 struct timeval tv; 1632 int ret; 1633 FD_ZERO (&fds); 1634 if (stdout_pipe[0] >= 0) 1635 FD_SET (stdout_pipe[0], &fds); 1636 if (stderr_pipe[0] >= 0) 1637 FD_SET (stderr_pipe[0], &fds); 1638 if (stdtst_pipe[0] >= 0) 1639 FD_SET (stdtst_pipe[0], &fds); 1640 tv.tv_sec = 0; 1641 tv.tv_usec = MIN (usec_timeout ? usec_timeout : 1000000, 100 * 1000); /* sleep at most 0.5 seconds to catch clock skews, etc. */ 1642 ret = select (MAX (MAX (stdout_pipe[0], stderr_pipe[0]), stdtst_pipe[0]) + 1, &fds, NULL, NULL, &tv); 1643 if (ret < 0 && errno != EINTR) 1644 { 1645 g_warning ("Unexpected error in select() while reading from child process (%d): %s", test_trap_last_pid, g_strerror (errno)); 1646 break; 1647 } 1648 if (stdout_pipe[0] >= 0 && FD_ISSET (stdout_pipe[0], &fds) && 1649 g_string_must_read (sout, stdout_pipe[0]) == 0) 1650 { 1651 close (stdout_pipe[0]); 1652 stdout_pipe[0] = -1; 1653 } 1654 if (stderr_pipe[0] >= 0 && FD_ISSET (stderr_pipe[0], &fds) && 1655 g_string_must_read (serr, stderr_pipe[0]) == 0) 1656 { 1657 close (stderr_pipe[0]); 1658 stderr_pipe[0] = -1; 1659 } 1660 if (stdtst_pipe[0] >= 0 && FD_ISSET (stdtst_pipe[0], &fds)) 1661 { 1662 guint8 buffer[4096]; 1663 gint l, r = read (stdtst_pipe[0], buffer, sizeof (buffer)); 1664 if (r > 0 && test_log_fd > 0) 1665 do 1666 l = write (pass_on_forked_log ? test_log_fd : -1, buffer, r); 1667 while (l < 0 && errno == EINTR); 1668 if (r == 0 || (r < 0 && errno != EINTR && errno != EAGAIN)) 1669 { 1670 close (stdtst_pipe[0]); 1671 stdtst_pipe[0] = -1; 1672 } 1673 } 1674 if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDOUT)) 1675 g_string_write_out (sout, 1, &soutpos); 1676 if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDERR)) 1677 g_string_write_out (serr, 2, &serrpos); 1678 if (usec_timeout) 1679 { 1680 guint64 nstamp = test_time_stamp(); 1681 int status = 0; 1682 sstamp = MIN (sstamp, nstamp); /* guard against backwards clock skews */ 1683 if (usec_timeout < nstamp - sstamp) 1684 { 1685 /* timeout reached, need to abort the child now */ 1686 kill_child (test_trap_last_pid, &status, 3); 1687 test_trap_last_status = 1024; /* timeout */ 1688 if (0 && WIFSIGNALED (status)) 1689 g_printerr ("%s: child timed out and received: %s\n", G_STRFUNC, g_strsignal (WTERMSIG (status))); 1690 need_wait = FALSE; 1691 break; 1692 } 1693 } 1694 } 1695 close (stdout_pipe[0]); 1696 close (stderr_pipe[0]); 1697 close (stdtst_pipe[0]); 1698 if (need_wait) 1699 { 1700 int status = 0; 1701 do 1702 wr = waitpid (test_trap_last_pid, &status, 0); 1703 while (wr < 0 && errno == EINTR); 1704 if (WIFEXITED (status)) /* normal exit */ 1705 test_trap_last_status = WEXITSTATUS (status); /* 0..255 */ 1706 else if (WIFSIGNALED (status)) 1707 test_trap_last_status = (WTERMSIG (status) << 12); /* signalled */ 1708 else /* WCOREDUMP (status) */ 1709 test_trap_last_status = 512; /* coredump */ 1710 } 1711 test_trap_last_stdout = g_string_free (sout, FALSE); 1712 test_trap_last_stderr = g_string_free (serr, FALSE); 1713 return FALSE; 1714 } 1715 #else 1716 g_message ("Not implemented: g_test_trap_fork"); 1717 1718 return FALSE; 1719 #endif 1720 } 1721 1722 /** 1723 * g_test_trap_has_passed: 1724 * 1725 * Check the result of the last g_test_trap_fork() call. 1726 * 1727 * Returns: %TRUE if the last forked child terminated successfully. 1728 * 1729 * Since: 2.16 1730 */ 1731 gboolean 1732 g_test_trap_has_passed (void) 1733 { 1734 return test_trap_last_status == 0; /* exit_status == 0 && !signal && !coredump */ 1735 } 1736 1737 /** 1738 * g_test_trap_reached_timeout: 1739 * 1740 * Check the result of the last g_test_trap_fork() call. 1741 * 1742 * Returns: %TRUE if the last forked child got killed due to a fork timeout. 1743 * 1744 * Since: 2.16 1745 */ 1746 gboolean 1747 g_test_trap_reached_timeout (void) 1748 { 1749 return 0 != (test_trap_last_status & 1024); /* timeout flag */ 1750 } 1751 1752 void 1753 g_test_trap_assertions (const char *domain, 1754 const char *file, 1755 int line, 1756 const char *func, 1757 guint64 assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */ 1758 const char *pattern) 1759 { 1760 #ifdef G_OS_UNIX 1761 gboolean must_pass = assertion_flags == 0; 1762 gboolean must_fail = assertion_flags == 1; 1763 gboolean match_result = 0 == (assertion_flags & 1); 1764 const char *stdout_pattern = (assertion_flags & 2) ? pattern : NULL; 1765 const char *stderr_pattern = (assertion_flags & 4) ? pattern : NULL; 1766 const char *match_error = match_result ? "failed to match" : "contains invalid match"; 1767 if (test_trap_last_pid == 0) 1768 g_error ("child process failed to exit after g_test_trap_fork() and before g_test_trap_assert*()"); 1769 if (must_pass && !g_test_trap_has_passed()) 1770 { 1771 char *msg = g_strdup_printf ("child process (%d) of test trap failed unexpectedly", test_trap_last_pid); 1772 g_assertion_message (domain, file, line, func, msg); 1773 g_free (msg); 1774 } 1775 if (must_fail && g_test_trap_has_passed()) 1776 { 1777 char *msg = g_strdup_printf ("child process (%d) did not fail as expected", test_trap_last_pid); 1778 g_assertion_message (domain, file, line, func, msg); 1779 g_free (msg); 1780 } 1781 if (stdout_pattern && match_result == !g_pattern_match_simple (stdout_pattern, test_trap_last_stdout)) 1782 { 1783 char *msg = g_strdup_printf ("stdout of child process (%d) %s: %s", test_trap_last_pid, match_error, stdout_pattern); 1784 g_assertion_message (domain, file, line, func, msg); 1785 g_free (msg); 1786 } 1787 if (stderr_pattern && match_result == !g_pattern_match_simple (stderr_pattern, test_trap_last_stderr)) 1788 { 1789 char *msg = g_strdup_printf ("stderr of child process (%d) %s: %s", test_trap_last_pid, match_error, stderr_pattern); 1790 g_assertion_message (domain, file, line, func, msg); 1791 g_free (msg); 1792 } 1793 #endif 1794 } 1795 1796 static void 1797 gstring_overwrite_int (GString *gstring, 1798 guint pos, 1799 guint32 vuint) 1800 { 1801 vuint = g_htonl (vuint); 1802 g_string_overwrite_len (gstring, pos, (const gchar*) &vuint, 4); 1803 } 1804 1805 static void 1806 gstring_append_int (GString *gstring, 1807 guint32 vuint) 1808 { 1809 vuint = g_htonl (vuint); 1810 g_string_append_len (gstring, (const gchar*) &vuint, 4); 1811 } 1812 1813 static void 1814 gstring_append_double (GString *gstring, 1815 double vdouble) 1816 { 1817 union { double vdouble; guint64 vuint64; } u; 1818 u.vdouble = vdouble; 1819 u.vuint64 = GUINT64_TO_BE (u.vuint64); 1820 g_string_append_len (gstring, (const gchar*) &u.vuint64, 8); 1821 } 1822 1823 static guint8* 1824 g_test_log_dump (GTestLogMsg *msg, 1825 guint *len) 1826 { 1827 GString *gstring = g_string_sized_new (1024); 1828 guint ui; 1829 gstring_append_int (gstring, 0); /* message length */ 1830 gstring_append_int (gstring, msg->log_type); 1831 gstring_append_int (gstring, msg->n_strings); 1832 gstring_append_int (gstring, msg->n_nums); 1833 gstring_append_int (gstring, 0); /* reserved */ 1834 for (ui = 0; ui < msg->n_strings; ui++) 1835 { 1836 guint l = strlen (msg->strings[ui]); 1837 gstring_append_int (gstring, l); 1838 g_string_append_len (gstring, msg->strings[ui], l); 1839 } 1840 for (ui = 0; ui < msg->n_nums; ui++) 1841 gstring_append_double (gstring, msg->nums[ui]); 1842 *len = gstring->len; 1843 gstring_overwrite_int (gstring, 0, *len); /* message length */ 1844 return (guint8*) g_string_free (gstring, FALSE); 1845 } 1846 1847 static inline long double 1848 net_double (const gchar **ipointer) 1849 { 1850 union { guint64 vuint64; double vdouble; } u; 1851 guint64 aligned_int64; 1852 memcpy (&aligned_int64, *ipointer, 8); 1853 *ipointer += 8; 1854 u.vuint64 = GUINT64_FROM_BE (aligned_int64); 1855 return u.vdouble; 1856 } 1857 1858 static inline guint32 1859 net_int (const gchar **ipointer) 1860 { 1861 guint32 aligned_int; 1862 memcpy (&aligned_int, *ipointer, 4); 1863 *ipointer += 4; 1864 return g_ntohl (aligned_int); 1865 } 1866 1867 static gboolean 1868 g_test_log_extract (GTestLogBuffer *tbuffer) 1869 { 1870 const gchar *p = tbuffer->data->str; 1871 GTestLogMsg msg; 1872 guint mlength; 1873 if (tbuffer->data->len < 4 * 5) 1874 return FALSE; 1875 mlength = net_int (&p); 1876 if (tbuffer->data->len < mlength) 1877 return FALSE; 1878 msg.log_type = net_int (&p); 1879 msg.n_strings = net_int (&p); 1880 msg.n_nums = net_int (&p); 1881 if (net_int (&p) == 0) 1882 { 1883 guint ui; 1884 msg.strings = g_new0 (gchar*, msg.n_strings + 1); 1885 msg.nums = g_new0 (long double, msg.n_nums); 1886 for (ui = 0; ui < msg.n_strings; ui++) 1887 { 1888 guint sl = net_int (&p); 1889 msg.strings[ui] = g_strndup (p, sl); 1890 p += sl; 1891 } 1892 for (ui = 0; ui < msg.n_nums; ui++) 1893 msg.nums[ui] = net_double (&p); 1894 if (p <= tbuffer->data->str + mlength) 1895 { 1896 g_string_erase (tbuffer->data, 0, mlength); 1897 tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg))); 1898 return TRUE; 1899 } 1900 } 1901 g_free (msg.nums); 1902 g_strfreev (msg.strings); 1903 g_error ("corrupt log stream from test program"); 1904 return FALSE; 1905 } 1906 1907 /** 1908 * g_test_log_buffer_new: 1909 * 1910 * Internal function for gtester to decode test log messages, no ABI guarantees provided. 1911 */ 1912 GTestLogBuffer* 1913 g_test_log_buffer_new (void) 1914 { 1915 GTestLogBuffer *tb = g_new0 (GTestLogBuffer, 1); 1916 tb->data = g_string_sized_new (1024); 1917 return tb; 1918 } 1919 1920 /** 1921 * g_test_log_buffer_free 1922 * 1923 * Internal function for gtester to free test log messages, no ABI guarantees provided. 1924 */ 1925 void 1926 g_test_log_buffer_free (GTestLogBuffer *tbuffer) 1927 { 1928 g_return_if_fail (tbuffer != NULL); 1929 while (tbuffer->msgs) 1930 g_test_log_msg_free (g_test_log_buffer_pop (tbuffer)); 1931 g_string_free (tbuffer->data, TRUE); 1932 g_free (tbuffer); 1933 } 1934 1935 /** 1936 * g_test_log_buffer_push 1937 * 1938 * Internal function for gtester to decode test log messages, no ABI guarantees provided. 1939 */ 1940 void 1941 g_test_log_buffer_push (GTestLogBuffer *tbuffer, 1942 guint n_bytes, 1943 const guint8 *bytes) 1944 { 1945 g_return_if_fail (tbuffer != NULL); 1946 if (n_bytes) 1947 { 1948 gboolean more_messages; 1949 g_return_if_fail (bytes != NULL); 1950 g_string_append_len (tbuffer->data, (const gchar*) bytes, n_bytes); 1951 do 1952 more_messages = g_test_log_extract (tbuffer); 1953 while (more_messages); 1954 } 1955 } 1956 1957 /** 1958 * g_test_log_buffer_pop: 1959 * 1960 * Internal function for gtester to retrieve test log messages, no ABI guarantees provided. 1961 */ 1962 GTestLogMsg* 1963 g_test_log_buffer_pop (GTestLogBuffer *tbuffer) 1964 { 1965 GTestLogMsg *msg = NULL; 1966 g_return_val_if_fail (tbuffer != NULL, NULL); 1967 if (tbuffer->msgs) 1968 { 1969 GSList *slist = g_slist_last (tbuffer->msgs); 1970 msg = slist->data; 1971 tbuffer->msgs = g_slist_delete_link (tbuffer->msgs, slist); 1972 } 1973 return msg; 1974 } 1975 1976 /** 1977 * g_test_log_msg_free: 1978 * 1979 * Internal function for gtester to free test log messages, no ABI guarantees provided. 1980 */ 1981 void 1982 g_test_log_msg_free (GTestLogMsg *tmsg) 1983 { 1984 g_return_if_fail (tmsg != NULL); 1985 g_strfreev (tmsg->strings); 1986 g_free (tmsg->nums); 1987 g_free (tmsg); 1988 } 1989 1990 /* --- macros docs START --- */ 1991 /** 1992 * g_test_add: 1993 * @testpath: The test path for a new test case. 1994 * @Fixture: The type of a fixture data structure. 1995 * @tdata: Data argument for the test functions. 1996 * @fsetup: The function to set up the fixture data. 1997 * @ftest: The actual test function. 1998 * @fteardown: The function to tear down the fixture data. 1999 * 2000 * Hook up a new test case at @testpath, similar to g_test_add_func(). 2001 * A fixture data structure with setup and teardown function may be provided 2002 * though, similar to g_test_create_case(). 2003 * g_test_add() is implemented as a macro, so that the fsetup(), ftest() and 2004 * fteardown() callbacks can expect a @Fixture pointer as first argument in 2005 * a type safe manner. 2006 * 2007 * Since: 2.16 2008 **/ 2009 /* --- macros docs END --- */ 2010 2011 #define __G_TEST_UTILS_C__ 2012 #include "galiasdef.c" 2013