[glib/fix-gnulib-msvc-isnan: 3/37] gtestutils: Add a new g_assert_no_errno() test macro



commit 45d5d58c2546fd1380e928ddca361902ba16713e
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Oct 31 11:22:16 2019 +0000

    gtestutils: Add a new g_assert_no_errno() test macro
    
    This is for use in testing POSIX-style functions like `rmdir()`, which
    return an integer < 0 on failure, and return their error information in
    `errno`.
    
    The new macro prints `errno` and `g_strerror (errno)` on failure.
    
    Includes a unit test.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 docs/reference/glib/glib-sections.txt |  1 +
 glib/gtestutils.c                     | 18 ++++++++++++++++++
 glib/gtestutils.h                     | 15 +++++++++++++++
 glib/tests/testing.c                  | 27 +++++++++++++++++++++++++++
 4 files changed, 61 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index b1d78ccc3..30cd94a78 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -3459,6 +3459,7 @@ g_assert_true
 g_assert_false
 g_assert_null
 g_assert_nonnull
+g_assert_no_errno
 g_test_set_nonfatal_assertions
 
 GTestCase
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index 1010dcc1b..d9e9b5edd 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -659,6 +659,24 @@
  * Since: 2.58
  */
 
+/**
+ * g_assert_no_errno:
+ * @expr: the expression to check
+ *
+ * Debugging macro to check that an expression has a non-negative return value,
+ * as used by traditional POSIX functions (such as `rmdir()`) to indicate
+ * success.
+ *
+ * If the assertion fails (i.e. the @expr returns a negative value), an error
+ * message is logged and the testcase is marked as failed. The error message
+ * will contain the value of `errno` and its human-readable message from
+ * g_strerror().
+ *
+ * This macro will clear the value of `errno` before executing @expr.
+ *
+ * Since: 2.66
+ */
+
 /**
  * g_assert_cmpmem:
  * @m1: (nullable): pointer to a buffer
diff --git a/glib/gtestutils.h b/glib/gtestutils.h
index 66b7ef3b7..298caa403 100644
--- a/glib/gtestutils.h
+++ b/glib/gtestutils.h
@@ -27,6 +27,7 @@
 #include <glib/gstring.h>
 #include <glib/gerror.h>
 #include <glib/gslist.h>
+#include <errno.h>
 #include <string.h>
 
 G_BEGIN_DECLS
@@ -110,6 +111,20 @@ typedef void (*GTestFixtureFunc) (gpointer      fixture,
       } \
   } \
   G_STMT_END
+#define g_assert_no_errno(expr)         G_STMT_START { \
+                                             int __ret, __errsv; \
+                                             errno = 0; \
+                                             __ret = expr; \
+                                             __errsv = errno; \
+                                             if (__ret < 0) \
+                                               { \
+                                                 gchar *__msg; \
+                                                 __msg = g_strdup_printf ("assertion failed (" #expr " >= 
0): errno %i: %s", __errsv, g_strerror (__errsv)); \
+                                                 g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, 
G_STRFUNC, __msg); \
+                                                 g_free (__msg); \
+                                               } \
+                                        } G_STMT_END \
+                                        GLIB_AVAILABLE_MACRO_IN_2_66
 #define g_assert_no_error(err)          G_STMT_START { \
                                              if (err) \
                                                g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, 
G_STRFUNC, \
diff --git a/glib/tests/testing.c b/glib/tests/testing.c
index d0ce2c1e7..ed4c8d6f7 100644
--- a/glib/tests/testing.c
+++ b/glib/tests/testing.c
@@ -108,6 +108,27 @@ test_assertions_bad_cmpfloat_epsilon (void)
   exit (0);
 }
 
+/* Emulates something like rmdir() failing. */
+static int
+return_errno (void)
+{
+  errno = ERANGE;  /* arbitrary non-zero value */
+  return -1;
+}
+
+/* Emulates something like rmdir() succeeding. */
+static int
+return_no_errno (void)
+{
+  return 0;
+}
+
+static void
+test_assertions_bad_no_errno (void)
+{
+  g_assert_no_errno (return_errno ());
+}
+
 static void
 test_assertions (void)
 {
@@ -137,6 +158,7 @@ test_assertions (void)
   g_assert_cmpmem (NULL, 0, NULL, 0);
   g_assert_cmpmem (NULL, 0, "foot", 0);
   g_assert_cmpmem ("foo", 0, NULL, 0);
+  g_assert_no_errno (return_no_errno ());
 
   v1 = g_variant_new_parsed ("['hello', 'there']");
   v2 = g_variant_new_parsed ("['hello', 'there']");
@@ -179,6 +201,10 @@ test_assertions (void)
   g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", 0, 0);
   g_test_trap_assert_failed ();
   g_test_trap_assert_stderr ("*assertion failed*");
+
+  g_test_trap_subprocess ("/misc/assertions/subprocess/bad_no_errno", 0, 0);
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*assertion failed*");
 }
 
 /* test g_test_timer* API */
@@ -1282,6 +1308,7 @@ main (int   argc,
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_data", test_assertions_bad_cmpmem_data);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_null", test_assertions_bad_cmpmem_null);
   g_test_add_func ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", test_assertions_bad_cmpfloat_epsilon);
+  g_test_add_func ("/misc/assertions/subprocess/bad_no_errno", test_assertions_bad_no_errno);
   g_test_add_data_func ("/misc/test-data", (void*) 0xc0c0baba, test_data_test);
   g_test_add ("/misc/primetoul", Fixturetest, (void*) 0xc0cac01a, fixturetest_setup, fixturetest_test, 
fixturetest_teardown);
   if (g_test_perf())


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]