LCOV - code coverage report
Current view: top level - egg - egg-testing.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 72.4 % 127 92
Test Date: 2024-12-15 20:37:51 Functions: 73.3 % 15 11

            Line data    Source code
       1              : /*
       2              :  * gnome-keyring
       3              :  *
       4              :  * Copyright (C) 2011 Collabora Ltd.
       5              :  *
       6              :  * This program is free software; you can redistribute it and/or modify
       7              :  * it under the terms of the GNU Lesser General Public License as
       8              :  * published by the Free Software Foundation; either version 2.1 of
       9              :  * the License, or (at your option) any later version.
      10              :  *
      11              :  * This program is distributed in the hope that it will be useful, but
      12              :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              :  *
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this program; if not, see
      18              :  * <http://www.gnu.org/licenses/>.
      19              :  *
      20              :  * Stef Walter <stefw@collabora.co.uk>
      21              :  */
      22              : 
      23              : #include "config.h"
      24              : 
      25              : #include "egg-testing.h"
      26              : 
      27              : #include <glib/gstdio.h>
      28              : 
      29              : #include <errno.h>
      30              : #include <unistd.h>
      31              : 
      32              : static const char HEXC[] = "0123456789ABCDEF";
      33              : 
      34              : static gchar*
      35            0 : hex_dump (const guchar *data, gsize n_data)
      36              : {
      37              :         GString *result;
      38              :         gsize i;
      39              :         guchar j;
      40              : 
      41            0 :         g_assert (data);
      42              : 
      43            0 :         result = g_string_sized_new (n_data * 2 + 1);
      44            0 :         for (i = 0; i < n_data; ++i) {
      45            0 :                 g_string_append (result, "\\x");
      46              : 
      47            0 :                 j = data[i] >> 4 & 0xf;
      48            0 :                 g_string_append_c (result, HEXC[j]);
      49            0 :                 j = data[i] & 0xf;
      50            0 :                 g_string_append_c (result, HEXC[j]);
      51              :         }
      52              : 
      53            0 :         return g_string_free (result, FALSE);
      54              : }
      55              : 
      56              : void
      57            0 : egg_assertion_message_cmpmem (const char     *domain,
      58              :                               const char     *file,
      59              :                               int             line,
      60              :                               const char     *func,
      61              :                               const char     *expr,
      62              :                               gconstpointer   arg1,
      63              :                               gsize           n_arg1,
      64              :                               const char     *cmp,
      65              :                               gconstpointer   arg2,
      66              :                               gsize           n_arg2)
      67              : {
      68              :   char *a1, *a2, *s;
      69            0 :   a1 = arg1 ? hex_dump (arg1, n_arg1) : g_strdup ("NULL");
      70            0 :   a2 = arg2 ? hex_dump (arg2, n_arg2) : g_strdup ("NULL");
      71            0 :   s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
      72            0 :   g_free (a1);
      73            0 :   g_free (a2);
      74            0 :   g_assertion_message (domain, file, line, func, s);
      75            0 :   g_free (s);
      76            0 : }
      77              : 
      78              : static void (*wait_stop_impl) (void);
      79              : static gboolean (*wait_until_impl) (int timeout);
      80              : static gboolean wait_waiting = FALSE;
      81              : 
      82              : void
      83           54 : egg_test_wait_stop (void)
      84              : {
      85           54 :         g_assert (wait_stop_impl != NULL);
      86           54 :         (wait_stop_impl) ();
      87           54 : }
      88              : 
      89              : gboolean
      90           60 : egg_test_wait_until (int timeout)
      91              : {
      92           60 :         g_assert (wait_until_impl != NULL);
      93           60 :         return (wait_until_impl) (timeout);
      94              : }
      95              : 
      96              : static GCond wait_condition;
      97              : static GCond wait_start;
      98              : static GMutex wait_mutex;
      99              : 
     100              : static void
     101            0 : thread_wait_stop (void)
     102              : {
     103            0 :         g_mutex_lock (&wait_mutex);
     104              : 
     105            0 :         if (!wait_waiting) {
     106            0 :                 gint64 time = g_get_monotonic_time () + 1 * G_TIME_SPAN_SECOND;
     107            0 :                 g_cond_wait_until (&wait_start, &wait_mutex, time);
     108              :         }
     109            0 :         g_assert (wait_waiting);
     110              : 
     111            0 :         g_cond_broadcast (&wait_condition);
     112            0 :         g_mutex_unlock (&wait_mutex);
     113            0 : }
     114              : 
     115              : static gboolean
     116            6 : thread_wait_until (int timeout)
     117              : {
     118              :         gboolean ret;
     119              : 
     120            6 :         g_mutex_lock (&wait_mutex);
     121              : 
     122            6 :         g_assert (!wait_waiting);
     123            6 :         wait_waiting = TRUE;
     124              : 
     125              :         {
     126            6 :                 gint64 time = g_get_monotonic_time () + ((timeout + 1000) * G_TIME_SPAN_MILLISECOND);
     127            6 :                 g_cond_broadcast (&wait_start);
     128            6 :                 ret = g_cond_wait_until (&wait_start, &wait_mutex, time);
     129              :         }
     130              : 
     131            6 :         g_assert (wait_waiting);
     132            6 :         wait_waiting = FALSE;
     133            6 :         g_mutex_unlock (&wait_mutex);
     134              : 
     135            6 :         return ret;
     136              : }
     137              : 
     138              : static gpointer
     139           14 : testing_thread (gpointer loop)
     140              : {
     141              :         /* Must have been defined by the test including this file */
     142           14 :         gint ret = g_test_run ();
     143           14 :         g_main_loop_quit (loop);
     144           14 :         return GINT_TO_POINTER (ret);
     145              : }
     146              : 
     147              : gint
     148           14 : egg_tests_run_in_thread_with_loop (void)
     149              : {
     150              :         GThread *thread;
     151              :         GMainLoop *loop;
     152              :         gpointer ret;
     153              : 
     154           14 :         loop = g_main_loop_new (NULL, FALSE);
     155           14 :         g_cond_init (&wait_condition);
     156           14 :         g_cond_init (&wait_start);
     157           14 :         g_mutex_init (&wait_mutex);
     158              : 
     159           14 :         wait_stop_impl = thread_wait_stop;
     160           14 :         wait_until_impl = thread_wait_until;
     161              : 
     162           14 :         thread = g_thread_new ("testing", testing_thread, loop);
     163           14 :         g_assert (thread);
     164              : 
     165           14 :         g_main_loop_run (loop);
     166           14 :         ret = g_thread_join (thread);
     167           14 :         g_main_loop_unref (loop);
     168              : 
     169           14 :         g_cond_clear (&wait_condition);
     170           14 :         g_mutex_clear (&wait_mutex);
     171              : 
     172           14 :         return GPOINTER_TO_INT (ret);
     173              : }
     174              : 
     175              : static GMainLoop *wait_loop = NULL;
     176              : 
     177              : static void
     178           54 : loop_wait_stop (void)
     179              : {
     180           54 :         g_assert (wait_loop != NULL);
     181           54 :         g_main_loop_quit (wait_loop);
     182           54 : }
     183              : 
     184              : static gboolean
     185            0 : on_loop_wait_timeout (gpointer data)
     186              : {
     187            0 :         gboolean *timed_out = data;
     188            0 :         *timed_out = TRUE;
     189              : 
     190            0 :         g_assert (wait_loop != NULL);
     191            0 :         g_main_loop_quit (wait_loop);
     192              : 
     193            0 :         return TRUE; /* we remove this source later */
     194              : }
     195              : 
     196              : static gboolean
     197           54 : loop_wait_until (int timeout)
     198              : {
     199           54 :         gboolean timed_out = FALSE;
     200              :         guint source;
     201              : 
     202           54 :         g_assert (wait_loop == NULL);
     203           54 :         wait_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
     204              : 
     205           54 :         source = g_timeout_add (timeout, on_loop_wait_timeout, &timed_out);
     206              : 
     207           54 :         g_main_loop_run (wait_loop);
     208              : 
     209           54 :         g_source_remove (source);
     210           54 :         g_main_loop_unref (wait_loop);
     211           54 :         wait_loop = NULL;
     212           54 :         return !timed_out;
     213              : }
     214              : 
     215              : gint
     216            5 : egg_tests_run_with_loop (void)
     217              : {
     218              :         gint ret;
     219              : 
     220            5 :         wait_stop_impl = loop_wait_stop;
     221            5 :         wait_until_impl = loop_wait_until;
     222              : 
     223            5 :         ret = g_test_run ();
     224              : 
     225            5 :         wait_stop_impl = NULL;
     226            5 :         wait_until_impl = NULL;
     227              : 
     228            5 :         while (g_main_context_iteration (NULL, FALSE));
     229              : 
     230            5 :         return ret;
     231              : }
     232              : 
     233              : void
     234          258 : egg_tests_copy_scratch_file (const gchar *directory,
     235              :                              const gchar *filename)
     236              : {
     237          258 :         GError *error = NULL;
     238              :         gchar *basename;
     239              :         gchar *contents;
     240              :         gchar *destination;
     241              :         gsize length;
     242              : 
     243          258 :         g_assert (directory);
     244              : 
     245          258 :         g_file_get_contents (filename, &contents, &length, &error);
     246          258 :         g_assert_no_error (error);
     247              : 
     248          258 :         basename = g_path_get_basename (filename);
     249          258 :         destination = g_build_filename (directory, basename, NULL);
     250          258 :         g_free (basename);
     251              : 
     252          258 :         g_file_set_contents (destination, contents, length, &error);
     253          258 :         g_assert_no_error (error);
     254          258 :         g_free (destination);
     255          258 :         g_free (contents);
     256          258 : }
     257              : 
     258              : gchar *
     259          146 : egg_tests_create_scratch_directory (const gchar *file_to_copy,
     260              :                                     ...)
     261              : {
     262              :         gchar *basename;
     263              :         gchar *directory;
     264              :         va_list va;
     265              : 
     266          146 :         basename = g_path_get_basename (g_get_prgname ());
     267          146 :         directory = g_strdup_printf ("/tmp/scratch-%s.XXXXXX", basename);
     268          146 :         g_free (basename);
     269              : 
     270          146 :         if (!g_mkdtemp (directory))
     271            0 :                 g_assert_not_reached ();
     272              : 
     273          146 :         va_start (va, file_to_copy);
     274              : 
     275          404 :         while (file_to_copy != NULL) {
     276          258 :                 egg_tests_copy_scratch_file (directory, file_to_copy);
     277          258 :                 file_to_copy = va_arg (va, const gchar *);
     278              :         }
     279              : 
     280          146 :         va_end (va);
     281              : 
     282          146 :         return directory;
     283              : }
     284              : 
     285              : void
     286          146 : egg_tests_remove_scratch_directory (const gchar *directory)
     287              : {
     288          146 :         gchar *argv[] = { "rm", "-rf", (gchar *)directory, NULL };
     289          146 :         GError *error = NULL;
     290              :         gint rm_status;
     291              : 
     292          146 :         g_assert_cmpstr (directory, !=, "");
     293          146 :         g_assert_cmpstr (directory, !=, "/");
     294              : 
     295          146 :         g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL,
     296              :                       NULL, NULL, NULL, &rm_status, &error);
     297          146 :         g_assert_no_error (error);
     298          146 :         g_assert_cmpint (rm_status, ==, 0);
     299          146 : }
        

Generated by: LCOV version 2.0-1