LCOV - code coverage report
Current view: top level - glib/glib - gtestutils.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 1175 1456 80.7 %
Date: 2024-04-23 05:16:05 Functions: 93 101 92.1 %
Branches: 556 848 65.6 %

           Branch data     Line data    Source code
       1                 :            : /* GLib testing utilities
       2                 :            :  * Copyright (C) 2007 Imendio AB
       3                 :            :  * Authors: Tim Janik, Sven Herzberg
       4                 :            :  *
       5                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :            :  *
       7                 :            :  * This library is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU Lesser General Public
       9                 :            :  * License as published by the Free Software Foundation; either
      10                 :            :  * version 2.1 of the License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This library is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :            :  * Lesser General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU Lesser General Public
      18                 :            :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19                 :            :  */
      20                 :            : 
      21                 :            : #include "config.h"
      22                 :            : 
      23                 :            : #include "gtestutils.h"
      24                 :            : #include "gfileutils.h"
      25                 :            : 
      26                 :            : #include <sys/types.h>
      27                 :            : #ifdef G_OS_UNIX
      28                 :            : #include <sys/wait.h>
      29                 :            : #include <sys/time.h>
      30                 :            : #include <fcntl.h>
      31                 :            : #include <unistd.h>
      32                 :            : #endif
      33                 :            : #include <string.h>
      34                 :            : #include <stdlib.h>
      35                 :            : #include <stdio.h>
      36                 :            : #include <inttypes.h>
      37                 :            : #ifdef HAVE_SYS_PRCTL_H
      38                 :            : #include <sys/prctl.h>
      39                 :            : #endif
      40                 :            : #ifdef HAVE_SYS_RESOURCE_H
      41                 :            : #include <sys/resource.h>
      42                 :            : #endif
      43                 :            : #ifdef G_OS_WIN32
      44                 :            : #include <crtdbg.h>
      45                 :            : #include <io.h>
      46                 :            : #include <windows.h>
      47                 :            : #endif
      48                 :            : #include <errno.h>
      49                 :            : #include <signal.h>
      50                 :            : #ifdef HAVE_SYS_SELECT_H
      51                 :            : #include <sys/select.h>
      52                 :            : #endif /* HAVE_SYS_SELECT_H */
      53                 :            : #include <glib/gstdio.h>
      54                 :            : 
      55                 :            : #include "gmain.h"
      56                 :            : #include "gpattern.h"
      57                 :            : #include "grand.h"
      58                 :            : #include "gstrfuncs.h"
      59                 :            : #include "gtimer.h"
      60                 :            : #include "gslice.h"
      61                 :            : #include "gspawn.h"
      62                 :            : #include "glib-private.h"
      63                 :            : #include "gutilsprivate.h"
      64                 :            : 
      65                 :            : #define TAP_VERSION G_STRINGIFY (13)
      66                 :            : /* FIXME: Remove '#' prefix when we'll depend on a meson version supporting TAP 14
      67                 :            :  * See https://gitlab.gnome.org/GNOME/glib/-/issues/2885 */
      68                 :            : #define TAP_SUBTEST_PREFIX "#    "  /* a 4-space indented line */
      69                 :            : 
      70                 :            : /**
      71                 :            :  * g_test_initialized:
      72                 :            :  *
      73                 :            :  * Returns %TRUE if g_test_init() has been called.
      74                 :            :  *
      75                 :            :  * Returns: %TRUE if g_test_init() has been called.
      76                 :            :  *
      77                 :            :  * Since: 2.36
      78                 :            :  */
      79                 :            : 
      80                 :            : /**
      81                 :            :  * g_test_quick:
      82                 :            :  *
      83                 :            :  * Returns %TRUE if tests are run in quick mode.
      84                 :            :  * Exactly one of g_test_quick() and g_test_slow() is active in any run;
      85                 :            :  * there is no "medium speed".
      86                 :            :  *
      87                 :            :  * By default, tests are run in quick mode. In tests that use
      88                 :            :  * g_test_init(), the options `-m quick`, `-m slow` and `-m thorough`
      89                 :            :  * can be used to change this.
      90                 :            :  *
      91                 :            :  * Returns: %TRUE if in quick mode
      92                 :            :  */
      93                 :            : 
      94                 :            : /**
      95                 :            :  * g_test_slow:
      96                 :            :  *
      97                 :            :  * Returns %TRUE if tests are run in slow mode.
      98                 :            :  * Exactly one of g_test_quick() and g_test_slow() is active in any run;
      99                 :            :  * there is no "medium speed".
     100                 :            :  *
     101                 :            :  * By default, tests are run in quick mode. In tests that use
     102                 :            :  * g_test_init(), the options `-m quick`, `-m slow` and `-m thorough`
     103                 :            :  * can be used to change this.
     104                 :            :  *
     105                 :            :  * Returns: the opposite of g_test_quick()
     106                 :            :  */
     107                 :            : 
     108                 :            : /**
     109                 :            :  * g_test_thorough:
     110                 :            :  *
     111                 :            :  * Returns %TRUE if tests are run in thorough mode, equivalent to
     112                 :            :  * g_test_slow().
     113                 :            :  *
     114                 :            :  * By default, tests are run in quick mode. In tests that use
     115                 :            :  * g_test_init(), the options `-m quick`, `-m slow` and `-m thorough`
     116                 :            :  * can be used to change this.
     117                 :            :  *
     118                 :            :  * Returns: the same thing as g_test_slow()
     119                 :            :  */
     120                 :            : 
     121                 :            : /**
     122                 :            :  * g_test_perf:
     123                 :            :  *
     124                 :            :  * Returns %TRUE if tests are run in performance mode.
     125                 :            :  *
     126                 :            :  * By default, tests are run in quick mode. In tests that use
     127                 :            :  * g_test_init(), the option `-m perf` enables performance tests, while
     128                 :            :  * `-m quick` disables them.
     129                 :            :  *
     130                 :            :  * Returns: %TRUE if in performance mode
     131                 :            :  */
     132                 :            : 
     133                 :            : /**
     134                 :            :  * g_test_undefined:
     135                 :            :  *
     136                 :            :  * Returns %TRUE if tests may provoke assertions and other formally-undefined
     137                 :            :  * behaviour, to verify that appropriate warnings are given. It might, in some
     138                 :            :  * cases, be useful to turn this off with if running tests under valgrind;
     139                 :            :  * in tests that use g_test_init(), the option `-m no-undefined` disables
     140                 :            :  * those tests, while `-m undefined` explicitly enables them (normally
     141                 :            :  * the default behaviour).
     142                 :            :  *
     143                 :            :  * Since GLib 2.68, if GLib was compiled with gcc or clang and
     144                 :            :  * [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer)
     145                 :            :  * is enabled, the default changes to not exercising undefined behaviour.
     146                 :            :  *
     147                 :            :  * Returns: %TRUE if tests may provoke programming errors
     148                 :            :  */
     149                 :            : 
     150                 :            : /**
     151                 :            :  * g_test_verbose:
     152                 :            :  *
     153                 :            :  * Returns %TRUE if tests are run in verbose mode.
     154                 :            :  * In tests that use g_test_init(), the option `--verbose` enables this,
     155                 :            :  * while `-q` or `--quiet` disables it.
     156                 :            :  * The default is neither g_test_verbose() nor g_test_quiet().
     157                 :            :  *
     158                 :            :  * Returns: %TRUE if in verbose mode
     159                 :            :  */
     160                 :            : 
     161                 :            : /**
     162                 :            :  * g_test_quiet:
     163                 :            :  *
     164                 :            :  * Returns %TRUE if tests are run in quiet mode.
     165                 :            :  * In tests that use g_test_init(), the option `-q` or `--quiet` enables
     166                 :            :  * this, while `--verbose` disables it.
     167                 :            :  * The default is neither g_test_verbose() nor g_test_quiet().
     168                 :            :  *
     169                 :            :  * Returns: %TRUE if in quiet mode
     170                 :            :  */
     171                 :            : 
     172                 :            : /**
     173                 :            :  * g_test_queue_unref:
     174                 :            :  * @gobject: the object to unref
     175                 :            :  *
     176                 :            :  * Enqueue an object to be released with g_object_unref() during
     177                 :            :  * the next teardown phase. This is equivalent to calling
     178                 :            :  * g_test_queue_destroy() with a destroy callback of g_object_unref().
     179                 :            :  *
     180                 :            :  * Since: 2.16
     181                 :            :  */
     182                 :            : 
     183                 :            : /**
     184                 :            :  * GTestSubprocessFlags:
     185                 :            :  * @G_TEST_SUBPROCESS_DEFAULT: Default behaviour. Since: 2.74
     186                 :            :  * @G_TEST_SUBPROCESS_INHERIT_STDIN: If this flag is given, the child
     187                 :            :  *     process will inherit the parent's stdin. Otherwise, the child's
     188                 :            :  *     stdin is redirected to `/dev/null`.
     189                 :            :  * @G_TEST_SUBPROCESS_INHERIT_STDOUT: If this flag is given, the child
     190                 :            :  *     process will inherit the parent's stdout. Otherwise, the child's
     191                 :            :  *     stdout will not be visible, but it will be captured to allow
     192                 :            :  *     later tests with g_test_trap_assert_stdout().
     193                 :            :  * @G_TEST_SUBPROCESS_INHERIT_STDERR: If this flag is given, the child
     194                 :            :  *     process will inherit the parent's stderr. Otherwise, the child's
     195                 :            :  *     stderr will not be visible, but it will be captured to allow
     196                 :            :  *     later tests with g_test_trap_assert_stderr().
     197                 :            :  *
     198                 :            :  * Flags to pass to g_test_trap_subprocess() to control input and output.
     199                 :            :  *
     200                 :            :  * Note that in contrast with g_test_trap_fork(), the default is to
     201                 :            :  * not show stdout and stderr.
     202                 :            :  */
     203                 :            : 
     204                 :            : /**
     205                 :            :  * g_test_trap_assert_passed:
     206                 :            :  *
     207                 :            :  * Assert that the last test subprocess passed.
     208                 :            :  * See g_test_trap_subprocess().
     209                 :            :  *
     210                 :            :  * Since: 2.16
     211                 :            :  */
     212                 :            : 
     213                 :            : /**
     214                 :            :  * g_test_trap_assert_failed:
     215                 :            :  *
     216                 :            :  * Assert that the last test subprocess failed.
     217                 :            :  * See g_test_trap_subprocess().
     218                 :            :  *
     219                 :            :  * This is sometimes used to test situations that are formally considered to
     220                 :            :  * be undefined behaviour, like inputs that fail a g_return_if_fail()
     221                 :            :  * check. In these situations you should skip the entire test, including the
     222                 :            :  * call to g_test_trap_subprocess(), unless g_test_undefined() returns %TRUE
     223                 :            :  * to indicate that undefined behaviour may be tested.
     224                 :            :  *
     225                 :            :  * Since: 2.16
     226                 :            :  */
     227                 :            : 
     228                 :            : /**
     229                 :            :  * g_test_trap_assert_stdout:
     230                 :            :  * @soutpattern: a glob-style [pattern][glib-Glob-style-pattern-matching]
     231                 :            :  *
     232                 :            :  * Assert that the stdout output of the last test subprocess matches
     233                 :            :  * @soutpattern. See g_test_trap_subprocess().
     234                 :            :  *
     235                 :            :  * Since: 2.16
     236                 :            :  */
     237                 :            : 
     238                 :            : /**
     239                 :            :  * g_test_trap_assert_stdout_unmatched:
     240                 :            :  * @soutpattern: a glob-style [pattern][glib-Glob-style-pattern-matching]
     241                 :            :  *
     242                 :            :  * Assert that the stdout output of the last test subprocess
     243                 :            :  * does not match @soutpattern. See g_test_trap_subprocess().
     244                 :            :  *
     245                 :            :  * Since: 2.16
     246                 :            :  */
     247                 :            : 
     248                 :            : /**
     249                 :            :  * g_test_trap_assert_stderr:
     250                 :            :  * @serrpattern: a glob-style [pattern][glib-Glob-style-pattern-matching]
     251                 :            :  *
     252                 :            :  * Assert that the stderr output of the last test subprocess
     253                 :            :  * matches @serrpattern. See  g_test_trap_subprocess().
     254                 :            :  *
     255                 :            :  * This is sometimes used to test situations that are formally
     256                 :            :  * considered to be undefined behaviour, like code that hits a
     257                 :            :  * g_assert() or g_error(). In these situations you should skip the
     258                 :            :  * entire test, including the call to g_test_trap_subprocess(), unless
     259                 :            :  * g_test_undefined() returns %TRUE to indicate that undefined
     260                 :            :  * behaviour may be tested.
     261                 :            :  *
     262                 :            :  * Since: 2.16
     263                 :            :  */
     264                 :            : 
     265                 :            : /**
     266                 :            :  * g_test_trap_assert_stderr_unmatched:
     267                 :            :  * @serrpattern: a glob-style [pattern][glib-Glob-style-pattern-matching]
     268                 :            :  *
     269                 :            :  * Assert that the stderr output of the last test subprocess
     270                 :            :  * does not match @serrpattern. See g_test_trap_subprocess().
     271                 :            :  *
     272                 :            :  * Since: 2.16
     273                 :            :  */
     274                 :            : 
     275                 :            : /**
     276                 :            :  * g_test_rand_bit:
     277                 :            :  *
     278                 :            :  * Get a reproducible random bit (0 or 1), see g_test_rand_int()
     279                 :            :  * for details on test case random numbers.
     280                 :            :  *
     281                 :            :  * Since: 2.16
     282                 :            :  */
     283                 :            : 
     284                 :            : /**
     285                 :            :  * g_assert:
     286                 :            :  * @expr: the expression to check
     287                 :            :  *
     288                 :            :  * Debugging macro to terminate the application if the assertion
     289                 :            :  * fails. If the assertion fails (i.e. the expression is not true),
     290                 :            :  * an error message is logged and the application is terminated.
     291                 :            :  *
     292                 :            :  * The macro can be turned off in final releases of code by defining
     293                 :            :  * `G_DISABLE_ASSERT` when compiling the application, so code must
     294                 :            :  * not depend on any side effects from @expr. Similarly, it must not be used
     295                 :            :  * in unit tests, otherwise the unit tests will be ineffective if compiled with
     296                 :            :  * `G_DISABLE_ASSERT`. Use g_assert_true() and related macros in unit tests
     297                 :            :  * instead.
     298                 :            :  */
     299                 :            : 
     300                 :            : /**
     301                 :            :  * g_assert_not_reached:
     302                 :            :  *
     303                 :            :  * Debugging macro to terminate the application if it is ever
     304                 :            :  * reached. If it is reached, an error message is logged and the
     305                 :            :  * application is terminated.
     306                 :            :  *
     307                 :            :  * The macro can be turned off in final releases of code by defining
     308                 :            :  * `G_DISABLE_ASSERT` when compiling the application. Hence, it should not be
     309                 :            :  * used in unit tests, where assertions should always be effective.
     310                 :            :  */
     311                 :            : 
     312                 :            : /**
     313                 :            :  * g_assert_true:
     314                 :            :  * @expr: the expression to check
     315                 :            :  *
     316                 :            :  * Debugging macro to check that an expression is true.
     317                 :            :  *
     318                 :            :  * If the assertion fails (i.e. the expression is not true),
     319                 :            :  * an error message is logged and the application is either
     320                 :            :  * terminated or the testcase marked as failed.
     321                 :            :  *
     322                 :            :  * Note that unlike g_assert(), this macro is unaffected by whether
     323                 :            :  * `G_DISABLE_ASSERT` is defined. Hence it should only be used in tests and,
     324                 :            :  * conversely, g_assert() should not be used in tests.
     325                 :            :  *
     326                 :            :  * See g_test_set_nonfatal_assertions().
     327                 :            :  *
     328                 :            :  * Since: 2.38
     329                 :            :  */
     330                 :            : 
     331                 :            : /**
     332                 :            :  * g_assert_false:
     333                 :            :  * @expr: the expression to check
     334                 :            :  *
     335                 :            :  * Debugging macro to check an expression is false.
     336                 :            :  *
     337                 :            :  * If the assertion fails (i.e. the expression is not false),
     338                 :            :  * an error message is logged and the application is either
     339                 :            :  * terminated or the testcase marked as failed.
     340                 :            :  *
     341                 :            :  * Note that unlike g_assert(), this macro is unaffected by whether
     342                 :            :  * `G_DISABLE_ASSERT` is defined. Hence it should only be used in tests and,
     343                 :            :  * conversely, g_assert() should not be used in tests.
     344                 :            :  *
     345                 :            :  * See g_test_set_nonfatal_assertions().
     346                 :            :  *
     347                 :            :  * Since: 2.38
     348                 :            :  */
     349                 :            : 
     350                 :            : /**
     351                 :            :  * g_assert_null:
     352                 :            :  * @expr: the expression to check
     353                 :            :  *
     354                 :            :  * Debugging macro to check an expression is %NULL.
     355                 :            :  *
     356                 :            :  * If the assertion fails (i.e. the expression is not %NULL),
     357                 :            :  * an error message is logged and the application is either
     358                 :            :  * terminated or the testcase marked as failed.
     359                 :            :  *
     360                 :            :  * Note that unlike g_assert(), this macro is unaffected by whether
     361                 :            :  * `G_DISABLE_ASSERT` is defined. Hence it should only be used in tests and,
     362                 :            :  * conversely, g_assert() should not be used in tests.
     363                 :            :  *
     364                 :            :  * See g_test_set_nonfatal_assertions().
     365                 :            :  *
     366                 :            :  * Since: 2.38
     367                 :            :  */
     368                 :            : 
     369                 :            : /**
     370                 :            :  * g_assert_nonnull:
     371                 :            :  * @expr: the expression to check
     372                 :            :  *
     373                 :            :  * Debugging macro to check an expression is not %NULL.
     374                 :            :  *
     375                 :            :  * If the assertion fails (i.e. the expression is %NULL),
     376                 :            :  * an error message is logged and the application is either
     377                 :            :  * terminated or the testcase marked as failed.
     378                 :            :  *
     379                 :            :  * Note that unlike g_assert(), this macro is unaffected by whether
     380                 :            :  * `G_DISABLE_ASSERT` is defined. Hence it should only be used in tests and,
     381                 :            :  * conversely, g_assert() should not be used in tests.
     382                 :            :  *
     383                 :            :  * See g_test_set_nonfatal_assertions().
     384                 :            :  *
     385                 :            :  * Since: 2.40
     386                 :            :  */
     387                 :            : 
     388                 :            : /**
     389                 :            :  * g_assert_cmpstr:
     390                 :            :  * @s1: a string (may be %NULL)
     391                 :            :  * @cmp: The comparison operator to use.
     392                 :            :  *     One of `==`, `!=`, `<`, `>`, `<=`, `>=`.
     393                 :            :  * @s2: another string (may be %NULL)
     394                 :            :  *
     395                 :            :  * Debugging macro to compare two strings. If the comparison fails,
     396                 :            :  * an error message is logged and the application is either terminated
     397                 :            :  * or the testcase marked as failed.
     398                 :            :  * The strings are compared using g_strcmp0().
     399                 :            :  *
     400                 :            :  * The effect of `g_assert_cmpstr (s1, op, s2)` is
     401                 :            :  * the same as `g_assert_true (g_strcmp0 (s1, s2) op 0)`.
     402                 :            :  * The advantage of this macro is that it can produce a message that
     403                 :            :  * includes the actual values of @s1 and @s2.
     404                 :            :  *
     405                 :            :  * |[<!-- language="C" --> 
     406                 :            :  *   g_assert_cmpstr (mystring, ==, "fubar");
     407                 :            :  * ]|
     408                 :            :  *
     409                 :            :  * Since: 2.16
     410                 :            :  */
     411                 :            : 
     412                 :            : /**
     413                 :            :  * g_assert_cmpstrv:
     414                 :            :  * @strv1: (nullable): a string array (may be %NULL)
     415                 :            :  * @strv2: (nullable): another string array (may be %NULL)
     416                 :            :  *
     417                 :            :  * Debugging macro to check if two %NULL-terminated string arrays (i.e. 2
     418                 :            :  * #GStrv) are equal. If they are not equal, an error message is logged and the
     419                 :            :  * application is either terminated or the testcase marked as failed.
     420                 :            :  * If both arrays are %NULL, the check passes. If one array is %NULL but the
     421                 :            :  * other is not, an error message is logged.
     422                 :            :  *
     423                 :            :  * The effect of `g_assert_cmpstrv (strv1, strv2)` is the same as
     424                 :            :  * `g_assert_true (g_strv_equal (strv1, strv2))` (if both arrays are not
     425                 :            :  * %NULL). The advantage of this macro is that it can produce a message that
     426                 :            :  * includes how @strv1 and @strv2 are different.
     427                 :            :  *
     428                 :            :  * |[<!-- language="C" -->
     429                 :            :  *   const char *expected[] = { "one", "two", "three", NULL };
     430                 :            :  *   g_assert_cmpstrv (mystrv, expected);
     431                 :            :  * ]|
     432                 :            :  *
     433                 :            :  * Since: 2.68
     434                 :            :  */
     435                 :            : 
     436                 :            : /**
     437                 :            :  * g_assert_cmpint:
     438                 :            :  * @n1: an integer
     439                 :            :  * @cmp: The comparison operator to use.
     440                 :            :  *     One of `==`, `!=`, `<`, `>`, `<=`, `>=`.
     441                 :            :  * @n2: another integer
     442                 :            :  *
     443                 :            :  * Debugging macro to compare two integers.
     444                 :            :  *
     445                 :            :  * The effect of `g_assert_cmpint (n1, op, n2)` is
     446                 :            :  * the same as `g_assert_true (n1 op n2)`. The advantage
     447                 :            :  * of this macro is that it can produce a message that includes the
     448                 :            :  * actual values of @n1 and @n2.
     449                 :            :  *
     450                 :            :  * Since: 2.16
     451                 :            :  */
     452                 :            : 
     453                 :            : /**
     454                 :            :  * g_assert_cmpuint:
     455                 :            :  * @n1: an unsigned integer
     456                 :            :  * @cmp: The comparison operator to use.
     457                 :            :  *     One of `==`, `!=`, `<`, `>`, `<=`, `>=`.
     458                 :            :  * @n2: another unsigned integer
     459                 :            :  *
     460                 :            :  * Debugging macro to compare two unsigned integers.
     461                 :            :  *
     462                 :            :  * The effect of `g_assert_cmpuint (n1, op, n2)` is
     463                 :            :  * the same as `g_assert_true (n1 op n2)`. The advantage
     464                 :            :  * of this macro is that it can produce a message that includes the
     465                 :            :  * actual values of @n1 and @n2.
     466                 :            :  *
     467                 :            :  * Since: 2.16
     468                 :            :  */
     469                 :            : 
     470                 :            : /**
     471                 :            :  * g_assert_cmphex:
     472                 :            :  * @n1: an unsigned integer
     473                 :            :  * @cmp: The comparison operator to use.
     474                 :            :  *     One of `==`, `!=`, `<`, `>`, `<=`, `>=`.
     475                 :            :  * @n2: another unsigned integer
     476                 :            :  *
     477                 :            :  * Debugging macro to compare to unsigned integers.
     478                 :            :  *
     479                 :            :  * This is a variant of g_assert_cmpuint() that displays the numbers
     480                 :            :  * in hexadecimal notation in the message.
     481                 :            :  *
     482                 :            :  * Since: 2.16
     483                 :            :  */
     484                 :            : 
     485                 :            : /**
     486                 :            :  * g_assert_cmpfloat:
     487                 :            :  * @n1: a floating point number
     488                 :            :  * @cmp: The comparison operator to use.
     489                 :            :  *     One of `==`, `!=`, `<`, `>`, `<=`, `>=`.
     490                 :            :  * @n2: another floating point number
     491                 :            :  *
     492                 :            :  * Debugging macro to compare two floating point numbers.
     493                 :            :  *
     494                 :            :  * The effect of `g_assert_cmpfloat (n1, op, n2)` is
     495                 :            :  * the same as `g_assert_true (n1 op n2)`. The advantage
     496                 :            :  * of this macro is that it can produce a message that includes the
     497                 :            :  * actual values of @n1 and @n2.
     498                 :            :  *
     499                 :            :  * Since: 2.16
     500                 :            :  */
     501                 :            : 
     502                 :            : /**
     503                 :            :  * g_assert_cmpfloat_with_epsilon:
     504                 :            :  * @n1: a floating point number
     505                 :            :  * @n2: another floating point number
     506                 :            :  * @epsilon: a numeric value that expresses the expected tolerance
     507                 :            :  *   between @n1 and @n2
     508                 :            :  *
     509                 :            :  * Debugging macro to compare two floating point numbers within an epsilon.
     510                 :            :  *
     511                 :            :  * The effect of `g_assert_cmpfloat_with_epsilon (n1, n2, epsilon)` is
     512                 :            :  * the same as `g_assert_true (abs (n1 - n2) < epsilon)`. The advantage
     513                 :            :  * of this macro is that it can produce a message that includes the
     514                 :            :  * actual values of @n1 and @n2.
     515                 :            :  *
     516                 :            :  * Since: 2.58
     517                 :            :  */
     518                 :            : 
     519                 :            : /**
     520                 :            :  * g_assert_no_errno:
     521                 :            :  * @expr: the expression to check
     522                 :            :  *
     523                 :            :  * Debugging macro to check that an expression has a non-negative return value,
     524                 :            :  * as used by traditional POSIX functions (such as `rmdir()`) to indicate
     525                 :            :  * success.
     526                 :            :  *
     527                 :            :  * If the assertion fails (i.e. the @expr returns a negative value), an error
     528                 :            :  * message is logged and the testcase is marked as failed. The error message
     529                 :            :  * will contain the value of `errno` and its human-readable message from
     530                 :            :  * g_strerror().
     531                 :            :  *
     532                 :            :  * This macro will clear the value of `errno` before executing @expr.
     533                 :            :  *
     534                 :            :  * Since: 2.66
     535                 :            :  */
     536                 :            : 
     537                 :            : /**
     538                 :            :  * g_assert_cmpmem:
     539                 :            :  * @m1: (nullable): pointer to a buffer
     540                 :            :  * @l1: length of @m1
     541                 :            :  * @m2: (nullable): pointer to another buffer
     542                 :            :  * @l2: length of @m2
     543                 :            :  *
     544                 :            :  * Debugging macro to compare memory regions. If the comparison fails,
     545                 :            :  * an error message is logged and the application is either terminated
     546                 :            :  * or the testcase marked as failed.
     547                 :            :  *
     548                 :            :  * The effect of `g_assert_cmpmem (m1, l1, m2, l2)` is
     549                 :            :  * the same as `g_assert_true (l1 == l2 && memcmp (m1, m2, l1) == 0)`.
     550                 :            :  * The advantage of this macro is that it can produce a message that
     551                 :            :  * includes the actual values of @l1 and @l2.
     552                 :            :  *
     553                 :            :  * @m1 may be %NULL if (and only if) @l1 is zero; similarly for @m2 and @l2.
     554                 :            :  *
     555                 :            :  * |[<!-- language="C" -->
     556                 :            :  *   g_assert_cmpmem (buf->data, buf->len, expected, sizeof (expected));
     557                 :            :  * ]|
     558                 :            :  *
     559                 :            :  * Since: 2.46
     560                 :            :  */
     561                 :            : 
     562                 :            : /**
     563                 :            :  * g_assert_cmpvariant:
     564                 :            :  * @v1: pointer to a #GVariant
     565                 :            :  * @v2: pointer to another #GVariant
     566                 :            :  *
     567                 :            :  * Debugging macro to compare two #GVariants. If the comparison fails,
     568                 :            :  * an error message is logged and the application is either terminated
     569                 :            :  * or the testcase marked as failed. The variants are compared using
     570                 :            :  * g_variant_equal().
     571                 :            :  *
     572                 :            :  * The effect of `g_assert_cmpvariant (v1, v2)` is the same as
     573                 :            :  * `g_assert_true (g_variant_equal (v1, v2))`. The advantage of this macro is
     574                 :            :  * that it can produce a message that includes the actual values of @v1 and @v2.
     575                 :            :  *
     576                 :            :  * Since: 2.60
     577                 :            :  */
     578                 :            : 
     579                 :            : /**
     580                 :            :  * g_assert_no_error:
     581                 :            :  * @err: a #GError, possibly %NULL
     582                 :            :  *
     583                 :            :  * Debugging macro to check that a #GError is not set.
     584                 :            :  *
     585                 :            :  * The effect of `g_assert_no_error (err)` is
     586                 :            :  * the same as `g_assert_true (err == NULL)`. The advantage
     587                 :            :  * of this macro is that it can produce a message that includes
     588                 :            :  * the error message and code.
     589                 :            :  *
     590                 :            :  * Since: 2.20
     591                 :            :  */
     592                 :            : 
     593                 :            : /**
     594                 :            :  * g_assert_error:
     595                 :            :  * @err: a #GError, possibly %NULL
     596                 :            :  * @dom: the expected error domain (a #GQuark)
     597                 :            :  * @c: the expected error code
     598                 :            :  *
     599                 :            :  * Debugging macro to check that a method has returned
     600                 :            :  * the correct #GError.
     601                 :            :  *
     602                 :            :  * The effect of `g_assert_error (err, dom, c)` is
     603                 :            :  * the same as `g_assert_true (err != NULL && err->domain
     604                 :            :  * == dom && err->code == c)`. The advantage of this
     605                 :            :  * macro is that it can produce a message that includes the incorrect
     606                 :            :  * error message and code.
     607                 :            :  *
     608                 :            :  * This can only be used to test for a specific error. If you want to
     609                 :            :  * test that @err is set, but don't care what it's set to, just use
     610                 :            :  * `g_assert_nonnull (err)`.
     611                 :            :  *
     612                 :            :  * Since: 2.20
     613                 :            :  */
     614                 :            : 
     615                 :            : /**
     616                 :            :  * GTestCase:
     617                 :            :  *
     618                 :            :  * An opaque structure representing a test case.
     619                 :            :  */
     620                 :            : 
     621                 :            : /**
     622                 :            :  * GTestSuite:
     623                 :            :  *
     624                 :            :  * An opaque structure representing a test suite.
     625                 :            :  */
     626                 :            : 
     627                 :            : 
     628                 :            : /* Global variable for storing assertion messages; this is the counterpart to
     629                 :            :  * glibc's (private) __abort_msg variable, and allows developers and crash
     630                 :            :  * analysis systems like Apport and ABRT to fish out assertion messages from
     631                 :            :  * core dumps, instead of having to catch them on screen output.
     632                 :            :  */
     633                 :            : GLIB_VAR char *__glib_assert_msg;
     634                 :            : char *__glib_assert_msg = NULL;
     635                 :            : 
     636                 :            : /* --- constants --- */
     637                 :            : #define G_TEST_STATUS_TIMED_OUT 1024
     638                 :            : 
     639                 :            : /* --- structures --- */
     640                 :            : struct GTestCase
     641                 :            : {
     642                 :            :   gchar  *name;
     643                 :            :   guint   fixture_size;
     644                 :            :   void   (*fixture_setup)    (void*, gconstpointer);
     645                 :            :   void   (*fixture_test)     (void*, gconstpointer);
     646                 :            :   void   (*fixture_teardown) (void*, gconstpointer);
     647                 :            :   gpointer test_data;
     648                 :            : };
     649                 :            : struct GTestSuite
     650                 :            : {
     651                 :            :   gchar  *name;
     652                 :            :   GSList *suites;
     653                 :            :   GSList *cases;
     654                 :            : };
     655                 :            : typedef struct DestroyEntry DestroyEntry;
     656                 :            : struct DestroyEntry
     657                 :            : {
     658                 :            :   DestroyEntry *next;
     659                 :            :   GDestroyNotify destroy_func;
     660                 :            :   gpointer       destroy_data;
     661                 :            : };
     662                 :            : 
     663                 :            : /* --- prototypes --- */
     664                 :            : static void     test_cleanup                    (void);
     665                 :            : static void     test_run_seed                   (const gchar *rseed);
     666                 :            : static void     test_trap_clear                 (void);
     667                 :            : static guint8*  g_test_log_dump                 (GTestLogMsg *msg,
     668                 :            :                                                  guint       *len);
     669                 :            : static void     gtest_default_log_handler       (const gchar    *log_domain,
     670                 :            :                                                  GLogLevelFlags  log_level,
     671                 :            :                                                  const gchar    *message,
     672                 :            :                                                  gpointer        unused_data);
     673                 :            : static void     g_test_tap_print                (unsigned    subtest_level,
     674                 :            :                                                  gboolean    commented,
     675                 :            :                                                  const char *format,
     676                 :            :                                                  ...) G_GNUC_PRINTF (3, 4);
     677                 :            : 
     678                 :            : static const char * const g_test_result_names[] = {
     679                 :            :   "OK",
     680                 :            :   "SKIP",
     681                 :            :   "FAIL",
     682                 :            :   "TODO"
     683                 :            : };
     684                 :            : 
     685                 :            : /* --- variables --- */
     686                 :            : static int         test_log_fd = -1;
     687                 :            : static gboolean    test_mode_fatal = TRUE;
     688                 :            : static gboolean    g_test_run_once = TRUE;
     689                 :            : static gboolean    test_isolate_dirs = FALSE;
     690                 :            : static gchar      *test_isolate_dirs_tmpdir = NULL;
     691                 :            : static const gchar *test_tmpdir = NULL;
     692                 :            : static gboolean    test_run_list = FALSE;
     693                 :            : static gchar      *test_run_seedstr = NULL;
     694                 :            : G_LOCK_DEFINE_STATIC (test_run_rand);
     695                 :            : static GRand      *test_run_rand = NULL;
     696                 :            : static gchar      *test_run_name = "";
     697                 :            : static gchar      *test_run_name_path = "";
     698                 :            : static GSList    **test_filename_free_list;
     699                 :            : static guint       test_run_forks = 0;
     700                 :            : static guint       test_run_count = 0;
     701                 :            : static guint       test_count = 0;
     702                 :            : static guint       test_skipped_count = 0;
     703                 :            : static GTestResult test_run_success = G_TEST_RUN_FAILURE;
     704                 :            : static gchar      *test_run_msg = NULL;
     705                 :            : static guint       test_startup_skip_count = 0;
     706                 :            : static GTimer     *test_user_timer = NULL;
     707                 :            : static double      test_user_stamp = 0;
     708                 :            : static GSList     *test_paths = NULL;
     709                 :            : static gboolean    test_prefix = FALSE;
     710                 :            : static gboolean    test_prefix_extended = FALSE;
     711                 :            : static GSList     *test_paths_skipped = NULL;
     712                 :            : static gboolean    test_prefix_skipped = FALSE;
     713                 :            : static gboolean    test_prefix_extended_skipped = FALSE;
     714                 :            : static GTestSuite *test_suite_root = NULL;
     715                 :            : static int         test_trap_last_status = 0;  /* unmodified platform-specific status */
     716                 :            : static GPid        test_trap_last_pid = 0;
     717                 :            : static char       *test_trap_last_subprocess = NULL;
     718                 :            : static char       *test_trap_last_stdout = NULL;
     719                 :            : static char       *test_trap_last_stderr = NULL;
     720                 :            : static char       *test_uri_base = NULL;
     721                 :            : static gboolean    test_debug_log = FALSE;
     722                 :            : static gboolean    test_tap_log = TRUE;  /* default to TAP as of GLib 2.62; see #1619; the non-TAP output mode is deprecated */
     723                 :            : static gboolean    test_nonfatal_assertions = FALSE;
     724                 :            : static DestroyEntry *test_destroy_queue = NULL;
     725                 :            : static const char *test_argv0 = NULL;           /* (nullable), points into global argv */
     726                 :            : static char       *test_argv0_dirname = NULL;   /* owned by GLib */
     727                 :            : static const char *test_disted_files_dir;       /* points into test_argv0_dirname or an environment variable */
     728                 :            : static const char *test_built_files_dir;        /* points into test_argv0_dirname or an environment variable */
     729                 :            : static char       *test_initial_cwd = NULL;
     730                 :            : static gboolean    test_in_forked_child = FALSE;
     731                 :            : static gboolean    test_in_subprocess = FALSE;
     732                 :            : static gboolean    test_is_subtest = FALSE;
     733                 :            : static GTestConfig mutable_test_config_vars = {
     734                 :            :   FALSE,        /* test_initialized */
     735                 :            :   TRUE,         /* test_quick */
     736                 :            :   FALSE,        /* test_perf */
     737                 :            :   FALSE,        /* test_verbose */
     738                 :            :   FALSE,        /* test_quiet */
     739                 :            :   TRUE,         /* test_undefined */
     740                 :            : };
     741                 :            : const GTestConfig * const g_test_config_vars = &mutable_test_config_vars;
     742                 :            : static gboolean  no_g_set_prgname = FALSE;
     743                 :            : static GPrintFunc g_default_print_func = NULL;
     744                 :            : 
     745                 :            : enum
     746                 :            : {
     747                 :            :   G_TEST_CASE_LARGS_RESULT = 0,
     748                 :            :   G_TEST_CASE_LARGS_RUN_FORKS = 1,
     749                 :            :   G_TEST_CASE_LARGS_EXECUTION_TIME = 2,
     750                 :            : 
     751                 :            :   G_TEST_CASE_LARGS_MAX
     752                 :            : };
     753                 :            : 
     754                 :            : /* --- functions --- */
     755                 :            : static inline gboolean
     756                 :      55282 : is_subtest (void)
     757                 :            : {
     758   [ +  +  +  +  :      55282 :   return test_is_subtest || test_in_forked_child || test_in_subprocess;
                   -  + ]
     759                 :            : }
     760                 :            : 
     761                 :            : static void
     762                 :      16773 : g_test_print_handler_full (const gchar *string,
     763                 :            :                            gboolean     use_tap_format,
     764                 :            :                            gboolean     is_tap_comment,
     765                 :            :                            unsigned     subtest_level)
     766                 :            : {
     767                 :      16773 :   g_assert (string != NULL);
     768                 :            : 
     769   [ +  +  +  + ]:      16773 :   if (G_LIKELY (use_tap_format) && strchr (string, '\n') != NULL)
     770                 :      16716 :     {
     771                 :            :       static gboolean last_had_final_newline = TRUE;
     772                 :      16716 :       GString *output = g_string_new_len (NULL, strlen (string) + 2);
     773                 :      16716 :       const char *line = string;
     774                 :            : 
     775                 :            :       do
     776                 :            :         {
     777                 :      33610 :           const char *next = strchr (line, '\n');
     778                 :            : 
     779   [ +  +  +  +  :      33610 :           if (last_had_final_newline && (next || *line != '\0'))
                   +  + ]
     780                 :            :             {
     781         [ +  + ]:      17309 :               for (unsigned l = 0; l < subtest_level; ++l)
     782   [ +  -  -  + ]:        830 :                 g_string_append (output, TAP_SUBTEST_PREFIX);
     783                 :            : 
     784         [ +  + ]:      16894 :               if G_LIKELY (is_tap_comment)
     785   [ +  -  -  + ]:      32302 :                 g_string_append (output, "# ");
     786                 :            :             }
     787                 :            : 
     788         [ +  + ]:      33610 :           if (next)
     789                 :            :             {
     790                 :      16894 :               next += 1; /* Include the newline */
     791         [ -  + ]:      16894 :               g_string_append_len (output, line, next - line);
     792                 :            :             }
     793                 :            :           else
     794                 :            :             {
     795         [ -  + ]:      16716 :               g_string_append (output, line);
     796                 :      16716 :               last_had_final_newline = (*line == '\0');
     797                 :            :             }
     798                 :            : 
     799                 :      33610 :           line = next;
     800                 :            :         }
     801         [ +  + ]:      33610 :       while (line != NULL);
     802                 :            : 
     803                 :      16716 :       g_default_print_func (output->str);
     804                 :      16716 :       g_string_free (g_steal_pointer (&output), TRUE);
     805                 :            :     }
     806                 :            :   else
     807                 :            :     {
     808                 :         57 :       g_default_print_func (string);
     809                 :            :     }
     810                 :      16773 : }
     811                 :            : 
     812                 :            : static void
     813                 :      15960 : g_test_print_handler (const gchar *string)
     814                 :            : {
     815                 :      15960 :   g_test_print_handler_full (string, test_tap_log, TRUE, is_subtest () ? 1 : 0);
     816                 :      15960 : }
     817                 :            : 
     818                 :            : static void
     819                 :        790 : g_test_tap_print (unsigned    subtest_level,
     820                 :            :                   gboolean    commented,
     821                 :            :                   const char *format,
     822                 :            :                   ...)
     823                 :            : {
     824                 :            :   va_list args;
     825                 :            :   char *string;
     826                 :            : 
     827                 :        790 :   va_start (args, format);
     828                 :        790 :   string = g_strdup_vprintf (format, args);
     829                 :        790 :   va_end (args);
     830                 :            : 
     831                 :        790 :   g_test_print_handler_full (string, TRUE, commented, subtest_level);
     832                 :        790 :   g_free (string);
     833                 :        790 : }
     834                 :            : 
     835                 :            : const char*
     836                 :          0 : g_test_log_type_name (GTestLogType log_type)
     837                 :            : {
     838   [ #  #  #  #  :          0 :   switch (log_type)
          #  #  #  #  #  
             #  #  #  # ]
     839                 :            :     {
     840                 :          0 :     case G_TEST_LOG_NONE:               return "none";
     841                 :          0 :     case G_TEST_LOG_ERROR:              return "error";
     842                 :          0 :     case G_TEST_LOG_START_BINARY:       return "binary";
     843                 :          0 :     case G_TEST_LOG_LIST_CASE:          return "list";
     844                 :          0 :     case G_TEST_LOG_SKIP_CASE:          return "skip";
     845                 :          0 :     case G_TEST_LOG_START_CASE:         return "start";
     846                 :          0 :     case G_TEST_LOG_STOP_CASE:          return "stop";
     847                 :          0 :     case G_TEST_LOG_MIN_RESULT:         return "minperf";
     848                 :          0 :     case G_TEST_LOG_MAX_RESULT:         return "maxperf";
     849                 :          0 :     case G_TEST_LOG_MESSAGE:            return "message";
     850                 :          0 :     case G_TEST_LOG_START_SUITE:        return "start suite";
     851                 :          0 :     case G_TEST_LOG_STOP_SUITE:         return "stop suite";
     852                 :            :     }
     853                 :          0 :   return "???";
     854                 :            : }
     855                 :            : 
     856                 :            : static void
     857                 :      32168 : g_test_log_send (guint         n_bytes,
     858                 :            :                  const guint8 *buffer)
     859                 :            : {
     860         [ +  + ]:      32168 :   if (test_log_fd >= 0)
     861                 :            :     {
     862                 :            :       int r;
     863                 :            :       do
     864                 :         45 :         r = write (test_log_fd, buffer, n_bytes);
     865   [ -  +  -  - ]:         45 :       while (r < 0 && errno == EINTR);
     866                 :            :     }
     867         [ -  + ]:      32168 :   if (test_debug_log)
     868                 :            :     {
     869                 :          0 :       GTestLogBuffer *lbuffer = g_test_log_buffer_new ();
     870                 :            :       GTestLogMsg *msg;
     871                 :            :       GString *output;
     872                 :            :       guint ui;
     873                 :          0 :       g_test_log_buffer_push (lbuffer, n_bytes, buffer);
     874                 :          0 :       msg = g_test_log_buffer_pop (lbuffer);
     875         [ #  # ]:          0 :       g_warn_if_fail (msg != NULL);
     876         [ #  # ]:          0 :       g_warn_if_fail (lbuffer->data->len == 0);
     877                 :          0 :       g_test_log_buffer_free (lbuffer);
     878                 :            :       /* print message */
     879                 :          0 :       output = g_string_new (NULL);
     880                 :          0 :       g_string_printf (output, "{*LOG(%s)", g_test_log_type_name (msg->log_type));
     881         [ #  # ]:          0 :       for (ui = 0; ui < msg->n_strings; ui++)
     882                 :          0 :         g_string_append_printf (output, ":{%s}", msg->strings[ui]);
     883         [ #  # ]:          0 :       if (msg->n_nums)
     884                 :            :         {
     885         [ #  # ]:          0 :           g_string_append (output, ":(");
     886         [ #  # ]:          0 :           for (ui = 0; ui < msg->n_nums; ui++)
     887                 :            :             {
     888         [ #  # ]:          0 :               if ((long double) (long) msg->nums[ui] == msg->nums[ui])
     889         [ #  # ]:          0 :                 g_string_append_printf (output, "%s%ld", ui ? ";" : "", (long) msg->nums[ui]);
     890                 :            :               else
     891         [ #  # ]:          0 :                 g_string_append_printf (output, "%s%.16g", ui ? ";" : "", (double) msg->nums[ui]);
     892                 :            :             }
     893                 :            :           g_string_append_c (output, ')');
     894                 :            :         }
     895         [ #  # ]:          0 :       g_string_append (output, ":LOG*}");
     896                 :          0 :       g_printerr ("%s\n", output->str);
     897                 :          0 :       g_string_free (output, TRUE);
     898                 :          0 :       g_test_log_msg_free (msg);
     899                 :            :     }
     900                 :      32168 : }
     901                 :            : 
     902                 :            : static void
     903                 :      32168 : g_test_log (GTestLogType lbit,
     904                 :            :             const gchar *string1,
     905                 :            :             const gchar *string2,
     906                 :            :             guint        n_args,
     907                 :            :             long double *largs)
     908                 :            : {
     909                 :            :   GTestResult result;
     910                 :            :   gboolean fail;
     911                 :            :   GTestLogMsg msg;
     912                 :      32168 :   gchar *astrings[3] = { NULL, NULL, NULL };
     913                 :            :   guint8 *dbuffer;
     914                 :            :   guint32 dbufferlen;
     915                 :            :   unsigned subtest_level;
     916                 :            :   gdouble timing;
     917                 :            : 
     918   [ +  +  +  -  :      32168 :   if (g_once_init_enter_pointer (&g_default_print_func))
                   +  + ]
     919                 :            :     {
     920                 :        633 :       g_once_init_leave_pointer (&g_default_print_func,
     921                 :            :                                  g_set_print_handler (g_test_print_handler));
     922                 :        633 :       g_assert_nonnull (g_default_print_func);
     923                 :            :     }
     924                 :            : 
     925                 :      32168 :   subtest_level = is_subtest () ? 1 : 0;
     926                 :            : 
     927   [ +  +  +  +  :      32168 :   switch (lbit)
          +  +  +  +  +  
                      + ]
     928                 :            :     {
     929                 :        632 :     case G_TEST_LOG_START_BINARY:
     930         [ +  + ]:        632 :       if (test_tap_log)
     931                 :            :         {
     932         [ +  + ]:        390 :           if (!is_subtest ())
     933                 :            :             {
     934                 :        343 :               g_test_tap_print (0, FALSE, "TAP version " TAP_VERSION "\n");
     935                 :            :             }
     936                 :            :           else
     937                 :            :             {
     938         [ +  - ]:         47 :               g_test_tap_print (subtest_level > 0 ? subtest_level - 1 : 0, TRUE,
     939                 :            :                                 "Subtest: %s\n", test_argv0);
     940                 :            :             }
     941                 :            : 
     942                 :        390 :           g_print ("random seed: %s\n", string2);
     943                 :            :         }
     944         [ -  + ]:        242 :       else if (g_test_verbose ())
     945                 :            :         {
     946                 :          0 :           g_print ("GTest: random seed: %s\n", string2);
     947                 :            :         }
     948                 :        632 :       break;
     949                 :       2410 :     case G_TEST_LOG_START_SUITE:
     950         [ +  + ]:       2410 :       if (test_tap_log)
     951                 :            :         {
     952                 :            :           /* We only print the TAP "plan" (1..n) ahead of time if we did
     953                 :            :            * not use the -p option to select specific tests to be run. */
     954         [ +  + ]:       1535 :           if (string1[0] != 0)
     955                 :       1159 :             g_print ("Start of %s tests\n", string1);
     956         [ +  + ]:        376 :           else if (test_paths == NULL)
     957                 :        360 :             g_test_tap_print (subtest_level, FALSE, "1..%d\n", test_count);
     958                 :            :         }
     959                 :       2410 :       break;
     960                 :       1902 :     case G_TEST_LOG_STOP_SUITE:
     961         [ +  + ]:       1902 :       if (test_tap_log)
     962                 :            :         {
     963                 :            :           /* If we didn't print the TAP "plan" at the beginning because
     964                 :            :            * we were using -p, we need to print how many tests we ran at
     965                 :            :            * the end instead. */
     966         [ +  + ]:       1535 :           if (string1[0] != 0)
     967                 :       1159 :             g_print ("End of %s tests\n", string1);
     968         [ +  + ]:        376 :           else if (test_paths != NULL)
     969                 :         16 :             g_test_tap_print (subtest_level, FALSE, "1..%d\n", test_run_count);
     970                 :            :         }
     971                 :       1902 :       break;
     972                 :       6897 :     case G_TEST_LOG_STOP_CASE:
     973                 :       6897 :       result = largs[G_TEST_CASE_LARGS_RESULT];
     974                 :       6897 :       timing = largs[G_TEST_CASE_LARGS_EXECUTION_TIME];
     975                 :       6897 :       fail = result == G_TEST_RUN_FAILURE;
     976         [ +  + ]:       6897 :       if (test_tap_log)
     977                 :            :         {
     978                 :            :           GString *tap_output;
     979                 :            : 
     980                 :            :           /* The TAP representation for an expected failure starts with
     981                 :            :            * "not ok", even though it does not actually count as failing
     982                 :            :            * due to the use of the TODO directive. "ok # TODO" would mean
     983                 :            :            * a test that was expected to fail unexpectedly succeeded,
     984                 :            :            * for which GTestResult does not currently have a
     985                 :            :            * representation. */
     986   [ +  +  +  + ]:       6764 :           if (fail || result == G_TEST_RUN_INCOMPLETE)
     987                 :         14 :             tap_output = g_string_new ("not ok");
     988                 :            :           else
     989                 :       6750 :             tap_output = g_string_new ("ok");
     990                 :            : 
     991         [ +  + ]:       6764 :           if (is_subtest ())
     992                 :         70 :             g_string_prepend (tap_output, TAP_SUBTEST_PREFIX);
     993                 :            : 
     994                 :       6764 :           g_string_append_printf (tap_output, " %d %s", test_run_count, string1);
     995         [ +  + ]:       6764 :           if (result == G_TEST_RUN_INCOMPLETE)
     996         [ +  - ]:          8 :             g_string_append_printf (tap_output, " # TODO %s", string2 ? string2 : "");
     997         [ +  + ]:       6756 :           else if (result == G_TEST_RUN_SKIPPED)
     998         [ +  - ]:         80 :             g_string_append_printf (tap_output, " # SKIP %s", string2 ? string2 : "");
     999   [ +  +  +  + ]:       6676 :           else if (result == G_TEST_RUN_FAILURE && string2 != NULL)
    1000                 :          2 :             g_string_append_printf (tap_output, " - %s", string2);
    1001                 :            : 
    1002         [ +  - ]:       6764 :           g_string_append_c (tap_output, '\n');
    1003                 :       6764 :           g_default_print_func (tap_output->str);
    1004                 :       6764 :           g_string_free (g_steal_pointer (&tap_output), TRUE);
    1005                 :            : 
    1006                 :            :           /* Print msg for any slow tests, where 'slow' means >= 0.5 secs */
    1007         [ +  + ]:       6764 :           if (timing > 0.5)
    1008                 :            :             {
    1009                 :        128 :               tap_output = g_string_new ("# ");
    1010                 :        128 :               g_string_append_printf (tap_output, "slow test %s executed in %0.2lf secs\n",
    1011                 :            :                                       string1, timing);
    1012                 :        128 :               g_default_print_func (tap_output->str);
    1013                 :        128 :               g_string_free (g_steal_pointer (&tap_output), TRUE);
    1014                 :            :             }
    1015                 :            :         }
    1016         [ -  + ]:        133 :       else if (g_test_verbose ())
    1017                 :          0 :         g_print ("GTest: result: %s\n", g_test_result_names[result]);
    1018   [ +  +  -  + ]:        133 :       else if (!g_test_quiet () && !test_in_subprocess)
    1019                 :          0 :         g_print ("%s\n", g_test_result_names[result]);
    1020   [ +  +  -  + ]:       6897 :       if (fail && test_mode_fatal)
    1021                 :            :         {
    1022         [ #  # ]:          0 :           if (test_tap_log)
    1023                 :          0 :             g_test_tap_print (0, FALSE, "Bail out!\n");
    1024                 :          0 :           g_abort ();
    1025                 :            :         }
    1026   [ +  +  +  + ]:       6897 :       if (result == G_TEST_RUN_SKIPPED || result == G_TEST_RUN_INCOMPLETE)
    1027                 :        104 :         test_skipped_count++;
    1028                 :       6897 :       break;
    1029                 :         24 :     case G_TEST_LOG_SKIP_CASE:
    1030         [ +  - ]:         24 :       if (test_tap_log)
    1031                 :            :         {
    1032                 :         24 :           g_test_tap_print (subtest_level, FALSE, "ok %d %s # SKIP\n",
    1033                 :            :                             test_run_count, string1);
    1034                 :            :         }
    1035                 :         24 :       break;
    1036                 :          7 :     case G_TEST_LOG_MIN_RESULT:
    1037         [ +  - ]:          7 :       if (test_tap_log)
    1038                 :          7 :         g_print ("min perf: %s\n", string1);
    1039         [ #  # ]:          0 :       else if (g_test_verbose ())
    1040                 :          0 :         g_print ("(MINPERF:%s)\n", string1);
    1041                 :          7 :       break;
    1042                 :         73 :     case G_TEST_LOG_MAX_RESULT:
    1043         [ +  - ]:         73 :       if (test_tap_log)
    1044                 :         73 :         g_print ("max perf: %s\n", string1);
    1045         [ #  # ]:          0 :       else if (g_test_verbose ())
    1046                 :          0 :         g_print ("(MAXPERF:%s)\n", string1);
    1047                 :         73 :       break;
    1048                 :      13193 :     case G_TEST_LOG_MESSAGE:
    1049         [ +  + ]:      13193 :       if (test_tap_log)
    1050                 :      13033 :         g_print ("%s\n", string1);
    1051         [ -  + ]:        160 :       else if (g_test_verbose ())
    1052                 :          0 :         g_print ("(MSG: %s)\n", string1);
    1053                 :      13193 :       break;
    1054                 :          2 :     case G_TEST_LOG_ERROR:
    1055         [ -  + ]:          2 :       if (test_tap_log)
    1056                 :            :         {
    1057                 :          0 :           char *message = g_strdup (string1);
    1058                 :            : 
    1059         [ #  # ]:          0 :           if (message)
    1060                 :            :             {
    1061                 :          0 :               char *line = message;
    1062                 :            : 
    1063         [ #  # ]:          0 :               while ((line = strchr (line, '\n')))
    1064                 :          0 :                   *(line++) = ' ';
    1065                 :            : 
    1066                 :          0 :               message = g_strstrip (message);
    1067                 :            :             }
    1068                 :            : 
    1069   [ #  #  #  # ]:          0 :           if (test_run_name && *test_run_name != '\0')
    1070                 :            :             {
    1071   [ #  #  #  # ]:          0 :               if (message && *message != '\0')
    1072                 :          0 :                 g_test_tap_print (subtest_level, FALSE, "not ok %s - %s\n",
    1073                 :            :                                   test_run_name, message);
    1074                 :            :               else
    1075                 :          0 :                 g_test_tap_print (subtest_level, FALSE, "not ok %s\n",
    1076                 :            :                                   test_run_name);
    1077                 :            : 
    1078                 :          0 :               g_clear_pointer (&message, g_free);
    1079                 :            :             }
    1080                 :            : 
    1081   [ #  #  #  # ]:          0 :           if (message && *message != '\0')
    1082                 :          0 :             g_test_tap_print (subtest_level, FALSE, "Bail out! %s\n", message);
    1083                 :            :           else
    1084                 :          0 :             g_test_tap_print (subtest_level, FALSE, "Bail out!\n");
    1085                 :            : 
    1086                 :          0 :           g_free (message);
    1087                 :            :         }
    1088         [ -  + ]:          2 :       else if (g_test_verbose ())
    1089                 :            :         {
    1090                 :          0 :           g_print ("(ERROR: %s)\n", string1);
    1091                 :            :         }
    1092                 :          2 :       break;
    1093                 :      32168 :     default: ;
    1094                 :            :     }
    1095                 :            : 
    1096                 :      32168 :   msg.log_type = lbit;
    1097   [ +  +  +  + ]:      32168 :   msg.n_strings = (string1 != NULL) + (string1 && string2);
    1098                 :      32168 :   msg.strings = astrings;
    1099                 :      32168 :   astrings[0] = (gchar*) string1;
    1100         [ +  + ]:      32168 :   astrings[1] = astrings[0] ? (gchar*) string2 : NULL;
    1101                 :      32168 :   msg.n_nums = n_args;
    1102                 :      32168 :   msg.nums = largs;
    1103                 :      32168 :   dbuffer = g_test_log_dump (&msg, &dbufferlen);
    1104                 :      32168 :   g_test_log_send (dbufferlen, dbuffer);
    1105                 :      32168 :   g_free (dbuffer);
    1106                 :            : 
    1107         [ +  + ]:      32168 :   switch (lbit)
    1108                 :            :     {
    1109                 :       7022 :     case G_TEST_LOG_START_CASE:
    1110         [ +  + ]:       7022 :       if (test_tap_log)
    1111                 :            :         ;
    1112         [ -  + ]:        258 :       else if (g_test_verbose ())
    1113                 :          0 :         g_print ("GTest: run: %s\n", string1);
    1114         [ +  + ]:        258 :       else if (!g_test_quiet ())
    1115                 :         26 :         g_print ("%s: ", string1);
    1116                 :       7022 :       break;
    1117                 :      32168 :     default: ;
    1118                 :            :     }
    1119                 :      32168 : }
    1120                 :            : 
    1121                 :            : /**
    1122                 :            :  * g_test_disable_crash_reporting:
    1123                 :            :  *
    1124                 :            :  * Attempt to disable system crash reporting infrastructure.
    1125                 :            :  *
    1126                 :            :  * This function should be called before exercising code paths that are
    1127                 :            :  * expected or intended to crash, to avoid wasting resources in system-wide
    1128                 :            :  * crash collection infrastructure such as systemd-coredump or abrt.
    1129                 :            :  *
    1130                 :            :  * Since: 2.78
    1131                 :            :  */
    1132                 :            : void
    1133                 :        243 : g_test_disable_crash_reporting (void)
    1134                 :            : {
    1135                 :            : #ifdef HAVE_SYS_RESOURCE_H
    1136                 :        243 :   struct rlimit limit = { 0, 0 };
    1137                 :            : 
    1138                 :        243 :   (void) setrlimit (RLIMIT_CORE, &limit);
    1139                 :            : #endif
    1140                 :            : 
    1141                 :            : #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
    1142                 :            :   /* On Linux, RLIMIT_CORE = 0 is ignored if core dumps are
    1143                 :            :    * configured to be written to a pipe, but PR_SET_DUMPABLE is not. */
    1144                 :        243 :   (void) prctl (PR_SET_DUMPABLE, 0, 0, 0, 0);
    1145                 :            : #endif
    1146                 :        243 : }
    1147                 :            : 
    1148                 :            : /* We intentionally parse the command line without GOptionContext
    1149                 :            :  * because otherwise you would never be able to test it.
    1150                 :            :  */
    1151                 :            : static void
    1152                 :        635 : parse_args (gint    *argc_p,
    1153                 :            :             gchar ***argv_p)
    1154                 :            : {
    1155                 :        635 :   guint argc = *argc_p;
    1156                 :        635 :   gchar **argv = *argv_p;
    1157                 :            :   guint i, e;
    1158                 :            : 
    1159                 :        635 :   test_argv0 = argv[0];  /* will be NULL iff argc == 0 */
    1160                 :        635 :   test_initial_cwd = g_get_current_dir ();
    1161                 :            : 
    1162                 :            :   /* parse known args */
    1163         [ +  + ]:       1588 :   for (i = 1; i < argc; i++)
    1164                 :            :     {
    1165         [ -  + ]:        956 :       if (strcmp (argv[i], "--g-fatal-warnings") == 0)
    1166                 :            :         {
    1167                 :          0 :           GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
    1168                 :          0 :           fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
    1169                 :          0 :           g_log_set_always_fatal (fatal_mask);
    1170                 :          0 :           argv[i] = NULL;
    1171                 :            :         }
    1172         [ +  + ]:        956 :       else if (strcmp (argv[i], "--keep-going") == 0 ||
    1173         [ -  + ]:        955 :                strcmp (argv[i], "-k") == 0)
    1174                 :            :         {
    1175                 :          1 :           test_mode_fatal = FALSE;
    1176                 :          1 :           argv[i] = NULL;
    1177                 :            :         }
    1178         [ -  + ]:        955 :       else if (strcmp (argv[i], "--debug-log") == 0)
    1179                 :            :         {
    1180                 :          0 :           test_debug_log = TRUE;
    1181                 :          0 :           argv[i] = NULL;
    1182                 :            :         }
    1183         [ +  + ]:        955 :       else if (strcmp (argv[i], "--tap") == 0)
    1184                 :            :         {
    1185                 :         45 :           test_tap_log = TRUE;
    1186                 :         45 :           argv[i] = NULL;
    1187                 :            :         }
    1188   [ +  -  +  + ]:        910 :       else if (strcmp ("--GTestLogFD", argv[i]) == 0 || strncmp ("--GTestLogFD=", argv[i], 13) == 0)
    1189                 :          2 :         {
    1190                 :          2 :           gchar *equal = argv[i] + 12;
    1191         [ +  - ]:          2 :           if (*equal == '=')
    1192                 :          2 :             test_log_fd = g_ascii_strtoull (equal + 1, NULL, 0);
    1193         [ #  # ]:          0 :           else if (i + 1 < argc)
    1194                 :            :             {
    1195                 :          0 :               argv[i++] = NULL;
    1196                 :          0 :               test_log_fd = g_ascii_strtoull (argv[i], NULL, 0);
    1197                 :            :             }
    1198                 :          2 :           argv[i] = NULL;
    1199                 :            : 
    1200                 :            :           /* Force non-TAP output when using gtester */
    1201                 :          2 :           test_tap_log = FALSE;
    1202                 :            :         }
    1203   [ +  +  -  + ]:        908 :       else if (strcmp ("--GTestSkipCount", argv[i]) == 0 || strncmp ("--GTestSkipCount=", argv[i], 17) == 0)
    1204                 :          6 :         {
    1205                 :          6 :           gchar *equal = argv[i] + 16;
    1206         [ -  + ]:          6 :           if (*equal == '=')
    1207                 :          0 :             test_startup_skip_count = g_ascii_strtoull (equal + 1, NULL, 0);
    1208         [ +  - ]:          6 :           else if (i + 1 < argc)
    1209                 :            :             {
    1210                 :          6 :               argv[i++] = NULL;
    1211                 :          6 :               test_startup_skip_count = g_ascii_strtoull (argv[i], NULL, 0);
    1212                 :            :             }
    1213                 :          6 :           argv[i] = NULL;
    1214                 :            :         }
    1215         [ +  + ]:        902 :       else if (strcmp ("--GTestSubprocess", argv[i]) == 0)
    1216                 :            :         {
    1217                 :        241 :           test_in_subprocess = TRUE;
    1218                 :            :           /* We typically expect these child processes to crash, and some
    1219                 :            :            * tests spawn a *lot* of them.  Avoid spamming system crash
    1220                 :            :            * collection programs such as systemd-coredump and abrt.
    1221                 :            :            */
    1222                 :        241 :           g_test_disable_crash_reporting ();
    1223                 :            : 
    1224                 :        241 :           argv[i] = NULL;
    1225                 :            : 
    1226                 :            :           /* Force non-TAP output when spawning a subprocess, since people often
    1227                 :            :            * test the stdout/stderr of the subprocess strictly */
    1228                 :        241 :           test_tap_log = FALSE;
    1229                 :            :         }
    1230   [ +  +  -  + ]:        661 :       else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0)
    1231                 :        261 :         {
    1232                 :        263 :           gchar *equal = argv[i] + 2;
    1233         [ -  + ]:        263 :           if (*equal == '=')
    1234                 :          0 :             test_paths = g_slist_prepend (test_paths, equal + 1);
    1235         [ +  - ]:        263 :           else if (i + 1 < argc)
    1236                 :            :             {
    1237                 :        263 :               argv[i++] = NULL;
    1238                 :        263 :               test_paths = g_slist_prepend (test_paths, argv[i]);
    1239                 :            :             }
    1240                 :        263 :           argv[i] = NULL;
    1241         [ +  + ]:        263 :           if (test_prefix_extended) {
    1242                 :          2 :             printf ("do not mix [-r | --run-prefix] with '-p'\n");
    1243                 :          2 :             exit (1);
    1244                 :            :           }
    1245                 :        261 :           test_prefix = TRUE;
    1246                 :            :         }
    1247         [ +  + ]:        398 :       else if (strcmp ("-r", argv[i]) == 0 ||
    1248         [ +  - ]:        390 :                strncmp ("-r=", argv[i], 3) == 0 ||
    1249         [ +  + ]:        390 :                strcmp ("--run-prefix", argv[i]) == 0 ||
    1250         [ -  + ]:        386 :                strncmp ("--run-prefix=", argv[i], 13) == 0)
    1251                 :         12 :         {
    1252                 :         12 :             gchar *equal = argv[i] + 2;
    1253         [ -  + ]:         12 :             if (*equal == '=')
    1254                 :          0 :               test_paths = g_slist_prepend (test_paths, equal + 1);
    1255         [ +  - ]:         12 :             else if (i + 1 < argc)
    1256                 :            :               {
    1257                 :         12 :                 argv[i++] = NULL;
    1258                 :         12 :                 test_paths = g_slist_prepend (test_paths, argv[i]);
    1259                 :            :               }
    1260                 :         12 :             argv[i] = NULL;
    1261         [ -  + ]:         12 :             if (test_prefix) {
    1262                 :          0 :               printf ("do not mix [-r | --run-prefix] with '-p'\n");
    1263                 :          0 :               exit (1);
    1264                 :            :             }
    1265                 :         12 :             test_prefix_extended = TRUE;
    1266                 :            :         }
    1267   [ +  +  -  + ]:        386 :       else if (strcmp ("-s", argv[i]) == 0 || strncmp ("-s=", argv[i], 3) == 0)
    1268                 :          9 :         {
    1269                 :          9 :           gchar *equal = argv[i] + 2;
    1270         [ -  + ]:          9 :           if (*equal == '=')
    1271                 :          0 :             test_paths_skipped = g_slist_prepend (test_paths_skipped, equal + 1);
    1272         [ +  - ]:          9 :           else if (i + 1 < argc)
    1273                 :            :             {
    1274                 :          9 :               argv[i++] = NULL;
    1275                 :          9 :               test_paths_skipped = g_slist_prepend (test_paths_skipped, argv[i]);
    1276                 :            :             }
    1277                 :          9 :           argv[i] = NULL;
    1278         [ -  + ]:          9 :           if (test_prefix_extended_skipped) {
    1279                 :          0 :             printf ("do not mix [-x | --skip-prefix] with '-s'\n");
    1280                 :          0 :             exit (1);
    1281                 :            :           }
    1282                 :          9 :           test_prefix_skipped = TRUE;
    1283                 :            :         }
    1284         [ +  + ]:        377 :       else if (strcmp ("-x", argv[i]) == 0 ||
    1285         [ +  - ]:        373 :                strncmp ("-x=", argv[i], 3) == 0 ||
    1286         [ +  + ]:        373 :                strcmp ("--skip-prefix", argv[i]) == 0 ||
    1287         [ -  + ]:        370 :                strncmp ("--skip-prefix=", argv[i], 14) == 0)
    1288                 :          6 :         {
    1289                 :          7 :           gchar *equal = argv[i] + 2;
    1290         [ -  + ]:          7 :           if (*equal == '=')
    1291                 :          0 :             test_paths_skipped = g_slist_prepend (test_paths_skipped, equal + 1);
    1292         [ +  - ]:          7 :           else if (i + 1 < argc)
    1293                 :            :             {
    1294                 :          7 :               argv[i++] = NULL;
    1295                 :          7 :               test_paths_skipped = g_slist_prepend (test_paths_skipped, argv[i]);
    1296                 :            :             }
    1297                 :          7 :           argv[i] = NULL;
    1298         [ +  + ]:          7 :           if (test_prefix_skipped) {
    1299                 :          1 :             printf ("do not mix [-x | --skip-prefix] with '-s'\n");
    1300                 :          1 :             exit (1);
    1301                 :            :           }
    1302                 :          6 :           test_prefix_extended_skipped = TRUE;
    1303                 :            :         }
    1304   [ +  -  +  + ]:        370 :       else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
    1305                 :          1 :         {
    1306                 :          1 :           gchar *equal = argv[i] + 2;
    1307                 :          1 :           const gchar *mode = "";
    1308         [ +  - ]:          1 :           if (*equal == '=')
    1309                 :          1 :             mode = equal + 1;
    1310         [ #  # ]:          0 :           else if (i + 1 < argc)
    1311                 :            :             {
    1312                 :          0 :               argv[i++] = NULL;
    1313                 :          0 :               mode = argv[i];
    1314                 :            :             }
    1315         [ -  + ]:          1 :           if (strcmp (mode, "perf") == 0)
    1316                 :          0 :             mutable_test_config_vars.test_perf = TRUE;
    1317         [ -  + ]:          1 :           else if (strcmp (mode, "slow") == 0)
    1318                 :          0 :             mutable_test_config_vars.test_quick = FALSE;
    1319         [ -  + ]:          1 :           else if (strcmp (mode, "thorough") == 0)
    1320                 :          0 :             mutable_test_config_vars.test_quick = FALSE;
    1321         [ +  - ]:          1 :           else if (strcmp (mode, "quick") == 0)
    1322                 :            :             {
    1323                 :          1 :               mutable_test_config_vars.test_quick = TRUE;
    1324                 :          1 :               mutable_test_config_vars.test_perf = FALSE;
    1325                 :            :             }
    1326         [ #  # ]:          0 :           else if (strcmp (mode, "undefined") == 0)
    1327                 :          0 :             mutable_test_config_vars.test_undefined = TRUE;
    1328         [ #  # ]:          0 :           else if (strcmp (mode, "no-undefined") == 0)
    1329                 :          0 :             mutable_test_config_vars.test_undefined = FALSE;
    1330                 :            :           else
    1331                 :          0 :             g_error ("unknown test mode: -m %s", mode);
    1332                 :          1 :           argv[i] = NULL;
    1333                 :            :         }
    1334   [ +  +  +  + ]:        369 :       else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0)
    1335                 :            :         {
    1336                 :        230 :           mutable_test_config_vars.test_quiet = TRUE;
    1337                 :        230 :           mutable_test_config_vars.test_verbose = FALSE;
    1338                 :        230 :           argv[i] = NULL;
    1339                 :            :         }
    1340         [ +  + ]:        139 :       else if (strcmp ("--verbose", argv[i]) == 0)
    1341                 :            :         {
    1342                 :          3 :           mutable_test_config_vars.test_quiet = FALSE;
    1343                 :          3 :           mutable_test_config_vars.test_verbose = TRUE;
    1344                 :          3 :           argv[i] = NULL;
    1345                 :            :         }
    1346         [ +  + ]:        136 :       else if (strcmp ("-l", argv[i]) == 0)
    1347                 :            :         {
    1348                 :          1 :           test_run_list = TRUE;
    1349                 :          1 :           argv[i] = NULL;
    1350                 :            :         }
    1351   [ +  -  -  + ]:        135 :       else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0)
    1352                 :          0 :         {
    1353                 :          0 :           gchar *equal = argv[i] + 6;
    1354         [ #  # ]:          0 :           if (*equal == '=')
    1355                 :          0 :             test_run_seedstr = equal + 1;
    1356         [ #  # ]:          0 :           else if (i + 1 < argc)
    1357                 :            :             {
    1358                 :          0 :               argv[i++] = NULL;
    1359                 :          0 :               test_run_seedstr = argv[i];
    1360                 :            :             }
    1361                 :          0 :           argv[i] = NULL;
    1362                 :            :         }
    1363         [ +  - ]:        135 :       else if (strcmp ("-?", argv[i]) == 0 ||
    1364         [ +  - ]:        135 :                strcmp ("-h", argv[i]) == 0 ||
    1365         [ -  + ]:        135 :                strcmp ("--help", argv[i]) == 0)
    1366                 :            :         {
    1367                 :          0 :           printf ("Usage:\n"
    1368                 :            :                   "  %s [OPTION...]\n\n"
    1369                 :            :                   "Help Options:\n"
    1370                 :            :                   "  -h, --help                     Show help options\n\n"
    1371                 :            :                   "Test Options:\n"
    1372                 :            :                   "  --g-fatal-warnings             Make all warnings fatal\n"
    1373                 :            :                   "  -l                             List test cases available in a test executable\n"
    1374                 :            :                   "  -m {perf|slow|thorough|quick}  Execute tests according to mode\n"
    1375                 :            :                   "  -m {undefined|no-undefined}    Execute tests according to mode\n"
    1376                 :            :                   "  -p TESTPATH                    Only start test cases matching TESTPATH\n"
    1377                 :            :                   "  -s TESTPATH                    Skip all tests matching TESTPATH\n"
    1378                 :            :                   "  [-r | --run-prefix] PREFIX     Only start test cases (or suites) matching PREFIX (incompatible with -p).\n"
    1379                 :            :                   "                                 Unlike the -p option (which only goes one level deep), this option would \n"
    1380                 :            :                   "                                 run all tests path that have PREFIX at the beginning of their name.\n"
    1381                 :            :                   "                                 Note that the prefix used should be a valid test path (and not a simple prefix).\n"
    1382                 :            :                   "  [-x | --skip-prefix] PREFIX    Skip all tests matching PREFIX (incompatible with -s)\n"
    1383                 :            :                   "                                 Unlike the -s option (which only skips the exact TESTPATH), this option will \n"
    1384                 :            :                   "                                 skip all the tests that begins with PREFIX).\n"
    1385                 :            :                   "  --seed=SEEDSTRING              Start tests with random seed SEEDSTRING\n"
    1386                 :            :                   "  --debug-log                    debug test logging output\n"
    1387                 :            :                   "  -q, --quiet                    Run tests quietly\n"
    1388                 :            :                   "  --verbose                      Run tests verbosely\n",
    1389                 :            :                   argv[0]);
    1390                 :          0 :           exit (0);
    1391                 :            :         }
    1392                 :            :     }
    1393                 :            : 
    1394                 :            :   /* We've been prepending to test_paths, but its order matters, so
    1395                 :            :    * permute it */
    1396                 :        632 :   test_paths = g_slist_reverse (test_paths);
    1397                 :            : 
    1398                 :            :   /* collapse argv */
    1399                 :        632 :   e = 0;
    1400         [ +  + ]:       2501 :   for (i = 0; i < argc; i++)
    1401         [ +  + ]:       1869 :     if (argv[i])
    1402                 :            :       {
    1403                 :        766 :         argv[e++] = argv[i];
    1404         [ -  + ]:        766 :         if (i >= e)
    1405                 :          0 :           argv[i] = NULL;
    1406                 :            :       }
    1407                 :        632 :   *argc_p = e;
    1408                 :        632 : }
    1409                 :            : 
    1410                 :            : /* A fairly naive `rm -rf` implementation to clean up after unit tests. */
    1411                 :            : static void
    1412                 :       2107 : rm_rf (const gchar *path)
    1413                 :            : {
    1414                 :       2107 :   GDir *dir = NULL;
    1415                 :            :   const gchar *entry;
    1416                 :            : 
    1417                 :       2107 :   dir = g_dir_open (path, 0, NULL);
    1418         [ +  + ]:       2107 :   if (dir == NULL)
    1419                 :            :     {
    1420                 :            :       /* Assume it’s a file. Ignore failure. */
    1421                 :        218 :       (void) g_remove (path);
    1422                 :        218 :       return;
    1423                 :            :     }
    1424                 :            : 
    1425         [ +  + ]:       3417 :   while ((entry = g_dir_read_name (dir)) != NULL)
    1426                 :            :     {
    1427                 :       1528 :       gchar *sub_path = g_build_filename (path, entry, NULL);
    1428                 :       1528 :       rm_rf (sub_path);
    1429                 :       1528 :       g_free (sub_path);
    1430                 :            :     }
    1431                 :            : 
    1432                 :       1889 :   g_dir_close (dir);
    1433                 :            : 
    1434                 :       1889 :   g_rmdir (path);
    1435                 :            : }
    1436                 :            : 
    1437                 :            : /* Implement the %G_TEST_OPTION_ISOLATE_DIRS option, iff it’s enabled. Create
    1438                 :            :  * a temporary directory for this unit test (disambiguated using @test_run_name)
    1439                 :            :  * and use g_set_user_dirs() to point various XDG directories into it, without
    1440                 :            :  * having to call setenv() in a process which potentially has threads running.
    1441                 :            :  *
    1442                 :            :  * Note that this is called for each unit test, and hence won’t have taken
    1443                 :            :  * effect before g_test_run() is called in the unit test’s main(). Hence
    1444                 :            :  * references to XDG variables in main() will not be using the temporary
    1445                 :            :  * directory. */
    1446                 :            : static gboolean
    1447                 :       7006 : test_do_isolate_dirs (GError **error)
    1448                 :            : {
    1449                 :       7006 :   gchar *subdir = NULL;
    1450                 :       7006 :   gchar *home_dir = NULL, *cache_dir = NULL, *config_dir = NULL;
    1451                 :       7006 :   gchar *state_dir = NULL, *data_dir = NULL, *runtime_dir = NULL;
    1452                 :            :   gchar *config_dirs[3];
    1453                 :            :   gchar *data_dirs[3];
    1454                 :            : 
    1455         [ +  + ]:       7006 :   if (!test_isolate_dirs)
    1456                 :       6483 :     return TRUE;
    1457                 :            : 
    1458                 :            :   /* The @test_run_name includes the test suites, so may be several directories
    1459                 :            :    * deep. Add a `.dirs` directory to contain all the paths we create, and
    1460                 :            :    * guarantee none of them clash with test paths below the current one — test
    1461                 :            :    * paths may not contain components starting with `.`. */
    1462                 :        523 :   subdir = g_build_filename (test_tmpdir, test_run_name_path, ".dirs", NULL);
    1463                 :            : 
    1464                 :            :   /* We have to create the runtime directory (because it must be bound to
    1465                 :            :    * the session lifetime, which we consider to be the lifetime of the unit
    1466                 :            :    * test for testing purposes — see
    1467                 :            :    * https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html.
    1468                 :            :    * We don’t need to create the other directories — the specification
    1469                 :            :    * requires that client code create them if they don’t exist. Not creating
    1470                 :            :    * them automatically is a good test of clients’ adherence to the spec
    1471                 :            :    * and error handling of missing directories. */
    1472                 :        523 :   runtime_dir = g_build_filename (subdir, "runtime", NULL);
    1473         [ -  + ]:        523 :   if (g_mkdir_with_parents (runtime_dir, 0700) != 0)
    1474                 :            :     {
    1475                 :          0 :       gint saved_errno = errno;
    1476                 :          0 :       g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
    1477                 :            :                    "Failed to create XDG_RUNTIME_DIR ‘%s’: %s",
    1478                 :            :                   runtime_dir, g_strerror (saved_errno));
    1479                 :          0 :       g_free (runtime_dir);
    1480                 :          0 :       g_free (subdir);
    1481                 :          0 :       return FALSE;
    1482                 :            :     }
    1483                 :            : 
    1484                 :        523 :   home_dir = g_build_filename (subdir, "home", NULL);
    1485                 :        523 :   cache_dir = g_build_filename (subdir, "cache", NULL);
    1486                 :        523 :   config_dir = g_build_filename (subdir, "config", NULL);
    1487                 :        523 :   data_dir = g_build_filename (subdir, "data", NULL);
    1488                 :        523 :   state_dir = g_build_filename (subdir, "state", NULL);
    1489                 :            : 
    1490                 :        523 :   config_dirs[0] = g_build_filename (subdir, "system-config1", NULL);
    1491                 :        523 :   config_dirs[1] = g_build_filename (subdir, "system-config2", NULL);
    1492                 :        523 :   config_dirs[2] = NULL;
    1493                 :            : 
    1494                 :        523 :   data_dirs[0] = g_build_filename (subdir, "system-data1", NULL);
    1495                 :        523 :   data_dirs[1] = g_build_filename (subdir, "system-data2", NULL);
    1496                 :        523 :   data_dirs[2] = NULL;
    1497                 :            : 
    1498                 :            :   /* Remember to update the documentation for %G_TEST_OPTION_ISOLATE_DIRS if
    1499                 :            :    * this list changes. */
    1500                 :        523 :   g_set_user_dirs ("HOME", home_dir,
    1501                 :            :                    "XDG_CACHE_HOME", cache_dir,
    1502                 :            :                    "XDG_CONFIG_DIRS", config_dirs,
    1503                 :            :                    "XDG_CONFIG_HOME", config_dir,
    1504                 :            :                    "XDG_DATA_DIRS", data_dirs,
    1505                 :            :                    "XDG_DATA_HOME", data_dir,
    1506                 :            :                    "XDG_STATE_HOME", state_dir,
    1507                 :            :                    "XDG_RUNTIME_DIR", runtime_dir,
    1508                 :            :                    NULL);
    1509                 :            : 
    1510                 :        523 :   g_free (runtime_dir);
    1511                 :        523 :   g_free (state_dir);
    1512                 :        523 :   g_free (data_dir);
    1513                 :        523 :   g_free (config_dir);
    1514                 :        523 :   g_free (cache_dir);
    1515                 :        523 :   g_free (home_dir);
    1516                 :        523 :   g_free (data_dirs[1]);
    1517                 :        523 :   g_free (data_dirs[0]);
    1518                 :        523 :   g_free (config_dirs[1]);
    1519                 :        523 :   g_free (config_dirs[0]);
    1520                 :        523 :   g_free (subdir);
    1521                 :            : 
    1522                 :        523 :   return TRUE;
    1523                 :            : }
    1524                 :            : 
    1525                 :            : /* Clean up after test_do_isolate_dirs(). */
    1526                 :            : static void
    1527                 :       6881 : test_rm_isolate_dirs (void)
    1528                 :            : {
    1529                 :       6881 :   gchar *subdir = NULL;
    1530                 :            : 
    1531         [ +  + ]:       6881 :   if (!test_isolate_dirs)
    1532                 :       6360 :     return;
    1533                 :            : 
    1534                 :        521 :   subdir = g_build_filename (test_tmpdir, test_run_name_path, NULL);
    1535                 :        521 :   rm_rf (subdir);
    1536                 :        521 :   g_free (subdir);
    1537                 :            : }
    1538                 :            : 
    1539                 :            : /**
    1540                 :            :  * g_test_init:
    1541                 :            :  * @argc: Address of the @argc parameter of the main() function.
    1542                 :            :  *        Changed if any arguments were handled.
    1543                 :            :  * @argv: Address of the @argv parameter of main().
    1544                 :            :  *        Any parameters understood by g_test_init() stripped before return.
    1545                 :            :  * @...: %NULL-terminated list of special options, documented below.
    1546                 :            :  *
    1547                 :            :  * Initialize the GLib testing framework, e.g. by seeding the
    1548                 :            :  * test random number generator, the name for g_get_prgname()
    1549                 :            :  * and parsing test related command line args.
    1550                 :            :  *
    1551                 :            :  * This should be called before calling any other `g_test_*()` functions.
    1552                 :            :  *
    1553                 :            :  * So far, the following arguments are understood:
    1554                 :            :  *
    1555                 :            :  * - `-l`: List test cases available in a test executable.
    1556                 :            :  * - `--seed=SEED`: Provide a random seed to reproduce test
    1557                 :            :  *   runs using random numbers.
    1558                 :            :  * - `--verbose`: Run tests verbosely.
    1559                 :            :  * - `-q`, `--quiet`: Run tests quietly.
    1560                 :            :  * - `-p PATH`: Execute all tests matching the given path.
    1561                 :            :  * - `-s PATH`: Skip all tests matching the given path.
    1562                 :            :  *   This can also be used to force a test to run that would otherwise
    1563                 :            :  *   be skipped (ie, a test whose name contains "/subprocess").
    1564                 :            :  * - `-m {perf|slow|thorough|quick|undefined|no-undefined}`: Execute tests according to these test modes:
    1565                 :            :  *
    1566                 :            :  *   `perf`: Performance tests, may take long and report results (off by default).
    1567                 :            :  *
    1568                 :            :  *   `slow`, `thorough`: Slow and thorough tests, may take quite long and maximize coverage
    1569                 :            :  *   (off by default).
    1570                 :            :  *
    1571                 :            :  *   `quick`: Quick tests, should run really quickly and give good coverage (the default).
    1572                 :            :  *
    1573                 :            :  *   `undefined`: Tests for undefined behaviour, may provoke programming errors
    1574                 :            :  *   under g_test_trap_subprocess() or g_test_expect_message() to check
    1575                 :            :  *   that appropriate assertions or warnings are given (the default).
    1576                 :            :  *
    1577                 :            :  *   `no-undefined`: Avoid tests for undefined behaviour
    1578                 :            :  *
    1579                 :            :  * - `--debug-log`: Debug test logging output.
    1580                 :            :  *
    1581                 :            :  * Options which can be passed to @... are:
    1582                 :            :  *
    1583                 :            :  *  - `"no_g_set_prgname"`: Causes g_test_init() to not call g_set_prgname().
    1584                 :            :  *  - %G_TEST_OPTION_ISOLATE_DIRS: Creates a unique temporary directory for each
    1585                 :            :  *    unit test and uses g_set_user_dirs() to set XDG directories to point into
    1586                 :            :  *    that temporary directory for the duration of the unit test. See the
    1587                 :            :  *    documentation for %G_TEST_OPTION_ISOLATE_DIRS.
    1588                 :            :  *
    1589                 :            :  * Since 2.58, if tests are compiled with `G_DISABLE_ASSERT` defined,
    1590                 :            :  * g_test_init() will print an error and exit. This is to prevent no-op tests
    1591                 :            :  * from being executed, as g_assert() is commonly (erroneously) used in unit
    1592                 :            :  * tests, and is a no-op when compiled with `G_DISABLE_ASSERT`. Ensure your
    1593                 :            :  * tests are compiled without `G_DISABLE_ASSERT` defined.
    1594                 :            :  *
    1595                 :            :  * Since: 2.16
    1596                 :            :  */
    1597                 :            : void
    1598                 :        635 : (g_test_init) (int    *argc,
    1599                 :            :                char ***argv,
    1600                 :            :                ...)
    1601                 :            : {
    1602                 :            :   static char seedstr[4 + 4 * 8 + 1];
    1603                 :            :   va_list args;
    1604                 :            :   gpointer option;
    1605                 :            :   /* make warnings and criticals fatal for all test programs */
    1606                 :        635 :   GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
    1607                 :            : 
    1608                 :        635 :   fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
    1609                 :        635 :   g_log_set_always_fatal (fatal_mask);
    1610                 :            :   /* check caller args */
    1611                 :        635 :   g_return_if_fail (argc != NULL);
    1612                 :        635 :   g_return_if_fail (argv != NULL);
    1613                 :        635 :   g_return_if_fail (g_test_config_vars->test_initialized == FALSE);
    1614                 :        635 :   mutable_test_config_vars.test_initialized = TRUE;
    1615                 :            : 
    1616                 :            : #ifdef _GLIB_ADDRESS_SANITIZER
    1617                 :            :   mutable_test_config_vars.test_undefined = FALSE;
    1618                 :            : #endif
    1619                 :            : 
    1620                 :            : #ifdef G_OS_WIN32
    1621                 :            :   // don't open a window for errors (like the "abort() was called one")
    1622                 :            :   _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
    1623                 :            :   _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
    1624                 :            :   // while gtest tests tend to use g_assert and friends
    1625                 :            :   // if they do use the C standard assert macro we want to
    1626                 :            :   // output a message to stderr, not open a popup window
    1627                 :            :   _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
    1628                 :            :   _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
    1629                 :            :   // in release mode abort() will pop up a windows error
    1630                 :            :   // reporting dialog, let's prevent that. Only msvcrxx and
    1631                 :            :   // the UCRT have this function, but there's no great way to
    1632                 :            :   // detect msvcrxx (that I know of) so only call this when using
    1633                 :            :   // the UCRT
    1634                 :            : #ifdef _UCRT
    1635                 :            :   _set_abort_behavior (0, _CALL_REPORTFAULT);
    1636                 :            : #endif
    1637                 :            : #endif
    1638                 :            : 
    1639                 :        635 :   va_start (args, argv);
    1640         [ +  + ]:        697 :   while ((option = va_arg (args, char *)))
    1641                 :            :     {
    1642         [ +  + ]:         62 :       if (g_strcmp0 (option, "no_g_set_prgname") == 0)
    1643                 :          1 :         no_g_set_prgname = TRUE;
    1644         [ +  - ]:         61 :       else if (g_strcmp0 (option, G_TEST_OPTION_ISOLATE_DIRS) == 0)
    1645                 :         61 :         test_isolate_dirs = TRUE;
    1646                 :            :     }
    1647                 :        635 :   va_end (args);
    1648                 :            : 
    1649                 :            :   /* parse args, sets up mode, changes seed, etc. */
    1650                 :        635 :   parse_args (argc, argv);
    1651                 :            : 
    1652         [ +  - ]:        632 :   if (test_run_seedstr == NULL)
    1653                 :            :     {
    1654                 :            :       /* setup random seed string */
    1655                 :        632 :       g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x",
    1656                 :            :                   g_random_int(), g_random_int(), g_random_int(), g_random_int());
    1657                 :        632 :       test_run_seedstr = seedstr;
    1658                 :            :     }
    1659                 :            : 
    1660   [ +  +  +  + ]:        632 :   if (!g_get_prgname () && !no_g_set_prgname)
    1661                 :        605 :     g_set_prgname_once ((*argv)[0]);
    1662                 :            : 
    1663         [ +  + ]:        632 :   if (g_getenv ("G_TEST_ROOT_PROCESS"))
    1664                 :            :     {
    1665                 :        288 :       test_is_subtest = TRUE;
    1666                 :            :     }
    1667   [ +  -  -  + ]:        344 :   else if (!g_setenv ("G_TEST_ROOT_PROCESS", test_argv0 ? test_argv0 : "root", TRUE))
    1668                 :            :     {
    1669                 :          0 :       g_printerr ("%s: Failed to set environment variable ‘%s’\n",
    1670                 :            :                   test_argv0, "G_TEST_ROOT_PROCESS");
    1671                 :          0 :       exit (1);
    1672                 :            :     }
    1673                 :            : 
    1674                 :            :   /* Set up the temporary directory for isolating the test. We have to do this
    1675                 :            :    * early, as we want the return values from g_get_user_data_dir() (and
    1676                 :            :    * friends) to return subdirectories of the temporary directory throughout
    1677                 :            :    * the setup function, test, and teardown function, for each unit test.
    1678                 :            :    * See test_do_isolate_dirs().
    1679                 :            :    *
    1680                 :            :    * The directory is deleted at the bottom of g_test_run().
    1681                 :            :    *
    1682                 :            :    * Rather than setting the XDG_* environment variables we use a new
    1683                 :            :    * G_TEST_TMPDIR variable which gives the top-level temporary directory. This
    1684                 :            :    * allows test subprocesses to reuse the same temporary directory when
    1685                 :            :    * g_test_init() is called in them. */
    1686         [ +  + ]:        632 :   if (test_isolate_dirs)
    1687                 :            :     {
    1688         [ +  + ]:         61 :       if (g_getenv ("G_TEST_TMPDIR") == NULL)
    1689                 :            :         {
    1690                 :         58 :           gchar *test_prgname = NULL;
    1691                 :         58 :           gchar *tmpl = NULL;
    1692                 :         58 :           GError *local_error = NULL;
    1693                 :            : 
    1694                 :         58 :           test_prgname = g_path_get_basename (g_get_prgname ());
    1695         [ -  + ]:         58 :           if (*test_prgname == '\0')
    1696                 :            :             {
    1697                 :          0 :               g_free (test_prgname);
    1698                 :          0 :               test_prgname = g_strdup ("unknown");
    1699                 :            :             }
    1700                 :         58 :           tmpl = g_strdup_printf ("test_%s_XXXXXX", test_prgname);
    1701                 :         58 :           g_free (test_prgname);
    1702                 :            : 
    1703                 :         58 :           test_isolate_dirs_tmpdir = g_dir_make_tmp (tmpl, &local_error);
    1704         [ -  + ]:         58 :           if (local_error != NULL)
    1705                 :            :             {
    1706                 :          0 :               g_printerr ("%s: Failed to create temporary directory: %s\n",
    1707                 :          0 :                           (*argv)[0], local_error->message);
    1708                 :          0 :               g_error_free (local_error);
    1709                 :          0 :               exit (1);
    1710                 :            :             }
    1711                 :         58 :           g_free (tmpl);
    1712                 :            : 
    1713                 :            :           /* Propagate the temporary directory to subprocesses. */
    1714         [ -  + ]:         58 :           if (!g_setenv ("G_TEST_TMPDIR", test_isolate_dirs_tmpdir, TRUE))
    1715                 :            :             {
    1716                 :          0 :               g_printerr ("%s: Failed to set environment variable ‘%s’\n",
    1717                 :          0 :                           (*argv)[0], "G_TEST_TMPDIR");
    1718                 :          0 :               exit (1);
    1719                 :            :             }
    1720                 :         58 :           _g_unset_cached_tmp_dir ();
    1721                 :            : 
    1722                 :            :           /* And clear the traditional environment variables so subprocesses
    1723                 :            :            * spawned by the code under test can’t trash anything. If a test
    1724                 :            :            * spawns a process, the test is responsible for propagating
    1725                 :            :            * appropriate environment variables.
    1726                 :            :            *
    1727                 :            :            * We assume that any in-process code will use g_get_user_data_dir()
    1728                 :            :            * and friends, rather than getenv() directly.
    1729                 :            :            *
    1730                 :            :            * We set them to ‘/dev/null’ as that should fairly obviously not
    1731                 :            :            * accidentally work, and should be fairly greppable. */
    1732                 :            :             {
    1733                 :         58 :               const gchar *overridden_environment_variables[] =
    1734                 :            :                 {
    1735                 :            :                   "HOME",
    1736                 :            :                   "XDG_CACHE_HOME",
    1737                 :            :                   "XDG_CONFIG_DIRS",
    1738                 :            :                   "XDG_CONFIG_HOME",
    1739                 :            :                   "XDG_DATA_DIRS",
    1740                 :            :                   "XDG_DATA_HOME",
    1741                 :            :                   "XDG_RUNTIME_DIR",
    1742                 :            :                 };
    1743                 :            :               gsize i;
    1744                 :            : 
    1745         [ +  + ]:        464 :               for (i = 0; i < G_N_ELEMENTS (overridden_environment_variables); i++)
    1746                 :            :                 {
    1747         [ -  + ]:        406 :                   if (!g_setenv (overridden_environment_variables[i], "/dev/null", TRUE))
    1748                 :            :                     {
    1749                 :          0 :                       g_printerr ("%s: Failed to set environment variable ‘%s’\n",
    1750                 :          0 :                                   (*argv)[0], overridden_environment_variables[i]);
    1751                 :          0 :                       exit (1);
    1752                 :            :                     }
    1753                 :            :                 }
    1754                 :            :             }
    1755                 :            :         }
    1756                 :            : 
    1757                 :            :       /* Cache this for the remainder of this process’ lifetime. */
    1758                 :         61 :       test_tmpdir = g_getenv ("G_TEST_TMPDIR");
    1759                 :            :     }
    1760                 :            : 
    1761                 :            :   /* verify GRand reliability, needed for reliable seeds */
    1762                 :            :   if (1)
    1763                 :            :     {
    1764                 :        632 :       GRand *rg = g_rand_new_with_seed (0xc8c49fb6);
    1765                 :        632 :       guint32 t1 = g_rand_int (rg), t2 = g_rand_int (rg), t3 = g_rand_int (rg), t4 = g_rand_int (rg);
    1766                 :            :       /* g_print ("GRand-current: 0x%x 0x%x 0x%x 0x%x\n", t1, t2, t3, t4); */
    1767   [ +  -  +  -  :        632 :       if (t1 != 0xfab39f9b || t2 != 0xb948fb0e || t3 != 0x3d31be26 || t4 != 0x43a19d66)
             +  -  -  + ]
    1768                 :          0 :         g_warning ("random numbers are not GRand-2.2 compatible, seeds may be broken (check $G_RANDOM_VERSION)");
    1769                 :        632 :       g_rand_free (rg);
    1770                 :            :     }
    1771                 :            : 
    1772                 :            :   /* check rand seed */
    1773                 :        632 :   test_run_seed (test_run_seedstr);
    1774                 :            : 
    1775                 :            :   /* report program start */
    1776                 :        632 :   g_log_set_default_handler (gtest_default_log_handler, NULL);
    1777                 :        632 :   g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL);
    1778                 :            : 
    1779         [ +  + ]:        633 :   test_argv0_dirname = (test_argv0 != NULL) ? g_path_get_dirname (test_argv0) : g_strdup (".");
    1780                 :            : 
    1781                 :            :   /* Make sure we get the real dirname that the test was run from */
    1782   [ +  -  -  +  :        632 :   if (g_str_has_suffix (test_argv0_dirname, "/.libs"))
             +  +  -  + ]
    1783                 :            :     {
    1784                 :            :       gchar *tmp;
    1785                 :          0 :       tmp = g_path_get_dirname (test_argv0_dirname);
    1786                 :          0 :       g_free (test_argv0_dirname);
    1787                 :          0 :       test_argv0_dirname = tmp;
    1788                 :            :     }
    1789                 :            : 
    1790                 :        632 :   test_disted_files_dir = g_getenv ("G_TEST_SRCDIR");
    1791         [ +  + ]:        632 :   if (!test_disted_files_dir)
    1792                 :          1 :     test_disted_files_dir = test_argv0_dirname;
    1793                 :            : 
    1794                 :        632 :   test_built_files_dir = g_getenv ("G_TEST_BUILDDIR");
    1795         [ +  + ]:        632 :   if (!test_built_files_dir)
    1796                 :          1 :     test_built_files_dir = test_argv0_dirname;
    1797                 :            : }
    1798                 :            : 
    1799                 :            : static void
    1800                 :        547 : test_cleanup (void)
    1801                 :            : {
    1802                 :            :   /* Free statically allocated variables */
    1803                 :            : 
    1804                 :        547 :   g_clear_pointer (&test_run_rand, g_rand_free);
    1805                 :            : 
    1806                 :        547 :   g_clear_pointer (&test_argv0_dirname, g_free);
    1807                 :            : 
    1808                 :        547 :   g_clear_pointer (&test_initial_cwd, g_free);
    1809                 :        547 : }
    1810                 :            : 
    1811                 :            : static void
    1812                 :       7638 : test_run_seed (const gchar *rseed)
    1813                 :            : {
    1814                 :       7638 :   guint seed_failed = 0;
    1815         [ +  + ]:       7638 :   if (test_run_rand)
    1816                 :       7006 :     g_rand_free (test_run_rand);
    1817                 :       7638 :   test_run_rand = NULL;
    1818         [ -  + ]:       7638 :   while (strchr (" \t\v\r\n\f", *rseed))
    1819                 :          0 :     rseed++;
    1820         [ +  - ]:       7638 :   if (strncmp (rseed, "R02S", 4) == 0)  /* seed for random generator 02 (GRand-2.2) */
    1821                 :            :     {
    1822                 :       7638 :       const char *s = rseed + 4;
    1823         [ +  - ]:       7638 :       if (strlen (s) >= 32)             /* require 4 * 8 chars */
    1824                 :            :         {
    1825                 :            :           guint32 seedarray[4];
    1826                 :       7638 :           gchar *p, hexbuf[9] = { 0, };
    1827                 :       7638 :           memcpy (hexbuf, s + 0, 8);
    1828                 :       7638 :           seedarray[0] = g_ascii_strtoull (hexbuf, &p, 16);
    1829   [ +  -  -  + ]:       7638 :           seed_failed += p != NULL && *p != 0;
    1830                 :       7638 :           memcpy (hexbuf, s + 8, 8);
    1831                 :       7638 :           seedarray[1] = g_ascii_strtoull (hexbuf, &p, 16);
    1832   [ +  -  -  + ]:       7638 :           seed_failed += p != NULL && *p != 0;
    1833                 :       7638 :           memcpy (hexbuf, s + 16, 8);
    1834                 :       7638 :           seedarray[2] = g_ascii_strtoull (hexbuf, &p, 16);
    1835   [ +  -  -  + ]:       7638 :           seed_failed += p != NULL && *p != 0;
    1836                 :       7638 :           memcpy (hexbuf, s + 24, 8);
    1837                 :       7638 :           seedarray[3] = g_ascii_strtoull (hexbuf, &p, 16);
    1838   [ +  -  -  + ]:       7638 :           seed_failed += p != NULL && *p != 0;
    1839         [ +  - ]:       7638 :           if (!seed_failed)
    1840                 :            :             {
    1841                 :       7638 :               test_run_rand = g_rand_new_with_seed_array (seedarray, 4);
    1842                 :       7638 :               return;
    1843                 :            :             }
    1844                 :            :         }
    1845                 :            :     }
    1846                 :          0 :   g_error ("Unknown or invalid random seed: %s", rseed);
    1847                 :            : }
    1848                 :            : 
    1849                 :            : /**
    1850                 :            :  * g_test_rand_int:
    1851                 :            :  *
    1852                 :            :  * Get a reproducible random integer number.
    1853                 :            :  *
    1854                 :            :  * The random numbers generated by the g_test_rand_*() family of functions
    1855                 :            :  * change with every new test program start, unless the --seed option is
    1856                 :            :  * given when starting test programs.
    1857                 :            :  *
    1858                 :            :  * For individual test cases however, the random number generator is
    1859                 :            :  * reseeded, to avoid dependencies between tests and to make --seed
    1860                 :            :  * effective for all test cases.
    1861                 :            :  *
    1862                 :            :  * Returns: a random number from the seeded random number generator.
    1863                 :            :  *
    1864                 :            :  * Since: 2.16
    1865                 :            :  */
    1866                 :            : gint32
    1867                 :    1329928 : g_test_rand_int (void)
    1868                 :            : {
    1869                 :            :   gint32 r;
    1870                 :            : 
    1871                 :    1329928 :   G_LOCK (test_run_rand);
    1872                 :    1329928 :   r = g_rand_int (test_run_rand);
    1873                 :    1329928 :   G_UNLOCK (test_run_rand);
    1874                 :            : 
    1875                 :    1329928 :   return r;
    1876                 :            : }
    1877                 :            : 
    1878                 :            : /**
    1879                 :            :  * g_test_rand_int_range:
    1880                 :            :  * @begin: the minimum value returned by this function
    1881                 :            :  * @end:   the smallest value not to be returned by this function
    1882                 :            :  *
    1883                 :            :  * Get a reproducible random integer number out of a specified range,
    1884                 :            :  * see g_test_rand_int() for details on test case random numbers.
    1885                 :            :  *
    1886                 :            :  * Returns: a number with @begin <= number < @end.
    1887                 :            :  * 
    1888                 :            :  * Since: 2.16
    1889                 :            :  */
    1890                 :            : gint32
    1891                 :   40969504 : g_test_rand_int_range (gint32          begin,
    1892                 :            :                        gint32          end)
    1893                 :            : {
    1894                 :            :   gint32 r;
    1895                 :            : 
    1896                 :   40969504 :   G_LOCK (test_run_rand);
    1897                 :   40969504 :   r = g_rand_int_range (test_run_rand, begin, end);
    1898                 :   40969504 :   G_UNLOCK (test_run_rand);
    1899                 :            : 
    1900                 :   40969504 :   return r;
    1901                 :            : }
    1902                 :            : 
    1903                 :            : /**
    1904                 :            :  * g_test_rand_double:
    1905                 :            :  *
    1906                 :            :  * Get a reproducible random floating point number,
    1907                 :            :  * see g_test_rand_int() for details on test case random numbers.
    1908                 :            :  *
    1909                 :            :  * Returns: a random number from the seeded random number generator.
    1910                 :            :  *
    1911                 :            :  * Since: 2.16
    1912                 :            :  */
    1913                 :            : double
    1914                 :      33917 : g_test_rand_double (void)
    1915                 :            : {
    1916                 :            :   double r;
    1917                 :            : 
    1918                 :      33917 :   G_LOCK (test_run_rand);
    1919                 :      33917 :   r = g_rand_double (test_run_rand);
    1920                 :      33917 :   G_UNLOCK (test_run_rand);
    1921                 :            : 
    1922                 :      33917 :   return r;
    1923                 :            : }
    1924                 :            : 
    1925                 :            : /**
    1926                 :            :  * g_test_rand_double_range:
    1927                 :            :  * @range_start: the minimum value returned by this function
    1928                 :            :  * @range_end: the minimum value not returned by this function
    1929                 :            :  *
    1930                 :            :  * Get a reproducible random floating pointer number out of a specified range,
    1931                 :            :  * see g_test_rand_int() for details on test case random numbers.
    1932                 :            :  *
    1933                 :            :  * Returns: a number with @range_start <= number < @range_end.
    1934                 :            :  *
    1935                 :            :  * Since: 2.16
    1936                 :            :  */
    1937                 :            : double
    1938                 :   14522348 : g_test_rand_double_range (double          range_start,
    1939                 :            :                           double          range_end)
    1940                 :            : {
    1941                 :            :   double r;
    1942                 :            : 
    1943                 :   14522348 :   G_LOCK (test_run_rand);
    1944                 :   14522348 :   r = g_rand_double_range (test_run_rand, range_start, range_end);
    1945                 :   14522348 :   G_UNLOCK (test_run_rand);
    1946                 :            : 
    1947                 :   14522348 :   return r;
    1948                 :            : }
    1949                 :            : 
    1950                 :            : /**
    1951                 :            :  * g_test_timer_start:
    1952                 :            :  *
    1953                 :            :  * Start a timing test. Call g_test_timer_elapsed() when the task is supposed
    1954                 :            :  * to be done. Call this function again to restart the timer.
    1955                 :            :  *
    1956                 :            :  * Since: 2.16
    1957                 :            :  */
    1958                 :            : void
    1959                 :         43 : g_test_timer_start (void)
    1960                 :            : {
    1961         [ +  + ]:         43 :   if (!test_user_timer)
    1962                 :          2 :     test_user_timer = g_timer_new();
    1963                 :         43 :   test_user_stamp = 0;
    1964                 :         43 :   g_timer_start (test_user_timer);
    1965                 :         43 : }
    1966                 :            : 
    1967                 :            : /**
    1968                 :            :  * g_test_timer_elapsed:
    1969                 :            :  *
    1970                 :            :  * Get the number of seconds since the last start of the timer with
    1971                 :            :  * g_test_timer_start().
    1972                 :            :  *
    1973                 :            :  * Returns: the time since the last start of the timer in seconds, as a double
    1974                 :            :  *
    1975                 :            :  * Since: 2.16
    1976                 :            :  */
    1977                 :            : double
    1978                 :         43 : g_test_timer_elapsed (void)
    1979                 :            : {
    1980         [ +  - ]:         43 :   test_user_stamp = test_user_timer ? g_timer_elapsed (test_user_timer, NULL) : 0;
    1981                 :         43 :   return test_user_stamp;
    1982                 :            : }
    1983                 :            : 
    1984                 :            : /**
    1985                 :            :  * g_test_timer_last:
    1986                 :            :  *
    1987                 :            :  * Report the last result of g_test_timer_elapsed().
    1988                 :            :  *
    1989                 :            :  * Returns: the last result of g_test_timer_elapsed(), as a double
    1990                 :            :  *
    1991                 :            :  * Since: 2.16
    1992                 :            :  */
    1993                 :            : double
    1994                 :          0 : g_test_timer_last (void)
    1995                 :            : {
    1996                 :          0 :   return test_user_stamp;
    1997                 :            : }
    1998                 :            : 
    1999                 :            : /**
    2000                 :            :  * g_test_minimized_result:
    2001                 :            :  * @minimized_quantity: the reported value
    2002                 :            :  * @format: the format string of the report message
    2003                 :            :  * @...: arguments to pass to the printf() function
    2004                 :            :  *
    2005                 :            :  * Report the result of a performance or measurement test.
    2006                 :            :  * The test should generally strive to minimize the reported
    2007                 :            :  * quantities (smaller values are better than larger ones),
    2008                 :            :  * this and @minimized_quantity can determine sorting
    2009                 :            :  * order for test result reports.
    2010                 :            :  *
    2011                 :            :  * Since: 2.16
    2012                 :            :  */
    2013                 :            : void
    2014                 :          7 : g_test_minimized_result (double          minimized_quantity,
    2015                 :            :                          const char     *format,
    2016                 :            :                          ...)
    2017                 :            : {
    2018                 :          7 :   long double largs = minimized_quantity;
    2019                 :            :   gchar *buffer;
    2020                 :            :   va_list args;
    2021                 :            : 
    2022                 :          7 :   va_start (args, format);
    2023                 :          7 :   buffer = g_strdup_vprintf (format, args);
    2024                 :          7 :   va_end (args);
    2025                 :            : 
    2026                 :          7 :   g_test_log (G_TEST_LOG_MIN_RESULT, buffer, NULL, 1, &largs);
    2027                 :          7 :   g_free (buffer);
    2028                 :          7 : }
    2029                 :            : 
    2030                 :            : /**
    2031                 :            :  * g_test_maximized_result:
    2032                 :            :  * @maximized_quantity: the reported value
    2033                 :            :  * @format: the format string of the report message
    2034                 :            :  * @...: arguments to pass to the printf() function
    2035                 :            :  *
    2036                 :            :  * Report the result of a performance or measurement test.
    2037                 :            :  * The test should generally strive to maximize the reported
    2038                 :            :  * quantities (larger values are better than smaller ones),
    2039                 :            :  * this and @maximized_quantity can determine sorting
    2040                 :            :  * order for test result reports.
    2041                 :            :  *
    2042                 :            :  * Since: 2.16
    2043                 :            :  */
    2044                 :            : void
    2045                 :         73 : g_test_maximized_result (double          maximized_quantity,
    2046                 :            :                          const char     *format,
    2047                 :            :                          ...)
    2048                 :            : {
    2049                 :         73 :   long double largs = maximized_quantity;
    2050                 :            :   gchar *buffer;
    2051                 :            :   va_list args;
    2052                 :            : 
    2053                 :         73 :   va_start (args, format);
    2054                 :         73 :   buffer = g_strdup_vprintf (format, args);
    2055                 :         73 :   va_end (args);
    2056                 :            : 
    2057                 :         73 :   g_test_log (G_TEST_LOG_MAX_RESULT, buffer, NULL, 1, &largs);
    2058                 :         73 :   g_free (buffer);
    2059                 :         73 : }
    2060                 :            : 
    2061                 :            : /**
    2062                 :            :  * g_test_message:
    2063                 :            :  * @format: the format string
    2064                 :            :  * @...:    printf-like arguments to @format
    2065                 :            :  *
    2066                 :            :  * Add a message to the test report.
    2067                 :            :  *
    2068                 :            :  * Since: 2.16
    2069                 :            :  */
    2070                 :            : void
    2071                 :       4871 : g_test_message (const char *format,
    2072                 :            :                 ...)
    2073                 :            : {
    2074                 :            :   gchar *buffer;
    2075                 :            :   va_list args;
    2076                 :            : 
    2077                 :       4871 :   va_start (args, format);
    2078                 :       4871 :   buffer = g_strdup_vprintf (format, args);
    2079                 :       4871 :   va_end (args);
    2080                 :            : 
    2081                 :       4871 :   g_test_log (G_TEST_LOG_MESSAGE, buffer, NULL, 0, NULL);
    2082                 :       4871 :   g_free (buffer);
    2083                 :       4871 : }
    2084                 :            : 
    2085                 :            : /**
    2086                 :            :  * g_test_bug_base:
    2087                 :            :  * @uri_pattern: the base pattern for bug URIs
    2088                 :            :  *
    2089                 :            :  * Specify the base URI for bug reports.
    2090                 :            :  *
    2091                 :            :  * The base URI is used to construct bug report messages for
    2092                 :            :  * g_test_message() when g_test_bug() is called.
    2093                 :            :  * Calling this function outside of a test case sets the
    2094                 :            :  * default base URI for all test cases. Calling it from within
    2095                 :            :  * a test case changes the base URI for the scope of the test
    2096                 :            :  * case only.
    2097                 :            :  * Bug URIs are constructed by appending a bug specific URI
    2098                 :            :  * portion to @uri_pattern, or by replacing the special string
    2099                 :            :  * `%s` within @uri_pattern if that is present.
    2100                 :            :  *
    2101                 :            :  * If g_test_bug_base() is not called, bug URIs are formed solely
    2102                 :            :  * from the value provided by g_test_bug().
    2103                 :            :  *
    2104                 :            :  * Since: 2.16
    2105                 :            :  */
    2106                 :            : void
    2107                 :          2 : g_test_bug_base (const char *uri_pattern)
    2108                 :            : {
    2109                 :          2 :   g_free (test_uri_base);
    2110                 :          2 :   test_uri_base = g_strdup (uri_pattern);
    2111                 :          2 : }
    2112                 :            : 
    2113                 :            : /**
    2114                 :            :  * g_test_bug:
    2115                 :            :  * @bug_uri_snippet: Bug specific bug tracker URI or URI portion.
    2116                 :            :  *
    2117                 :            :  * This function adds a message to test reports that
    2118                 :            :  * associates a bug URI with a test case.
    2119                 :            :  *
    2120                 :            :  * Bug URIs are constructed from a base URI set with g_test_bug_base()
    2121                 :            :  * and @bug_uri_snippet. If g_test_bug_base() has not been called, it is
    2122                 :            :  * assumed to be the empty string, so a full URI can be provided to
    2123                 :            :  * g_test_bug() instead.
    2124                 :            :  *
    2125                 :            :  * Since GLib 2.70, the base URI is not prepended to @bug_uri_snippet if it
    2126                 :            :  * is already a valid URI.
    2127                 :            :  *
    2128                 :            :  * Since: 2.16
    2129                 :            :  * See also: g_test_summary()
    2130                 :            :  */
    2131                 :            : void
    2132                 :        318 : g_test_bug (const char *bug_uri_snippet)
    2133                 :            : {
    2134                 :        318 :   const char *c = NULL;
    2135                 :            : 
    2136                 :        318 :   g_return_if_fail (bug_uri_snippet != NULL);
    2137                 :            : 
    2138   [ +  -  -  +  :        318 :   if (g_str_has_prefix (bug_uri_snippet, "http:") ||
             +  +  +  + ]
    2139   [ +  -  -  +  :        312 :       g_str_has_prefix (bug_uri_snippet, "https:"))
             +  +  +  + ]
    2140                 :            :     {
    2141                 :        316 :       g_test_message ("Bug Reference: %s", bug_uri_snippet);
    2142                 :        316 :       return;
    2143                 :            :     }
    2144                 :            : 
    2145         [ +  - ]:          2 :   if (test_uri_base != NULL)
    2146                 :          2 :     c = strstr (test_uri_base, "%s");
    2147         [ +  + ]:          2 :   if (c)
    2148                 :            :     {
    2149                 :          1 :       char *b = g_strndup (test_uri_base, c - test_uri_base);
    2150                 :          1 :       char *s = g_strconcat (b, bug_uri_snippet, c + 2, NULL);
    2151                 :          1 :       g_free (b);
    2152                 :          1 :       g_test_message ("Bug Reference: %s", s);
    2153                 :          1 :       g_free (s);
    2154                 :            :     }
    2155                 :            :   else
    2156                 :          1 :     g_test_message ("Bug Reference: %s%s",
    2157         [ +  - ]:          1 :                     test_uri_base ? test_uri_base : "", bug_uri_snippet);
    2158                 :            : }
    2159                 :            : 
    2160                 :            : /**
    2161                 :            :  * g_test_summary:
    2162                 :            :  * @summary: One or two sentences summarising what the test checks, and how it
    2163                 :            :  *    checks it.
    2164                 :            :  *
    2165                 :            :  * Set the summary for a test, which describes what the test checks, and how it
    2166                 :            :  * goes about checking it. This may be included in test report output, and is
    2167                 :            :  * useful documentation for anyone reading the source code or modifying a test
    2168                 :            :  * in future. It must be a single line.
    2169                 :            :  *
    2170                 :            :  * This should be called at the top of a test function.
    2171                 :            :  *
    2172                 :            :  * For example:
    2173                 :            :  * |[<!-- language="C" -->
    2174                 :            :  * static void
    2175                 :            :  * test_array_sort (void)
    2176                 :            :  * {
    2177                 :            :  *   g_test_summary ("Test my_array_sort() sorts the array correctly and stably, "
    2178                 :            :  *                   "including testing zero length and one-element arrays.");
    2179                 :            :  *
    2180                 :            :  *   …
    2181                 :            :  * }
    2182                 :            :  * ]|
    2183                 :            :  *
    2184                 :            :  * Since: 2.62
    2185                 :            :  * See also: g_test_bug()
    2186                 :            :  */
    2187                 :            : void
    2188                 :        363 : g_test_summary (const char *summary)
    2189                 :            : {
    2190                 :        363 :   g_return_if_fail (summary != NULL);
    2191                 :        363 :   g_return_if_fail (strchr (summary, '\n') == NULL);
    2192                 :        363 :   g_return_if_fail (strchr (summary, '\r') == NULL);
    2193                 :            : 
    2194                 :        363 :   g_test_message ("%s summary: %s", test_run_name, summary);
    2195                 :            : }
    2196                 :            : 
    2197                 :            : /**
    2198                 :            :  * g_test_get_root:
    2199                 :            :  *
    2200                 :            :  * Get the toplevel test suite for the test path API.
    2201                 :            :  *
    2202                 :            :  * Returns: the toplevel #GTestSuite
    2203                 :            :  *
    2204                 :            :  * Since: 2.16
    2205                 :            :  */
    2206                 :            : GTestSuite*
    2207                 :      30235 : g_test_get_root (void)
    2208                 :            : {
    2209         [ +  + ]:      30235 :   if (!test_suite_root)
    2210                 :            :     {
    2211                 :        608 :       test_suite_root = g_test_create_suite ("root");
    2212                 :        608 :       g_free (test_suite_root->name);
    2213                 :       1216 :       test_suite_root->name = g_strdup ("");
    2214                 :            :     }
    2215                 :            : 
    2216                 :      30235 :   return test_suite_root;
    2217                 :            : }
    2218                 :            : 
    2219                 :            : /**
    2220                 :            :  * g_test_run:
    2221                 :            :  *
    2222                 :            :  * Runs all tests under the toplevel suite which can be retrieved
    2223                 :            :  * with g_test_get_root(). Similar to g_test_run_suite(), the test
    2224                 :            :  * cases to be run are filtered according to test path arguments
    2225                 :            :  * (`-p testpath` and `-s testpath`) as parsed by g_test_init().
    2226                 :            :  * g_test_run_suite() or g_test_run() may only be called once in a
    2227                 :            :  * program.
    2228                 :            :  *
    2229                 :            :  * In general, the tests and sub-suites within each suite are run in
    2230                 :            :  * the order in which they are defined. However, note that prior to
    2231                 :            :  * GLib 2.36, there was a bug in the `g_test_add_*`
    2232                 :            :  * functions which caused them to create multiple suites with the same
    2233                 :            :  * name, meaning that if you created tests "/foo/simple",
    2234                 :            :  * "/bar/simple", and "/foo/using-bar" in that order, they would get
    2235                 :            :  * run in that order (since g_test_run() would run the first "/foo"
    2236                 :            :  * suite, then the "/bar" suite, then the second "/foo" suite). As of
    2237                 :            :  * 2.36, this bug is fixed, and adding the tests in that order would
    2238                 :            :  * result in a running order of "/foo/simple", "/foo/using-bar",
    2239                 :            :  * "/bar/simple". If this new ordering is sub-optimal (because it puts
    2240                 :            :  * more-complicated tests before simpler ones, making it harder to
    2241                 :            :  * figure out exactly what has failed), you can fix it by changing the
    2242                 :            :  * test paths to group tests by suite in a way that will result in the
    2243                 :            :  * desired running order. Eg, "/simple/foo", "/simple/bar",
    2244                 :            :  * "/complex/foo-using-bar".
    2245                 :            :  *
    2246                 :            :  * However, you should never make the actual result of a test depend
    2247                 :            :  * on the order that tests are run in. If you need to ensure that some
    2248                 :            :  * particular code runs before or after a given test case, use
    2249                 :            :  * g_test_add(), which lets you specify setup and teardown functions.
    2250                 :            :  *
    2251                 :            :  * If all tests are skipped or marked as incomplete (expected failures),
    2252                 :            :  * this function will return 0 if producing TAP output, or 77 (treated
    2253                 :            :  * as "skip test" by Automake) otherwise.
    2254                 :            :  *
    2255                 :            :  * Returns: 0 on success, 1 on failure (assuming it returns at all),
    2256                 :            :  *   0 or 77 if all tests were skipped with g_test_skip() and/or
    2257                 :            :  *   g_test_incomplete()
    2258                 :            :  *
    2259                 :            :  * Since: 2.16
    2260                 :            :  */
    2261                 :            : int
    2262                 :        608 : g_test_run (void)
    2263                 :            : {
    2264                 :            :   int ret;
    2265                 :            :   GTestSuite *suite;
    2266                 :            : 
    2267         [ -  + ]:        608 :   if (atexit (test_cleanup) != 0)
    2268                 :            :     {
    2269                 :          0 :       int errsv = errno;
    2270                 :          0 :       g_error ("Unable to register test cleanup to be run at exit: %s",
    2271                 :            :                g_strerror (errsv));
    2272                 :            :     }
    2273                 :            : 
    2274                 :        608 :   suite = g_test_get_root ();
    2275         [ +  + ]:        608 :   if (g_test_run_suite (suite) != 0)
    2276                 :            :     {
    2277                 :         11 :       ret = 1;
    2278                 :         11 :       goto out;
    2279                 :            :     }
    2280                 :            : 
    2281                 :            :   /* Clean up the temporary directory. */
    2282         [ +  + ]:        472 :   if (test_isolate_dirs_tmpdir != NULL)
    2283                 :            :     {
    2284                 :         58 :       rm_rf (test_isolate_dirs_tmpdir);
    2285                 :         58 :       g_free (test_isolate_dirs_tmpdir);
    2286                 :         58 :       test_isolate_dirs_tmpdir = NULL;
    2287                 :            :     }
    2288                 :            : 
    2289                 :            :   /* 77 is special to Automake's default driver, but not Automake's TAP driver
    2290                 :            :    * or Perl's prove(1) TAP driver. */
    2291         [ +  + ]:        472 :   if (test_tap_log)
    2292                 :            :     {
    2293                 :        360 :       ret = 0;
    2294                 :        360 :       goto out;
    2295                 :            :     }
    2296                 :            : 
    2297   [ +  -  +  + ]:        112 :   if (test_run_count > 0 && test_run_count == test_skipped_count)
    2298                 :            :     {
    2299                 :          4 :       ret = 77;
    2300                 :          4 :       goto out;
    2301                 :            :     }
    2302                 :            :   else
    2303                 :            :     {
    2304                 :        108 :       ret = 0;
    2305                 :        108 :       goto out;
    2306                 :            :     }
    2307                 :            : 
    2308                 :        483 : out:
    2309                 :        483 :   g_test_suite_free (suite);
    2310                 :        483 :   return ret;
    2311                 :            : }
    2312                 :            : 
    2313                 :            : /**
    2314                 :            :  * g_test_create_case:
    2315                 :            :  * @test_name:     the name for the test case
    2316                 :            :  * @data_size:     the size of the fixture data structure
    2317                 :            :  * @test_data:     test data argument for the test functions
    2318                 :            :  * @data_setup:    (scope async): the function to set up the fixture data
    2319                 :            :  * @data_test:     (scope async): the actual test function
    2320                 :            :  * @data_teardown: (scope async): the function to teardown the fixture data
    2321                 :            :  *
    2322                 :            :  * Create a new #GTestCase, named @test_name.
    2323                 :            :  *
    2324                 :            :  * This API is fairly low level, and calling g_test_add() or g_test_add_func()
    2325                 :            :  * is preferable.
    2326                 :            :  *
    2327                 :            :  * When this test is executed, a fixture structure of size @data_size
    2328                 :            :  * will be automatically allocated and filled with zeros. Then @data_setup is
    2329                 :            :  * called to initialize the fixture. After fixture setup, the actual test
    2330                 :            :  * function @data_test is called. Once the test run completes, the
    2331                 :            :  * fixture structure is torn down by calling @data_teardown and
    2332                 :            :  * after that the memory is automatically released by the test framework.
    2333                 :            :  *
    2334                 :            :  * Splitting up a test run into fixture setup, test function and
    2335                 :            :  * fixture teardown is most useful if the same fixture type is used for
    2336                 :            :  * multiple tests. In this cases, g_test_create_case() will be
    2337                 :            :  * called with the same type of fixture (the @data_size argument), but varying
    2338                 :            :  * @test_name and @data_test arguments.
    2339                 :            :  *
    2340                 :            :  * Returns: a newly allocated #GTestCase.
    2341                 :            :  *
    2342                 :            :  * Since: 2.16
    2343                 :            :  */
    2344                 :            : GTestCase*
    2345                 :      29404 : g_test_create_case (const char       *test_name,
    2346                 :            :                     gsize             data_size,
    2347                 :            :                     gconstpointer     test_data,
    2348                 :            :                     GTestFixtureFunc  data_setup,
    2349                 :            :                     GTestFixtureFunc  data_test,
    2350                 :            :                     GTestFixtureFunc  data_teardown)
    2351                 :            : {
    2352                 :            :   GTestCase *tc;
    2353                 :            : 
    2354                 :      29404 :   g_return_val_if_fail (test_name != NULL, NULL);
    2355                 :      29404 :   g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL);
    2356                 :      29404 :   g_return_val_if_fail (test_name[0] != 0, NULL);
    2357                 :      29404 :   g_return_val_if_fail (data_test != NULL, NULL);
    2358                 :            : 
    2359                 :      29404 :   tc = g_slice_new0 (GTestCase);
    2360                 :      29404 :   tc->name = g_strdup (test_name);
    2361                 :      29404 :   tc->test_data = (gpointer) test_data;
    2362                 :      29404 :   tc->fixture_size = data_size;
    2363                 :      29404 :   tc->fixture_setup = (void*) data_setup;
    2364                 :      29404 :   tc->fixture_test = (void*) data_test;
    2365                 :      29404 :   tc->fixture_teardown = (void*) data_teardown;
    2366                 :            : 
    2367                 :      29404 :   return tc;
    2368                 :            : }
    2369                 :            : 
    2370                 :            : static gint
    2371                 :     332201 : find_suite (gconstpointer l, gconstpointer s)
    2372                 :            : {
    2373                 :     332201 :   const GTestSuite *suite = l;
    2374                 :     332201 :   const gchar *str = s;
    2375                 :            : 
    2376                 :     332201 :   return strcmp (suite->name, str);
    2377                 :            : }
    2378                 :            : 
    2379                 :            : static gint
    2380                 :    5248777 : find_case (gconstpointer l, gconstpointer s)
    2381                 :            : {
    2382                 :    5248777 :   const GTestCase *tc = l;
    2383                 :    5248777 :   const gchar *str = s;
    2384                 :            : 
    2385                 :    5248777 :   return strcmp (tc->name, str);
    2386                 :            : }
    2387                 :            : 
    2388                 :            : /**
    2389                 :            :  * GTestFixtureFunc:
    2390                 :            :  * @fixture: (not nullable): the test fixture
    2391                 :            :  * @user_data: the data provided when registering the test
    2392                 :            :  *
    2393                 :            :  * The type used for functions that operate on test fixtures.  This is
    2394                 :            :  * used for the fixture setup and teardown functions as well as for the
    2395                 :            :  * testcases themselves.
    2396                 :            :  *
    2397                 :            :  * @user_data is a pointer to the data that was given when registering
    2398                 :            :  * the test case.
    2399                 :            :  *
    2400                 :            :  * @fixture will be a pointer to the area of memory allocated by the
    2401                 :            :  * test framework, of the size requested.  If the requested size was
    2402                 :            :  * zero then @fixture will be equal to @user_data.
    2403                 :            :  *
    2404                 :            :  * Since: 2.28
    2405                 :            :  */
    2406                 :            : void
    2407                 :      29404 : g_test_add_vtable (const char       *testpath,
    2408                 :            :                    gsize             data_size,
    2409                 :            :                    gconstpointer     test_data,
    2410                 :            :                    GTestFixtureFunc  data_setup,
    2411                 :            :                    GTestFixtureFunc  fixture_test_func,
    2412                 :            :                    GTestFixtureFunc  data_teardown)
    2413                 :            : {
    2414                 :            :   gchar **segments;
    2415                 :            :   guint ui;
    2416                 :            :   GTestSuite *suite;
    2417                 :            : 
    2418                 :      29404 :   g_return_if_fail (testpath != NULL);
    2419                 :      29404 :   g_return_if_fail (g_path_is_absolute (testpath));
    2420                 :      29404 :   g_return_if_fail (fixture_test_func != NULL);
    2421                 :      29404 :   g_return_if_fail (!test_isolate_dirs || strstr (testpath, "/.") == NULL);
    2422                 :            : 
    2423                 :      29404 :   suite = g_test_get_root();
    2424                 :      29404 :   segments = g_strsplit (testpath, "/", -1);
    2425         [ +  + ]:     150632 :   for (ui = 0; segments[ui] != NULL; ui++)
    2426                 :            :     {
    2427                 :     121228 :       const char *seg = segments[ui];
    2428                 :     121228 :       gboolean islast = segments[ui + 1] == NULL;
    2429   [ +  +  -  + ]:     121228 :       if (islast && !seg[0])
    2430                 :          0 :         g_error ("invalid test case path: %s", testpath);
    2431         [ +  + ]:     121228 :       else if (!seg[0])
    2432                 :      29404 :         continue;       /* initial or duplicate slash */
    2433         [ +  + ]:      91824 :       else if (!islast)
    2434                 :            :         {
    2435                 :            :           GSList *l;
    2436                 :            :           GTestSuite *csuite;
    2437                 :      62420 :           l = g_slist_find_custom (suite->suites, seg, find_suite);
    2438         [ +  + ]:      62420 :           if (l)
    2439                 :            :             {
    2440                 :      46437 :               csuite = l->data;
    2441                 :            :             }
    2442                 :            :           else
    2443                 :            :             {
    2444                 :      15983 :               csuite = g_test_create_suite (seg);
    2445                 :      15983 :               g_test_suite_add_suite (suite, csuite);
    2446                 :            :             }
    2447                 :      62420 :           suite = csuite;
    2448                 :            :         }
    2449                 :            :       else /* islast */
    2450                 :            :         {
    2451                 :            :           GTestCase *tc;
    2452                 :            : 
    2453         [ -  + ]:      29404 :           if (g_slist_find_custom (suite->cases, seg, find_case))
    2454                 :          0 :             g_error ("duplicate test case path: %s", testpath);
    2455                 :            : 
    2456                 :      29404 :           tc = g_test_create_case (seg, data_size, test_data, data_setup, fixture_test_func, data_teardown);
    2457                 :      29404 :           g_test_suite_add (suite, tc);
    2458                 :            :         }
    2459                 :            :     }
    2460                 :      29404 :   g_strfreev (segments);
    2461                 :            : }
    2462                 :            : 
    2463                 :            : /**
    2464                 :            :  * g_test_fail:
    2465                 :            :  *
    2466                 :            :  * Indicates that a test failed. This function can be called
    2467                 :            :  * multiple times from the same test. You can use this function
    2468                 :            :  * if your test failed in a recoverable way.
    2469                 :            :  * 
    2470                 :            :  * Do not use this function if the failure of a test could cause
    2471                 :            :  * other tests to malfunction.
    2472                 :            :  *
    2473                 :            :  * Calling this function will not stop the test from running, you
    2474                 :            :  * need to return from the test function yourself. So you can
    2475                 :            :  * produce additional diagnostic messages or even continue running
    2476                 :            :  * the test.
    2477                 :            :  *
    2478                 :            :  * If not called from inside a test, this function does nothing.
    2479                 :            :  *
    2480                 :            :  * Note that unlike g_test_skip() and g_test_incomplete(), this
    2481                 :            :  * function does not log a message alongside the test failure.
    2482                 :            :  * If details of the test failure are available, either log them with
    2483                 :            :  * g_test_message() before g_test_fail(), or use g_test_fail_printf()
    2484                 :            :  * instead.
    2485                 :            :  *
    2486                 :            :  * Since: 2.30
    2487                 :            :  **/
    2488                 :            : void
    2489                 :          9 : g_test_fail (void)
    2490                 :            : {
    2491                 :          9 :   test_run_success = G_TEST_RUN_FAILURE;
    2492                 :          9 :   g_clear_pointer (&test_run_msg, g_free);
    2493                 :          9 : }
    2494                 :            : 
    2495                 :            : /**
    2496                 :            :  * g_test_fail_printf:
    2497                 :            :  * @format: the format string
    2498                 :            :  * @...:    printf-like arguments to @format
    2499                 :            :  *
    2500                 :            :  * Equivalent to g_test_fail(), but also record a message like
    2501                 :            :  * g_test_skip_printf().
    2502                 :            :  *
    2503                 :            :  * Since: 2.70
    2504                 :            :  **/
    2505                 :            : void
    2506                 :          2 : g_test_fail_printf (const char *format,
    2507                 :            :                     ...)
    2508                 :            : {
    2509                 :            :   va_list args;
    2510                 :            : 
    2511                 :          2 :   test_run_success = G_TEST_RUN_FAILURE;
    2512                 :          2 :   va_start (args, format);
    2513                 :          2 :   g_free (test_run_msg);
    2514                 :          2 :   test_run_msg = g_strdup_vprintf (format, args);
    2515                 :          2 :   va_end (args);
    2516                 :          2 : }
    2517                 :            : 
    2518                 :            : /**
    2519                 :            :  * g_test_incomplete:
    2520                 :            :  * @msg: (nullable): explanation
    2521                 :            :  *
    2522                 :            :  * Indicates that a test failed because of some incomplete
    2523                 :            :  * functionality. This function can be called multiple times
    2524                 :            :  * from the same test.
    2525                 :            :  *
    2526                 :            :  * Calling this function will not stop the test from running, you
    2527                 :            :  * need to return from the test function yourself. So you can
    2528                 :            :  * produce additional diagnostic messages or even continue running
    2529                 :            :  * the test.
    2530                 :            :  *
    2531                 :            :  * If not called from inside a test, this function does nothing.
    2532                 :            :  *
    2533                 :            :  * Since: 2.38
    2534                 :            :  */
    2535                 :            : void
    2536                 :         12 : g_test_incomplete (const gchar *msg)
    2537                 :            : {
    2538                 :         12 :   test_run_success = G_TEST_RUN_INCOMPLETE;
    2539                 :         12 :   g_free (test_run_msg);
    2540                 :         12 :   test_run_msg = g_strdup (msg);
    2541                 :         12 : }
    2542                 :            : 
    2543                 :            : /**
    2544                 :            :  * g_test_incomplete_printf:
    2545                 :            :  * @format: the format string
    2546                 :            :  * @...:    printf-like arguments to @format
    2547                 :            :  *
    2548                 :            :  * Equivalent to g_test_incomplete(), but the explanation is formatted
    2549                 :            :  * as if by g_strdup_printf().
    2550                 :            :  *
    2551                 :            :  * Since: 2.70
    2552                 :            :  */
    2553                 :            : void
    2554                 :          2 : g_test_incomplete_printf (const char *format,
    2555                 :            :                           ...)
    2556                 :            : {
    2557                 :            :   va_list args;
    2558                 :            : 
    2559                 :          2 :   test_run_success = G_TEST_RUN_INCOMPLETE;
    2560                 :          2 :   va_start (args, format);
    2561                 :          2 :   g_free (test_run_msg);
    2562                 :          2 :   test_run_msg = g_strdup_vprintf (format, args);
    2563                 :          2 :   va_end (args);
    2564                 :          2 : }
    2565                 :            : 
    2566                 :            : /**
    2567                 :            :  * g_test_skip:
    2568                 :            :  * @msg: (nullable): explanation
    2569                 :            :  *
    2570                 :            :  * Indicates that a test was skipped.
    2571                 :            :  *
    2572                 :            :  * Calling this function will not stop the test from running, you
    2573                 :            :  * need to return from the test function yourself. So you can
    2574                 :            :  * produce additional diagnostic messages or even continue running
    2575                 :            :  * the test.
    2576                 :            :  *
    2577                 :            :  * If not called from inside a test, this function does nothing.
    2578                 :            :  *
    2579                 :            :  * Since: 2.38
    2580                 :            :  */
    2581                 :            : void
    2582                 :         87 : g_test_skip (const gchar *msg)
    2583                 :            : {
    2584                 :         87 :   test_run_success = G_TEST_RUN_SKIPPED;
    2585                 :         87 :   g_free (test_run_msg);
    2586                 :         87 :   test_run_msg = g_strdup (msg);
    2587                 :         87 : }
    2588                 :            : 
    2589                 :            : /**
    2590                 :            :  * g_test_skip_printf:
    2591                 :            :  * @format: the format string
    2592                 :            :  * @...:    printf-like arguments to @format
    2593                 :            :  *
    2594                 :            :  * Equivalent to g_test_skip(), but the explanation is formatted
    2595                 :            :  * as if by g_strdup_printf().
    2596                 :            :  *
    2597                 :            :  * Since: 2.70
    2598                 :            :  */
    2599                 :            : void
    2600                 :          3 : g_test_skip_printf (const char *format,
    2601                 :            :                     ...)
    2602                 :            : {
    2603                 :            :   va_list args;
    2604                 :            : 
    2605                 :          3 :   test_run_success = G_TEST_RUN_SKIPPED;
    2606                 :          3 :   va_start (args, format);
    2607                 :          3 :   g_free (test_run_msg);
    2608                 :          3 :   test_run_msg = g_strdup_vprintf (format, args);
    2609                 :          3 :   va_end (args);
    2610                 :          3 : }
    2611                 :            : 
    2612                 :            : /**
    2613                 :            :  * g_test_failed:
    2614                 :            :  *
    2615                 :            :  * Returns whether a test has already failed. This will
    2616                 :            :  * be the case when g_test_fail(), g_test_incomplete()
    2617                 :            :  * or g_test_skip() have been called, but also if an
    2618                 :            :  * assertion has failed.
    2619                 :            :  *
    2620                 :            :  * This can be useful to return early from a test if
    2621                 :            :  * continuing after a failed assertion might be harmful.
    2622                 :            :  *
    2623                 :            :  * The return value of this function is only meaningful
    2624                 :            :  * if it is called from inside a test function.
    2625                 :            :  *
    2626                 :            :  * Returns: %TRUE if the test has failed
    2627                 :            :  *
    2628                 :            :  * Since: 2.38
    2629                 :            :  */
    2630                 :            : gboolean
    2631                 :         21 : g_test_failed (void)
    2632                 :            : {
    2633                 :         21 :   return test_run_success != G_TEST_RUN_SUCCESS;
    2634                 :            : }
    2635                 :            : 
    2636                 :            : /**
    2637                 :            :  * g_test_set_nonfatal_assertions:
    2638                 :            :  *
    2639                 :            :  * Changes the behaviour of the various `g_assert_*()` macros,
    2640                 :            :  * g_test_assert_expected_messages() and the various
    2641                 :            :  * `g_test_trap_assert_*()` macros to not abort to program, but instead
    2642                 :            :  * call g_test_fail() and continue. (This also changes the behavior of
    2643                 :            :  * g_test_fail() so that it will not cause the test program to abort
    2644                 :            :  * after completing the failed test.)
    2645                 :            :  *
    2646                 :            :  * Note that the g_assert_not_reached() and g_assert() macros are not
    2647                 :            :  * affected by this.
    2648                 :            :  *
    2649                 :            :  * This function can only be called after g_test_init().
    2650                 :            :  *
    2651                 :            :  * Since: 2.38
    2652                 :            :  */
    2653                 :            : void
    2654                 :         53 : g_test_set_nonfatal_assertions (void)
    2655                 :            : {
    2656         [ -  + ]:         53 :   if (!g_test_config_vars->test_initialized)
    2657                 :          0 :     g_error ("g_test_set_nonfatal_assertions called without g_test_init");
    2658                 :         53 :   test_nonfatal_assertions = TRUE;
    2659                 :         53 :   test_mode_fatal = FALSE;
    2660                 :         53 : }
    2661                 :            : 
    2662                 :            : /**
    2663                 :            :  * GTestFunc:
    2664                 :            :  *
    2665                 :            :  * The type used for test case functions.
    2666                 :            :  *
    2667                 :            :  * Since: 2.28
    2668                 :            :  */
    2669                 :            : 
    2670                 :            : /**
    2671                 :            :  * g_test_add_func:
    2672                 :            :  * @testpath:  /-separated test case path name for the test.
    2673                 :            :  * @test_func: (scope async):  The test function to invoke for this test.
    2674                 :            :  *
    2675                 :            :  * Create a new test case, similar to g_test_create_case(). However
    2676                 :            :  * the test is assumed to use no fixture, and test suites are automatically
    2677                 :            :  * created on the fly and added to the root fixture, based on the
    2678                 :            :  * slash-separated portions of @testpath.
    2679                 :            :  *
    2680                 :            :  * If @testpath includes the component "subprocess" anywhere in it,
    2681                 :            :  * the test will be skipped by default, and only run if explicitly
    2682                 :            :  * required via the `-p` command-line option or g_test_trap_subprocess().
    2683                 :            :  *
    2684                 :            :  * No component of @testpath may start with a dot (`.`) if the
    2685                 :            :  * %G_TEST_OPTION_ISOLATE_DIRS option is being used; and it is recommended to
    2686                 :            :  * do so even if it isn’t.
    2687                 :            :  *
    2688                 :            :  * Since: 2.16
    2689                 :            :  */
    2690                 :            : void
    2691                 :       8166 : g_test_add_func (const char *testpath,
    2692                 :            :                  GTestFunc   test_func)
    2693                 :            : {
    2694                 :       8166 :   g_return_if_fail (testpath != NULL);
    2695                 :       8166 :   g_return_if_fail (testpath[0] == '/');
    2696                 :       8166 :   g_return_if_fail (test_func != NULL);
    2697                 :       8166 :   g_test_add_vtable (testpath, 0, NULL, NULL, (GTestFixtureFunc) test_func, NULL);
    2698                 :            : }
    2699                 :            : 
    2700                 :            : /**
    2701                 :            :  * GTestDataFunc:
    2702                 :            :  * @user_data: the data provided when registering the test
    2703                 :            :  *
    2704                 :            :  * The type used for test case functions that take an extra pointer
    2705                 :            :  * argument.
    2706                 :            :  *
    2707                 :            :  * Since: 2.28
    2708                 :            :  */
    2709                 :            : 
    2710                 :            : /**
    2711                 :            :  * g_test_add_data_func:
    2712                 :            :  * @testpath:  /-separated test case path name for the test.
    2713                 :            :  * @test_data: Test data argument for the test function.
    2714                 :            :  * @test_func: (scope async): The test function to invoke for this test.
    2715                 :            :  *
    2716                 :            :  * Create a new test case, similar to g_test_create_case(). However
    2717                 :            :  * the test is assumed to use no fixture, and test suites are automatically
    2718                 :            :  * created on the fly and added to the root fixture, based on the
    2719                 :            :  * slash-separated portions of @testpath. The @test_data argument
    2720                 :            :  * will be passed as first argument to @test_func.
    2721                 :            :  *
    2722                 :            :  * If @testpath includes the component "subprocess" anywhere in it,
    2723                 :            :  * the test will be skipped by default, and only run if explicitly
    2724                 :            :  * required via the `-p` command-line option or g_test_trap_subprocess().
    2725                 :            :  *
    2726                 :            :  * No component of @testpath may start with a dot (`.`) if the
    2727                 :            :  * %G_TEST_OPTION_ISOLATE_DIRS option is being used; and it is recommended to
    2728                 :            :  * do so even if it isn’t.
    2729                 :            :  *
    2730                 :            :  * Since: 2.16
    2731                 :            :  */
    2732                 :            : void
    2733                 :      16014 : g_test_add_data_func (const char     *testpath,
    2734                 :            :                       gconstpointer   test_data,
    2735                 :            :                       GTestDataFunc   test_func)
    2736                 :            : {
    2737                 :      16014 :   g_return_if_fail (testpath != NULL);
    2738                 :      16014 :   g_return_if_fail (testpath[0] == '/');
    2739                 :      16014 :   g_return_if_fail (test_func != NULL);
    2740                 :            : 
    2741                 :      16014 :   g_test_add_vtable (testpath, 0, test_data, NULL, (GTestFixtureFunc) test_func, NULL);
    2742                 :            : }
    2743                 :            : 
    2744                 :            : /**
    2745                 :            :  * g_test_add_data_func_full:
    2746                 :            :  * @testpath: /-separated test case path name for the test.
    2747                 :            :  * @test_data: Test data argument for the test function.
    2748                 :            :  * @test_func: The test function to invoke for this test.
    2749                 :            :  * @data_free_func: #GDestroyNotify for @test_data.
    2750                 :            :  *
    2751                 :            :  * Create a new test case, as with g_test_add_data_func(), but freeing
    2752                 :            :  * @test_data after the test run is complete.
    2753                 :            :  *
    2754                 :            :  * Since: 2.34
    2755                 :            :  */
    2756                 :            : void
    2757                 :       5008 : g_test_add_data_func_full (const char     *testpath,
    2758                 :            :                            gpointer        test_data,
    2759                 :            :                            GTestDataFunc   test_func,
    2760                 :            :                            GDestroyNotify  data_free_func)
    2761                 :            : {
    2762                 :       5008 :   g_return_if_fail (testpath != NULL);
    2763                 :       5008 :   g_return_if_fail (testpath[0] == '/');
    2764                 :       5008 :   g_return_if_fail (test_func != NULL);
    2765                 :            : 
    2766                 :       5008 :   g_test_add_vtable (testpath, 0, test_data, NULL,
    2767                 :            :                      (GTestFixtureFunc) test_func,
    2768                 :            :                      (GTestFixtureFunc) data_free_func);
    2769                 :            : }
    2770                 :            : 
    2771                 :            : static gboolean
    2772                 :        915 : g_test_suite_case_exists (GTestSuite *suite,
    2773                 :            :                           const char *test_path)
    2774                 :            : {
    2775                 :            :   GSList *iter;
    2776                 :            :   char *slash;
    2777                 :            :   GTestCase *tc;
    2778                 :            : 
    2779                 :        915 :   test_path++;
    2780                 :        915 :   slash = strchr (test_path, '/');
    2781                 :            : 
    2782         [ +  + ]:        915 :   if (slash)
    2783                 :            :     {
    2784         [ +  + ]:       3846 :       for (iter = suite->suites; iter; iter = iter->next)
    2785                 :            :         {
    2786                 :       3843 :           GTestSuite *child_suite = iter->data;
    2787                 :            : 
    2788         [ +  + ]:       3843 :           if (!strncmp (child_suite->name, test_path, slash - test_path))
    2789         [ +  + ]:        692 :             if (g_test_suite_case_exists (child_suite, slash))
    2790                 :        689 :               return TRUE;
    2791                 :            :         }
    2792                 :            :     }
    2793                 :            :   else
    2794                 :            :     {
    2795         [ +  - ]:        936 :       for (iter = suite->cases; iter; iter = iter->next)
    2796                 :            :         {
    2797                 :        936 :           tc = iter->data;
    2798         [ +  + ]:        936 :           if (!strcmp (tc->name, test_path))
    2799                 :        223 :             return TRUE;
    2800                 :            :         }
    2801                 :            :     }
    2802                 :            : 
    2803                 :          3 :   return FALSE;
    2804                 :            : }
    2805                 :            : 
    2806                 :            : /**
    2807                 :            :  * g_test_create_suite:
    2808                 :            :  * @suite_name: a name for the suite
    2809                 :            :  *
    2810                 :            :  * Create a new test suite with the name @suite_name.
    2811                 :            :  *
    2812                 :            :  * Returns: A newly allocated #GTestSuite instance.
    2813                 :            :  *
    2814                 :            :  * Since: 2.16
    2815                 :            :  */
    2816                 :            : GTestSuite*
    2817                 :      16591 : g_test_create_suite (const char *suite_name)
    2818                 :            : {
    2819                 :            :   GTestSuite *ts;
    2820                 :      16591 :   g_return_val_if_fail (suite_name != NULL, NULL);
    2821                 :      16591 :   g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL);
    2822                 :      16591 :   g_return_val_if_fail (suite_name[0] != 0, NULL);
    2823                 :      16591 :   ts = g_slice_new0 (GTestSuite);
    2824                 :      16591 :   ts->name = g_strdup (suite_name);
    2825                 :      16591 :   return ts;
    2826                 :            : }
    2827                 :            : 
    2828                 :            : /**
    2829                 :            :  * g_test_suite_add:
    2830                 :            :  * @suite: a #GTestSuite
    2831                 :            :  * @test_case: a #GTestCase
    2832                 :            :  *
    2833                 :            :  * Adds @test_case to @suite.
    2834                 :            :  *
    2835                 :            :  * Since: 2.16
    2836                 :            :  */
    2837                 :            : void
    2838                 :      29404 : g_test_suite_add (GTestSuite     *suite,
    2839                 :            :                   GTestCase      *test_case)
    2840                 :            : {
    2841                 :      29404 :   g_return_if_fail (suite != NULL);
    2842                 :      29404 :   g_return_if_fail (test_case != NULL);
    2843                 :            : 
    2844                 :      29404 :   suite->cases = g_slist_append (suite->cases, test_case);
    2845                 :            : }
    2846                 :            : 
    2847                 :            : /**
    2848                 :            :  * g_test_suite_add_suite:
    2849                 :            :  * @suite:       a #GTestSuite
    2850                 :            :  * @nestedsuite: another #GTestSuite
    2851                 :            :  *
    2852                 :            :  * Adds @nestedsuite to @suite.
    2853                 :            :  *
    2854                 :            :  * Since: 2.16
    2855                 :            :  */
    2856                 :            : void
    2857                 :      15983 : g_test_suite_add_suite (GTestSuite     *suite,
    2858                 :            :                         GTestSuite     *nestedsuite)
    2859                 :            : {
    2860                 :      15983 :   g_return_if_fail (suite != NULL);
    2861                 :      15983 :   g_return_if_fail (nestedsuite != NULL);
    2862                 :            : 
    2863                 :      15983 :   suite->suites = g_slist_append (suite->suites, nestedsuite);
    2864                 :            : }
    2865                 :            : 
    2866                 :            : /**
    2867                 :            :  * g_test_queue_free:
    2868                 :            :  * @gfree_pointer: the pointer to be stored.
    2869                 :            :  *
    2870                 :            :  * Enqueue a pointer to be released with g_free() during the next
    2871                 :            :  * teardown phase. This is equivalent to calling g_test_queue_destroy()
    2872                 :            :  * with a destroy callback of g_free().
    2873                 :            :  *
    2874                 :            :  * Since: 2.16
    2875                 :            :  */
    2876                 :            : void
    2877                 :          1 : g_test_queue_free (gpointer gfree_pointer)
    2878                 :            : {
    2879         [ +  - ]:          1 :   if (gfree_pointer)
    2880                 :          1 :     g_test_queue_destroy (g_free, gfree_pointer);
    2881                 :          1 : }
    2882                 :            : 
    2883                 :            : /**
    2884                 :            :  * g_test_queue_destroy:
    2885                 :            :  * @destroy_func:       Destroy callback for teardown phase.
    2886                 :            :  * @destroy_data:       Destroy callback data.
    2887                 :            :  *
    2888                 :            :  * Enqueues a callback @destroy_func to be executed during the next test case
    2889                 :            :  * teardown phase.
    2890                 :            :  *
    2891                 :            :  * This is most useful to auto destroy allocated test resources at the end of a
    2892                 :            :  * test run. Resources are released in reverse queue order, that means
    2893                 :            :  * enqueueing callback `A` before callback `B` will cause `B()` to be called
    2894                 :            :  * before `A()` during teardown.
    2895                 :            :  *
    2896                 :            :  * Since: 2.16
    2897                 :            :  */
    2898                 :            : void
    2899                 :          1 : g_test_queue_destroy (GDestroyNotify destroy_func,
    2900                 :            :                       gpointer       destroy_data)
    2901                 :            : {
    2902                 :            :   DestroyEntry *dentry;
    2903                 :            : 
    2904                 :          1 :   g_return_if_fail (destroy_func != NULL);
    2905                 :            : 
    2906                 :          1 :   dentry = g_slice_new0 (DestroyEntry);
    2907                 :          1 :   dentry->destroy_func = destroy_func;
    2908                 :          1 :   dentry->destroy_data = destroy_data;
    2909                 :          1 :   dentry->next = test_destroy_queue;
    2910                 :          1 :   test_destroy_queue = dentry;
    2911                 :            : }
    2912                 :            : 
    2913                 :            : static gint
    2914                 :        122 : test_has_prefix (gconstpointer a,
    2915                 :            :                  gconstpointer b)
    2916                 :            : {
    2917                 :        122 :     const gchar *test_path_skipped_local = (const gchar *)a;
    2918                 :        122 :     const gchar* test_run_name_local = (const gchar*)b;
    2919         [ +  + ]:        122 :     if (test_prefix_extended_skipped)
    2920                 :            :       {
    2921                 :            :         /* If both are null, we consider that it doesn't match */
    2922   [ +  -  -  + ]:         50 :         if (!test_path_skipped_local || !test_run_name_local)
    2923                 :          0 :           return FALSE;
    2924                 :         50 :         return strncmp (test_run_name_local, test_path_skipped_local, strlen (test_path_skipped_local));
    2925                 :            :       }
    2926                 :         72 :     return g_strcmp0 (test_run_name_local, test_path_skipped_local);
    2927                 :            : }
    2928                 :            : 
    2929                 :            : static gboolean test_should_run (const char *test_path,
    2930                 :            :                                  const char *cmp_path);
    2931                 :            : 
    2932                 :            : static gboolean
    2933                 :      19253 : test_case_run (GTestCase  *tc,
    2934                 :            :                const char *test_run_name,
    2935                 :            :                const char *path)
    2936                 :            : {
    2937                 :      19253 :   gchar *old_base = NULL;
    2938                 :      19253 :   GSList **old_free_list, *filename_free_list = NULL;
    2939                 :      19253 :   gboolean success = G_TEST_RUN_SUCCESS;
    2940                 :      19253 :   gboolean free_test_data = TRUE;
    2941                 :            : 
    2942                 :      19253 :   old_base = g_strdup (test_uri_base);
    2943                 :      19253 :   old_free_list = test_filename_free_list;
    2944                 :      19253 :   test_filename_free_list = &filename_free_list;
    2945                 :            : 
    2946         [ +  + ]:      19253 :   if (!test_should_run (test_run_name, path))
    2947                 :            :     {
    2948                 :            :       /* Silently skip the test and return success. This happens if it’s a
    2949                 :            :        * /subprocess path. */
    2950                 :      12201 :       success = G_TEST_RUN_SKIPPED;
    2951                 :            :     }
    2952         [ +  + ]:       7052 :   else if (++test_run_count <= test_startup_skip_count)
    2953                 :         24 :     g_test_log (G_TEST_LOG_SKIP_CASE, test_run_name, NULL, 0, NULL);
    2954         [ +  + ]:       7028 :   else if (test_run_list)
    2955                 :            :     {
    2956                 :          6 :       g_print ("%s\n", test_run_name);
    2957                 :          6 :       g_test_log (G_TEST_LOG_LIST_CASE, test_run_name, NULL, 0, NULL);
    2958                 :            :     }
    2959                 :            :   else
    2960                 :            :     {
    2961                 :       7022 :       GTimer *test_run_timer = g_timer_new();
    2962                 :            :       long double largs[G_TEST_CASE_LARGS_MAX];
    2963                 :            :       void *fixture;
    2964                 :       7022 :       g_test_log (G_TEST_LOG_START_CASE, test_run_name, NULL, 0, NULL);
    2965                 :       7022 :       test_run_forks = 0;
    2966                 :       7022 :       test_run_success = G_TEST_RUN_SUCCESS;
    2967                 :       7022 :       g_clear_pointer (&test_run_msg, g_free);
    2968                 :       7022 :       g_test_log_set_fatal_handler (NULL, NULL);
    2969   [ +  +  +  + ]:       7022 :       if (test_paths_skipped && g_slist_find_custom (test_paths_skipped, test_run_name, (GCompareFunc)test_has_prefix))
    2970                 :         16 :         g_test_skip ("by request (-s option)");
    2971                 :            :       else
    2972                 :            :         {
    2973                 :       7006 :           GError *local_error = NULL;
    2974                 :            : 
    2975         [ -  + ]:       7006 :           if (!test_do_isolate_dirs (&local_error))
    2976                 :            :             {
    2977                 :          0 :               g_test_log (G_TEST_LOG_ERROR, local_error->message, NULL, 0, NULL);
    2978                 :          0 :               g_test_fail ();
    2979                 :          0 :               g_error_free (local_error);
    2980                 :            :             }
    2981                 :            :           else
    2982                 :            :             {
    2983                 :       7006 :               g_timer_start (test_run_timer);
    2984         [ +  + ]:       7006 :               fixture = tc->fixture_size ? g_malloc0 (tc->fixture_size) : tc->test_data;
    2985                 :       7006 :               test_run_seed (test_run_seedstr);
    2986         [ +  + ]:       7006 :               if (tc->fixture_setup)
    2987                 :        173 :                 tc->fixture_setup (fixture, tc->test_data);
    2988                 :       7006 :               tc->fixture_test (fixture, tc->test_data);
    2989                 :       6881 :               test_trap_clear();
    2990         [ +  + ]:       6882 :               while (test_destroy_queue)
    2991                 :            :                 {
    2992                 :          1 :                   DestroyEntry *dentry = test_destroy_queue;
    2993                 :          1 :                   test_destroy_queue = dentry->next;
    2994                 :          1 :                   dentry->destroy_func (dentry->destroy_data);
    2995                 :          1 :                   g_slice_free (DestroyEntry, dentry);
    2996                 :            :                 }
    2997         [ +  + ]:       6881 :               if (tc->fixture_teardown)
    2998                 :       2108 :                 tc->fixture_teardown (fixture, tc->test_data);
    2999                 :       6881 :               free_test_data = FALSE;
    3000         [ +  + ]:       6881 :               if (tc->fixture_size)
    3001                 :        162 :                 g_free (fixture);
    3002                 :       6881 :               g_timer_stop (test_run_timer);
    3003                 :            :             }
    3004                 :            : 
    3005                 :       6881 :           test_rm_isolate_dirs ();
    3006                 :            :         }
    3007                 :       6897 :       success = test_run_success;
    3008                 :       6897 :       test_run_success = G_TEST_RUN_FAILURE;
    3009                 :       6897 :       largs[G_TEST_CASE_LARGS_RESULT] = success; /* OK */
    3010                 :       6897 :       largs[G_TEST_CASE_LARGS_RUN_FORKS] = test_run_forks;
    3011                 :       6897 :       largs[G_TEST_CASE_LARGS_EXECUTION_TIME] = g_timer_elapsed (test_run_timer, NULL);
    3012                 :       6897 :       g_test_log (G_TEST_LOG_STOP_CASE, test_run_name, test_run_msg, G_N_ELEMENTS (largs), largs);
    3013                 :       6897 :       g_clear_pointer (&test_run_msg, g_free);
    3014                 :       6897 :       g_timer_destroy (test_run_timer);
    3015                 :            :     }
    3016                 :            : 
    3017                 :            :   /* In case the test didn’t run (due to being skipped or an error), the test
    3018                 :            :    * data may still need to be freed, as the client’s main() function may have
    3019                 :            :    * passed ownership of it into g_test_add_data_func_full() with a
    3020                 :            :    * #GDestroyNotify. */
    3021   [ +  +  +  +  :      19128 :   if (free_test_data && tc->fixture_size == 0 && tc->fixture_teardown != NULL)
                   +  + ]
    3022                 :       3072 :     tc->fixture_teardown (tc->test_data, tc->test_data);
    3023                 :            : 
    3024                 :      19128 :   g_slist_free_full (filename_free_list, g_free);
    3025                 :      19128 :   test_filename_free_list = old_free_list;
    3026                 :      19128 :   g_free (test_uri_base);
    3027                 :      19128 :   test_uri_base = old_base;
    3028                 :            : 
    3029         [ +  + ]:      12316 :   return (success == G_TEST_RUN_SUCCESS ||
    3030   [ +  +  +  + ]:      31444 :           success == G_TEST_RUN_SKIPPED ||
    3031                 :            :           success == G_TEST_RUN_INCOMPLETE);
    3032                 :            : }
    3033                 :            : 
    3034                 :            : static gboolean
    3035                 :      12774 : path_has_prefix (const char *path,
    3036                 :            :                  const char *prefix)
    3037                 :            : {
    3038                 :      12774 :   int prefix_len = strlen (prefix);
    3039                 :            : 
    3040         [ +  + ]:      13576 :   return (strncmp (path, prefix, prefix_len) == 0 &&
    3041         [ +  + ]:        802 :           (path[prefix_len] == '\0' ||
    3042         [ +  + ]:        686 :            path[prefix_len] == '/'));
    3043                 :            : }
    3044                 :            : 
    3045                 :            : static gboolean
    3046                 :      19253 : test_should_run (const char *test_path,
    3047                 :            :                  const char *cmp_path)
    3048                 :            : {
    3049         [ +  + ]:      19253 :   if (strstr (test_run_name, "/subprocess"))
    3050                 :            :     {
    3051         [ +  + ]:       4010 :       if (g_strcmp0 (test_path, cmp_path) == 0)
    3052                 :        162 :         return TRUE;
    3053                 :            : 
    3054         [ +  + ]:       3848 :       if (g_test_verbose ())
    3055                 :            :         {
    3056         [ +  - ]:         33 :           if (test_tap_log)
    3057                 :         33 :             g_print ("skipping: %s\n", test_run_name);
    3058                 :            :           else
    3059                 :          0 :             g_print ("GTest: skipping: %s\n", test_run_name);
    3060                 :            :         }
    3061                 :       3848 :       return FALSE;
    3062                 :            :     }
    3063                 :            : 
    3064   [ +  +  +  + ]:      15243 :   return !cmp_path || path_has_prefix (test_path, cmp_path);
    3065                 :            : }
    3066                 :            : 
    3067                 :            : /* Recurse through @suite, running tests matching @path (or all tests
    3068                 :            :  * if @path is %NULL).
    3069                 :            :  */
    3070                 :            : static int
    3071                 :       2410 : g_test_run_suite_internal (GTestSuite *suite,
    3072                 :            :                            const char *path)
    3073                 :            : {
    3074                 :       2410 :   guint n_bad = 0;
    3075                 :       2410 :   gchar *old_name = test_run_name;
    3076                 :       2410 :   gchar *old_name_path = test_run_name_path;
    3077                 :            :   GSList *iter;
    3078                 :            : 
    3079                 :       2410 :   g_return_val_if_fail (suite != NULL, -1);
    3080                 :            : 
    3081                 :       2410 :   g_test_log (G_TEST_LOG_START_SUITE, suite->name, NULL, 0, NULL);
    3082                 :            : 
    3083         [ +  + ]:      21538 :   for (iter = suite->cases; iter; iter = iter->next)
    3084                 :            :     {
    3085                 :      19253 :       GTestCase *tc = iter->data;
    3086                 :            : 
    3087                 :      19253 :       test_run_name = g_build_path ("/", old_name, tc->name, NULL);
    3088                 :      19253 :       test_run_name_path = g_build_path (G_DIR_SEPARATOR_S, old_name_path, tc->name, NULL);
    3089                 :            : 
    3090         [ +  + ]:      19253 :       if (!test_case_run (tc, test_run_name, path))
    3091                 :         11 :         n_bad++;
    3092                 :            : 
    3093                 :      19128 :       g_free (test_run_name);
    3094                 :      19128 :       g_free (test_run_name_path);
    3095                 :            :     }
    3096                 :            : 
    3097         [ +  + ]:       7296 :   for (iter = suite->suites; iter; iter = iter->next)
    3098                 :            :     {
    3099                 :       5394 :       GTestSuite *ts = iter->data;
    3100                 :            : 
    3101                 :       5394 :       test_run_name = g_build_path ("/", old_name, ts->name, NULL);
    3102                 :       5394 :       test_run_name_path = g_build_path (G_DIR_SEPARATOR_S, old_name_path, ts->name, NULL);
    3103         [ +  + ]:       5394 :       if (test_prefix_extended) {
    3104   [ +  -  +  + ]:         54 :         if (!path || path_has_prefix (test_run_name, path))
    3105                 :          6 :           n_bad += g_test_run_suite_internal (ts, test_run_name);
    3106   [ +  -  +  + ]:         48 :         else if (!path || path_has_prefix (path, test_run_name))
    3107                 :          6 :           n_bad += g_test_run_suite_internal (ts, path);
    3108   [ +  +  +  + ]:       5340 :       } else if (!path || path_has_prefix (path, test_run_name)) {
    3109                 :       1766 :         n_bad += g_test_run_suite_internal (ts, path);
    3110                 :            :       }
    3111                 :            : 
    3112                 :       5011 :       g_free (test_run_name);
    3113                 :       5011 :       g_free (test_run_name_path);
    3114                 :            :     }
    3115                 :            : 
    3116                 :       1902 :   test_run_name = old_name;
    3117                 :       1902 :   test_run_name_path = old_name_path;
    3118                 :            : 
    3119                 :       1902 :   g_test_log (G_TEST_LOG_STOP_SUITE, suite->name, NULL, 0, NULL);
    3120                 :            : 
    3121                 :       1902 :   return n_bad;
    3122                 :            : }
    3123                 :            : 
    3124                 :            : static int
    3125                 :       9455 : g_test_suite_count (GTestSuite *suite)
    3126                 :            : {
    3127                 :       9455 :   int n = 0;
    3128                 :            :   GSList *iter;
    3129                 :            : 
    3130                 :       9455 :   g_return_val_if_fail (suite != NULL, -1);
    3131                 :            : 
    3132         [ +  + ]:      26989 :   for (iter = suite->cases; iter; iter = iter->next)
    3133                 :            :     {
    3134                 :      17534 :       GTestCase *tc = iter->data;
    3135                 :            : 
    3136         [ +  + ]:      17534 :       if (strcmp (tc->name, "subprocess") != 0)
    3137                 :      17479 :         n++;
    3138                 :            :     }
    3139                 :            : 
    3140         [ +  + ]:      25415 :   for (iter = suite->suites; iter; iter = iter->next)
    3141                 :            :     {
    3142                 :      15960 :       GTestSuite *ts = iter->data;
    3143                 :            : 
    3144         [ +  + ]:      15960 :       if (strcmp (ts->name, "subprocess") != 0)
    3145                 :       8847 :         n += g_test_suite_count (ts);
    3146                 :            :     }
    3147                 :            : 
    3148                 :       9455 :   return n;
    3149                 :            : }
    3150                 :            : 
    3151                 :            : /**
    3152                 :            :  * g_test_run_suite:
    3153                 :            :  * @suite: a #GTestSuite
    3154                 :            :  *
    3155                 :            :  * Execute the tests within @suite and all nested #GTestSuites.
    3156                 :            :  * The test suites to be executed are filtered according to
    3157                 :            :  * test path arguments (`-p testpath` and `-s testpath`) as parsed by
    3158                 :            :  * g_test_init(). See the g_test_run() documentation for more
    3159                 :            :  * information on the order that tests are run in.
    3160                 :            :  *
    3161                 :            :  * g_test_run_suite() or g_test_run() may only be called once
    3162                 :            :  * in a program.
    3163                 :            :  *
    3164                 :            :  * Returns: 0 on success
    3165                 :            :  *
    3166                 :            :  * Since: 2.16
    3167                 :            :  */
    3168                 :            : int
    3169                 :        608 : g_test_run_suite (GTestSuite *suite)
    3170                 :            : {
    3171                 :        608 :   int n_bad = 0;
    3172                 :            : 
    3173                 :        608 :   g_return_val_if_fail (g_test_run_once == TRUE, -1);
    3174                 :            : 
    3175                 :        608 :   g_test_run_once = FALSE;
    3176                 :        608 :   test_count = g_test_suite_count (suite);
    3177                 :            : 
    3178                 :        608 :   test_run_name = g_strdup_printf ("/%s", suite->name);
    3179                 :        608 :   test_run_name_path = g_build_path (G_DIR_SEPARATOR_S, suite->name, NULL);
    3180                 :            : 
    3181         [ +  + ]:        608 :   if (test_paths)
    3182                 :            :     {
    3183                 :            :       GSList *iter;
    3184                 :            : 
    3185         [ +  + ]:        393 :       for (iter = test_paths; iter; iter = iter->next)
    3186                 :        271 :         n_bad += g_test_run_suite_internal (suite, iter->data);
    3187                 :            :     }
    3188                 :            :   else
    3189                 :        361 :     n_bad = g_test_run_suite_internal (suite, NULL);
    3190                 :            : 
    3191                 :        483 :   g_clear_pointer (&test_run_name, g_free);
    3192                 :        483 :   g_clear_pointer (&test_run_name_path, g_free);
    3193                 :            : 
    3194                 :        483 :   return n_bad;
    3195                 :            : }
    3196                 :            : 
    3197                 :            : /**
    3198                 :            :  * g_test_case_free:
    3199                 :            :  * @test_case: a #GTestCase
    3200                 :            :  *
    3201                 :            :  * Free the @test_case.
    3202                 :            :  *
    3203                 :            :  * Since: 2.70
    3204                 :            :  */
    3205                 :            : void
    3206                 :      14001 : g_test_case_free (GTestCase *test_case)
    3207                 :            : {
    3208                 :      14001 :   g_free (test_case->name);
    3209                 :      14001 :   g_slice_free (GTestCase, test_case);
    3210                 :      14001 : }
    3211                 :            : 
    3212                 :            : /**
    3213                 :            :  * g_test_suite_free:
    3214                 :            :  * @suite: a #GTestSuite
    3215                 :            :  *
    3216                 :            :  * Free the @suite and all nested #GTestSuites.
    3217                 :            :  *
    3218                 :            :  * Since: 2.70
    3219                 :            :  */
    3220                 :            : void
    3221                 :       2537 : g_test_suite_free (GTestSuite *suite)
    3222                 :            : {
    3223                 :       2537 :   g_slist_free_full (suite->cases, (GDestroyNotify)g_test_case_free);
    3224                 :            : 
    3225                 :       2537 :   g_free (suite->name);
    3226                 :            : 
    3227                 :       2537 :   g_slist_free_full (suite->suites, (GDestroyNotify)g_test_suite_free);
    3228                 :            : 
    3229                 :       2537 :   g_slice_free (GTestSuite, suite);
    3230                 :       2537 : }
    3231                 :            : 
    3232                 :            : static void
    3233                 :       8323 : gtest_default_log_handler (const gchar    *log_domain,
    3234                 :            :                            GLogLevelFlags  log_level,
    3235                 :            :                            const gchar    *message,
    3236                 :            :                            gpointer        unused_data)
    3237                 :            : {
    3238                 :            :   const gchar *strv[16];
    3239                 :       8323 :   gboolean fatal = FALSE;
    3240                 :            :   gchar *msg;
    3241                 :       8323 :   guint i = 0;
    3242                 :            : 
    3243         [ +  + ]:       8323 :   if (log_domain)
    3244                 :            :     {
    3245                 :       8322 :       strv[i++] = log_domain;
    3246                 :       8322 :       strv[i++] = "-";
    3247                 :            :     }
    3248         [ +  + ]:       8323 :   if (log_level & G_LOG_FLAG_FATAL)
    3249                 :            :     {
    3250                 :          2 :       strv[i++] = "FATAL-";
    3251                 :          2 :       fatal = TRUE;
    3252                 :            :     }
    3253         [ -  + ]:       8323 :   if (log_level & G_LOG_FLAG_RECURSION)
    3254                 :          0 :     strv[i++] = "RECURSIVE-";
    3255         [ -  + ]:       8323 :   if (log_level & G_LOG_LEVEL_ERROR)
    3256                 :          0 :     strv[i++] = "ERROR";
    3257         [ +  + ]:       8323 :   if (log_level & G_LOG_LEVEL_CRITICAL)
    3258                 :          7 :     strv[i++] = "CRITICAL";
    3259         [ +  + ]:       8323 :   if (log_level & G_LOG_LEVEL_WARNING)
    3260                 :          4 :     strv[i++] = "WARNING";
    3261         [ +  + ]:       8323 :   if (log_level & G_LOG_LEVEL_MESSAGE)
    3262                 :          3 :     strv[i++] = "MESSAGE";
    3263         [ +  + ]:       8323 :   if (log_level & G_LOG_LEVEL_INFO)
    3264                 :          1 :     strv[i++] = "INFO";
    3265         [ +  + ]:       8323 :   if (log_level & G_LOG_LEVEL_DEBUG)
    3266                 :       8308 :     strv[i++] = "DEBUG";
    3267                 :       8323 :   strv[i++] = ": ";
    3268                 :       8323 :   strv[i++] = message;
    3269                 :       8323 :   strv[i++] = NULL;
    3270                 :            : 
    3271                 :       8323 :   msg = g_strjoinv ("", (gchar**) strv);
    3272         [ +  + ]:       8323 :   g_test_log (fatal ? G_TEST_LOG_ERROR : G_TEST_LOG_MESSAGE, msg, NULL, 0, NULL);
    3273                 :       8323 :   g_free (msg);
    3274                 :            : 
    3275         [ +  + ]:       8323 :   if (!test_tap_log)
    3276                 :        119 :     g_log_default_handler (log_domain, log_level, message, unused_data);
    3277                 :       8323 : }
    3278                 :            : 
    3279                 :            : void
    3280                 :          1 : g_assertion_message (const char     *domain,
    3281                 :            :                      const char     *file,
    3282                 :            :                      int             line,
    3283                 :            :                      const char     *func,
    3284                 :            :                      const char     *message)
    3285                 :            : {
    3286                 :            :   char lstr[32];
    3287                 :            :   char *s;
    3288                 :            : 
    3289         [ -  + ]:          1 :   if (!message)
    3290                 :          0 :     message = "code should not be reached";
    3291                 :          1 :   g_snprintf (lstr, 32, "%d", line);
    3292   [ +  -  +  -  :          1 :   s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "",
                   +  - ]
    3293                 :            :                    "ERROR:", file, ":", lstr, ":",
    3294         [ +  - ]:          1 :                    func, func[0] ? ":" : "",
    3295                 :            :                    " ", message, NULL);
    3296                 :          1 :   g_printerr ("**\n%s\n", s);
    3297                 :            : 
    3298                 :            :   /* Don't print a fatal error indication if assertions are non-fatal, or
    3299                 :            :    * if we are a child process that might be sharing the parent's stdout. */
    3300   [ -  +  -  -  :          1 :   if (test_nonfatal_assertions || test_in_subprocess || test_in_forked_child)
                   -  - ]
    3301                 :          1 :     g_test_log (G_TEST_LOG_MESSAGE, s, NULL, 0, NULL);
    3302                 :            :   else
    3303                 :          0 :     g_test_log (G_TEST_LOG_ERROR, s, NULL, 0, NULL);
    3304                 :            : 
    3305         [ +  - ]:          1 :   if (test_nonfatal_assertions)
    3306                 :            :     {
    3307                 :          1 :       g_free (s);
    3308                 :          1 :       g_test_fail ();
    3309                 :          1 :       return;
    3310                 :            :     }
    3311                 :            : 
    3312                 :            :   /* store assertion message in global variable, so that it can be found in a
    3313                 :            :    * core dump */
    3314         [ #  # ]:          0 :   if (__glib_assert_msg != NULL)
    3315                 :            :     /* free the old one */
    3316                 :          0 :     free (__glib_assert_msg);
    3317                 :          0 :   __glib_assert_msg = (char*) malloc (strlen (s) + 1);
    3318                 :          0 :   strcpy (__glib_assert_msg, s);
    3319                 :            : 
    3320                 :          0 :   g_free (s);
    3321                 :            : 
    3322         [ #  # ]:          0 :   if (test_in_subprocess)
    3323                 :            :     {
    3324                 :            :       /* If this is a test case subprocess then it probably hit this
    3325                 :            :        * assertion on purpose, so just exit() rather than abort()ing,
    3326                 :            :        * to avoid triggering any system crash-reporting daemon.
    3327                 :            :        */
    3328                 :          0 :       _exit (1);
    3329                 :            :     }
    3330                 :            :   else
    3331                 :          0 :     g_abort ();
    3332                 :            : }
    3333                 :            : 
    3334                 :            : /**
    3335                 :            :  * g_assertion_message_expr: (skip)
    3336                 :            :  * @domain: (nullable): log domain
    3337                 :            :  * @file: file containing the assertion
    3338                 :            :  * @line: line number of the assertion
    3339                 :            :  * @func: function containing the assertion
    3340                 :            :  * @expr: (nullable): expression which failed
    3341                 :            :  *
    3342                 :            :  * Internal function used to print messages from the public g_assert() and
    3343                 :            :  * g_assert_not_reached() macros.
    3344                 :            :  */
    3345                 :            : void
    3346                 :          0 : g_assertion_message_expr (const char     *domain,
    3347                 :            :                           const char     *file,
    3348                 :            :                           int             line,
    3349                 :            :                           const char     *func,
    3350                 :            :                           const char     *expr)
    3351                 :            : {
    3352                 :            :   char *s;
    3353         [ #  # ]:          0 :   if (!expr)
    3354                 :          0 :     s = g_strdup ("code should not be reached");
    3355                 :            :   else
    3356                 :          0 :     s = g_strconcat ("assertion failed: (", expr, ")", NULL);
    3357                 :          0 :   g_assertion_message (domain, file, line, func, s);
    3358                 :          0 :   g_free (s);
    3359                 :            : 
    3360                 :            :   /* Normally g_assertion_message() won't return, but we need this for
    3361                 :            :    * when test_nonfatal_assertions is set, since
    3362                 :            :    * g_assertion_message_expr() is used for always-fatal assertions.
    3363                 :            :    */
    3364         [ #  # ]:          0 :   if (test_in_subprocess)
    3365                 :          0 :     _exit (1);
    3366                 :            :   else
    3367                 :          0 :     g_abort ();
    3368                 :            : }
    3369                 :            : 
    3370                 :            : void
    3371                 :          1 : g_assertion_message_cmpint (const char     *domain,
    3372                 :            :                             const char     *file,
    3373                 :            :                             int             line,
    3374                 :            :                             const char     *func,
    3375                 :            :                             const char     *expr,
    3376                 :            :                             guint64         arg1,
    3377                 :            :                             const char     *cmp,
    3378                 :            :                             guint64         arg2,
    3379                 :            :                             char            numtype)
    3380                 :            : {
    3381                 :          1 :   char *s = NULL;
    3382                 :            : 
    3383   [ +  -  -  - ]:          1 :   switch (numtype)
    3384                 :            :     {
    3385                 :          1 :     case 'i':
    3386                 :          1 :       s = g_strdup_printf ("assertion failed (%s): "
    3387                 :            :                            "(%" PRIi64 " %s %" PRIi64 ")",
    3388                 :            :                            expr, (int64_t) arg1, cmp, (int64_t) arg2);
    3389                 :          1 :       break;
    3390                 :          0 :     case 'u':
    3391                 :          0 :       s = g_strdup_printf ("assertion failed (%s): "
    3392                 :            :                            "(%" PRIu64 " %s %" PRIu64 ")",
    3393                 :            :                            expr, (uint64_t) arg1, cmp, (uint64_t) arg2);
    3394                 :          0 :       break;
    3395                 :          0 :     case 'x':
    3396                 :          0 :       s = g_strdup_printf ("assertion failed (%s): "
    3397                 :            :                            "(0x%08" PRIx64 " %s 0x%08" PRIx64 ")",
    3398                 :            :                            expr, (uint64_t) arg1, cmp, (uint64_t) arg2);
    3399                 :          0 :       break;
    3400                 :          0 :     default:
    3401                 :            :       g_assert_not_reached ();
    3402                 :            :     }
    3403                 :          1 :   g_assertion_message (domain, file, line, func, s);
    3404                 :          1 :   g_free (s);
    3405                 :          1 : }
    3406                 :            : 
    3407                 :            : void
    3408                 :          0 : g_assertion_message_cmpnum (const char     *domain,
    3409                 :            :                             const char     *file,
    3410                 :            :                             int             line,
    3411                 :            :                             const char     *func,
    3412                 :            :                             const char     *expr,
    3413                 :            :                             long double     arg1,
    3414                 :            :                             const char     *cmp,
    3415                 :            :                             long double     arg2,
    3416                 :            :                             char            numtype)
    3417                 :            : {
    3418                 :          0 :   char *s = NULL;
    3419                 :            : 
    3420      [ #  #  # ]:          0 :   switch (numtype)
    3421                 :            :     {
    3422                 :          0 :     case 'f':   s = g_strdup_printf ("assertion failed (%s): (%.9g %s %.9g)", expr, (double) arg1, cmp, (double) arg2); break;
    3423                 :            :       /* ideally use: floats=%.7g double=%.17g */
    3424                 :          0 :     case 'i':
    3425                 :            :     case 'x':
    3426                 :            :       /* Backwards compatibility to apps compiled before 2.78 */
    3427                 :          0 :       g_assertion_message_cmpint (domain, file, line, func, expr,
    3428                 :            :                                   (guint64) arg1, cmp, (guint64) arg2, numtype);
    3429                 :          0 :       break;
    3430                 :          0 :     default:
    3431                 :            :       g_assert_not_reached ();
    3432                 :            :     }
    3433                 :          0 :   g_assertion_message (domain, file, line, func, s);
    3434                 :          0 :   g_free (s);
    3435                 :          0 : }
    3436                 :            : 
    3437                 :            : void
    3438                 :          0 : g_assertion_message_cmpstr (const char     *domain,
    3439                 :            :                             const char     *file,
    3440                 :            :                             int             line,
    3441                 :            :                             const char     *func,
    3442                 :            :                             const char     *expr,
    3443                 :            :                             const char     *arg1,
    3444                 :            :                             const char     *cmp,
    3445                 :            :                             const char     *arg2)
    3446                 :            : {
    3447                 :          0 :   char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
    3448         [ #  # ]:          0 :   a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL");
    3449         [ #  # ]:          0 :   a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL");
    3450                 :          0 :   g_free (t1);
    3451                 :          0 :   g_free (t2);
    3452                 :          0 :   s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
    3453                 :          0 :   g_free (a1);
    3454                 :          0 :   g_free (a2);
    3455                 :          0 :   g_assertion_message (domain, file, line, func, s);
    3456                 :          0 :   g_free (s);
    3457                 :          0 : }
    3458                 :            : 
    3459                 :            : void
    3460                 :          0 : g_assertion_message_cmpstrv (const char         *domain,
    3461                 :            :                              const char         *file,
    3462                 :            :                              int                 line,
    3463                 :            :                              const char         *func,
    3464                 :            :                              const char         *expr,
    3465                 :            :                              const char * const *arg1,
    3466                 :            :                              const char * const *arg2,
    3467                 :            :                              gsize               first_wrong_idx)
    3468                 :            : {
    3469                 :          0 :   const char *s1 = arg1[first_wrong_idx], *s2 = arg2[first_wrong_idx];
    3470                 :          0 :   char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
    3471                 :            : 
    3472                 :          0 :   a1 = g_strconcat ("\"", t1 = g_strescape (s1, NULL), "\"", NULL);
    3473                 :          0 :   a2 = g_strconcat ("\"", t2 = g_strescape (s2, NULL), "\"", NULL);
    3474                 :          0 :   g_free (t1);
    3475                 :          0 :   g_free (t2);
    3476                 :          0 :   s = g_strdup_printf ("assertion failed (%s): first differing element at index %" G_GSIZE_FORMAT ": %s does not equal %s",
    3477                 :            :                        expr, first_wrong_idx, a1, a2);
    3478                 :          0 :   g_free (a1);
    3479                 :          0 :   g_free (a2);
    3480                 :          0 :   g_assertion_message (domain, file, line, func, s);
    3481                 :          0 :   g_free (s);
    3482                 :          0 : }
    3483                 :            : 
    3484                 :            : void
    3485                 :          0 : g_assertion_message_error (const char     *domain,
    3486                 :            :                            const char     *file,
    3487                 :            :                            int             line,
    3488                 :            :                            const char     *func,
    3489                 :            :                            const char     *expr,
    3490                 :            :                            const GError   *error,
    3491                 :            :                            GQuark          error_domain,
    3492                 :            :                            int             error_code)
    3493                 :            : {
    3494                 :            :   GString *gstring;
    3495                 :            : 
    3496                 :            :   /* This is used by both g_assert_error() and g_assert_no_error(), so there
    3497                 :            :    * are three cases: expected an error but got the wrong error, expected
    3498                 :            :    * an error but got no error, and expected no error but got an error.
    3499                 :            :    */
    3500                 :            : 
    3501                 :          0 :   gstring = g_string_new ("assertion failed ");
    3502         [ #  # ]:          0 :   if (error_domain)
    3503                 :          0 :       g_string_append_printf (gstring, "(%s == (%s, %d)): ", expr,
    3504                 :            :                               g_quark_to_string (error_domain), error_code);
    3505                 :            :   else
    3506                 :          0 :     g_string_append_printf (gstring, "(%s == NULL): ", expr);
    3507                 :            : 
    3508         [ #  # ]:          0 :   if (error)
    3509                 :          0 :       g_string_append_printf (gstring, "%s (%s, %d)", error->message,
    3510                 :          0 :                               g_quark_to_string (error->domain), error->code);
    3511                 :            :   else
    3512                 :          0 :     g_string_append_printf (gstring, "%s is NULL", expr);
    3513                 :            : 
    3514                 :          0 :   g_assertion_message (domain, file, line, func, gstring->str);
    3515                 :          0 :   g_string_free (gstring, TRUE);
    3516                 :          0 : }
    3517                 :            : 
    3518                 :            : /**
    3519                 :            :  * g_strcmp0:
    3520                 :            :  * @str1: (nullable): a C string or %NULL
    3521                 :            :  * @str2: (nullable): another C string or %NULL
    3522                 :            :  *
    3523                 :            :  * Compares @str1 and @str2 like strcmp(). Handles %NULL
    3524                 :            :  * gracefully by sorting it before non-%NULL strings.
    3525                 :            :  * Comparing two %NULL pointers returns 0.
    3526                 :            :  *
    3527                 :            :  * Returns: an integer less than, equal to, or greater than zero, if @str1 is <, == or > than @str2.
    3528                 :            :  *
    3529                 :            :  * Since: 2.16
    3530                 :            :  */
    3531                 :            : int
    3532                 :    1585009 : g_strcmp0 (const char     *str1,
    3533                 :            :            const char     *str2)
    3534                 :            : {
    3535         [ +  + ]:    1585009 :   if (!str1)
    3536                 :       2689 :     return -(str1 != str2);
    3537         [ +  + ]:    1582320 :   if (!str2)
    3538                 :      20774 :     return str1 != str2;
    3539                 :    1561546 :   return strcmp (str1, str2);
    3540                 :            : }
    3541                 :            : 
    3542                 :            : static void
    3543                 :       7227 : test_trap_clear (void)
    3544                 :            : {
    3545                 :       7227 :   test_trap_last_status = 0;
    3546                 :       7227 :   test_trap_last_pid = 0;
    3547                 :       7227 :   g_clear_pointer (&test_trap_last_subprocess, g_free);
    3548                 :       7227 :   g_clear_pointer (&test_trap_last_stdout, g_free);
    3549                 :       7227 :   g_clear_pointer (&test_trap_last_stderr, g_free);
    3550                 :       7227 : }
    3551                 :            : 
    3552                 :            : #ifdef G_OS_UNIX
    3553                 :            : 
    3554                 :            : static int
    3555                 :          6 : safe_dup2 (int fd1,
    3556                 :            :            int fd2)
    3557                 :            : {
    3558                 :            :   int ret;
    3559                 :            :   do
    3560                 :          6 :     ret = dup2 (fd1, fd2);
    3561   [ -  +  -  - ]:          6 :   while (ret < 0 && errno == EINTR);
    3562                 :          6 :   return ret;
    3563                 :            : }
    3564                 :            : 
    3565                 :            : #endif
    3566                 :            : 
    3567                 :            : typedef struct {
    3568                 :            :   GPid pid;
    3569                 :            :   GMainLoop *loop;
    3570                 :            :   int child_status;  /* unmodified platform-specific status */
    3571                 :            : 
    3572                 :            :   GIOChannel *stdout_io;
    3573                 :            :   gboolean echo_stdout;
    3574                 :            :   GString *stdout_str;
    3575                 :            : 
    3576                 :            :   GIOChannel *stderr_io;
    3577                 :            :   gboolean echo_stderr;
    3578                 :            :   GString *stderr_str;
    3579                 :            : } WaitForChildData;
    3580                 :            : 
    3581                 :            : static void
    3582                 :       1038 : check_complete (WaitForChildData *data)
    3583                 :            : {
    3584   [ +  +  +  +  :       1038 :   if (data->child_status != -1 && data->stdout_io == NULL && data->stderr_io == NULL)
                   +  + ]
    3585                 :        346 :     g_main_loop_quit (data->loop);
    3586                 :       1038 : }
    3587                 :            : 
    3588                 :            : static void
    3589                 :        346 : child_exited (GPid     pid,
    3590                 :            :               gint     status,
    3591                 :            :               gpointer user_data)
    3592                 :            : {
    3593                 :        346 :   WaitForChildData *data = user_data;
    3594                 :            : 
    3595                 :        346 :   g_assert (status != -1);
    3596                 :        346 :   data->child_status = status;
    3597                 :            : 
    3598                 :        346 :   check_complete (data);
    3599                 :        346 : }
    3600                 :            : 
    3601                 :            : static gboolean
    3602                 :          1 : child_timeout (gpointer user_data)
    3603                 :            : {
    3604                 :          1 :   WaitForChildData *data = user_data;
    3605                 :            : 
    3606                 :            : #ifdef G_OS_WIN32
    3607                 :            :   TerminateProcess (data->pid, G_TEST_STATUS_TIMED_OUT);
    3608                 :            : #else
    3609                 :          1 :   kill (data->pid, SIGALRM);
    3610                 :            : #endif
    3611                 :            : 
    3612                 :          1 :   return FALSE;
    3613                 :            : }
    3614                 :            : 
    3615                 :            : static gboolean
    3616                 :       1073 : child_read (GIOChannel *io, GIOCondition cond, gpointer user_data)
    3617                 :            : {
    3618                 :       1073 :   WaitForChildData *data = user_data;
    3619                 :            :   GIOStatus status;
    3620                 :            :   gsize nread, nwrote, total;
    3621                 :            :   gchar buf[4096];
    3622                 :       1073 :   FILE *echo_file = NULL;
    3623                 :            : 
    3624                 :       1073 :   status = g_io_channel_read_chars (io, buf, sizeof (buf), &nread, NULL);
    3625   [ +  -  +  + ]:       1073 :   if (status == G_IO_STATUS_ERROR || status == G_IO_STATUS_EOF)
    3626                 :            :     {
    3627                 :            :       // FIXME data->error = (status == G_IO_STATUS_ERROR);
    3628         [ +  + ]:        692 :       if (io == data->stdout_io)
    3629                 :        346 :         g_clear_pointer (&data->stdout_io, g_io_channel_unref);
    3630                 :            :       else
    3631                 :        346 :         g_clear_pointer (&data->stderr_io, g_io_channel_unref);
    3632                 :            : 
    3633                 :        692 :       check_complete (data);
    3634                 :        692 :       return FALSE;
    3635                 :            :     }
    3636         [ -  + ]:        381 :   else if (status == G_IO_STATUS_AGAIN)
    3637                 :          0 :     return TRUE;
    3638                 :            : 
    3639         [ +  + ]:        381 :   if (io == data->stdout_io)
    3640                 :            :     {
    3641         [ -  + ]:        180 :       g_string_append_len (data->stdout_str, buf, nread);
    3642         [ +  + ]:        180 :       if (data->echo_stdout)
    3643                 :            :         {
    3644         [ -  + ]:         61 :           if G_UNLIKELY (!test_tap_log)
    3645                 :          0 :             echo_file = stdout;
    3646                 :            :         }
    3647                 :            :     }
    3648                 :            :   else
    3649                 :            :     {
    3650         [ -  + ]:        201 :       g_string_append_len (data->stderr_str, buf, nread);
    3651         [ +  + ]:        201 :       if (data->echo_stderr)
    3652                 :          1 :         echo_file = stderr;
    3653                 :            :     }
    3654                 :            : 
    3655         [ +  + ]:        381 :   if (echo_file)
    3656                 :            :     {
    3657         [ +  + ]:          2 :       for (total = 0; total < nread; total += nwrote)
    3658                 :            :         {
    3659                 :            :           int errsv;
    3660                 :            : 
    3661                 :          1 :           nwrote = fwrite (buf + total, 1, nread - total, echo_file);
    3662                 :          1 :           errsv = errno;
    3663         [ -  + ]:          1 :           if (nwrote == 0)
    3664                 :          0 :             g_error ("write failed: %s", g_strerror (errsv));
    3665                 :            :         }
    3666                 :            :     }
    3667                 :            : 
    3668                 :        381 :   return TRUE;
    3669                 :            : }
    3670                 :            : 
    3671                 :            : static void
    3672                 :        346 : wait_for_child (GPid pid,
    3673                 :            :                 int stdout_fd, gboolean echo_stdout,
    3674                 :            :                 int stderr_fd, gboolean echo_stderr,
    3675                 :            :                 guint64 timeout)
    3676                 :            : {
    3677                 :            :   WaitForChildData data;
    3678                 :            :   GMainContext *context;
    3679                 :            :   GSource *source;
    3680                 :            : 
    3681                 :        346 :   data.pid = pid;
    3682                 :        346 :   data.child_status = -1;
    3683                 :            : 
    3684                 :        346 :   context = g_main_context_new ();
    3685                 :        346 :   data.loop = g_main_loop_new (context, FALSE);
    3686                 :            : 
    3687                 :        346 :   source = g_child_watch_source_new (pid);
    3688                 :        346 :   g_source_set_callback (source, (GSourceFunc) child_exited, &data, NULL);
    3689                 :        346 :   g_source_attach (source, context);
    3690                 :        346 :   g_source_unref (source);
    3691                 :            : 
    3692                 :        346 :   data.echo_stdout = echo_stdout;
    3693                 :        346 :   data.stdout_str = g_string_new (NULL);
    3694                 :        346 :   data.stdout_io = g_io_channel_unix_new (stdout_fd);
    3695                 :        346 :   g_io_channel_set_close_on_unref (data.stdout_io, TRUE);
    3696                 :        346 :   g_io_channel_set_encoding (data.stdout_io, NULL, NULL);
    3697                 :        346 :   g_io_channel_set_buffered (data.stdout_io, FALSE);
    3698                 :        346 :   source = g_io_create_watch (data.stdout_io, G_IO_IN | G_IO_ERR | G_IO_HUP);
    3699                 :        346 :   g_source_set_callback (source, (GSourceFunc) child_read, &data, NULL);
    3700                 :        346 :   g_source_attach (source, context);
    3701                 :        346 :   g_source_unref (source);
    3702                 :            : 
    3703                 :        346 :   data.echo_stderr = echo_stderr;
    3704                 :        346 :   data.stderr_str = g_string_new (NULL);
    3705                 :        346 :   data.stderr_io = g_io_channel_unix_new (stderr_fd);
    3706                 :        346 :   g_io_channel_set_close_on_unref (data.stderr_io, TRUE);
    3707                 :        346 :   g_io_channel_set_encoding (data.stderr_io, NULL, NULL);
    3708                 :        346 :   g_io_channel_set_buffered (data.stderr_io, FALSE);
    3709                 :        346 :   source = g_io_create_watch (data.stderr_io, G_IO_IN | G_IO_ERR | G_IO_HUP);
    3710                 :        346 :   g_source_set_callback (source, (GSourceFunc) child_read, &data, NULL);
    3711                 :        346 :   g_source_attach (source, context);
    3712                 :        346 :   g_source_unref (source);
    3713                 :            : 
    3714         [ +  + ]:        346 :   if (timeout)
    3715                 :            :     {
    3716                 :          6 :       source = g_timeout_source_new (0);
    3717                 :          6 :       g_source_set_ready_time (source, g_get_monotonic_time () + timeout);
    3718                 :          6 :       g_source_set_callback (source, (GSourceFunc) child_timeout, &data, NULL);
    3719                 :          6 :       g_source_attach (source, context);
    3720                 :          6 :       g_source_unref (source);
    3721                 :            :     }
    3722                 :            : 
    3723                 :        346 :   g_main_loop_run (data.loop);
    3724                 :        346 :   g_main_loop_unref (data.loop);
    3725                 :        346 :   g_main_context_unref (context);
    3726                 :            : 
    3727   [ +  +  +  -  :        346 :   if (echo_stdout && test_tap_log && data.stdout_str->len > 0)
                   +  + ]
    3728                 :            :     {
    3729                 :         23 :       gboolean added_newline = FALSE;
    3730                 :            : 
    3731         [ +  + ]:         23 :       if (data.stdout_str->str[data.stdout_str->len - 1] != '\n')
    3732                 :            :         {
    3733         [ +  - ]:          1 :           g_string_append_c (data.stdout_str, '\n');
    3734                 :          1 :           added_newline = TRUE;
    3735                 :            :         }
    3736                 :            : 
    3737                 :         23 :       g_test_print_handler_full (data.stdout_str->str, TRUE, TRUE, 1);
    3738                 :            : 
    3739         [ +  + ]:         23 :       if (added_newline)
    3740                 :          1 :         g_string_truncate (data.stdout_str, data.stdout_str->len - 1);
    3741                 :            :     }
    3742                 :            : 
    3743                 :        346 :   test_trap_last_pid = pid;
    3744                 :        346 :   test_trap_last_status = data.child_status;
    3745                 :        346 :   test_trap_last_stdout = g_string_free (data.stdout_str, FALSE);
    3746                 :        346 :   test_trap_last_stderr = g_string_free (data.stderr_str, FALSE);
    3747                 :            : 
    3748                 :        346 :   g_clear_pointer (&data.stdout_io, g_io_channel_unref);
    3749                 :        346 :   g_clear_pointer (&data.stderr_io, g_io_channel_unref);
    3750                 :        346 : }
    3751                 :            : 
    3752                 :            : /**
    3753                 :            :  * g_test_trap_fork:
    3754                 :            :  * @usec_timeout:    Timeout for the forked test in micro seconds.
    3755                 :            :  * @test_trap_flags: Flags to modify forking behaviour.
    3756                 :            :  *
    3757                 :            :  * Fork the current test program to execute a test case that might
    3758                 :            :  * not return or that might abort.
    3759                 :            :  *
    3760                 :            :  * If @usec_timeout is non-0, the forked test case is aborted and
    3761                 :            :  * considered failing if its run time exceeds it.
    3762                 :            :  *
    3763                 :            :  * The forking behavior can be configured with the #GTestTrapFlags flags.
    3764                 :            :  *
    3765                 :            :  * In the following example, the test code forks, the forked child
    3766                 :            :  * process produces some sample output and exits successfully.
    3767                 :            :  * The forking parent process then asserts successful child program
    3768                 :            :  * termination and validates child program outputs.
    3769                 :            :  *
    3770                 :            :  * |[<!-- language="C" --> 
    3771                 :            :  *   static void
    3772                 :            :  *   test_fork_patterns (void)
    3773                 :            :  *   {
    3774                 :            :  *     if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
    3775                 :            :  *       {
    3776                 :            :  *         g_print ("some stdout text: somagic17\n");
    3777                 :            :  *         g_printerr ("some stderr text: semagic43\n");
    3778                 :            :  *         exit (0); // successful test run
    3779                 :            :  *       }
    3780                 :            :  *     g_test_trap_assert_passed ();
    3781                 :            :  *     g_test_trap_assert_stdout ("*somagic17*");
    3782                 :            :  *     g_test_trap_assert_stderr ("*semagic43*");
    3783                 :            :  *   }
    3784                 :            :  * ]|
    3785                 :            :  *
    3786                 :            :  * Returns: %TRUE for the forked child and %FALSE for the executing parent process.
    3787                 :            :  *
    3788                 :            :  * Since: 2.16
    3789                 :            :  *
    3790                 :            :  * Deprecated: This function is implemented only on Unix platforms,
    3791                 :            :  * is not always reliable due to problems inherent in fork-without-exec
    3792                 :            :  * and doesn't set close-on-exec flag on its file descriptors.
    3793                 :            :  * Use g_test_trap_subprocess() instead.
    3794                 :            :  */
    3795                 :            : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    3796                 :            : gboolean
    3797                 :          3 : g_test_trap_fork (guint64        usec_timeout,
    3798                 :            :                   GTestTrapFlags test_trap_flags)
    3799                 :            : {
    3800                 :            : #ifdef G_OS_UNIX
    3801                 :          3 :   int stdout_pipe[2] = { -1, -1 };
    3802                 :          3 :   int stderr_pipe[2] = { -1, -1 };
    3803                 :            :   int errsv;
    3804                 :            : 
    3805                 :          3 :   test_trap_clear();
    3806   [ +  -  -  + ]:          3 :   if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0)
    3807                 :            :     {
    3808                 :          0 :       errsv = errno;
    3809                 :          0 :       g_error ("failed to create pipes to fork test program: %s", g_strerror (errsv));
    3810                 :            :     }
    3811                 :          3 :   test_trap_last_pid = fork ();
    3812                 :          5 :   errsv = errno;
    3813         [ -  + ]:          5 :   if (test_trap_last_pid < 0)
    3814                 :          0 :     g_error ("failed to fork test program: %s", g_strerror (errsv));
    3815         [ +  + ]:          5 :   if (test_trap_last_pid == 0)  /* child */
    3816                 :            :     {
    3817                 :          2 :       int fd0 = -1;
    3818                 :          2 :       test_in_forked_child = TRUE;
    3819                 :          2 :       close (stdout_pipe[0]);
    3820                 :          2 :       close (stderr_pipe[0]);
    3821         [ +  - ]:          2 :       if (!(test_trap_flags & G_TEST_TRAP_INHERIT_STDIN))
    3822                 :            :         {
    3823                 :          2 :           fd0 = g_open ("/dev/null", O_RDONLY, 0);
    3824         [ -  + ]:          2 :           if (fd0 < 0)
    3825                 :          0 :             g_error ("failed to open /dev/null for stdin redirection");
    3826                 :            :         }
    3827   [ +  -  +  -  :          2 :       if (safe_dup2 (stdout_pipe[1], 1) < 0 || safe_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && safe_dup2 (fd0, 0) < 0))
             +  -  -  + ]
    3828                 :            :         {
    3829                 :          0 :           errsv = errno;
    3830                 :          0 :           g_error ("failed to dup2() in forked test program: %s", g_strerror (errsv));
    3831                 :            :         }
    3832         [ +  - ]:          2 :       if (fd0 >= 3)
    3833                 :          2 :         close (fd0);
    3834         [ +  - ]:          2 :       if (stdout_pipe[1] >= 3)
    3835                 :          2 :         close (stdout_pipe[1]);
    3836         [ +  - ]:          2 :       if (stderr_pipe[1] >= 3)
    3837                 :          2 :         close (stderr_pipe[1]);
    3838                 :            : 
    3839                 :            :       /* We typically expect these child processes to crash, and some
    3840                 :            :        * tests spawn a *lot* of them.  Avoid spamming system crash
    3841                 :            :        * collection programs such as systemd-coredump and abrt.
    3842                 :            :        */
    3843                 :          2 :       g_test_disable_crash_reporting ();
    3844                 :            : 
    3845                 :          2 :       return TRUE;
    3846                 :            :     }
    3847                 :            :   else                          /* parent */
    3848                 :            :     {
    3849                 :          3 :       test_run_forks++;
    3850                 :          3 :       close (stdout_pipe[1]);
    3851                 :          3 :       close (stderr_pipe[1]);
    3852                 :            : 
    3853                 :          3 :       wait_for_child (test_trap_last_pid,
    3854                 :          3 :                       stdout_pipe[0], !(test_trap_flags & G_TEST_TRAP_SILENCE_STDOUT),
    3855                 :          3 :                       stderr_pipe[0], !(test_trap_flags & G_TEST_TRAP_SILENCE_STDERR),
    3856                 :            :                       usec_timeout);
    3857                 :          3 :       return FALSE;
    3858                 :            :     }
    3859                 :            : #else
    3860                 :            :   g_message ("Not implemented: g_test_trap_fork");
    3861                 :            : 
    3862                 :            :   return FALSE;
    3863                 :            : #endif
    3864                 :            : }
    3865                 :            : G_GNUC_END_IGNORE_DEPRECATIONS
    3866                 :            : 
    3867                 :            : /**
    3868                 :            :  * g_test_trap_subprocess:
    3869                 :            :  * @test_path: (nullable): Test to run in a subprocess
    3870                 :            :  * @usec_timeout: Timeout for the subprocess test in micro seconds.
    3871                 :            :  * @test_flags:   Flags to modify subprocess behaviour.
    3872                 :            :  *
    3873                 :            :  * Respawns the test program to run only @test_path in a subprocess.
    3874                 :            :  *
    3875                 :            :  * This is equivalent to calling g_test_trap_subprocess_with_envp() with `envp`
    3876                 :            :  * set to %NULL. See the documentation for that function for full details.
    3877                 :            :  *
    3878                 :            :  * Since: 2.38
    3879                 :            :  */
    3880                 :            : void
    3881                 :        337 : g_test_trap_subprocess (const char           *test_path,
    3882                 :            :                         guint64               usec_timeout,
    3883                 :            :                         GTestSubprocessFlags  test_flags)
    3884                 :            : {
    3885                 :        337 :   g_test_trap_subprocess_with_envp (test_path, NULL, usec_timeout, test_flags);
    3886                 :        337 : }
    3887                 :            : 
    3888                 :            : /**
    3889                 :            :  * g_test_trap_subprocess_with_envp:
    3890                 :            :  * @test_path: (nullable): Test to run in a subprocess
    3891                 :            :  * @envp: (array zero-terminated=1) (nullable) (element-type filename): Environment
    3892                 :            :  *   to run the test in, or %NULL to inherit the parent’s environment. This must
    3893                 :            :  *   be in the GLib filename encoding.
    3894                 :            :  * @usec_timeout: Timeout for the subprocess test in micro seconds.
    3895                 :            :  * @test_flags:   Flags to modify subprocess behaviour.
    3896                 :            :  *
    3897                 :            :  * Respawns the test program to run only @test_path in a subprocess with the
    3898                 :            :  * given @envp environment.
    3899                 :            :  *
    3900                 :            :  * This can be used for a test case that might not return, or that
    3901                 :            :  * might abort.
    3902                 :            :  *
    3903                 :            :  * If @test_path is %NULL then the same test is re-run in a subprocess.
    3904                 :            :  * You can use g_test_subprocess() to determine whether the test is in
    3905                 :            :  * a subprocess or not.
    3906                 :            :  *
    3907                 :            :  * @test_path can also be the name of the parent test, followed by
    3908                 :            :  * "`/subprocess/`" and then a name for the specific subtest (or just
    3909                 :            :  * ending with "`/subprocess`" if the test only has one child test);
    3910                 :            :  * tests with names of this form will automatically be skipped in the
    3911                 :            :  * parent process.
    3912                 :            :  *
    3913                 :            :  * If @envp is %NULL, the parent process’ environment will be inherited.
    3914                 :            :  *
    3915                 :            :  * If @usec_timeout is non-0, the test subprocess is aborted and
    3916                 :            :  * considered failing if its run time exceeds it.
    3917                 :            :  *
    3918                 :            :  * The subprocess behavior can be configured with the
    3919                 :            :  * #GTestSubprocessFlags flags.
    3920                 :            :  *
    3921                 :            :  * You can use methods such as g_test_trap_assert_passed(),
    3922                 :            :  * g_test_trap_assert_failed(), and g_test_trap_assert_stderr() to
    3923                 :            :  * check the results of the subprocess. (But note that
    3924                 :            :  * g_test_trap_assert_stdout() and g_test_trap_assert_stderr()
    3925                 :            :  * cannot be used if @test_flags specifies that the child should
    3926                 :            :  * inherit the parent stdout/stderr.) 
    3927                 :            :  *
    3928                 :            :  * If your `main ()` needs to behave differently in
    3929                 :            :  * the subprocess, you can call g_test_subprocess() (after calling
    3930                 :            :  * g_test_init()) to see whether you are in a subprocess.
    3931                 :            :  *
    3932                 :            :  * Internally, this function tracks the child process using
    3933                 :            :  * g_child_watch_source_new(), so your process must not ignore `SIGCHLD`, and
    3934                 :            :  * must not attempt to watch or wait for the child process via another
    3935                 :            :  * mechanism.
    3936                 :            :  *
    3937                 :            :  * The following example tests that calling
    3938                 :            :  * `my_object_new(1000000)` will abort with an error
    3939                 :            :  * message.
    3940                 :            :  *
    3941                 :            :  * |[<!-- language="C" --> 
    3942                 :            :  *   static void
    3943                 :            :  *   test_create_large_object (void)
    3944                 :            :  *   {
    3945                 :            :  *     if (g_test_subprocess ())
    3946                 :            :  *       {
    3947                 :            :  *         my_object_new (1000000);
    3948                 :            :  *         return;
    3949                 :            :  *       }
    3950                 :            :  *
    3951                 :            :  *     // Reruns this same test in a subprocess
    3952                 :            :  *     g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
    3953                 :            :  *     g_test_trap_assert_failed ();
    3954                 :            :  *     g_test_trap_assert_stderr ("*ERROR*too large*");
    3955                 :            :  *   }
    3956                 :            :  *
    3957                 :            :  *   static void
    3958                 :            :  *   test_different_username (void)
    3959                 :            :  *   {
    3960                 :            :  *     if (g_test_subprocess ())
    3961                 :            :  *       {
    3962                 :            :  *         // Code under test goes here
    3963                 :            :  *         g_message ("Username is now simulated as %s", g_getenv ("USER"));
    3964                 :            :  *         return;
    3965                 :            :  *       }
    3966                 :            :  *
    3967                 :            :  *     // Reruns this same test in a subprocess
    3968                 :            :  *     g_autoptr(GStrv) envp = g_get_environ ();
    3969                 :            :  *     envp = g_environ_setenv (g_steal_pointer (&envp), "USER", "charlie", TRUE);
    3970                 :            :  *     g_test_trap_subprocess_with_envp (NULL, envp, 0, G_TEST_SUBPROCESS_DEFAULT);
    3971                 :            :  *     g_test_trap_assert_passed ();
    3972                 :            :  *     g_test_trap_assert_stdout ("Username is now simulated as charlie");
    3973                 :            :  *   }
    3974                 :            :  *
    3975                 :            :  *   int
    3976                 :            :  *   main (int argc, char **argv)
    3977                 :            :  *   {
    3978                 :            :  *     g_test_init (&argc, &argv, NULL);
    3979                 :            :  *
    3980                 :            :  *     g_test_add_func ("/myobject/create-large-object",
    3981                 :            :  *                      test_create_large_object);
    3982                 :            :  *     g_test_add_func ("/myobject/different-username",
    3983                 :            :  *                      test_different_username);
    3984                 :            :  *     return g_test_run ();
    3985                 :            :  *   }
    3986                 :            :  * ]|
    3987                 :            :  *
    3988                 :            :  * Since: 2.80
    3989                 :            :  */
    3990                 :            : void
    3991                 :        343 : g_test_trap_subprocess_with_envp (const char           *test_path,
    3992                 :            :                                   const char * const   *envp,
    3993                 :            :                                   guint64               usec_timeout,
    3994                 :            :                                   GTestSubprocessFlags  test_flags)
    3995                 :            : {
    3996                 :        343 :   GError *error = NULL;
    3997                 :            :   GPtrArray *argv;
    3998                 :            :   GSpawnFlags flags;
    3999                 :            :   int stdout_fd, stderr_fd;
    4000                 :            :   GPid pid;
    4001                 :            : 
    4002                 :            :   /* Sanity check that they used GTestSubprocessFlags, not GTestTrapFlags */
    4003                 :        343 :   g_assert ((test_flags & (G_TEST_TRAP_INHERIT_STDIN | G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) == 0);
    4004                 :            : 
    4005         [ +  + ]:        343 :   if (test_path)
    4006                 :            :     {
    4007         [ -  + ]:        223 :       if (!g_test_suite_case_exists (g_test_get_root (), test_path))
    4008                 :          0 :         g_error ("g_test_trap_subprocess: test does not exist: %s", test_path);
    4009                 :            :     }
    4010                 :            :   else
    4011                 :            :     {
    4012                 :        120 :       test_path = test_run_name;
    4013                 :            :     }
    4014                 :            : 
    4015         [ +  + ]:        343 :   if (g_test_verbose ())
    4016                 :            :     {
    4017         [ +  - ]:         36 :       if (test_tap_log)
    4018                 :         36 :         g_print ("subprocess: %s\n", test_path);
    4019                 :            :       else
    4020                 :          0 :         g_print ("GTest: subprocess: %s\n", test_path);
    4021                 :            :     }
    4022                 :            : 
    4023                 :        343 :   test_trap_clear ();
    4024                 :        343 :   test_trap_last_subprocess = g_strdup (test_path);
    4025                 :            : 
    4026         [ -  + ]:        343 :   if (test_argv0 == NULL)
    4027                 :          0 :     g_error ("g_test_trap_subprocess() requires argv0 to be passed to g_test_init()");
    4028                 :            : 
    4029                 :        343 :   argv = g_ptr_array_new ();
    4030                 :        343 :   g_ptr_array_add (argv, (char *) test_argv0);
    4031                 :        343 :   g_ptr_array_add (argv, "-q");
    4032                 :        343 :   g_ptr_array_add (argv, "-p");
    4033                 :        343 :   g_ptr_array_add (argv, (char *)test_path);
    4034                 :        343 :   g_ptr_array_add (argv, "--GTestSubprocess");
    4035         [ -  + ]:        343 :   if (test_log_fd != -1)
    4036                 :            :     {
    4037                 :            :       char log_fd_buf[128];
    4038                 :            : 
    4039                 :          0 :       g_ptr_array_add (argv, "--GTestLogFD");
    4040                 :          0 :       g_snprintf (log_fd_buf, sizeof (log_fd_buf), "%d", test_log_fd);
    4041                 :          0 :       g_ptr_array_add (argv, log_fd_buf);
    4042                 :            :     }
    4043                 :        343 :   g_ptr_array_add (argv, NULL);
    4044                 :            : 
    4045                 :        343 :   flags = G_SPAWN_DO_NOT_REAP_CHILD;
    4046         [ -  + ]:        343 :   if (test_log_fd != -1)
    4047                 :          0 :     flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
    4048         [ -  + ]:        343 :   if (test_flags & G_TEST_TRAP_INHERIT_STDIN)
    4049                 :          0 :     flags |= G_SPAWN_CHILD_INHERITS_STDIN;
    4050                 :            : 
    4051         [ -  + ]:        343 :   if (!g_spawn_async_with_pipes (test_initial_cwd,
    4052                 :        343 :                                  (char **)argv->pdata,
    4053                 :            :                                  (char **) envp, flags,
    4054                 :            :                                  NULL, NULL,
    4055                 :            :                                  &pid, NULL, &stdout_fd, &stderr_fd,
    4056                 :            :                                  &error))
    4057                 :            :     {
    4058                 :          0 :       g_error ("g_test_trap_subprocess() failed: %s",
    4059                 :            :                error->message);
    4060                 :            :     }
    4061                 :        343 :   g_ptr_array_free (argv, TRUE);
    4062                 :            : 
    4063                 :        343 :   wait_for_child (pid,
    4064                 :        343 :                   stdout_fd, !!(test_flags & G_TEST_SUBPROCESS_INHERIT_STDOUT),
    4065                 :        343 :                   stderr_fd, !!(test_flags & G_TEST_SUBPROCESS_INHERIT_STDERR),
    4066                 :            :                   usec_timeout);
    4067                 :        343 : }
    4068                 :            : 
    4069                 :            : /**
    4070                 :            :  * g_test_subprocess:
    4071                 :            :  *
    4072                 :            :  * Returns %TRUE (after g_test_init() has been called) if the test
    4073                 :            :  * program is running under g_test_trap_subprocess().
    4074                 :            :  *
    4075                 :            :  * Returns: %TRUE if the test program is running under
    4076                 :            :  * g_test_trap_subprocess().
    4077                 :            :  *
    4078                 :            :  * Since: 2.38
    4079                 :            :  */
    4080                 :            : gboolean
    4081                 :        220 : g_test_subprocess (void)
    4082                 :            : {
    4083                 :        220 :   return test_in_subprocess;
    4084                 :            : }
    4085                 :            : 
    4086                 :            : /**
    4087                 :            :  * g_test_trap_has_passed:
    4088                 :            :  *
    4089                 :            :  * Check the result of the last g_test_trap_subprocess() call.
    4090                 :            :  *
    4091                 :            :  * Returns: %TRUE if the last test subprocess terminated successfully.
    4092                 :            :  *
    4093                 :            :  * Since: 2.16
    4094                 :            :  */
    4095                 :            : gboolean
    4096                 :        346 : g_test_trap_has_passed (void)
    4097                 :            : {
    4098                 :            : #ifdef G_OS_UNIX
    4099         [ +  + ]:        688 :   return (WIFEXITED (test_trap_last_status) &&
    4100         [ +  + ]:        342 :       WEXITSTATUS (test_trap_last_status) == 0);
    4101                 :            : #else
    4102                 :            :   return test_trap_last_status == 0;
    4103                 :            : #endif
    4104                 :            : }
    4105                 :            : 
    4106                 :            : /**
    4107                 :            :  * g_test_trap_reached_timeout:
    4108                 :            :  *
    4109                 :            :  * Check the result of the last g_test_trap_subprocess() call.
    4110                 :            :  *
    4111                 :            :  * Returns: %TRUE if the last test subprocess got killed due to a timeout.
    4112                 :            :  *
    4113                 :            :  * Since: 2.16
    4114                 :            :  */
    4115                 :            : gboolean
    4116                 :          1 : g_test_trap_reached_timeout (void)
    4117                 :            : {
    4118                 :            : #ifdef G_OS_UNIX
    4119         [ +  - ]:          2 :   return (WIFSIGNALED (test_trap_last_status) &&
    4120         [ +  - ]:          1 :       WTERMSIG (test_trap_last_status) == SIGALRM);
    4121                 :            : #else
    4122                 :            :   return test_trap_last_status == G_TEST_STATUS_TIMED_OUT;
    4123                 :            : #endif
    4124                 :            : }
    4125                 :            : 
    4126                 :            : static gboolean
    4127                 :          0 : log_child_output (const gchar *process_id)
    4128                 :            : {
    4129                 :            :   gchar *escaped;
    4130                 :            : 
    4131                 :            : #ifdef G_OS_UNIX
    4132         [ #  # ]:          0 :   if (WIFEXITED (test_trap_last_status)) /* normal exit */
    4133                 :            :     {
    4134         [ #  # ]:          0 :       if (WEXITSTATUS (test_trap_last_status) == 0)
    4135                 :          0 :         g_test_message ("child process (%s) exit status: 0 (success)",
    4136                 :            :             process_id);
    4137                 :            :       else
    4138                 :          0 :         g_test_message ("child process (%s) exit status: %d (error)",
    4139                 :          0 :             process_id, WEXITSTATUS (test_trap_last_status));
    4140                 :            :     }
    4141         [ #  # ]:          0 :   else if (WIFSIGNALED (test_trap_last_status) &&
    4142         [ #  # ]:          0 :       WTERMSIG (test_trap_last_status) == SIGALRM)
    4143                 :            :     {
    4144                 :          0 :       g_test_message ("child process (%s) timed out", process_id);
    4145                 :            :     }
    4146         [ #  # ]:          0 :   else if (WIFSIGNALED (test_trap_last_status))
    4147                 :            :     {
    4148                 :          0 :       const gchar *maybe_dumped_core = "";
    4149                 :            : 
    4150                 :            : #ifdef WCOREDUMP
    4151         [ #  # ]:          0 :       if (WCOREDUMP (test_trap_last_status))
    4152                 :          0 :         maybe_dumped_core = ", core dumped";
    4153                 :            : #endif
    4154                 :            : 
    4155                 :          0 :       g_test_message ("child process (%s) killed by signal %d (%s)%s",
    4156                 :            :           process_id, WTERMSIG (test_trap_last_status),
    4157                 :            :           g_strsignal (WTERMSIG (test_trap_last_status)),
    4158                 :            :           maybe_dumped_core);
    4159                 :            :     }
    4160                 :            :   else
    4161                 :            :     {
    4162                 :          0 :       g_test_message ("child process (%s) unknown wait status %d",
    4163                 :            :           process_id, test_trap_last_status);
    4164                 :            :     }
    4165                 :            : #else
    4166                 :            :   if (test_trap_last_status == 0)
    4167                 :            :     g_test_message ("child process (%s) exit status: 0 (success)",
    4168                 :            :         process_id);
    4169                 :            :   else
    4170                 :            :     g_test_message ("child process (%s) exit status: %d (error)",
    4171                 :            :         process_id, test_trap_last_status);
    4172                 :            : #endif
    4173                 :            : 
    4174                 :          0 :   escaped = g_strescape (test_trap_last_stdout, NULL);
    4175                 :          0 :   g_test_message ("child process (%s) stdout: \"%s\"", process_id, escaped);
    4176                 :          0 :   g_free (escaped);
    4177                 :            : 
    4178                 :          0 :   escaped = g_strescape (test_trap_last_stderr, NULL);
    4179                 :          0 :   g_test_message ("child process (%s) stderr: \"%s\"", process_id, escaped);
    4180                 :          0 :   g_free (escaped);
    4181                 :            : 
    4182                 :            :   /* so we can use short-circuiting:
    4183                 :            :    * logged_child_output = logged_child_output || log_child_output (...) */
    4184                 :          0 :   return TRUE;
    4185                 :            : }
    4186                 :            : 
    4187                 :            : void
    4188                 :        775 : g_test_trap_assertions (const char     *domain,
    4189                 :            :                         const char     *file,
    4190                 :            :                         int             line,
    4191                 :            :                         const char     *func,
    4192                 :            :                         guint64         assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */
    4193                 :            :                         const char     *pattern)
    4194                 :            : {
    4195                 :        775 :   gboolean must_pass = assertion_flags == 0;
    4196                 :        775 :   gboolean must_fail = assertion_flags == 1;
    4197                 :        775 :   gboolean match_result = 0 == (assertion_flags & 1);
    4198                 :        775 :   gboolean logged_child_output = FALSE;
    4199         [ +  + ]:        775 :   const char *stdout_pattern = (assertion_flags & 2) ? pattern : NULL;
    4200         [ +  + ]:        775 :   const char *stderr_pattern = (assertion_flags & 4) ? pattern : NULL;
    4201         [ +  + ]:        775 :   const char *match_error = match_result ? "failed to match" : "contains invalid match";
    4202                 :            :   char *process_id;
    4203                 :            : 
    4204                 :            : #ifdef G_OS_UNIX
    4205         [ +  + ]:        775 :   if (test_trap_last_subprocess != NULL)
    4206                 :            :     {
    4207                 :        769 :       process_id = g_strdup_printf ("%s [%d]", test_trap_last_subprocess,
    4208                 :            :                                     test_trap_last_pid);
    4209                 :            :     }
    4210         [ +  - ]:          6 :   else if (test_trap_last_pid != 0)
    4211                 :          6 :     process_id = g_strdup_printf ("%d", test_trap_last_pid);
    4212                 :            : #else
    4213                 :            :   if (test_trap_last_subprocess != NULL)
    4214                 :            :     process_id = g_strdup (test_trap_last_subprocess);
    4215                 :            : #endif
    4216                 :            :   else
    4217                 :          0 :     g_error ("g_test_trap_ assertion with no trapped test");
    4218                 :            : 
    4219   [ +  +  -  + ]:        775 :   if (must_pass && !g_test_trap_has_passed())
    4220                 :            :     {
    4221                 :            :       char *msg;
    4222                 :            : 
    4223   [ #  #  #  # ]:          0 :       logged_child_output = logged_child_output || log_child_output (process_id);
    4224                 :            : 
    4225                 :          0 :       msg = g_strdup_printf ("child process (%s) failed unexpectedly", process_id);
    4226                 :          0 :       g_assertion_message (domain, file, line, func, msg);
    4227                 :          0 :       g_free (msg);
    4228                 :            :     }
    4229   [ +  +  -  + ]:        775 :   if (must_fail && g_test_trap_has_passed())
    4230                 :            :     {
    4231                 :            :       char *msg;
    4232                 :            : 
    4233   [ #  #  #  # ]:          0 :       logged_child_output = logged_child_output || log_child_output (process_id);
    4234                 :            : 
    4235                 :          0 :       msg = g_strdup_printf ("child process (%s) did not fail as expected", process_id);
    4236                 :          0 :       g_assertion_message (domain, file, line, func, msg);
    4237                 :          0 :       g_free (msg);
    4238                 :            :     }
    4239   [ +  +  -  + ]:        775 :   if (stdout_pattern && match_result == !g_pattern_match_simple (stdout_pattern, test_trap_last_stdout))
    4240                 :            :     {
    4241                 :            :       char *msg;
    4242                 :            : 
    4243   [ #  #  #  # ]:          0 :       logged_child_output = logged_child_output || log_child_output (process_id);
    4244                 :            : 
    4245                 :          0 :       g_test_message ("stdout was:\n%s", test_trap_last_stdout);
    4246                 :            : 
    4247                 :          0 :       msg = g_strdup_printf ("stdout of child process (%s) %s: %s",
    4248                 :            :                              process_id, match_error, stdout_pattern);
    4249                 :          0 :       g_assertion_message (domain, file, line, func, msg);
    4250                 :          0 :       g_free (msg);
    4251                 :            :     }
    4252   [ +  +  -  + ]:        775 :   if (stderr_pattern && match_result == !g_pattern_match_simple (stderr_pattern, test_trap_last_stderr))
    4253                 :            :     {
    4254                 :            :       char *msg;
    4255                 :            : 
    4256   [ #  #  #  # ]:          0 :       logged_child_output = logged_child_output || log_child_output (process_id);
    4257                 :            : 
    4258                 :          0 :       g_test_message ("stderr was:\n%s", test_trap_last_stderr);
    4259                 :            : 
    4260                 :          0 :       msg = g_strdup_printf ("stderr of child process (%s) %s: %s",
    4261                 :            :                              process_id, match_error, stderr_pattern);
    4262                 :          0 :       g_assertion_message (domain, file, line, func, msg);
    4263                 :          0 :       g_free (msg);
    4264                 :            :     }
    4265                 :            : 
    4266                 :            :   (void) logged_child_output;  /* shut up scan-build about the final unread assignment */
    4267                 :            : 
    4268                 :        775 :   g_free (process_id);
    4269                 :        775 : }
    4270                 :            : 
    4271                 :            : static void
    4272                 :      32168 : gstring_overwrite_int (GString *gstring,
    4273                 :            :                        guint    pos,
    4274                 :            :                        guint32  vuint)
    4275                 :            : {
    4276                 :      32168 :   vuint = g_htonl (vuint);
    4277                 :      32168 :   g_string_overwrite_len (gstring, pos, (const gchar*) &vuint, 4);
    4278                 :      32168 : }
    4279                 :            : 
    4280                 :            : static void
    4281                 :     193742 : gstring_append_int (GString *gstring,
    4282                 :            :                     guint32  vuint)
    4283                 :            : {
    4284         [ -  + ]:     193742 :   vuint = g_htonl (vuint);
    4285                 :            :   g_string_append_len (gstring, (const gchar*) &vuint, 4);
    4286                 :     193742 : }
    4287                 :            : 
    4288                 :            : static void
    4289                 :      20771 : gstring_append_double (GString *gstring,
    4290                 :            :                        double   vdouble)
    4291                 :            : {
    4292                 :            :   union { double vdouble; guint64 vuint64; } u;
    4293                 :      20771 :   u.vdouble = vdouble;
    4294         [ -  + ]:      20771 :   u.vuint64 = GUINT64_TO_BE (u.vuint64);
    4295                 :            :   g_string_append_len (gstring, (const gchar*) &u.vuint64, 8);
    4296                 :      20771 : }
    4297                 :            : 
    4298                 :            : static guint8*
    4299                 :      32168 : g_test_log_dump (GTestLogMsg *msg,
    4300                 :            :                  guint       *len)
    4301                 :            : {
    4302                 :      32168 :   GString *gstring = g_string_sized_new (1024);
    4303                 :            :   guint ui;
    4304                 :      32168 :   gstring_append_int (gstring, 0);              /* message length */
    4305                 :      32168 :   gstring_append_int (gstring, msg->log_type);
    4306                 :      32168 :   gstring_append_int (gstring, msg->n_strings);
    4307                 :      32168 :   gstring_append_int (gstring, msg->n_nums);
    4308                 :      32168 :   gstring_append_int (gstring, 0);      /* reserved */
    4309         [ +  + ]:      65070 :   for (ui = 0; ui < msg->n_strings; ui++)
    4310                 :            :     {
    4311                 :      32902 :       guint l = strlen (msg->strings[ui]);
    4312                 :      32902 :       gstring_append_int (gstring, l);
    4313         [ -  + ]:      32902 :       g_string_append_len (gstring, msg->strings[ui], l);
    4314                 :            :     }
    4315         [ +  + ]:      52939 :   for (ui = 0; ui < msg->n_nums; ui++)
    4316                 :      20771 :     gstring_append_double (gstring, msg->nums[ui]);
    4317                 :      32168 :   *len = gstring->len;
    4318                 :      32168 :   gstring_overwrite_int (gstring, 0, *len);     /* message length */
    4319                 :      32168 :   return (guint8*) g_string_free (gstring, FALSE);
    4320                 :            : }
    4321                 :            : 
    4322                 :            : static inline long double
    4323                 :         12 : net_double (const gchar **ipointer)
    4324                 :            : {
    4325                 :            :   union { guint64 vuint64; double vdouble; } u;
    4326                 :            :   guint64 aligned_int64;
    4327                 :         12 :   memcpy (&aligned_int64, *ipointer, 8);
    4328                 :         12 :   *ipointer += 8;
    4329                 :         12 :   u.vuint64 = GUINT64_FROM_BE (aligned_int64);
    4330                 :         12 :   return u.vdouble;
    4331                 :            : }
    4332                 :            : 
    4333                 :            : static inline guint32
    4334                 :        401 : net_int (const gchar **ipointer)
    4335                 :            : {
    4336                 :            :   guint32 aligned_int;
    4337                 :        401 :   memcpy (&aligned_int, *ipointer, 4);
    4338                 :        401 :   *ipointer += 4;
    4339                 :        401 :   return g_ntohl (aligned_int);
    4340                 :            : }
    4341                 :            : 
    4342                 :            : static gboolean
    4343                 :         78 : g_test_log_extract (GTestLogBuffer *tbuffer)
    4344                 :            : {
    4345                 :         78 :   const gchar *p = tbuffer->data->str;
    4346                 :            :   GTestLogMsg msg;
    4347                 :            :   guint mlength;
    4348         [ +  + ]:         78 :   if (tbuffer->data->len < 4 * 5)
    4349                 :         12 :     return FALSE;
    4350                 :         66 :   mlength = net_int (&p);
    4351         [ -  + ]:         66 :   if (tbuffer->data->len < mlength)
    4352                 :          0 :     return FALSE;
    4353                 :         66 :   msg.log_type = net_int (&p);
    4354                 :         66 :   msg.n_strings = net_int (&p);
    4355                 :         66 :   msg.n_nums = net_int (&p);
    4356         [ +  - ]:         66 :   if (net_int (&p) == 0)
    4357                 :            :     {
    4358                 :            :       guint ui;
    4359                 :         66 :       msg.strings = g_new0 (gchar*, msg.n_strings + 1);
    4360                 :         66 :       msg.nums = g_new0 (long double, msg.n_nums);
    4361         [ +  + ]:        137 :       for (ui = 0; ui < msg.n_strings; ui++)
    4362                 :            :         {
    4363                 :         71 :           guint sl = net_int (&p);
    4364                 :         71 :           msg.strings[ui] = g_strndup (p, sl);
    4365                 :         71 :           p += sl;
    4366                 :            :         }
    4367         [ +  + ]:         78 :       for (ui = 0; ui < msg.n_nums; ui++)
    4368                 :         12 :         msg.nums[ui] = net_double (&p);
    4369         [ +  - ]:         66 :       if (p <= tbuffer->data->str + mlength)
    4370                 :            :         {
    4371                 :         66 :           g_string_erase (tbuffer->data, 0, mlength);
    4372                 :         66 :           tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg)));
    4373                 :         66 :           return TRUE;
    4374                 :            :         }
    4375                 :            : 
    4376                 :          0 :       g_free (msg.nums);
    4377                 :          0 :       g_strfreev (msg.strings);
    4378                 :            :     }
    4379                 :            : 
    4380                 :          0 :   g_error ("corrupt log stream from test program");
    4381                 :            :   return FALSE;
    4382                 :            : }
    4383                 :            : 
    4384                 :            : /**
    4385                 :            :  * g_test_log_buffer_new:
    4386                 :            :  *
    4387                 :            :  * Internal function for gtester to decode test log messages, no ABI guarantees provided.
    4388                 :            :  */
    4389                 :            : GTestLogBuffer*
    4390                 :          5 : g_test_log_buffer_new (void)
    4391                 :            : {
    4392                 :          5 :   GTestLogBuffer *tb = g_new0 (GTestLogBuffer, 1);
    4393                 :          5 :   tb->data = g_string_sized_new (1024);
    4394                 :          5 :   return tb;
    4395                 :            : }
    4396                 :            : 
    4397                 :            : /**
    4398                 :            :  * g_test_log_buffer_free:
    4399                 :            :  *
    4400                 :            :  * Internal function for gtester to free test log messages, no ABI guarantees provided.
    4401                 :            :  */
    4402                 :            : void
    4403                 :          5 : g_test_log_buffer_free (GTestLogBuffer *tbuffer)
    4404                 :            : {
    4405                 :          5 :   g_return_if_fail (tbuffer != NULL);
    4406         [ -  + ]:          5 :   while (tbuffer->msgs)
    4407                 :          0 :     g_test_log_msg_free (g_test_log_buffer_pop (tbuffer));
    4408                 :          5 :   g_string_free (tbuffer->data, TRUE);
    4409                 :          5 :   g_free (tbuffer);
    4410                 :            : }
    4411                 :            : 
    4412                 :            : /**
    4413                 :            :  * g_test_log_buffer_push:
    4414                 :            :  *
    4415                 :            :  * Internal function for gtester to decode test log messages, no ABI guarantees provided.
    4416                 :            :  */
    4417                 :            : void
    4418                 :         12 : g_test_log_buffer_push (GTestLogBuffer *tbuffer,
    4419                 :            :                         guint           n_bytes,
    4420                 :            :                         const guint8   *bytes)
    4421                 :            : {
    4422                 :         12 :   g_return_if_fail (tbuffer != NULL);
    4423         [ +  - ]:         12 :   if (n_bytes)
    4424                 :            :     {
    4425                 :            :       gboolean more_messages;
    4426                 :         12 :       g_return_if_fail (bytes != NULL);
    4427         [ -  + ]:         12 :       g_string_append_len (tbuffer->data, (const gchar*) bytes, n_bytes);
    4428                 :            :       do
    4429                 :         78 :         more_messages = g_test_log_extract (tbuffer);
    4430         [ +  + ]:         78 :       while (more_messages);
    4431                 :            :     }
    4432                 :            : }
    4433                 :            : 
    4434                 :            : /**
    4435                 :            :  * g_test_log_buffer_pop:
    4436                 :            :  *
    4437                 :            :  * Internal function for gtester to retrieve test log messages, no ABI guarantees provided.
    4438                 :            :  */
    4439                 :            : GTestLogMsg*
    4440                 :         71 : g_test_log_buffer_pop (GTestLogBuffer *tbuffer)
    4441                 :            : {
    4442                 :         71 :   GTestLogMsg *msg = NULL;
    4443                 :         71 :   g_return_val_if_fail (tbuffer != NULL, NULL);
    4444         [ +  + ]:         71 :   if (tbuffer->msgs)
    4445                 :            :     {
    4446                 :         66 :       GSList *slist = g_slist_last (tbuffer->msgs);
    4447                 :         66 :       msg = slist->data;
    4448                 :         66 :       tbuffer->msgs = g_slist_delete_link (tbuffer->msgs, slist);
    4449                 :            :     }
    4450                 :         71 :   return msg;
    4451                 :            : }
    4452                 :            : 
    4453                 :            : /**
    4454                 :            :  * g_test_log_msg_free:
    4455                 :            :  *
    4456                 :            :  * Internal function for gtester to free test log messages, no ABI guarantees provided.
    4457                 :            :  */
    4458                 :            : void
    4459                 :         66 : g_test_log_msg_free (GTestLogMsg *tmsg)
    4460                 :            : {
    4461                 :         66 :   g_return_if_fail (tmsg != NULL);
    4462                 :         66 :   g_strfreev (tmsg->strings);
    4463                 :         66 :   g_free (tmsg->nums);
    4464                 :         66 :   g_free (tmsg);
    4465                 :            : }
    4466                 :            : 
    4467                 :            : static gchar *
    4468                 :        743 : g_test_build_filename_va (GTestFileType  file_type,
    4469                 :            :                           const gchar   *first_path,
    4470                 :            :                           va_list        ap)
    4471                 :            : {
    4472                 :            :   const gchar *pathv[16];
    4473                 :            :   gsize num_path_segments;
    4474                 :            : 
    4475         [ +  + ]:        743 :   if (file_type == G_TEST_DIST)
    4476                 :        378 :     pathv[0] = test_disted_files_dir;
    4477         [ +  - ]:        365 :   else if (file_type == G_TEST_BUILT)
    4478                 :        365 :     pathv[0] = test_built_files_dir;
    4479                 :            :   else
    4480                 :            :     g_assert_not_reached ();
    4481                 :            : 
    4482                 :        743 :   pathv[1] = first_path;
    4483                 :            : 
    4484         [ +  - ]:       1134 :   for (num_path_segments = 2; num_path_segments < G_N_ELEMENTS (pathv); num_path_segments++)
    4485                 :            :     {
    4486                 :       1134 :       pathv[num_path_segments] = va_arg (ap, const char *);
    4487         [ +  + ]:       1134 :       if (pathv[num_path_segments] == NULL)
    4488                 :        743 :         break;
    4489                 :            :     }
    4490                 :            : 
    4491                 :        743 :   g_assert_cmpint (num_path_segments, <, G_N_ELEMENTS (pathv));
    4492                 :            : 
    4493                 :        743 :   return g_build_filenamev ((gchar **) pathv);
    4494                 :            : }
    4495                 :            : 
    4496                 :            : /**
    4497                 :            :  * g_test_build_filename:
    4498                 :            :  * @file_type: the type of file (built vs. distributed)
    4499                 :            :  * @first_path: the first segment of the pathname
    4500                 :            :  * @...: %NULL-terminated additional path segments
    4501                 :            :  *
    4502                 :            :  * Creates the pathname to a data file that is required for a test.
    4503                 :            :  *
    4504                 :            :  * This function is conceptually similar to g_build_filename() except
    4505                 :            :  * that the first argument has been replaced with a #GTestFileType
    4506                 :            :  * argument.
    4507                 :            :  *
    4508                 :            :  * The data file should either have been distributed with the module
    4509                 :            :  * containing the test (%G_TEST_DIST) or built as part of the build
    4510                 :            :  * system of that module (%G_TEST_BUILT).
    4511                 :            :  *
    4512                 :            :  * In order for this function to work in srcdir != builddir situations,
    4513                 :            :  * the G_TEST_SRCDIR and G_TEST_BUILDDIR environment variables need to
    4514                 :            :  * have been defined.  As of 2.38, this is done by the glib.mk
    4515                 :            :  * included in GLib.  Please ensure that your copy is up to date before
    4516                 :            :  * using this function.
    4517                 :            :  *
    4518                 :            :  * In case neither variable is set, this function will fall back to
    4519                 :            :  * using the dirname portion of argv[0], possibly removing ".libs".
    4520                 :            :  * This allows for casual running of tests directly from the commandline
    4521                 :            :  * in the srcdir == builddir case and should also support running of
    4522                 :            :  * installed tests, assuming the data files have been installed in the
    4523                 :            :  * same relative path as the test binary.
    4524                 :            :  *
    4525                 :            :  * Returns: the path of the file, to be freed using g_free()
    4526                 :            :  *
    4527                 :            :  * Since: 2.38
    4528                 :            :  **/
    4529                 :            : /**
    4530                 :            :  * GTestFileType:
    4531                 :            :  * @G_TEST_DIST: a file that was included in the distribution tarball
    4532                 :            :  * @G_TEST_BUILT: a file that was built on the compiling machine
    4533                 :            :  *
    4534                 :            :  * The type of file to return the filename for, when used with
    4535                 :            :  * g_test_build_filename().
    4536                 :            :  *
    4537                 :            :  * These two options correspond rather directly to the 'dist' and
    4538                 :            :  * 'built' terminology that automake uses and are explicitly used to
    4539                 :            :  * distinguish between the 'srcdir' and 'builddir' being separate.  All
    4540                 :            :  * files in your project should either be dist (in the
    4541                 :            :  * `EXTRA_DIST` or `dist_schema_DATA`
    4542                 :            :  * sense, in which case they will always be in the srcdir) or built (in
    4543                 :            :  * the `BUILT_SOURCES` sense, in which case they will
    4544                 :            :  * always be in the builddir).
    4545                 :            :  *
    4546                 :            :  * Note: as a general rule of automake, files that are generated only as
    4547                 :            :  * part of the build-from-git process (but then are distributed with the
    4548                 :            :  * tarball) always go in srcdir (even if doing a srcdir != builddir
    4549                 :            :  * build from git) and are considered as distributed files.
    4550                 :            :  *
    4551                 :            :  * Since: 2.38
    4552                 :            :  **/
    4553                 :            : gchar *
    4554                 :        615 : g_test_build_filename (GTestFileType  file_type,
    4555                 :            :                        const gchar   *first_path,
    4556                 :            :                        ...)
    4557                 :            : {
    4558                 :            :   gchar *result;
    4559                 :            :   va_list ap;
    4560                 :            : 
    4561                 :        615 :   g_assert (g_test_initialized ());
    4562                 :            : 
    4563                 :        615 :   va_start (ap, first_path);
    4564                 :        615 :   result = g_test_build_filename_va (file_type, first_path, ap);
    4565                 :        615 :   va_end (ap);
    4566                 :            : 
    4567                 :        615 :   return result;
    4568                 :            : }
    4569                 :            : 
    4570                 :            : /**
    4571                 :            :  * g_test_get_dir:
    4572                 :            :  * @file_type: the type of file (built vs. distributed)
    4573                 :            :  *
    4574                 :            :  * Gets the pathname of the directory containing test files of the type
    4575                 :            :  * specified by @file_type.
    4576                 :            :  *
    4577                 :            :  * This is approximately the same as calling g_test_build_filename("."),
    4578                 :            :  * but you don't need to free the return value.
    4579                 :            :  *
    4580                 :            :  * Returns: (type filename): the path of the directory, owned by GLib
    4581                 :            :  *
    4582                 :            :  * Since: 2.38
    4583                 :            :  **/
    4584                 :            : const gchar *
    4585                 :         24 : g_test_get_dir (GTestFileType file_type)
    4586                 :            : {
    4587                 :         24 :   g_assert (g_test_initialized ());
    4588                 :            : 
    4589         [ +  + ]:         24 :   if (file_type == G_TEST_DIST)
    4590                 :          6 :     return test_disted_files_dir;
    4591         [ +  - ]:         18 :   else if (file_type == G_TEST_BUILT)
    4592                 :         18 :     return test_built_files_dir;
    4593                 :            : 
    4594                 :            :   g_assert_not_reached ();
    4595                 :            : }
    4596                 :            : 
    4597                 :            : /**
    4598                 :            :  * g_test_get_filename:
    4599                 :            :  * @file_type: the type of file (built vs. distributed)
    4600                 :            :  * @first_path: the first segment of the pathname
    4601                 :            :  * @...: %NULL-terminated additional path segments
    4602                 :            :  *
    4603                 :            :  * Gets the pathname to a data file that is required for a test.
    4604                 :            :  *
    4605                 :            :  * This is the same as g_test_build_filename() with two differences.
    4606                 :            :  * The first difference is that you must only use this function from within
    4607                 :            :  * a testcase function.  The second difference is that you need not free
    4608                 :            :  * the return value — it will be automatically freed when the testcase
    4609                 :            :  * finishes running.
    4610                 :            :  *
    4611                 :            :  * It is safe to use this function from a thread inside of a testcase
    4612                 :            :  * but you must ensure that all such uses occur before the main testcase
    4613                 :            :  * function returns (ie: it is best to ensure that all threads have been
    4614                 :            :  * joined).
    4615                 :            :  *
    4616                 :            :  * Returns: the path, automatically freed at the end of the testcase
    4617                 :            :  *
    4618                 :            :  * Since: 2.38
    4619                 :            :  **/
    4620                 :            : const gchar *
    4621                 :        128 : g_test_get_filename (GTestFileType  file_type,
    4622                 :            :                      const gchar   *first_path,
    4623                 :            :                      ...)
    4624                 :            : {
    4625                 :            :   gchar *result;
    4626                 :            :   GSList *node;
    4627                 :            :   va_list ap;
    4628                 :            : 
    4629                 :        128 :   g_assert (g_test_initialized ());
    4630         [ -  + ]:        128 :   if (test_filename_free_list == NULL)
    4631                 :          0 :     g_error ("g_test_get_filename() can only be used within testcase functions");
    4632                 :            : 
    4633                 :        128 :   va_start (ap, first_path);
    4634                 :        128 :   result = g_test_build_filename_va (file_type, first_path, ap);
    4635                 :        128 :   va_end (ap);
    4636                 :            : 
    4637                 :        128 :   node = g_slist_prepend (NULL, result);
    4638                 :            :   do
    4639                 :        128 :     node->next = *test_filename_free_list;
    4640         [ -  + ]:        128 :   while (!g_atomic_pointer_compare_and_exchange (test_filename_free_list, node->next, node));
    4641                 :            : 
    4642                 :        128 :   return result;
    4643                 :            : }
    4644                 :            : 
    4645                 :            : /**
    4646                 :            :  * g_test_get_path:
    4647                 :            :  *
    4648                 :            :  * Gets the test path for the test currently being run.
    4649                 :            :  *
    4650                 :            :  * In essence, it will be the same string passed as the first argument to
    4651                 :            :  * e.g. g_test_add() when the test was added.
    4652                 :            :  *
    4653                 :            :  * This function returns a valid string only within a test function.
    4654                 :            :  *
    4655                 :            :  * Note that this is a test path, not a file system path.
    4656                 :            :  *
    4657                 :            :  * Returns: the test path for the test currently being run
    4658                 :            :  *
    4659                 :            :  * Since: 2.68
    4660                 :            :  **/
    4661                 :            : const char *
    4662                 :         10 : g_test_get_path (void)
    4663                 :            : {
    4664                 :         10 :   return test_run_name;
    4665                 :            : }

Generated by: LCOV version 1.14