LCOV - code coverage report
Current view: top level - glib - gtestutils.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 81.7 % 1472 1203
Test Date: 2026-02-10 05:15:13 Functions: 93.3 % 104 97
Branches: - 0 0

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

Generated by: LCOV version 2.0-1