tests/check/: use the new macro
[platform/upstream/gstreamer.git] / tests / check / gst / gstminiobject.c
1 /* GStreamer
2  *
3  * unit test for GstMiniObject
4  *
5  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
6  * Copyright (C) <2005> Tim-Philipp Müller <tim centricular net>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <gst/check/gstcheck.h>
25
26 GST_START_TEST (test_copy)
27 {
28   GstBuffer *buffer, *copy;
29
30   buffer = gst_buffer_new_and_alloc (4);
31
32   copy = GST_BUFFER (gst_mini_object_copy (GST_MINI_OBJECT (buffer)));
33
34   fail_if (copy == NULL, "Copy of buffer returned NULL");
35   fail_unless (GST_BUFFER_SIZE (copy) == 4,
36       "Copy of buffer has different size");
37 }
38
39 GST_END_TEST;
40
41 GST_START_TEST (test_is_writable)
42 {
43   GstBuffer *buffer;
44   GstMiniObject *mobj;
45
46   buffer = gst_buffer_new_and_alloc (4);
47   mobj = GST_MINI_OBJECT (buffer);
48
49   fail_unless (gst_mini_object_is_writable (mobj),
50       "A buffer with one ref should be writable");
51
52   GST_MINI_OBJECT_FLAG_SET (mobj, GST_MINI_OBJECT_FLAG_READONLY);
53   fail_if (gst_mini_object_is_writable (mobj),
54       "A buffer with READONLY set should not be writable");
55   GST_MINI_OBJECT_FLAG_UNSET (mobj, GST_MINI_OBJECT_FLAG_READONLY);
56   fail_unless (gst_mini_object_is_writable (mobj),
57       "A buffer with one ref and READONLY not set should be writable");
58
59   fail_if (gst_mini_object_ref (mobj) == NULL, "Could not ref the mobj");
60
61   fail_if (gst_mini_object_is_writable (mobj),
62       "A buffer with two refs should not be writable");
63 }
64
65 GST_END_TEST;
66
67 GST_START_TEST (test_make_writable)
68 {
69   GstBuffer *buffer;
70   GstMiniObject *mobj, *mobj2, *mobj3;
71
72   buffer = gst_buffer_new_and_alloc (4);
73   mobj = GST_MINI_OBJECT (buffer);
74
75   mobj2 = gst_mini_object_make_writable (mobj);
76   fail_unless (GST_IS_BUFFER (mobj2), "make_writable did not return a buffer");
77   fail_unless (mobj == mobj2,
78       "make_writable returned a copy for a buffer with refcount 1");
79
80   mobj2 = gst_mini_object_ref (mobj);
81   mobj3 = gst_mini_object_make_writable (mobj);
82   fail_unless (GST_IS_BUFFER (mobj3), "make_writable did not return a buffer");
83   fail_if (mobj == mobj3,
84       "make_writable returned same object for a buffer with refcount > 1");
85
86   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (mobj) == 1,
87       "refcount of original mobj object should be back to 1");
88
89   mobj2 = gst_mini_object_make_writable (mobj);
90   fail_unless (GST_IS_BUFFER (mobj2), "make_writable did not return a buffer");
91   fail_unless (mobj == mobj2,
92       "make_writable returned a copy for a buffer with refcount 1");
93
94 }
95
96 GST_END_TEST;
97
98 gint num_threads = 10;
99 gint refs_per_thread = 10000;
100
101 /* test thread-safe refcounting of GstMiniObject */
102 void
103 thread_ref (GstMiniObject * mobj)
104 {
105   int j;
106
107   THREAD_START ();
108
109   for (j = 0; j < refs_per_thread; ++j) {
110     gst_mini_object_ref (mobj);
111
112     if (j % num_threads == 0)
113       THREAD_SWITCH ();
114   }
115   GST_DEBUG ("thread stopped");
116 }
117
118 GST_START_TEST (test_ref_threaded)
119 {
120   GstBuffer *buffer;
121   GstMiniObject *mobj;
122   gint expected;
123
124   buffer = gst_buffer_new_and_alloc (4);
125
126   mobj = GST_MINI_OBJECT (buffer);
127
128   MAIN_START_THREADS (num_threads, thread_ref, mobj);
129
130   MAIN_STOP_THREADS ();
131
132   expected = num_threads * refs_per_thread + 1;
133   ASSERT_MINI_OBJECT_REFCOUNT (mobj, "miniobject", expected);
134 }
135
136 GST_END_TEST;
137
138 void
139 thread_unref (GstMiniObject * mobj)
140 {
141   int j;
142
143   THREAD_START ();
144
145   for (j = 0; j < refs_per_thread; ++j) {
146     gst_mini_object_unref (mobj);
147
148     if (j % num_threads == 0)
149       THREAD_SWITCH ();
150   }
151 }
152
153 GST_START_TEST (test_unref_threaded)
154 {
155   GstBuffer *buffer;
156   GstMiniObject *mobj;
157   int i;
158
159   buffer = gst_buffer_new_and_alloc (4);
160
161   mobj = GST_MINI_OBJECT (buffer);
162
163   for (i = 0; i < num_threads * refs_per_thread; ++i)
164     gst_mini_object_ref (mobj);
165
166   MAIN_START_THREADS (num_threads, thread_unref, mobj);
167
168   MAIN_STOP_THREADS ();
169
170   ASSERT_MINI_OBJECT_REFCOUNT (mobj, "miniobject", 1);
171
172   /* final unref */
173   gst_mini_object_unref (mobj);
174 }
175
176 GST_END_TEST;
177
178 /* ======== value collection test ======== */
179 typedef struct _MyFoo
180 {
181   GObject object;
182 } MyFoo;
183
184 typedef struct _MyFooClass
185 {
186   GObjectClass gobject_class;
187 } MyFooClass;
188
189 enum
190 {
191   PROP_BUFFER = 1
192 };
193
194 G_DEFINE_TYPE (MyFoo, my_foo, G_TYPE_OBJECT)
195
196      static void my_foo_init (MyFoo * foo)
197 {
198 }
199
200 static void
201 my_foo_get_property (GObject * object, guint prop_id, GValue * value,
202     GParamSpec * pspec)
203 {
204   GstBuffer *new_buf;
205
206   g_assert (prop_id == PROP_BUFFER);
207
208   new_buf = gst_buffer_new_and_alloc (1024);
209   gst_value_set_mini_object (value, GST_MINI_OBJECT (new_buf));
210   gst_buffer_unref (new_buf);
211 }
212
213 static void
214 my_foo_set_property (GObject * object, guint prop_id, const GValue * value,
215     GParamSpec * pspec)
216 {
217   GstMiniObject *mini_obj;
218
219   g_assert (prop_id == PROP_BUFFER);
220
221   mini_obj = gst_value_get_mini_object (value);
222   g_assert (GST_IS_MINI_OBJECT (mini_obj));
223   g_assert (GST_IS_BUFFER (mini_obj));
224
225 #if 0
226   /* gst_value_dup_mini_object() does not exist yet */
227   mini_obj = gst_value_dup_mini_object (value);
228   g_assert (GST_IS_MINI_OBJECT (mini_obj));
229   g_assert (GST_IS_BUFFER (mini_obj));
230   gst_mini_object_unref (mini_obj);
231 #endif
232 }
233
234
235 static void
236 my_foo_class_init (MyFooClass * klass)
237 {
238   GObjectClass *gobject_klass = G_OBJECT_CLASS (klass);
239
240   gobject_klass->get_property = my_foo_get_property;
241   gobject_klass->set_property = my_foo_set_property;
242
243   g_object_class_install_property (gobject_klass, PROP_BUFFER,
244       gst_param_spec_mini_object ("buffer", "Buffer",
245           "a newly created GstBuffer", GST_TYPE_BUFFER, G_PARAM_READWRITE));
246 }
247
248 GST_START_TEST (test_value_collection)
249 {
250   GstBuffer *buf = NULL;
251   MyFoo *foo;
252
253   foo = (MyFoo *) g_object_new (my_foo_get_type (), NULL);
254
255   /* test g_object_get() refcounting */
256   g_object_get (foo, "buffer", &buf, NULL);
257   g_assert (GST_IS_BUFFER (buf));
258   g_assert (GST_MINI_OBJECT_REFCOUNT_VALUE (GST_MINI_OBJECT_CAST (buf)) == 1);
259   gst_buffer_unref (buf);
260
261   /* test g_object_set() refcounting */
262   buf = gst_buffer_new_and_alloc (1024);
263   g_object_set (foo, "buffer", buf, NULL);
264   g_assert (GST_MINI_OBJECT_REFCOUNT_VALUE (GST_MINI_OBJECT_CAST (buf)) == 1);
265   gst_buffer_unref (buf);
266
267   g_object_unref (foo);
268 }
269
270 GST_END_TEST;
271
272
273 Suite *
274 gst_mini_object_suite (void)
275 {
276   Suite *s = suite_create ("GstMiniObject");
277   TCase *tc_chain = tcase_create ("general");
278
279   /* turn off timeout */
280   tcase_set_timeout (tc_chain, 60);
281
282   suite_add_tcase (s, tc_chain);
283   tcase_add_test (tc_chain, test_copy);
284   tcase_add_test (tc_chain, test_is_writable);
285   tcase_add_test (tc_chain, test_make_writable);
286   tcase_add_test (tc_chain, test_ref_threaded);
287   tcase_add_test (tc_chain, test_unref_threaded);
288   tcase_add_test (tc_chain, test_value_collection);
289   return s;
290 }
291
292 GST_CHECK_MAIN (gst_mini_object);