b86363fb94de5e947f5c98fb83c31726afdc40fb
[platform/upstream/gstreamer.git] / tests / check / gstcheck.h
1 /* GStreamer
2  *
3  * Common code for GStreamer unittests
4  *
5  * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #ifndef __GST_CHECK_H__
24 #define __GST_CHECK_H__
25
26 #include <signal.h>
27 #include <string.h>
28 #include <stdlib.h>
29
30 #include <check.h>
31
32 #include <gst/gst.h>
33
34 GST_DEBUG_CATEGORY_EXTERN (check_debug);
35 #define GST_CAT_DEFAULT check_debug
36
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
40  * messages
41  */
42 extern gboolean _gst_check_threads_running;
43 extern gboolean _gst_check_raised_critical;
44 extern gboolean _gst_check_expecting_log;
45
46 void gst_check_init (int *argc, char **argv[]);
47
48 /***
49  * wrappers for START_TEST and END_TEST
50  */
51 #define GST_START_TEST(__testname) \
52 static void __testname (void)\
53 {\
54   GST_DEBUG ("test start"); \
55   tcase_fn_start (""# __testname, __FILE__, __LINE__);
56
57 #define GST_END_TEST END_TEST
58
59 /***
60  * thread test macros and variables
61  */
62 extern GList *thread_list;
63 extern GMutex *mutex;
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 */
66
67 #define MAIN_START_THREADS(count, function, data)               \
68 MAIN_INIT();                                                    \
69 MAIN_START_THREAD_FUNCTIONS(count, function, data);             \
70 MAIN_SYNCHRONIZE();
71
72 #define MAIN_INIT()                     \
73 G_STMT_START {                          \
74   _gst_check_threads_running = TRUE;    \
75                                         \
76   mutex = g_mutex_new ();               \
77   start_cond = g_cond_new ();           \
78   sync_cond = g_cond_new ();            \
79 } G_STMT_END;
80
81 #define MAIN_START_THREAD_FUNCTIONS(count, function, data)      \
82 G_STMT_START {                                                  \
83   int i;                                                        \
84   for (i = 0; i < count; ++i) {                                 \
85     MAIN_START_THREAD_FUNCTION (i, function, data);             \
86   }                                                             \
87 } G_STMT_END;
88
89 #define MAIN_START_THREAD_FUNCTION(i, function, data)           \
90 G_STMT_START {                                                  \
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,     \
95         TRUE, NULL);                                            \
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);                                     \
100                                                                 \
101     thread_list = g_list_append (thread_list, thread);          \
102 } G_STMT_END;
103
104
105 #define MAIN_SYNCHRONIZE()              \
106 G_STMT_START {                          \
107   g_message ("MAIN: synchronizing\n");  \
108   g_cond_broadcast (sync_cond);         \
109   g_message ("MAIN: synchronized\n");   \
110 } G_STMT_END;
111
112 #define MAIN_STOP_THREADS()                                     \
113 G_STMT_START {                                                  \
114   _gst_check_threads_running = FALSE;                           \
115                                                                 \
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");                                 \
120 } G_STMT_END;
121
122 #define THREAD_START()                                          \
123 THREAD_STARTED();                                               \
124 THREAD_SYNCHRONIZE();
125
126 #define THREAD_STARTED()                                        \
127 G_STMT_START {                                                  \
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);                                   \
132 } G_STMT_END;
133
134 #define THREAD_SYNCHRONIZE()                                    \
135 G_STMT_START {                                                  \
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);                                       \
141 } G_STMT_END;
142
143 #define THREAD_SWITCH()                                         \
144 G_STMT_START {                                                  \
145   /* a minimal sleep is a context switch */                     \
146   g_usleep (1);                                                 \
147 } G_STMT_END;
148
149 #define THREAD_TEST_RUNNING()   (_gst_check_threads_running == TRUE)
150
151 /* additional assertions */
152 #define ASSERT_CRITICAL(code)                                   \
153 G_STMT_START {                                                  \
154   _gst_check_expecting_log = TRUE;                              \
155   _gst_check_raised_critical = FALSE;                           \
156   code;                                                         \
157   _fail_unless (_gst_check_raised_critical, __FILE__, __LINE__, \
158                 "Expected g_critical, got nothing: '"#code"'"); \
159   _gst_check_expecting_log = FALSE;                             \
160 } G_STMT_END
161
162 #define ASSERT_OBJECT_REFCOUNT(object, name, value)             \
163 G_STMT_START {                                                  \
164   int rc;                                                       \
165   rc = GST_OBJECT_REFCOUNT_VALUE (object);                      \
166   fail_unless (rc == value,                                     \
167                name " refcount is %d instead of %d", rc, value);\
168 } G_STMT_END
169
170 #define ASSERT_CAPS_REFCOUNT(caps, name, value)                 \
171         ASSERT_MINI_OBJECT_REFCOUNT(caps, name, value)
172
173 #define ASSERT_BUFFER_REFCOUNT(buffer, name, value)             \
174         ASSERT_MINI_OBJECT_REFCOUNT(buffer, name, value)
175
176 #define ASSERT_MINI_OBJECT_REFCOUNT(caps, name, value)          \
177 G_STMT_START {                                                  \
178   int rc;                                                       \
179   rc = GST_MINI_OBJECT_REFCOUNT_VALUE (caps);                   \
180   fail_unless (rc == value,                                     \
181                name " refcount is %d instead of %d", rc, value);\
182 } G_STMT_END
183
184
185 #endif /* __GST_CHECK_H__ */
186