6ebf387e17c82c3d6b2469a802bca03bb196635e
[platform/upstream/gstreamer.git] / tests / check / pipelines / simple-launch-lines.c
1 /* GStreamer
2  * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
3  *
4  * simple_launch_lines.c: Unit test for simple pipelines
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22
23 #include "../gstcheck.h"
24
25
26 static GstElement *
27 setup_pipeline (gchar * pipe_descr)
28 {
29   GstElement *pipeline;
30
31   pipeline = gst_parse_launch (pipe_descr, NULL);
32   g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
33   return pipeline;
34 }
35
36 /* events is a mask of expected events. tevent is the expected terminal event.
37    the poll call will time out after half a second.
38  */
39 static void
40 run_pipeline (GstElement * pipe, gchar * descr,
41     GstMessageType events, GstMessageType tevent)
42 {
43   GstBus *bus;
44   GstMessageType revent;
45
46   bus = gst_element_get_bus (pipe);
47   g_assert (bus);
48   gst_element_set_state (pipe, GST_STATE_PLAYING);
49
50   while (1) {
51     revent = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2);
52
53     /* always have to pop the message before getting back into poll */
54     if (revent != GST_MESSAGE_UNKNOWN)
55       gst_message_unref (gst_bus_pop (bus));
56
57     if (revent == tevent) {
58       break;
59     } else if (revent == GST_MESSAGE_UNKNOWN) {
60       g_critical ("Unexpected timeout in gst_bus_poll, looking for %d: %s",
61           tevent, descr);
62       break;
63     } else if (revent & events) {
64       continue;
65     }
66     g_critical ("Unexpected message received of type %d, looking for %d: %s",
67         revent, tevent, descr);
68   }
69
70   gst_element_set_state (pipe, GST_STATE_NULL);
71   gst_object_unref (GST_OBJECT (pipe));
72 }
73
74 START_TEST (test_2_elements)
75 {
76   gchar *s;
77
78   /* has-loop got unimplemented at some point, so these aren't actually testing
79    * what they're supposed to -- a big ol' FIXME */
80
81   s = "fakesrc has-loop=false ! fakesink has-loop=true";
82   run_pipeline (setup_pipeline (s), s,
83       GST_MESSAGE_STATE_CHANGED, GST_MESSAGE_UNKNOWN);
84
85   s = "fakesrc has-loop=true ! fakesink has-loop=false";
86   run_pipeline (setup_pipeline (s), s,
87       GST_MESSAGE_STATE_CHANGED, GST_MESSAGE_UNKNOWN);
88
89   s = "fakesrc has-loop=false num-buffers=10 ! fakesink has-loop=true";
90   run_pipeline (setup_pipeline (s), s,
91       GST_MESSAGE_STATE_CHANGED, GST_MESSAGE_EOS);
92
93   s = "fakesrc has-loop=true num-buffers=10 ! fakesink has-loop=false";
94   run_pipeline (setup_pipeline (s), s,
95       GST_MESSAGE_STATE_CHANGED, GST_MESSAGE_EOS);
96
97   /* Should raise a critical, but doesn't with has-loop not working
98      s = "fakesrc has-loop=false ! fakesink has-loop=false";
99      ASSERT_CRITICAL (run_pipeline (setup_pipeline (s), s,
100      GST_MESSAGE_STATE_CHANGED, GST_MESSAGE_UNKNOWN)); */
101 }
102 END_TEST static void
103 got_handoff (GstElement * sink, GstBuffer * buf, GstPad * pad, gpointer unused)
104 {
105   gst_element_post_message
106       (sink, gst_message_new_application (gst_structure_new ("foo", NULL)));
107 }
108
109 static void
110 assert_live_count (GType type, gint live)
111 {
112   GstAllocTrace *trace;
113   const gchar *name;
114
115   if (gst_alloc_trace_available ()) {
116     name = g_type_name (type);
117     g_assert (name);
118     trace = gst_alloc_trace_get (name);
119     if (trace) {
120       g_return_if_fail (trace->live == live);
121     }
122   } else {
123     g_print ("\nSkipping live count tests; recompile with traces to enable\n");
124   }
125 }
126
127 START_TEST (test_stop_from_app)
128 {
129   GstElement *fakesrc, *fakesink, *pipeline;
130   GstBus *bus;
131   GstMessageType revent;
132
133   assert_live_count (GST_TYPE_BUFFER, 0);
134
135   fakesrc = gst_element_factory_make ("fakesrc", NULL);
136   fakesink = gst_element_factory_make ("fakesink", NULL);
137   pipeline = gst_element_factory_make ("pipeline", NULL);
138
139   g_return_if_fail (fakesrc && fakesink && pipeline);
140
141   gst_element_link (fakesrc, fakesink);
142   gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
143
144   g_object_set (fakesink, "signal-handoffs", (gboolean) TRUE, NULL);
145   g_signal_connect (fakesink, "handoff", G_CALLBACK (got_handoff), NULL);
146
147   gst_element_set_state (pipeline, GST_STATE_PLAYING);
148
149   bus = gst_element_get_bus (pipeline);
150   g_assert (bus);
151
152   /* will time out after half a second */
153   revent = gst_bus_poll (bus, GST_MESSAGE_APPLICATION, GST_SECOND / 2);
154
155   g_return_if_fail (revent == GST_MESSAGE_APPLICATION);
156   gst_message_unref (gst_bus_pop (bus));
157
158   gst_element_set_state (pipeline, GST_STATE_NULL);
159   gst_object_unref (GST_OBJECT (pipeline));
160
161   assert_live_count (GST_TYPE_BUFFER, 0);
162 }
163 END_TEST Suite * simple_launch_lines_suite (void)
164 {
165   Suite *s = suite_create ("Pipelines");
166   TCase *tc_chain = tcase_create ("linear");
167
168   /* time out after 20s, not the default 3 */
169   tcase_set_timeout (tc_chain, 20);
170
171   suite_add_tcase (s, tc_chain);
172   tcase_add_test (tc_chain, test_2_elements);
173   tcase_add_test (tc_chain, test_stop_from_app);
174   return s;
175 }
176
177 int
178 main (int argc, char **argv)
179 {
180   int nf;
181
182   Suite *s = simple_launch_lines_suite ();
183   SRunner *sr = srunner_create (s);
184
185   gst_check_init (&argc, &argv);
186
187   srunner_run_all (sr, CK_NORMAL);
188   nf = srunner_ntests_failed (sr);
189   srunner_free (sr);
190
191   return nf;
192 }