identity: refactor and add tests using GstHarness
[platform/upstream/gstreamer.git] / tests / check / elements / identity.c
1 /* GStreamer
2  *
3  * unit test for identity
4  *
5  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
6  * Copyright (C) <2015> Havard Graff           <havard@pexip.com>
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., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include <gst/check/gstcheck.h>
25 #include <gst/check/gstharness.h>
26
27 GST_START_TEST (test_one_buffer)
28 {
29   GstHarness *h = gst_harness_new ("identity");
30   GstBuffer *buffer_in;
31   GstBuffer *buffer_out;
32
33   gst_harness_set_src_caps_str (h, "mycaps");
34
35   buffer_in = gst_buffer_new_and_alloc (4);
36   ASSERT_BUFFER_REFCOUNT (buffer_in, "buffer", 1);
37
38   gst_buffer_fill (buffer_in, 0, "data", 4);
39
40   /* pushing gives away my reference ... */
41   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));
42
43   /* ... but it should end up being collected on GstHarness queue */
44   fail_unless_equals_int (1, gst_harness_buffers_in_queue (h));
45   buffer_out = gst_harness_pull (h);
46
47   fail_unless (buffer_in == buffer_out);
48   ASSERT_BUFFER_REFCOUNT (buffer_out, "buffer", 1);
49
50   /* cleanup */
51   gst_buffer_unref (buffer_out);
52   gst_harness_teardown (h);
53 }
54 GST_END_TEST;
55
56 static void
57 handoff_func (GstElement * identity, GstBuffer * buf,  GstBuffer ** ret)
58 {
59   (void)identity;
60   *ret = buf;
61 }
62
63 GST_START_TEST (test_signal_handoffs)
64 {
65   GstHarness *h = gst_harness_new ("identity");
66   GstBuffer *buffer_in;
67   GstBuffer *buffer_signaled = NULL;
68   gst_harness_set_src_caps_str (h, "mycaps");
69
70   /* connect to the handoff signal */
71   g_signal_connect (h->element, "handoff",
72       G_CALLBACK (handoff_func), &buffer_signaled);
73
74   /* first, turn off signal-handoffs */
75   g_object_set (h->element, "signal-handoffs", FALSE, NULL);
76
77   /* then push a buffer */
78   buffer_in = gst_buffer_new_and_alloc (4);
79   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));
80
81   /* verify that we got no buffer signaled */
82   fail_unless (buffer_signaled == NULL);
83
84   /* now turn on signal-handoffs */
85   g_object_set (h->element, "signal-handoffs", TRUE, NULL);
86
87   /* then push another buffer */
88   buffer_in = gst_buffer_new_and_alloc (4);
89   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer_in));
90
91   /* verify the buffer signaled is equal to the one pushed in */
92   fail_unless (buffer_signaled == buffer_in);
93   ASSERT_BUFFER_REFCOUNT (buffer_signaled, "buffer", 1);
94
95   /* cleanup */
96   gst_harness_teardown (h);
97 }
98 GST_END_TEST;
99
100 GST_START_TEST (test_sync_on_timestamp)
101 {
102   /* the reason to use the queue in front of the identity element
103      is to effectively make gst_harness_push asynchronous, not locking
104      up the test, waiting for gst_clock_id_wait */
105   GstHarness * h = gst_harness_new_parse ("queue ! identity sync=1");
106   GstBuffer *buf;
107   GstClock *clock;
108   GstClockTime timestamp = 123456789;
109
110   /* use testclock */
111   gst_harness_use_testclock (h);
112   gst_harness_set_src_caps_str (h, "mycaps");
113
114   /* make a buffer and set the timestamp */
115   buf = gst_buffer_new ();
116   GST_BUFFER_PTS (buf) = timestamp;
117
118   /* push the buffer, and verify it does *not* make it through */
119   gst_harness_push (h, buf);
120   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
121
122   /* verify the identity element has registered exactly one GstClockID */
123   fail_unless (gst_harness_wait_for_clock_id_waits (h, 1, 42));
124
125   /* crank the clock and pull the buffer */
126   gst_harness_crank_single_clock_wait (h);
127   buf = gst_harness_pull (h);
128
129   /* verify that the buffer has the right timestamp, and that the time on
130      the clock is equal to the timestamp */
131   fail_unless_equals_int64 (timestamp, GST_BUFFER_PTS (buf));
132   clock = gst_element_get_clock (h->element);
133   fail_unless_equals_int64 (timestamp, gst_clock_get_time (clock));
134
135   /* cleanup */
136   gst_object_unref (clock);
137   gst_buffer_unref (buf);
138   gst_harness_teardown (h);
139 }
140 GST_END_TEST;
141
142 GST_START_TEST (test_stopping_element_unschedules_sync)
143 {
144   /* the reason to use the queue in front of the identity element
145      is to effectively make gst_harness_push asynchronous, not locking
146      up the test, waiting for gst_clock_id_wait */
147   GstHarness * h = gst_harness_new_parse ("queue ! identity sync=1");
148   GstBuffer *buf;
149   GstClockTime timestamp = 123456789;
150
151   /* use testclock */
152   gst_harness_use_testclock (h);
153   gst_harness_set_src_caps_str (h, "mycaps");
154
155   /* make a buffer and set the timestamp */
156   buf = gst_buffer_new ();
157   GST_BUFFER_PTS (buf) = timestamp;
158
159   /* push the buffer, and verify it does *not* make it through */
160   gst_harness_push (h, buf);
161   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
162
163   /* verify the identity element has registered exactly one GstClockID */
164   fail_unless (gst_harness_wait_for_clock_id_waits (h, 1, 42));
165
166   /* setting identity to READY should unschedule the sync */
167   gst_element_set_state (h->element, GST_STATE_READY);
168
169   /* verify the identity element no longer waits on the clock */
170   fail_unless (gst_harness_wait_for_clock_id_waits (h, 0, 42));
171
172   /* and that the waiting buffer was dropped */
173   fail_unless_equals_int (0, gst_harness_buffers_received (h));
174
175   gst_harness_teardown (h);
176 }
177 GST_END_TEST;
178
179 static Suite *
180 identity_suite (void)
181 {
182   Suite *s = suite_create ("identity");
183   TCase *tc_chain = tcase_create ("general");
184
185   suite_add_tcase (s, tc_chain);
186   tcase_add_test (tc_chain, test_one_buffer);
187   tcase_add_test (tc_chain, test_signal_handoffs);
188   tcase_add_test (tc_chain, test_sync_on_timestamp);
189   tcase_add_test (tc_chain, test_stopping_element_unschedules_sync);
190
191
192   return s;
193 }
194
195 GST_CHECK_MAIN (identity);