validate: Fix testsuite
authorThibault Saunier <tsaunier@gnome.org>
Thu, 21 Jan 2016 10:13:55 +0000 (11:13 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Thu, 21 Jan 2016 10:21:01 +0000 (11:21 +0100)
Use fake elements instead of real ones in our tests so that
we control exactly the number of issues generated.

Until now we were trying to hide extra issues with a probe dropping
events and buffers but since 2dfa548f3645844082c3db65d96d87255701b3ad
"pad: Append hooks instead of prepending to call them in the order they were added"
in core, hidding will not work.

validate/tests/check/validate/padmonitor.c
validate/tests/check/validate/reporting.c
validate/tests/check/validate/test-utils.c
validate/tests/check/validate/test-utils.h

index 675a10d..19f12fb 100644 (file)
@@ -367,78 +367,51 @@ GST_START_TEST (flow_aggregation)
 
 GST_END_TEST;
 
-static GstPadProbeReturn
-drop_buffers (GstPad * pad, GstPadProbeInfo * info, gpointer unused)
-{
-  return GST_PAD_PROBE_DROP;
-}
-
 GST_START_TEST (issue_concatenation)
 {
-  GstPad *srcpad1, *srcpad2, *sinkpad, *funnel_sink1, *funnel_sink2;
-  GstElement *src1, *src2, *sink, *funnel;
+  GstPad *srcpad1, *srcpad2, *sinkpad, *fakemixer_sink1, *fakemixer_sink2;
+  GstElement *src1, *src2, *sink, *fakemixer;
   GstValidateRunner *runner;
   GstValidatePadMonitor *srcpad_monitor1, *srcpad_monitor2, *sinkpad_monitor;
-  GstValidatePadMonitor *funnel_sink_monitor1, *funnel_sink_monitor2;
-  GstSegment segment;
+  GstValidatePadMonitor *fakemixer_sink_monitor1, *fakemixer_sink_monitor2;
   GList *reports;
   gint n_reports;
-  gulong probe_id1, probe_id2;
 
   fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "subchain", TRUE));
   runner = gst_validate_runner_new ();
 
-  src1 = create_and_monitor_element ("fakesrc", "fakesrc1", runner);
-  src2 = create_and_monitor_element ("fakesrc", "fakesrc2", runner);
-  funnel = create_and_monitor_element ("funnel", "funnel", runner);
+  src1 = create_and_monitor_element ("fakesrc2", NULL, runner);
+  src2 = create_and_monitor_element ("fakesrc2", NULL, runner);
+  fakemixer = create_and_monitor_element ("fakemixer", "fakemixer", runner);
   sink = create_and_monitor_element ("fakesink", "fakesink", runner);
 
   srcpad1 = gst_element_get_static_pad (src1, "src");
   srcpad_monitor1 = g_object_get_data (G_OBJECT (srcpad1), "validate-monitor");
   srcpad2 = gst_element_get_static_pad (src2, "src");
   srcpad_monitor2 = g_object_get_data (G_OBJECT (srcpad2), "validate-monitor");
-  funnel_sink1 = gst_element_get_request_pad (funnel, "sink_%u");
-  funnel_sink_monitor1 =
-      g_object_get_data (G_OBJECT (funnel_sink1), "validate-monitor");
-  funnel_sink2 = gst_element_get_request_pad (funnel, "sink_%u");
-  funnel_sink_monitor2 =
-      g_object_get_data (G_OBJECT (funnel_sink2), "validate-monitor");
+  fakemixer_sink1 = gst_element_get_request_pad (fakemixer, "sink_%u");
+  fakemixer_sink_monitor1 =
+      g_object_get_data (G_OBJECT (fakemixer_sink1), "validate-monitor");
+  fakemixer_sink2 = gst_element_get_request_pad (fakemixer, "sink_%u");
+  fakemixer_sink_monitor2 =
+      g_object_get_data (G_OBJECT (fakemixer_sink2), "validate-monitor");
   sinkpad = gst_element_get_static_pad (sink, "sink");
   sinkpad_monitor = g_object_get_data (G_OBJECT (sinkpad), "validate-monitor");
 
-  fail_unless (gst_element_link (funnel, sink));
-  fail_unless (gst_pad_link (srcpad1, funnel_sink1) == GST_PAD_LINK_OK);
-  fail_unless (gst_pad_link (srcpad2, funnel_sink2) == GST_PAD_LINK_OK);
-
-  /* There's gonna be some clunkiness in here because of funnel */
-  probe_id1 = gst_pad_add_probe (srcpad1,
-      GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST |
-      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, (GstPadProbeCallback) drop_buffers,
-      NULL, NULL);
-  probe_id2 =
-      gst_pad_add_probe (srcpad2,
-      GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST |
-      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, (GstPadProbeCallback) drop_buffers,
-      NULL, NULL);
+  fail_unless (gst_element_link (fakemixer, sink));
+  fail_unless (gst_pad_link (srcpad1, fakemixer_sink1) == GST_PAD_LINK_OK);
+  fail_unless (gst_pad_link (srcpad2, fakemixer_sink2) == GST_PAD_LINK_OK);
 
   /* We want to handle the src behaviour ourselves */
   fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, TRUE));
   fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, TRUE));
 
-  /* Setup all needed events */
-  gst_segment_init (&segment, GST_FORMAT_TIME);
-  segment.start = 0;
-  segment.stop = GST_SECOND;
-
-  fail_unless (gst_pad_push_event (srcpad1,
-          gst_event_new_stream_start ("the-stream")));
-  fail_unless (gst_pad_push_event (srcpad1, gst_event_new_segment (&segment)));
-
-  fail_unless (gst_pad_push_event (srcpad2,
-          gst_event_new_stream_start ("the-stream")));
-  fail_unless (gst_pad_push_event (srcpad2, gst_event_new_segment (&segment)));
+  gst_check_setup_events_with_stream_id (srcpad1, fakemixer, NULL,
+      GST_FORMAT_TIME, "stream1");
+  gst_check_setup_events_with_stream_id (srcpad2, fakemixer, NULL,
+      GST_FORMAT_TIME, "stream2");
 
-  fail_unless_equals_int (gst_element_set_state (funnel, GST_STATE_PLAYING),
+  fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_PLAYING),
       GST_STATE_CHANGE_SUCCESS);
   fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_PLAYING),
       GST_STATE_CHANGE_ASYNC);
@@ -461,18 +434,18 @@ GST_START_TEST (issue_concatenation)
       sinkpad_monitor);
   fail_unless_equals_int (n_reports, 1);
   n_reports = gst_validate_reporter_get_reports_count ((GstValidateReporter *)
-      funnel_sink_monitor1);
+      fakemixer_sink_monitor1);
   fail_unless_equals_int (n_reports, 1);
 
-  /* But not the pad monitor of the other funnel sink */
+  /* But not the pad monitor of the other fakemixer sink */
   n_reports = gst_validate_reporter_get_reports_count ((GstValidateReporter *)
-      funnel_sink_monitor2);
+      fakemixer_sink_monitor2);
   fail_unless_equals_int (n_reports, 0);
   n_reports = gst_validate_reporter_get_reports_count ((GstValidateReporter *)
       srcpad_monitor2);
   fail_unless_equals_int (n_reports, 0);
 
-  /* Once again but on the other funnel sink */
+  /* Once again but on the other fakemixer sink */
   fail_unless (gst_pad_push_event (srcpad2, gst_event_new_flush_stop (TRUE)));
 
   /* The runner now sees two reports */
@@ -488,11 +461,11 @@ GST_START_TEST (issue_concatenation)
       sinkpad_monitor);
   fail_unless_equals_int (n_reports, 1);
   n_reports = gst_validate_reporter_get_reports_count ((GstValidateReporter *)
-      funnel_sink_monitor1);
+      fakemixer_sink_monitor1);
   fail_unless_equals_int (n_reports, 1);
 
   n_reports = gst_validate_reporter_get_reports_count ((GstValidateReporter *)
-      funnel_sink_monitor2);
+      fakemixer_sink_monitor2);
   fail_unless_equals_int (n_reports, 1);
   n_reports = gst_validate_reporter_get_reports_count ((GstValidateReporter *)
       srcpad_monitor2);
@@ -501,28 +474,25 @@ GST_START_TEST (issue_concatenation)
   /* clean up */
   fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, FALSE));
   fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, FALSE));
-  fail_unless_equals_int (gst_element_set_state (funnel, GST_STATE_NULL),
+  fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_NULL),
       GST_STATE_CHANGE_SUCCESS);
   fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_NULL),
       GST_STATE_CHANGE_SUCCESS);
 
-  gst_pad_remove_probe (srcpad1, probe_id1);
-  gst_pad_remove_probe (srcpad2, probe_id2);
-
   /* The reporter, the runner */
   _check_reports_refcount (srcpad1, 2);
   /* The reporter, the master report */
-  _check_reports_refcount (funnel_sink1, 2);
+  _check_reports_refcount (fakemixer_sink1, 2);
   free_element_monitor (src1);
   free_element_monitor (src2);
-  free_element_monitor (funnel);
+  free_element_monitor (fakemixer);
   free_element_monitor (sink);
   gst_object_unref (srcpad1);
   gst_object_unref (srcpad2);
   gst_object_unref (sinkpad);
-  gst_object_unref (funnel_sink1);
-  gst_object_unref (funnel_sink2);
-  check_destroyed (funnel, funnel_sink1, funnel_sink2, NULL);
+  gst_object_unref (fakemixer_sink1);
+  gst_object_unref (fakemixer_sink2);
+  check_destroyed (fakemixer, fakemixer_sink1, fakemixer_sink2, NULL);
   check_destroyed (src1, srcpad1, NULL);
   check_destroyed (src2, srcpad2, NULL);
   check_destroyed (sink, sinkpad, NULL);
@@ -1077,6 +1047,7 @@ gst_validate_suite (void)
   suite_add_tcase (s, tc_chain);
 
   gst_validate_init ();
+  fake_elements_register ();
 
   tcase_add_test (tc_chain, buffer_before_segment);
   tcase_add_test (tc_chain, buffer_outside_segment);
index 7246b5f..ca7a92b 100644 (file)
@@ -120,43 +120,28 @@ GST_START_TEST (test_report_levels)
 
 GST_END_TEST;
 
-static GstPadProbeReturn
-drop_buffers (GstPad * pad, GstPadProbeInfo * info, gpointer unused)
-{
-  return GST_PAD_PROBE_DROP;
-}
-
 static void
 _create_issues (GstValidateRunner * runner)
 {
   GstPad *srcpad1, *srcpad2, *sinkpad, *funnel_sink1, *funnel_sink2;
-  GstElement *src1, *src2, *sink, *funnel;
+  GstElement *src1, *src2, *sink, *fakemixer;
   GstSegment segment;
-  gulong probe_id1, probe_id2;
 
-  src1 = create_and_monitor_element ("fakesrc", "fakesrc1", runner);
-  src2 = create_and_monitor_element ("fakesrc", "fakesrc2", runner);
-  funnel = create_and_monitor_element ("funnel", "funnel", runner);
+  src1 = create_and_monitor_element ("fakesrc2", "fakesrc1", runner);
+  src2 = create_and_monitor_element ("fakesrc2", "fakesrc2", runner);
+  fakemixer = create_and_monitor_element ("fakemixer", "fakemixer", runner);
   sink = create_and_monitor_element ("fakesink", "fakesink", runner);
 
   srcpad1 = gst_element_get_static_pad (src1, "src");
   srcpad2 = gst_element_get_static_pad (src2, "src");
-  funnel_sink1 = gst_element_get_request_pad (funnel, "sink_%u");
-  funnel_sink2 = gst_element_get_request_pad (funnel, "sink_%u");
+  funnel_sink1 = gst_element_get_request_pad (fakemixer, "sink_%u");
+  funnel_sink2 = gst_element_get_request_pad (fakemixer, "sink_%u");
   sinkpad = gst_element_get_static_pad (sink, "sink");
 
-  fail_unless (gst_element_link (funnel, sink));
+  fail_unless (gst_element_link (fakemixer, sink));
   fail_unless (gst_pad_link (srcpad1, funnel_sink1) == GST_PAD_LINK_OK);
   fail_unless (gst_pad_link (srcpad2, funnel_sink2) == GST_PAD_LINK_OK);
 
-  /* There's gonna be some clunkiness in here because of funnel */
-  probe_id1 = gst_pad_add_probe (srcpad1,
-      GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-      (GstPadProbeCallback) drop_buffers, NULL, NULL);
-  probe_id2 = gst_pad_add_probe (srcpad2,
-      GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-      (GstPadProbeCallback) drop_buffers, NULL, NULL);
-
   /* We want to handle the src behaviour ourselves */
   fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, TRUE));
   fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, TRUE));
@@ -174,7 +159,7 @@ _create_issues (GstValidateRunner * runner)
           gst_event_new_stream_start ("the-stream")));
   fail_unless (gst_pad_push_event (srcpad2, gst_event_new_segment (&segment)));
 
-  fail_unless_equals_int (gst_element_set_state (funnel, GST_STATE_PLAYING),
+  fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_PLAYING),
       GST_STATE_CHANGE_SUCCESS);
   fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_PLAYING),
       GST_STATE_CHANGE_ASYNC);
@@ -183,26 +168,23 @@ _create_issues (GstValidateRunner * runner)
   _gst_check_expecting_log = TRUE;
   fail_unless (gst_pad_push_event (srcpad1, gst_event_new_flush_stop (TRUE)));
 
-  /* Once again but on the other funnel sink */
+  /* Once again but on the other fakemixer sink */
   fail_unless (gst_pad_push_event (srcpad2, gst_event_new_flush_stop (TRUE)));
 
   /* clean up */
   fail_unless (gst_pad_activate_mode (srcpad1, GST_PAD_MODE_PUSH, FALSE));
   fail_unless (gst_pad_activate_mode (srcpad2, GST_PAD_MODE_PUSH, FALSE));
-  fail_unless_equals_int (gst_element_set_state (funnel, GST_STATE_NULL),
+  fail_unless_equals_int (gst_element_set_state (fakemixer, GST_STATE_NULL),
       GST_STATE_CHANGE_SUCCESS);
   fail_unless_equals_int (gst_element_set_state (sink, GST_STATE_NULL),
       GST_STATE_CHANGE_SUCCESS);
 
-  gst_pad_remove_probe (srcpad1, probe_id1);
-  gst_pad_remove_probe (srcpad2, probe_id2);
-
   gst_object_unref (srcpad1);
   gst_object_unref (srcpad2);
   gst_object_unref (sinkpad);
   gst_object_unref (funnel_sink1);
   gst_object_unref (funnel_sink2);
-  check_destroyed (funnel, funnel_sink1, funnel_sink2, NULL);
+  check_destroyed (fakemixer, funnel_sink1, funnel_sink2, NULL);
   check_destroyed (src1, srcpad1, NULL);
   check_destroyed (src2, srcpad2, NULL);
   check_destroyed (sink, sinkpad, NULL);
@@ -236,7 +218,7 @@ GST_START_TEST (test_global_levels)
   fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "all", TRUE));
   runner = gst_validate_runner_new ();
   _create_issues (runner);
-  /* One report for each pad monitor, plus one for funnel src and fakesink sink */
+  /* One report for each pad monitor, plus one for fakemixer src and fakesink sink */
   fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 8);
   g_object_unref (runner);
 }
@@ -247,8 +229,8 @@ GST_START_TEST (test_specific_levels)
 {
   GstValidateRunner *runner;
 
-  fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "none,fakesrc1:synthetic",
-          TRUE));
+  fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS",
+          "none,fakesrc1:synthetic", TRUE));
   runner = gst_validate_runner_new ();
   _create_issues (runner);
   /* One issue should go through the none filter */
@@ -264,8 +246,8 @@ GST_START_TEST (test_specific_levels)
   fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 5);
   g_object_unref (runner);
 
-  fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS", "subchain,sink:monitor",
-          TRUE));
+  fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS",
+          "subchain,sink:monitor", TRUE));
   runner = gst_validate_runner_new ();
   _create_issues (runner);
   /* 3 issues because both fake sources will have subsequent subchains of
@@ -274,12 +256,12 @@ GST_START_TEST (test_specific_levels)
   g_object_unref (runner);
 
   fail_unless (g_setenv ("GST_VALIDATE_REPORTING_DETAILS",
-          "synthetic,fakesrc1:subchain,fakesrc2:subchain,funnel*::src*:monitor",
+          "synthetic,fakesrc1:subchain,fakesrc2:subchain,fakemixer*::src*:monitor",
           TRUE));
   runner = gst_validate_runner_new ();
   _create_issues (runner);
-  /* 4 issues because the funnel sink issues will be concatenated with the
-   * fakesrc issues, the funnel src will report its issue separately, and the
+  /* 4 issues because the fakemixer sink issues will be concatenated with the
+   * fakesrc issues, the fakemixer src will report its issue separately, and the
    * sink will not find a report immediately upstream */
   fail_unless_equals_int (gst_validate_runner_get_reports_count (runner), 4);
   g_object_unref (runner);
@@ -303,6 +285,7 @@ gst_validate_suite (void)
   suite_add_tcase (s, tc_chain);
 
   gst_validate_init ();
+  fake_elements_register ();
 
   tcase_add_test (tc_chain, test_report_levels);
   tcase_add_test (tc_chain, test_global_levels);
index 5159fdb..b50a02a 100644 (file)
@@ -212,6 +212,9 @@ free_element_monitor (GstElement * element)
   g_object_unref (G_OBJECT (monitor));
 }
 
+/******************************************
+ *          Fake decoder                  *
+ ******************************************/
 static GstStaticPadTemplate fake_decoder_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -299,3 +302,226 @@ fake_decoder_new (void)
 {
   return GST_ELEMENT (g_object_new (FAKE_DECODER_TYPE, NULL));
 }
+
+/******************************************
+ *          Fake mixer                    *
+ ******************************************/
+static GstElementClass *fake_mixer_parent_class = NULL;
+
+static GstStaticPadTemplate fake_mixer_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS ("something")
+    );
+
+static GstStaticPadTemplate fake_mixer_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink_%u",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS ("something")
+    );
+
+static gboolean
+_mixer_event (GstPad * pad, GstObject * obj, GstEvent * event)
+{
+  FakeMixer *self = FAKE_MIXER (obj);
+
+  switch (event->type) {
+    case GST_EVENT_STREAM_START:
+      if (g_atomic_int_compare_and_exchange (&self->sent_stream_start, FALSE,
+              TRUE)) {
+        return gst_pad_event_default (pad, obj, event);
+      } else {
+        gst_event_unref (event);
+        return TRUE;
+      }
+    case GST_EVENT_SEGMENT:
+      if (g_atomic_int_compare_and_exchange (&self->sent_segment, FALSE, TRUE)) {
+        return gst_pad_event_default (pad, obj, event);
+      } else {
+        gst_event_unref (event);
+        return TRUE;
+      }
+    default:
+      return gst_pad_event_default (pad, obj, event);
+  }
+}
+
+static GstFlowReturn
+_mixer_chain (GstPad * pad, GstObject * self, GstBuffer * buffer)
+{
+  gst_buffer_unref (buffer);
+
+  return FAKE_MIXER (self)->return_value;
+}
+
+static GstPad *
+_request_new_pad (GstElement * element,
+    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
+{
+  GstPad *pad;
+  GstPadTemplate *pad_template;
+
+  pad_template =
+      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
+          (element)), "sink_%u");
+  pad = gst_pad_new_from_template (pad_template, req_name);
+
+  gst_pad_set_chain_function (pad, _mixer_chain);
+  gst_pad_set_event_function (pad, _mixer_event);
+
+  gst_element_add_pad (element, pad);
+
+  return pad;
+}
+
+static void
+fake_mixer_init (FakeMixer * self, FakeMixerClass * g_class)
+{
+  GstPad *pad;
+  GstElement *element = GST_ELEMENT (self);
+  GstPadTemplate *pad_template;
+
+  pad_template =
+      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
+  pad = gst_pad_new_from_template (pad_template, "src");
+  gst_element_add_pad (element, pad);
+
+  pad_template =
+      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
+
+  self->return_value = GST_FLOW_OK;
+}
+
+static void
+fake_mixer_class_init (FakeMixerClass * self_class)
+{
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
+
+  fake_mixer_parent_class = g_type_class_peek_parent (self_class);
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&fake_mixer_src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&fake_mixer_sink_template));
+  gst_element_class_set_static_metadata (gstelement_class,
+      "Fake mixer", "Mixer", "Some mixer", "Thibault Saunier");
+
+  gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (_request_new_pad);
+}
+
+GType
+fake_mixer_get_type (void)
+{
+  static volatile gsize type = 0;
+
+  if (g_once_init_enter (&type)) {
+    GType _type;
+    static const GTypeInfo info = {
+      sizeof (FakeMixerClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) fake_mixer_class_init,
+      NULL,
+      NULL,
+      sizeof (FakeMixer),
+      0,
+      (GInstanceInitFunc) fake_mixer_init,
+    };
+
+    _type = g_type_register_static (GST_TYPE_ELEMENT, "FakeMixer", &info, 0);
+    g_once_init_leave (&type, _type);
+  }
+  return type;
+}
+
+GstElement *
+fake_mixer_new (void)
+{
+  return GST_ELEMENT (g_object_new (FAKE_MIXER_TYPE, NULL));
+}
+
+/******************************************
+ *              Fake Source               *
+ *******************************************/
+static GstElementClass *fake_src_parent_class = NULL;
+
+static GstStaticPadTemplate fake_src_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS ("something")
+    );
+
+static void
+fake_src_init (FakeSrc * self, FakeSrcClass * g_class)
+{
+  GstPad *pad;
+  GstElement *element = GST_ELEMENT (self);
+  GstPadTemplate *pad_template;
+
+  pad_template =
+      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
+  pad = gst_pad_new_from_template (pad_template, "src");
+  gst_element_add_pad (element, pad);
+
+  pad_template =
+      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
+
+  self->return_value = GST_FLOW_OK;
+}
+
+static void
+fake_src_class_init (FakeSrcClass * self_class)
+{
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (self_class);
+
+  fake_src_parent_class = g_type_class_peek_parent (self_class);
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&fake_src_src_template));
+  gst_element_class_set_static_metadata (gstelement_class,
+      "Fake src", "Source", "Some src", "Thibault Saunier");
+}
+
+GType
+fake_src_get_type (void)
+{
+  static volatile gsize type = 0;
+
+  if (g_once_init_enter (&type)) {
+    GType _type;
+    static const GTypeInfo info = {
+      sizeof (FakeSrcClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) fake_src_class_init,
+      NULL,
+      NULL,
+      sizeof (FakeSrc),
+      0,
+      (GInstanceInitFunc) fake_src_init,
+    };
+
+    _type = g_type_register_static (GST_TYPE_ELEMENT, "FakeSrc", &info, 0);
+    g_once_init_leave (&type, _type);
+  }
+  return type;
+}
+
+GstElement *
+fake_src_new (void)
+{
+  return GST_ELEMENT (g_object_new (FAKE_SRC_TYPE, NULL));
+}
+
+
+void
+fake_elements_register (void)
+{
+  gst_element_register (NULL, "fakemixer", 0, FAKE_MIXER_TYPE);
+  gst_element_register (NULL, "fakedecoder", 0, FAKE_DECODER_TYPE);
+  gst_element_register (NULL, "fakedemuxer", 0, FAKE_DEMUXER_TYPE);
+  gst_element_register (NULL, "fakesrc2", 0, FAKE_SRC_TYPE);
+}
index 1854048..11ae5b9 100644 (file)
@@ -74,6 +74,53 @@ typedef struct {
 GType fake_decoder_get_type  (void);
 GstElement * fake_decoder_new (void);
 
+typedef struct {
+  GstElement parent;
+
+  GstFlowReturn return_value;
+
+  /* <private> */
+  gboolean sent_stream_start;
+  gboolean sent_segment;
+} FakeMixer;
+
+typedef struct {
+  GstElementClass parent;
+} FakeMixerClass;
+
+#define FAKE_MIXER_TYPE (fake_mixer_get_type ())
+#define FAKE_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_MIXER_TYPE, FakeMixer))
+#define FAKE_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_MIXER_TYPE, FakeMixerClass))
+#define IS_FAKE_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_MIXER_TYPE))
+#define IS_FAKE_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_MIXER_TYPE))
+#define FAKE_MIXER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_MIXER_TYPE, FakeMixerClass))
+
+GType fake_mixer_get_type  (void);
+GstElement * fake_mixer_new (void);
+
+typedef struct {
+  GstElement parent;
+
+  GstFlowReturn return_value;
+
+} FakeSrc;
+
+typedef struct {
+  GstElementClass parent;
+} FakeSrcClass;
+
+#define FAKE_SRC_TYPE (fake_src_get_type ())
+#define FAKE_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FAKE_SRC_TYPE, FakeSrc))
+#define FAKE_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FAKE_SRC_TYPE, FakeSrcClass))
+#define IS_FAKE_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FAKE_SRC_TYPE))
+#define IS_FAKE_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FAKE_SRC_TYPE))
+#define FAKE_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FAKE_SRC_TYPE, FakeSrcClass))
+
+GType fake_src_get_type  (void);
+GstElement * fake_src_new (void);
+
+void fake_elements_register (void);
+
 G_END_DECLS
 
 #endif /* _GST_VALIDATE_TEST_UTILS */