1 /* GLib testing utilities 2 * Copyright (C) 2007 Imendio AB 3 * Authors: Tim Janik 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 * Boston, MA 02111-1307, USA. 19 */ 20 21 #if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) 22 #error "Only <glib.h> can be included directly." 23 #endif 24 25 #ifndef __G_TEST_UTILS_H__ 26 #define __G_TEST_UTILS_H__ 27 28 #include <glib.h> 29 30 G_BEGIN_DECLS 31 32 typedef struct GTestCase GTestCase; 33 typedef struct GTestSuite GTestSuite; 34 35 /* assertion API */ 36 #define g_assert_cmpstr(s1, cmp, s2) do { const char *__s1 = (s1), *__s2 = (s2); \ 37 if (g_strcmp0 (__s1, __s2) cmp 0) ; else \ 38 g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 39 #s1 " " #cmp " " #s2, __s1, #cmp, __s2); } while (0) 40 #define g_assert_cmpint(n1, cmp, n2) do { gint64 __n1 = (n1), __n2 = (n2); \ 41 if (__n1 cmp __n2) ; else \ 42 g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 43 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0) 44 #define g_assert_cmpuint(n1, cmp, n2) do { guint64 __n1 = (n1), __n2 = (n2); \ 45 if (__n1 cmp __n2) ; else \ 46 g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 47 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0) 48 #define g_assert_cmphex(n1, cmp, n2) do { guint64 __n1 = (n1), __n2 = (n2); \ 49 if (__n1 cmp __n2) ; else \ 50 g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 51 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'x'); } while (0) 52 #define g_assert_cmpfloat(n1,cmp,n2) do { long double __n1 = (n1), __n2 = (n2); \ 53 if (__n1 cmp __n2) ; else \ 54 g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 55 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'f'); } while (0) 56 #define g_assert_no_error(err) do { if (err) \ 57 g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 58 #err, err, 0, 0); } while (0) 59 #define g_assert_error(err, dom, c) do { if (!err || (err)->domain != dom || (err)->code != c) \ 60 g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 61 #err, err, dom, c); } while (0) 62 #ifdef G_DISABLE_ASSERT 63 #define g_assert_not_reached() do { (void) 0; } while (0) 64 #define g_assert(expr) do { (void) 0; } while (0) 65 #else /* !G_DISABLE_ASSERT */ 66 #define g_assert_not_reached() do { g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, NULL); } while (0) 67 #define g_assert(expr) do { if G_LIKELY (expr) ; else \ 68 g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ 69 #expr); } while (0) 70 #endif /* !G_DISABLE_ASSERT */ 71 72 int g_strcmp0 (const char *str1, 73 const char *str2); 74 75 /* report performance results */ 76 void g_test_minimized_result (double minimized_quantity, 77 const char *format, 78 ...) G_GNUC_PRINTF (2, 3); 79 void g_test_maximized_result (double maximized_quantity, 80 const char *format, 81 ...) G_GNUC_PRINTF (2, 3); 82 83 /* initialize testing framework */ 84 void g_test_init (int *argc, 85 char ***argv, 86 ...); 87 /* query testing framework config */ 88 #define g_test_quick() (g_test_config_vars->test_quick) 89 #define g_test_slow() (!g_test_config_vars->test_quick) 90 #define g_test_thorough() (!g_test_config_vars->test_quick) 91 #define g_test_perf() (g_test_config_vars->test_perf) 92 #define g_test_verbose() (g_test_config_vars->test_verbose) 93 #define g_test_quiet() (g_test_config_vars->test_quiet) 94 /* run all tests under toplevel suite (path: /) */ 95 int g_test_run (void); 96 /* hook up a test functions under test path */ 97 void g_test_add_func (const char *testpath, 98 void (*test_func) (void)); 99 void g_test_add_data_func (const char *testpath, 100 gconstpointer test_data, 101 void (*test_func) (gconstpointer)); 102 /* hook up a test with fixture under test path */ 103 #define g_test_add(testpath, Fixture, tdata, fsetup, ftest, fteardown) \ 104 G_STMT_START { \ 105 void (*add_vtable) (const char*, \ 106 gsize, \ 107 gconstpointer, \ 108 void (*) (Fixture*, gconstpointer), \ 109 void (*) (Fixture*, gconstpointer), \ 110 void (*) (Fixture*, gconstpointer)) = (void (*) (const gchar *, gsize, gconstpointer, void (*) (Fixture*, gconstpointer), void (*) (Fixture*, gconstpointer), void (*) (Fixture*, gconstpointer))) g_test_add_vtable; \ 111 add_vtable \ 112 (testpath, sizeof (Fixture), tdata, fsetup, ftest, fteardown); \ 113 } G_STMT_END 114 115 /* add test messages to the test report */ 116 void g_test_message (const char *format, 117 ...) G_GNUC_PRINTF (1, 2); 118 void g_test_bug_base (const char *uri_pattern); 119 void g_test_bug (const char *bug_uri_snippet); 120 /* measure test timings */ 121 void g_test_timer_start (void); 122 double g_test_timer_elapsed (void); /* elapsed seconds */ 123 double g_test_timer_last (void); /* repeat last elapsed() result */ 124 125 /* automatically g_free or g_object_unref upon teardown */ 126 void g_test_queue_free (gpointer gfree_pointer); 127 void g_test_queue_destroy (GDestroyNotify destroy_func, 128 gpointer destroy_data); 129 #define g_test_queue_unref(gobject) g_test_queue_destroy (g_object_unref, gobject) 130 131 /* test traps are guards used around forked tests */ 132 typedef enum { 133 G_TEST_TRAP_SILENCE_STDOUT = 1 << 7, 134 G_TEST_TRAP_SILENCE_STDERR = 1 << 8, 135 G_TEST_TRAP_INHERIT_STDIN = 1 << 9 136 } GTestTrapFlags; 137 gboolean g_test_trap_fork (guint64 usec_timeout, 138 GTestTrapFlags test_trap_flags); 139 gboolean g_test_trap_has_passed (void); 140 gboolean g_test_trap_reached_timeout (void); 141 #define g_test_trap_assert_passed() g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 0, 0) 142 #define g_test_trap_assert_failed() g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 1, 0) 143 #define g_test_trap_assert_stdout(soutpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 2, soutpattern) 144 #define g_test_trap_assert_stdout_unmatched(soutpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 3, soutpattern) 145 #define g_test_trap_assert_stderr(serrpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 4, serrpattern) 146 #define g_test_trap_assert_stderr_unmatched(serrpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 5, serrpattern) 147 148 /* provide seed-able random numbers for tests */ 149 #define g_test_rand_bit() (0 != (g_test_rand_int() & (1 << 15))) 150 gint32 g_test_rand_int (void); 151 gint32 g_test_rand_int_range (gint32 begin, 152 gint32 end); 153 double g_test_rand_double (void); 154 double g_test_rand_double_range (double range_start, 155 double range_end); 156 157 /* semi-internal API */ 158 GTestCase* g_test_create_case (const char *test_name, 159 gsize data_size, 160 gconstpointer test_data, 161 void (*data_setup) (void), 162 void (*data_test) (void), 163 void (*data_teardown) (void)); 164 GTestSuite* g_test_create_suite (const char *suite_name); 165 GTestSuite* g_test_get_root (void); 166 void g_test_suite_add (GTestSuite *suite, 167 GTestCase *test_case); 168 void g_test_suite_add_suite (GTestSuite *suite, 169 GTestSuite *nestedsuite); 170 int g_test_run_suite (GTestSuite *suite); 171 172 /* internal ABI */ 173 void g_test_trap_assertions (const char *domain, 174 const char *file, 175 int line, 176 const char *func, 177 guint64 assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */ 178 const char *pattern); 179 void g_assertion_message (const char *domain, 180 const char *file, 181 int line, 182 const char *func, 183 const char *message) G_GNUC_NORETURN; 184 void g_assertion_message_expr (const char *domain, 185 const char *file, 186 int line, 187 const char *func, 188 const char *expr) G_GNUC_NORETURN; 189 void g_assertion_message_cmpstr (const char *domain, 190 const char *file, 191 int line, 192 const char *func, 193 const char *expr, 194 const char *arg1, 195 const char *cmp, 196 const char *arg2) G_GNUC_NORETURN; 197 void g_assertion_message_cmpnum (const char *domain, 198 const char *file, 199 int line, 200 const char *func, 201 const char *expr, 202 long double arg1, 203 const char *cmp, 204 long double arg2, 205 char numtype) G_GNUC_NORETURN; 206 void g_assertion_message_error (const char *domain, 207 const char *file, 208 int line, 209 const char *func, 210 const char *expr, 211 GError *error, 212 GQuark error_domain, 213 int error_code) G_GNUC_NORETURN; 214 void g_test_add_vtable (const char *testpath, 215 gsize data_size, 216 gconstpointer test_data, 217 void (*data_setup) (void), 218 void (*data_test) (void), 219 void (*data_teardown) (void)); 220 typedef struct { 221 gboolean test_initialized; 222 gboolean test_quick; /* disable thorough tests */ 223 gboolean test_perf; /* run performance tests */ 224 gboolean test_verbose; /* extra info */ 225 gboolean test_quiet; /* reduce output */ 226 } GTestConfig; 227 GLIB_VAR const GTestConfig * const g_test_config_vars; 228 229 /* internal logging API */ 230 typedef enum { 231 G_TEST_LOG_NONE, 232 G_TEST_LOG_ERROR, /* s:msg */ 233 G_TEST_LOG_START_BINARY, /* s:binaryname s:seed */ 234 G_TEST_LOG_LIST_CASE, /* s:testpath */ 235 G_TEST_LOG_SKIP_CASE, /* s:testpath */ 236 G_TEST_LOG_START_CASE, /* s:testpath */ 237 G_TEST_LOG_STOP_CASE, /* d:status d:nforks d:elapsed */ 238 G_TEST_LOG_MIN_RESULT, /* s:blurb d:result */ 239 G_TEST_LOG_MAX_RESULT, /* s:blurb d:result */ 240 G_TEST_LOG_MESSAGE /* s:blurb */ 241 } GTestLogType; 242 243 typedef struct { 244 GTestLogType log_type; 245 guint n_strings; 246 gchar **strings; /* NULL terminated */ 247 guint n_nums; 248 long double *nums; 249 } GTestLogMsg; 250 typedef struct { 251 /*< private >*/ 252 GString *data; 253 GSList *msgs; 254 } GTestLogBuffer; 255 256 const char* g_test_log_type_name (GTestLogType log_type); 257 GTestLogBuffer* g_test_log_buffer_new (void); 258 void g_test_log_buffer_free (GTestLogBuffer *tbuffer); 259 void g_test_log_buffer_push (GTestLogBuffer *tbuffer, 260 guint n_bytes, 261 const guint8 *bytes); 262 GTestLogMsg* g_test_log_buffer_pop (GTestLogBuffer *tbuffer); 263 void g_test_log_msg_free (GTestLogMsg *tmsg); 264 265 G_END_DECLS 266 267 #endif /* __G_TEST_UTILS_H__ */ 268