3 * Common code for GStreamer unittests
5 * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
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 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #ifndef __GST_CHECK_H__
24 #define __GST_CHECK_H__
34 GST_DEBUG_CATEGORY_EXTERN (check_debug);
35 #define GST_CAT_DEFAULT check_debug
37 /* logging function for tests
38 * a test uses g_message() to log a debug line
39 * a gst unit test can be run with GST_TEST_DEBUG env var set to see the
42 extern gboolean _gst_check_threads_running;
43 extern gboolean _gst_check_raised_critical;
44 extern gboolean _gst_check_expecting_log;
46 void gst_check_init (int *argc, char **argv[]);
49 * wrappers for START_TEST and END_TEST
51 #define GST_START_TEST(__testname) \
52 static void __testname (void)\
54 GST_DEBUG ("test start"); \
55 tcase_fn_start (""# __testname, __FILE__, __LINE__);
57 #define GST_END_TEST END_TEST
60 * thread test macros and variables
62 extern GList *thread_list;
64 extern GCond *start_cond; /* used to notify main thread of thread startups */
65 extern GCond *sync_cond; /* used to synchronize all threads and main thread */
67 #define MAIN_START_THREADS(count, function, data) \
69 MAIN_START_THREAD_FUNCTIONS(count, function, data); \
74 _gst_check_threads_running = TRUE; \
76 mutex = g_mutex_new (); \
77 start_cond = g_cond_new (); \
78 sync_cond = g_cond_new (); \
81 #define MAIN_START_THREAD_FUNCTIONS(count, function, data) \
84 for (i = 0; i < count; ++i) { \
85 MAIN_START_THREAD_FUNCTION (i, function, data); \
89 #define MAIN_START_THREAD_FUNCTION(i, function, data) \
91 GThread *thread = NULL; \
92 g_message ("MAIN: creating thread %d\n", i); \
93 g_mutex_lock (mutex); \
94 thread = g_thread_create ((GThreadFunc) function, data, \
96 /* wait for thread to signal us that it's ready */ \
97 g_message ("MAIN: waiting for thread %d\n", i); \
98 g_cond_wait (start_cond, mutex); \
99 g_mutex_unlock (mutex); \
101 thread_list = g_list_append (thread_list, thread); \
105 #define MAIN_SYNCHRONIZE() \
107 g_message ("MAIN: synchronizing\n"); \
108 g_cond_broadcast (sync_cond); \
109 g_message ("MAIN: synchronized\n"); \
112 #define MAIN_STOP_THREADS() \
114 _gst_check_threads_running = FALSE; \
116 /* join all threads */ \
117 g_message ("MAIN: joining\n"); \
118 g_list_foreach (thread_list, (GFunc) g_thread_join, NULL); \
119 g_message ("MAIN: joined\n"); \
122 #define THREAD_START() \
124 THREAD_SYNCHRONIZE();
126 #define THREAD_STARTED() \
128 /* signal main thread that we started */ \
129 g_message ("THREAD %p: started\n", g_thread_self ()); \
130 g_mutex_lock (mutex); \
131 g_cond_signal (start_cond); \
134 #define THREAD_SYNCHRONIZE() \
136 /* synchronize everyone */ \
137 g_message ("THREAD %p: syncing\n", g_thread_self ()); \
138 g_cond_wait (sync_cond, mutex); \
139 g_message ("THREAD %p: synced\n", g_thread_self ()); \
140 g_mutex_unlock (mutex); \
143 #define THREAD_SWITCH() \
145 /* a minimal sleep is a context switch */ \
149 #define THREAD_TEST_RUNNING() (_gst_check_threads_running == TRUE)
151 /* additional assertions */
152 #define ASSERT_CRITICAL(code) \
154 _gst_check_expecting_log = TRUE; \
155 _gst_check_raised_critical = FALSE; \
157 _fail_unless (_gst_check_raised_critical, __FILE__, __LINE__, \
158 "Expected g_critical, got nothing: '"#code"'"); \
159 _gst_check_expecting_log = FALSE; \
162 #define ASSERT_OBJECT_REFCOUNT(object, name, value) \
165 rc = GST_OBJECT_REFCOUNT_VALUE (object); \
166 fail_unless (rc == value, \
167 name " refcount is %d instead of %d", rc, value);\
170 #define ASSERT_CAPS_REFCOUNT(caps, name, value) \
171 ASSERT_MINI_OBJECT_REFCOUNT(caps, name, value)
173 #define ASSERT_BUFFER_REFCOUNT(buffer, name, value) \
174 ASSERT_MINI_OBJECT_REFCOUNT(buffer, name, value)
176 #define ASSERT_MINI_OBJECT_REFCOUNT(caps, name, value) \
179 rc = GST_MINI_OBJECT_REFCOUNT_VALUE (caps); \
180 fail_unless (rc == value, \
181 name " refcount is %d instead of %d", rc, value);\
185 #endif /* __GST_CHECK_H__ */