LCOV - code coverage report
Current view: top level - glib/glib/tests - protocol.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 152 168 90.5 %
Date: 2024-04-23 05:16:05 Functions: 12 12 100.0 %
Branches: 29 41 70.7 %

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

Generated by: LCOV version 1.14